Android physical devices through the host's default adb server
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 18/100
- Issue type
- Feature
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- android, typescript
- Domain
- mobile
Research direction
Start with src/drivers/android/index.ts to see how AndroidDriver routes calls, then adb-server.ts for the existing probe and timeout pattern the spec reuses. The two new files are default-adb-server.ts (protocol gate) and physical-handler.ts; the spec names their functions and the reason codes. Done means each row of the input table gives the stated result against the fake driver, and a blocked protocol runs no adb command.
Written by the indexing model from the issue text.
Description
Part of #428.
Scope
After this PR, an operator can enroll a real Android phone, and agents can lease it, through the Android driver. The driver reaches phones through the host's default adb server (port 5037), always with -s <serial>. It inspects a phone for device add, reads which enrolled phones are present, reclaims a released phone by uninstalling user apps, and runs adb for device.exec on a leased phone. (The lease environment, ANDROID_SERIAL and ANDROID_ADB_SERVER_PORT=5037, is #438's.) Before every physical call it reads the default server's adb protocol version and sends nothing when that differs from Simlock's adb. doctor then names both versions. Tasks 1a–3 built the core side against the fake driver; this task is the real Android side of ADR 0022 §5–§8. The phone lane gets its Android test.
In short
Today, after tasks 1a–4, device add --platform android cannot enroll anything: the Android driver has no physical handler. After this PR, a phone plugged in by USB with USB debugging authorized can be enrolled, leased and reclaimed. Simlock never stops the host's adb server and never restarts one that speaks another protocol version.
New terms:
- default adb server: the adb server on port 5037 that plain
adband Android Studio use, e.g. the oneadb devicestalks to on a Mac. Simlock's own server (port 5038, USB off) stays for emulators only. - USB transport: a line of
adb devices -lthat carries ausb:field, e.g.R58M123ABC device usb:1-1 product:o1s model:SM_G991B transport_id:3. A line without it (192.168.1.5:5555 device …) is a network transport. The transport decides; the serial's shape never does. - adb protocol version: the number an adb client and server must share, or the client kills the server and starts its own.
adb versionprints it last (Android Debug Bridge version 1.0.41is 41). The server answers it tohost:versionover its socket, which restarts nothing. - physical handler: the part of the Android driver that serves physical devices. The driver routes each call to it when the device is
physical: true.
flowchart LR
A["device add / grant / watcher / release / device.exec"] --> D["AndroidDriver"]
D -->|"physical: false"| E["emulator side<br/>Simlock's server, unchanged"]
D -->|"physical: true"| P["physical handler (new)"]
P --> V{"host:version on 5037<br/>same protocol? (new)"}
V -->|yes| C["adb -P 5037 -s <serial> …"]
V -->|"no / unreadable"| N["no command: not present, refused;<br/>doctor names both versions"]
# before (tasks 1a-4 landed)
$ simlock device add --platform android R58M123ABC
Refused: this driver cannot read physical devices yet. (#437's placeholder, reason not-connected)
# after
$ simlock device add --platform android R58M123ABC
Enrolled SM-G991B (API 34), 12 user apps recorded.
$ simlock doctor # Android Studio's older adb runs the default server
driver-advisory android adb-protocol-mismatch: the adb server on port 5037 speaks protocol 40 and Simlock's adb speaks 41. …
| Input | Before (after task 4) | After |
|---|---|---|
device add --platform android R58M123ABC, phone on USB, USB debugging authorized |
refused | enrolled under R58M123ABC: ro.product.model, API level, user apps of the current user |
same, USB debugging not authorized (unauthorized) |
refused | refused: USB debugging not authorized (untrusted) |
device add --platform android 192.168.1.5:5555 (network transport only) |
refused | refused: only USB-connected devices can be enrolled (network-only) |
device add --platform android emulator-5554 (a developer's own emulator on the default server) |
refused | refused: only USB-connected devices can be enrolled (network-only) |
device add --platform android R58M123ABC, not listed, or listed offline |
refused | refused: not connected (not-connected) |
any device add --platform android … while the default server speaks another protocol |
refused | refused: not connected (not-connected), the message naming both protocol versions; no adb command runs |
lease --platform android --physical, the enrolled phone free and present |
no phone enrollable | granted; environment ANDROID_SERIAL=R58M123ABC, ANDROID_ADB_SERVER_PORT=5037 (#438) |
| an enrolled phone unauthorized, or unplugged, for the grace period | stays ready (no real presence read) |
absent (untrusted), absent (not-present) |
| an enrolled phone with its screen locked | — | present: adb shows no lock state, so it stays in rotation |
| release of that lease | — | each user app not on the enrollment list uninstalled for the current user; listed apps found missing reported |
device.exec adb shell getprop on that lease |
— | runs adb -P 5037 -s R58M123ABC shell getprop |
device.exec adb kill-server on that lease |
— | refused |
| the default server switches to another protocol while the phone is leased | — | no command sent; the phone reads not present, so the lease ends device-lost after the grace period (task 3) |
simlock adb devices, lease --platform android |
Simlock's server, emulators | unchanged |
If this goes wrong, an operator would see an authorized phone refused, apps left on a released phone, Android Studio's adb server restarted, emulator leases stalling while a phone hangs, or a command run on a phone nobody enrolled.
Technical spec
Modules touched
flowchart LR
CORE["core callers: enrollment, grant, reclaim,<br/>watcher, device.exec (tasks 1b-4)"] --> AD["drivers/android/index.ts<br/>AndroidDriver *"]
DOC["core/doctor: advisories"] --> AD
AD --> EM["emulator side: AdbServerSupervisor,<br/>AdbRegistrar (unchanged)"]
AD --> PH["drivers/android/physical-handler.ts (new)"]
PH --> PG["drivers/android/default-adb-server.ts (new)<br/>protocol gate"]
PH --> PR["ports: ProcessRunner"]
PG --> TCP["ports: TcpProbe"]
PG --> PR
EM --> PR
EM --> TCP
One device add through the hops, with the failure reply:
sequenceDiagram
participant C as CLI
participant D as Daemon (enrollment, task 1b)
participant P as Android physical handler
participant S as Default adb server :5037
participant R as Phone on USB
C->>D: device add --platform android R58M123ABC
D->>P: inspectPhysical("R58M123ABC")
P->>S: host:version (socket)
S-->>P: OKAY 0004 0029 (protocol 41)
alt same protocol as Simlock's adb
P->>S: adb -P 5037 devices -l
S-->>P: R58M123ABC device usb:1-1 …
P->>R: -s R58M123ABC: getprop, am get-current-user, pm list packages -3
R-->>P: model, API level, user id, apps
P-->>D: inspection
D-->>C: Enrolled SM-G991B (API 34), 12 user apps recorded
else other protocol, unreadable reply, or no USB transport in state device
P-->>D: refusal with its reason; no command named the serial
D-->>C: Refused: <reason>
end
src/drivers/android/default-adb-server.ts(new): the protocol gate. It is the one place that decides whether a physical command may run (architecture rule 10).- Simlock's protocol: the last number of
adb version's first line (1.0.41→ 41). Read with Simlock'sadb, 30 s limit. Cached for the driver's life once read; a failed read is not cached. - The server's protocol:
TcpProbe.isListening(5037), thenTcpProbe.send(5037, "000chost:version")with a 5 s limit (theIDENTITY_TIMEOUT_MSprecedent inadb-server.ts:16). A replyOKAY+0004+ four hex digits is the version. Anything else is unreadable. - Verdict:
openwhen nothing listens on 5037 (Simlock'sadbthen starts a server of its own version, as anyadbdoes) or both numbers match.blockedwhen they differ or either is unreadable. Fail closed (safety rule 9). - Every physical call reads the verdict anew, so a fixed server is used again on the next call, with no restart. The latest verdict is kept for the synchronous
passthrough, which uses the most recent check. - Never sends
kill, never runskill-serverorstart-server, never signals a process.
- Simlock's protocol: the last number of
src/drivers/android/physical-handler.ts(new): every physical call. Each runsadb -P 5037, with the injected base environment plusANDROID_ADB_SERVER_PORT=5037, and withoutANDROID_SERIALorADB_SERVER_SOCKETfrom that base. It never usesAndroidDriver#env(index.ts:713), which points at Simlock's server. Limits: 30 s per read, 60 s per uninstall (ADR 0022 §5; architecture rule 11). A read past its limit, or with no exit code, is a failed read. Physical calls take no per-device lock and no port allocation, so they never wait behind, or block, an emulator call.inspectPhysical(id): gate; oneadb devices -l. The line whose serial equalsiddecides:- USB transport in state
device: inspected. Canonical ID is that serial. Then, with-s <serial>:shell getprop ro.product.model(model),shell getprop ro.build.version.sdk(OS version, the API level),shell am get-current-user(user id),shell pm list packages -3 --user <id>(enrollment app list). Class is alwaysphone(ADR 0022 §6: every Android device isphone). - USB transport in state
unauthorized: refuseduntrusted, USB debugging not authorized. - Only network transports, or an emulator line (
emulator-5554 device …, nousb:field): refusednetwork-only, "only USB-connected devices can be enrolled". - Not listed, another state (
offline,no permissions, …), or a failedadb devices -l: refusednot-connected. - Gate
blocked: refusednot-connected, with a message naming both protocol versions (or "unreadable" for one it could not read). Noadbcommand runs. - A failed read after the device was found (getprop, user id, package list):
inspectPhysicalrejects with the read's error; task 1b's path for a failed inspection answersINTERNALand writes nothing. - The reason codes are #437's
DEVICE_NOT_ENROLLABLEreasons. - No command names the serial until its line is a USB transport in state
device.
- USB transport in state
listPresentPhysical(enrolledIds): gate; oneadb devices -l. One entry per given serial, none for any other (safety rule 8 as amended): a serial that is not enrolled gets no entry and no command. Present: on a USB transport in statedevice, with its OS version fromgetprop ro.build.version.sdkon that serial (#439'sosVersion). Not presentuntrusted: stateunauthorized. Not presentnot-present: missing,offline, another state, or only on a network transport. A locked phone is present: adb shows no lock state (ADR 0022 §7). A failed or timed-out listing, a failedgetpropon a serial, or ablockedgate answers the serials concerned not presentnot-presentand does not reject (ADR 0022 §5: a read past its limit is "not present").reclaimof a physical device: gate (blockedrejects, no command); read the user id and the user'spm list packages -3; for each package not onenrolledApps,shell pm uninstall --user <id> <package>, one at a time, stopping at the first failure; then list again. The packages come from #438'suninstallPlan. Result: strategyuninstall,missingApps= enrolled packages not on the first list. It rejects when an uninstall exits non-zero, prints anything butSuccess, or passes 60 s; or when the second list still holds a package off the enrollment list. The core then reads presence and picksabsentorquarantined(task 3).- Package lines are a claim (safety rule 10): a line must be
package:followed by letters, digits,_and.only. Any other line fails the read, so no unchecked text reachesadb shell. passthrough("adb", <physical device>, args, context)(the signature task 4 left, ADR 0022 §5):adb -P 5037 -s <serial> <args>, envANDROID_ADB_SERVER_PORT=5037. Refused withPassthroughRefusedError:- when the most recent gate verdict is
blocked, or no physical call has read one yet in this daemon ("try again"); - any caller argument before the subcommand (
-s,-t,-d,-e,-P,-H,-L,--one-device, any other): Simlock supplies the scope, so the command stays aimed at the leased phone; kill-server,start-server,connect,disconnect,pair,reconnect,tcpip,usb, anywhere in the arguments: each stops, restarts or moves a server or transport other holders share, or takes the phone off USB for the next holder;- bare
shellwith no terminal, as for emulators.
- when the most recent gate verdict is
estimate({operation: "reclaim"}, <physical spec>): 30 000 ms, both clean levels (one listing, a few uninstalls, one listing). Only doctor's stall rule reads it for an unclaimed reclaim (stallThresholdMs,core/doctor.ts:973).
src/drivers/android/index.ts:AndroidDriverroutes onphysicalto the handler forinspectPhysical,listPresentPhysical,reclaim,passthroughandestimate.leaseEnvironmentkeeps #438's physical answer. Every emulator path is unchanged.advisories()(new on this driver) runs the gate and returnsadb-protocol-mismatchwhen it isblockedwith a server present, whether or not any Android device is enrolled. The message names both protocol numbers, or "unreadable" for one it could not read, says no command goes to physical Android devices until they match, and says Simlock will not restart that server.dispose()is unchanged: it stops Simlock's own server and nothing on 5037.e2e/slow-android-physical.test.ts(new): the phone lane for Android, tagphysical(task 4), skipped unlessSIMLOCK_PHYSICAL_ANDROIDnames the phone's USB serial andSIMLOCK_PHYSICAL_ANDROID_APKnames an APK to install. The skip message names the missing variable. Each person step (unplug, plug back) is a prompt in the lane's log, and the lane waits up to 120 s for it.docs/internal/agent-rules/toolchain.md: in the slow-lane table task 4 extended, a row for the Android phone:command -v adbfinds it,adb devices -llists$SIMLOCK_PHYSICAL_ANDROIDon a USB transport in statedevice,SIMLOCK_PHYSICAL_ANDROID_APKnames an APK, and the command isscripts/slow-e2e.sh --physical e2e/slow-android-physical.test.ts.docs/CLI.md:- Prerequisites gain "Android physical devices": connected by USB, USB debugging authorized for this host. Simlock reaches them through the host's default adb server (port 5037), which it starts if none runs and never stops. Simlock cannot see an Android lock screen: a locked phone stays in rotation.
- The
doctorsection gains theadb-protocol-mismatchadvisory: what it means and that the fix is running that server with an adb of the same protocol.
docs/internal/KNOWN-PITFALLS.md: an entry. A default server of another protocol started between Simlock's version read and the command it guards is restarted by Simlock'sadbclient. adb offers no way to stop that. The window is one call long.
Contract and event changes
None. Searched src/contract/ and src/bus/index.ts: the driver methods, PresentPhysical with osVersion and its reasons, ReclaimResult.missingApps, strategy uninstall, absentReason and the events were added by tasks 1b–3. The driver-advisory doctor finding exists (core/doctor.ts:88); its code is the driver's own text. No protocol bump.
Other code on the same state
The state: the default adb server on 5037, the enrolled phones on it, and the gate's verdict. Line numbers are on main at bfeb5ca; tasks 1a–4 move them.
AdbServerSupervisor(src/drivers/android/adb-server.ts:104) owns Simlock's server. It refuses 5037 as its port (adb-server.ts:167), and starts its server withADB_USB=0(:43-49), so phones never appear there. The handler never uses Simlock's port. No overlap.- Every emulator call goes through
AndroidDriver#env(index.ts:713):listManaged(:1015) and#scanAdbSerials(:1067, matches onlyemulator-\d+),makeReady, emulatorreclaim(:932),passthroughwith no device (:650),leaseEnvironmentfor an emulator (:636). None reaches 5037; the handler reaches nothing else. Unchanged. #withDeviceLock(index.ts:2041) andPortAllocator(index.ts:2068) serialise emulator work. Physical calls take neither, so a hung phone call never delays an emulator call, and the reverse.AdbRegistrar(src/drivers/android/adb-registrar.ts:25) sendshost:emulatorto Simlock's port only. The gate sendshost:versionto 5037 only. Different servers.Doctor#collectAdvisories(src/core/doctor.ts:492) callsadvisories(); a rejecting call contributes nothing. Soadvisories()returns the mismatch as a finding and never rejects for it.- Core callers of the physical methods: enrollment (task 1b), grant presence check and reclaim (task 2), the physical-device watcher (task 3),
device.execrouting (src/core/driver-catalog.ts:74,src/daemon/dispatcher.ts:539, as task 4 left them). The core's operation claim orders enrollment, reclaim and quarantine retries; the driver keeps no per-device state. The watcher's presence read can run while a reclaim uninstalls. Both are calls on one adb server; the read changes nothing on the phone. The core's claim decides the state, so the reclaim's outcome wins. - Other adb clients on the host (Android Studio, an agent's plain
adb, a second Simlock instance) share 5037 and see the phones. One of another protocol restarts the server, as adb does; Simlock's next gate read sees it and sends nothing. Simlock never restarts it, except in the one-call window in the KNOWN-PITFALLS entry. An agent's ownadbon its leased phone is the agent's; Simlock uninstalls only after release. - A
device.execstill running when the watcher marks the phone absent runs until it ends orexec.timeoutMsstops it, as for emulators today (KNOWN-PITFALLS "Adevice.execcommand is authorized once, at its start").
Rules in play
safety.mdrule 1 as amended: the only destructive act ispm uninstallof a user app off the enrollment list, for the current user. No reboot, erase, or command on a phone that is not enrolled, apart from the admin's owndevice addinspection.safety.mdrules 7, 8 as amended: presence reads only enrolled serials; a non-enrolled serial gets no entry and no command.safety.mdrule 9 as amended: the default server is never stopped and never restarted by Simlock; the gate fails closed on an unreadable version.safety.mdrule 10:adb devices -llines and package lines are claims; package names are checked before they reachadb shell.architecture.mdrules 2, 10, 11: adb knowledge stays insrc/drivers/android/; the gate is the one place that allows a physical command; every physical wait is bounded.testing.mdrules 1–4: the "never" lines below assert over every physical method's calls, not one.
Tests
Seam: AndroidDriver.create with ScriptedProcessRunner, FakeTcpProbe and MemoryFilesystem, modelled on src/drivers/android/index.test.ts. Phone lane: withDaemon({ driver: "real" }) and the HTTP device.exec route, modelled on e2e/slow-android-smoke.test.ts and e2e/device-exec.test.ts.
- every physical method reads
host:versionon port 5037 before its firstadbcommand - no physical method, and no
passthroughresult, ever runskill-serverorstart-serveragainst 5037, anddispose()sends nothing to 5037 - with a default server of another protocol:
listPresentPhysicalanswers every given serial not presentnot-present,inspectPhysicalis refusednot-connectedwith a message naming both protocol numbers,reclaimrejects, and none of them starts a process afteradb version - a
host:versionreply that is notOKAY0004plus four hex digits, and anadb versionwith no protocol number, each block physical commands like a mismatch - with nothing listening on 5037, physical commands run
- a server that matched again after a mismatch gets commands on the next call, and nothing restarts it
advisories()returnsadb-protocol-mismatchnaming both protocol numbers on a mismatch, "unreadable" for one it could not read, and nothing on a match or with no server on 5037advisories()reports the mismatch on a driver that has never been asked about a physical device (no Android device enrolled)- every physical command runs
adb -P 5037withANDROID_ADB_SERVER_PORT=5037and noANDROID_SERIALfrom the base environment; every device command carries-s <serial> inspectPhysicalof a serial on a USB transport in statedevicereturns that serial,ro.product.model, the API level, classphone, and the packagespm list packages -3 --user <id>lists for the idam get-current-userprintsinspectPhysicalof a serial in stateunauthorizedis refuseduntrusted, and runs no command naming itinspectPhysicalof a serial only on a network transport (192.168.1.5:5555, an mDNS_adb-tls-connect._tcpname) is refusednetwork-onlywith "only USB-connected devices can be enrolled", and runs no command naming itinspectPhysicalofemulator-5554listed on the default server is refusednetwork-onlywith "only USB-connected devices can be enrolled", and runs no command naming it- the transport decides, not the shape: a serial shaped like
host:porton a USB transport is inspected, and a USB-shaped serial on a network line is refused inspectPhysicalof a serial not listed, listedoffline, or with a failedadb devices -lis refusednot-connectedinspectPhysicalrejects when a read after the device was found failslistPresentPhysicalanswers a given serial on USB in statedevicepresent with its API level, an unauthorized one not presentuntrusted, and an offline, network-only or missing one not presentnot-presentlistPresentPhysicalgives no entry, and runs no command, for a USB phone that is not among the given serialslistPresentPhysicalanswers every given serial not presentnot-present, and does not reject, whenadb devices -lfails or has no exit codelistPresentPhysicalanswers a present serial whosegetpropfails not presentnot-presentreclaimuninstalls, for the current user, each package off the enrollment list, uninstalls no listed package, reports listed packages not installed asmissingApps, and returns strategyuninstallreclaimwith nothing off the list runs no uninstallreclaimrejects, and runs no later uninstall, when an uninstall printsFailure […], exits non-zero, or has no exit codereclaimrejects when the second listing still holds a package off the enrollment list- a package line with a character outside letters, digits,
_and.fails the listing, and no uninstall runs - reads pass a 30 000 ms limit and uninstalls a 60 000 ms limit to the process runner
- while a physical
adb devices -lhangs,listManagedfor emulators resolves passthrough("adb", <physical device>, ["shell", "getprop"])returnsadb -P 5037 -s <serial> shell getpropwithANDROID_ADB_SERVER_PORT=5037passthroughon a physical device refuses a caller argument before the subcommand (-s,-t,-d,-e,-P,-H,-L,--one-device,--reply-fd), andkill-server,start-server,connect,disconnect,pair,reconnect,tcpip,usb, and bareshellwith no terminalpassthroughon a physical device is refused when the latest gate verdict isblocked, and before any gate readpassthroughwith no device still runs on Simlock's own server (today'sindex.test.tspassthrough tests, unchanged and green)estimateof a reclaim for a physical spec is 30 000 ms at both clean levels; for an emulator spec it is unchanged- (phone lane)
simlock device add --platform android $SIMLOCK_PHYSICAL_ANDROIDenrolls it with the model and API leveladb shell getpropreports and as many apps aspm list packages -3lists for the current user - (phone lane)
simlock lease --platform android --physicalgrants that serial withANDROID_SERIALset to it andANDROID_ADB_SERVER_PORT=5037, anddevice.execadb shell getprop ro.serialnoover HTTP prints the serial - (phone lane) after installing
$SIMLOCK_PHYSICAL_ANDROID_APKwith plainadb -sand releasing, the device isready, the APK's package is gone, and every enrolled package is still installed - (phone lane) with a short
health.probeIntervalMs, the phone unplugged when the test asks in its log becomesabsentwithabsentReasonnot-presentwithin 120 s, and plugged back becomesready - (phone lane) without
SIMLOCK_PHYSICAL_ANDROIDorSIMLOCK_PHYSICAL_ANDROID_APKthe file skips, naming the missing variable
Done when
- With a default adb server of another protocol version, the Android driver runs no command on a physical device,
device addis refusednot-connectednaming both versions, andadvisories()names both versions even with no Android device enrolled (driver tests above). - No physical call stops or starts the default server, and
dispose()leaves it (driver tests above). - A hung phone call does not delay an emulator call (driver test above).
- On a Mac with an Android SDK, one Android phone on USB with USB debugging authorized,
SIMLOCK_PHYSICAL_ANDROIDset to its serial andSIMLOCK_PHYSICAL_ANDROID_APKto an APK:device addenrolls it, a--physicallease gets it withANDROID_SERIAL,device.execreaches it, and after release the installed app is gone and every enrolled app remains. Proved bye2e/slow-android-physical.test.ts, run throughscripts/slow-e2e.shas task 4's iOS phone lane runs. - On the same machine, the phone unplugged on the test's prompt becomes
absent (not-present), and plugged back becomesready(same test). - Without the two variables,
e2e/slow-android-physical.test.tsskips and names the missing one. docs/CLI.mdlists the Android physical-device prerequisites and theadb-protocol-mismatchadvisory;toolchain.mdhas the Android phone row.
Out of scope
- Routing physical requests and
device.execthrough a gateway (task 6). - Wi-Fi debugging, work profiles and other Android users.
- Restarting or fixing a default server of another protocol version.
- Guarding against another adb client restarting the default server.
- The iOS physical handler (task 4).
Depends on
- #435
- #440
Approval
- Approved for delivery
Written by an agent.
- Dominant language
- TypeScript
- Stars
- 19
- Forks
- 1
- Avg merge
- 9h 56m
- Merged PRs (30d)
- 134
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from callstackincubator/simlock
-
bug:new
Difficulty 1/5 Under an hour Newbie friendliness 70/100
callstackincubator/simlock#430 ·
Maintainers usually reply within 1 day
-
bug:new
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
callstackincubator/simlock#424 ·
Maintainers usually reply within 1 day
-
daemon-lifecycle e2e: the it.fails status test passes for the wrong reasonPossibly taken @V3RON claimed this 2 days ago. Openbug:triage
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
callstackincubator/simlock#422 · 1 comment · 1 assignee ·
Maintainers usually reply within 1 day
-
task:draft
Difficulty 5/5 Over a week Newbie friendliness 8/100
callstackincubator/simlock#442 ·
Maintainers usually reply within 1 day
-
task:draft
Difficulty 5/5 Over a week Newbie friendliness 12/100
callstackincubator/simlock#440 ·
Maintainers usually reply within 1 day
All issues in callstackincubator/simlock
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
NousResearch/hermes-agent#136483 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
-
factory-active factory-automatic task-bug-reproduction-success task-identify-harness-labels-done task-identify-issue-type-done
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
vercel/ai#22796 · 2 comments ·
Maintainers usually reply within 1 day
-
[Bug]: Web chat input doesn't regain focus after a reply finishesPossibly taken @GaijinSystems claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
zeroclaw-labs/zeroclaw#11658 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
babylonlabs-io/babylon-toolkit#2711 ·
Maintainers usually reply within 1 day