native macOS codings agent orchestrator prowl.onev.cat
Something went wrong. Try again.
11 kB · 341 lines
Swift
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342import Testing
@testable import supacode
struct AgentClassifierTests { @Test func identifiesDirectAgentProcessNames() { #expect(identifyAgent(processName: "pi") == .pi) #expect(identifyAgent(processName: "omp") == .omp) #expect(identifyAgent(processName: "oh-my-pi") == .omp) #expect(identifyAgent(processName: "claude") == .claude) #expect(identifyAgent(processName: "claude-code") == .claude) #expect(identifyAgent(processName: "codex") == .codex) #expect(identifyAgent(processName: "omx") == .codex) #expect(identifyAgent(processName: "oh-my-codex") == .codex) #expect(identifyAgent(processName: "gemini") == .gemini) #expect(identifyAgent(processName: "cursor") == .cursor) #expect(identifyAgent(processName: "cursor-agent") == .cursor) #expect(identifyAgent(processName: "cline") == .cline) #expect(identifyAgent(processName: "opencode") == .opencode) #expect(identifyAgent(processName: "open-code") == .opencode) #expect(identifyAgent(processName: "github-copilot") == .copilot) #expect(identifyAgent(processName: "ghcs") == .copilot) #expect(identifyAgent(processName: "kimi") == .kimi) #expect(identifyAgent(processName: "Kimi Code") == .kimi) #expect(identifyAgent(processName: "droid") == .droid) #expect(identifyAgent(processName: "amp") == .amp) #expect(identifyAgent(processName: "amp-local") == .amp) #expect(identifyAgent(processName: "qwen") == .qwen) #expect(identifyAgent(processName: "qodercli") == .qoder) #expect(identifyAgent(processName: "grok") == .grok) #expect(identifyAgent(processName: "grok-0.2.101-macos-aarch64") == .grok) // Model ids must not be treated as the install binary. #expect(identifyAgent(processName: "grok-4") == nil) #expect(identifyAgent(processName: "grok-4.5") == nil) }
@Test func identifiesGrokAgentAliasCommandLines() throws { // Production argv0 is basename-only; full path is cmdline's first token. let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "agent", argv0: "agent", cmdline: "/Users/me/.grok/bin/agent --always-approve" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .grok) #expect(result.name == "agent") // The shared `agent` name maps to the Cursor icon in CommandIconMap; // the icon token must resolve through the detected agent instead. #expect(result.iconLookupToken == "grok") }
@Test func ignoresAgentProcessWithGrokModelArgument() { // Unrelated `agent` CLIs that merely take a grok model id must stay unknown. // Production-shaped: basename argv0, no `/.grok/` in the executable path. let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "agent", argv0: "agent", cmdline: "/usr/local/bin/agent --model grok-4" ) ] ) #expect(identifyAgentInJob(job) == nil) }
@Test func ignoresWrappedRuntimeWithGrokModelToken() { // Wrapped-runtime cmdline tokens are score-40 candidates; model ids — // bare `grok` included — must not flip the job to Grok. for cmdline in [ "node /tmp/app.js --model grok-4.5", "node /tmp/app.js --model grok", ] { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess(pid: 100, name: "node", argv0: "node", cmdline: cmdline) ] ) #expect(identifyAgentInJob(job) == nil) } }
@Test func identifiesDirectGrokProcess() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "grok", argv0: "grok", cmdline: "grok --always-approve" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .grok) #expect(result.name == "grok") }
@Test func identifiesVersionedGrokBinaryPath() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "grok-0.2.101-macos-aarch64", argv0: "/Users/me/.grok/downloads/grok-0.2.101-macos-aarch64", cmdline: "/Users/me/.grok/downloads/grok-0.2.101-macos-aarch64" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .grok) }
@Test func identifiesOhMyPiCommandNames() throws { #expect(identifyAgent(processName: "omp") == .omp) #expect(identifyAgent(processName: "oh-my-pi") == .omp)
let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "bun", argv0: "bun", cmdline: "bun /opt/homebrew/bin/omp --model gpt-5" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .omp) #expect(result.name == "omp") #expect(result.process.pid == 100) }
@Test func identifiesCursorAgentAliasCommandLines() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "agent", argv0: "/Users/onevcat/.local/bin/agent", cmdline: """ /Users/onevcat/.local/bin/agent --use-system-ca \ /Users/onevcat/.local/share/cursor-agent/versions/2026.05.09-0afadcc/index.js """ ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .cursor) #expect(result.name == "agent") // Same icon either way ("agent" and "cursor" both map to the Cursor // asset); the token just resolves through the detected agent now. #expect(result.iconLookupToken == "cursor") }
@Test func ignoresGenericAgentProcessWithoutCursorContext() { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "agent", argv0: "agent", cmdline: "agent --serve" ) ] )
#expect(identifyAgent(processName: "agent") == nil) #expect(identifyAgentInJob(job) == nil) }
@Test func identifiesCursorAgentCommandLines() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "node", argv0: "node", cmdline: "node /opt/homebrew/bin/cursor-agent" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .cursor) #expect(result.name == "cursor-agent") }
@Test func ignoresPlainShellsAndUnknownProcesses() { #expect(identifyAgent(processName: "zsh") == nil) #expect(identifyAgent(processName: "bash") == nil) #expect(identifyAgent(processName: "node") == nil) #expect(identifyAgent(processName: "vim") == nil) }
@Test func identifiesWrappedRuntimeCommandLines() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "node", argv0: "node", cmdline: "node /opt/homebrew/bin/codex --model gpt-5" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .codex) #expect(result.name == "codex") }
@Test func identifiesQoderCLIWrappedByNode() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "node", argv0: "node", cmdline: "node /opt/homebrew/lib/node_modules/@qoder-ai/qodercli/bundle/qodercli.js" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .qoder) #expect(result.name == "qodercli") }
@Test func identifiesOmxAsCodexWrapper() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess( pid: 100, name: "node", argv0: "node", cmdline: "node /opt/homebrew/bin/omx --madmax --high" ) ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .codex) #expect(result.name == "omx") }
@Test func prefersDirectAgentProcessOverWrapper() throws { let job = ForegroundJob( processGroupID: 42, processes: [ ForegroundProcess(pid: 100, name: "node", argv0: "node", cmdline: "node /tmp/codex"), ForegroundProcess(pid: 101, name: "claude", argv0: "claude", cmdline: "claude"), ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .claude) #expect(result.name == "claude") #expect(result.process.pid == 101) }
@Test func launchProcessIsTheTopmostJobAncestorOfTheIdentifiedProcess() throws { // Droid ≥ 0.202 forks its engine as a second `droid` process; `proc_listpids` // lists the newest member first, so the child is scanned before the launcher. let job = ForegroundJob( processGroupID: 100, processes: [ ForegroundProcess( pid: 101, parentProcessID: 100, name: "droid", argv0: "droid", cmdline: "droid exec --input-format stream-jsonrpc --output-format stream-jsonrpc" ), ForegroundProcess( pid: 100, parentProcessID: 50, name: "droid", argv0: "droid", cmdline: "droid --settings /tmp/settings.json" ), ] )
let result = try #require(identifyAgentInJob(job)) #expect(result.agent == .droid) #expect(result.launchProcessID == 100) }
@Test func launchProcessIsTheIdentifiedProcessWhenItsParentIsOutsideTheJob() throws { let shellChild = ForegroundJob( processGroupID: 100, processes: [ ForegroundProcess(pid: 100, parentProcessID: 50, name: "claude", argv0: "claude", cmdline: "claude") ] ) #expect(try #require(identifyAgentInJob(shellChild)).launchProcessID == 100)
let unknownParent = ForegroundJob( processGroupID: 100, processes: [ ForegroundProcess(pid: 100, name: "codex", argv0: "codex", cmdline: "codex") ] ) #expect(try #require(identifyAgentInJob(unknownParent)).launchProcessID == 100) }
@Test func launchProcessWalkStopsOnACorruptParentCycle() { let job = ForegroundJob( processGroupID: 100, processes: [ ForegroundProcess(pid: 101, parentProcessID: 100, name: "droid", argv0: "droid", cmdline: "droid"), ForegroundProcess(pid: 100, parentProcessID: 101, name: "droid", argv0: "droid", cmdline: "droid"), ] ) #expect([100, 101].contains(job.launchProcessID(of: 101))) }}