shennian 0.2.0 → 0.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/dist/bin/shennian.d.ts +0 -1
  2. package/dist/bin/shennian.js +0 -1
  3. package/dist/src/agents/adapter.d.ts +0 -1
  4. package/dist/src/agents/adapter.js +0 -1
  5. package/dist/src/agents/claude.d.ts +1 -1
  6. package/dist/src/agents/claude.js +12 -6
  7. package/dist/src/agents/codex.d.ts +18 -1
  8. package/dist/src/agents/codex.js +372 -13
  9. package/dist/src/agents/command-spec.d.ts +28 -3
  10. package/dist/src/agents/command-spec.js +251 -10
  11. package/dist/src/agents/cursor.d.ts +0 -1
  12. package/dist/src/agents/cursor.js +2 -4
  13. package/dist/src/agents/custom.d.ts +0 -6
  14. package/dist/src/agents/custom.js +4 -40
  15. package/dist/src/agents/detect.d.ts +0 -1
  16. package/dist/src/agents/detect.js +0 -1
  17. package/dist/src/agents/gemini.d.ts +0 -1
  18. package/dist/src/agents/gemini.js +7 -3
  19. package/dist/src/agents/model-registry/cache.d.ts +0 -1
  20. package/dist/src/agents/model-registry/cache.js +0 -1
  21. package/dist/src/agents/model-registry/discovery.d.ts +0 -1
  22. package/dist/src/agents/model-registry/discovery.js +90 -48
  23. package/dist/src/agents/model-registry/parsers.d.ts +4 -1
  24. package/dist/src/agents/model-registry/parsers.js +168 -1
  25. package/dist/src/agents/model-registry/runner.d.ts +2 -7
  26. package/dist/src/agents/model-registry/runner.js +3 -134
  27. package/dist/src/agents/model-registry/service.d.ts +0 -1
  28. package/dist/src/agents/model-registry/service.js +12 -10
  29. package/dist/src/agents/model-registry/types.d.ts +0 -1
  30. package/dist/src/agents/model-registry/types.js +0 -1
  31. package/dist/src/agents/model-registry.d.ts +3 -2
  32. package/dist/src/agents/model-registry.js +3 -2
  33. package/dist/src/agents/openclaw.d.ts +0 -1
  34. package/dist/src/agents/openclaw.js +13 -4
  35. package/dist/src/agents/pi.d.ts +0 -1
  36. package/dist/src/agents/pi.js +0 -1
  37. package/dist/src/commands/agent.d.ts +0 -1
  38. package/dist/src/commands/agent.js +2 -33
  39. package/dist/src/commands/daemon.d.ts +6 -1
  40. package/dist/src/commands/daemon.js +153 -18
  41. package/dist/src/commands/pair-qr.d.ts +0 -1
  42. package/dist/src/commands/pair-qr.js +0 -1
  43. package/dist/src/commands/pair.d.ts +0 -1
  44. package/dist/src/commands/pair.js +0 -1
  45. package/dist/src/commands/upgrade.d.ts +0 -1
  46. package/dist/src/commands/upgrade.js +0 -1
  47. package/dist/src/config/index.d.ts +0 -1
  48. package/dist/src/config/index.js +0 -1
  49. package/dist/src/fs/handler.d.ts +0 -1
  50. package/dist/src/fs/handler.js +18 -1
  51. package/dist/src/fs/security.d.ts +0 -1
  52. package/dist/src/fs/security.js +5 -1
  53. package/dist/src/index.d.ts +0 -1
  54. package/dist/src/index.js +36 -8
  55. package/dist/src/log-reporter.d.ts +0 -1
  56. package/dist/src/log-reporter.js +2 -20
  57. package/dist/src/native-fusion/parsers.d.ts +0 -1
  58. package/dist/src/native-fusion/parsers.js +407 -44
  59. package/dist/src/native-fusion/service.d.ts +0 -1
  60. package/dist/src/native-fusion/service.js +16 -10
  61. package/dist/src/native-fusion/state.d.ts +0 -1
  62. package/dist/src/native-fusion/state.js +0 -1
  63. package/dist/src/native-fusion/types.d.ts +0 -1
  64. package/dist/src/native-fusion/types.js +0 -1
  65. package/dist/src/region.d.ts +0 -1
  66. package/dist/src/region.js +0 -1
  67. package/dist/src/relay/client.d.ts +11 -2
  68. package/dist/src/relay/client.js +22 -4
  69. package/dist/src/session/handlers/agents.d.ts +0 -1
  70. package/dist/src/session/handlers/agents.js +0 -1
  71. package/dist/src/session/handlers/chat.d.ts +0 -1
  72. package/dist/src/session/handlers/chat.js +49 -8
  73. package/dist/src/session/handlers/control.d.ts +0 -1
  74. package/dist/src/session/handlers/control.js +0 -1
  75. package/dist/src/session/handlers/fs.d.ts +0 -1
  76. package/dist/src/session/handlers/fs.js +37 -3
  77. package/dist/src/session/manager.d.ts +1 -1
  78. package/dist/src/session/manager.js +23 -4
  79. package/dist/src/session/store.d.ts +0 -1
  80. package/dist/src/session/store.js +0 -1
  81. package/dist/src/session/types.d.ts +6 -1
  82. package/dist/src/session/types.js +0 -1
  83. package/dist/src/upgrade/engine.d.ts +0 -1
  84. package/dist/src/upgrade/engine.js +0 -1
  85. package/package.json +3 -2
  86. package/dist/bin/shennian.d.ts.map +0 -1
  87. package/dist/bin/shennian.js.map +0 -1
  88. package/dist/src/__experiments__/probe-debug.d.ts +0 -2
  89. package/dist/src/__experiments__/probe-debug.d.ts.map +0 -1
  90. package/dist/src/__experiments__/probe-debug.js +0 -66
  91. package/dist/src/__experiments__/probe-debug.js.map +0 -1
  92. package/dist/src/__experiments__/probe-final-benchmark.d.ts +0 -3
  93. package/dist/src/__experiments__/probe-final-benchmark.d.ts.map +0 -1
  94. package/dist/src/__experiments__/probe-final-benchmark.js +0 -234
  95. package/dist/src/__experiments__/probe-final-benchmark.js.map +0 -1
  96. package/dist/src/__experiments__/probe-models-final.d.ts +0 -19
  97. package/dist/src/__experiments__/probe-models-final.d.ts.map +0 -1
  98. package/dist/src/__experiments__/probe-models-final.js +0 -250
  99. package/dist/src/__experiments__/probe-models-final.js.map +0 -1
  100. package/dist/src/__experiments__/probe-models.d.ts +0 -7
  101. package/dist/src/__experiments__/probe-models.d.ts.map +0 -1
  102. package/dist/src/__experiments__/probe-models.js +0 -251
  103. package/dist/src/__experiments__/probe-models.js.map +0 -1
  104. package/dist/src/__tests__/agents-e2e.d.ts +0 -21
  105. package/dist/src/__tests__/agents-e2e.d.ts.map +0 -1
  106. package/dist/src/__tests__/agents-e2e.js +0 -146
  107. package/dist/src/__tests__/agents-e2e.js.map +0 -1
  108. package/dist/src/__tests__/claude-adapter.test.d.ts +0 -2
  109. package/dist/src/__tests__/claude-adapter.test.d.ts.map +0 -1
  110. package/dist/src/__tests__/claude-adapter.test.js +0 -75
  111. package/dist/src/__tests__/claude-adapter.test.js.map +0 -1
  112. package/dist/src/__tests__/codex-adapter.test.d.ts +0 -2
  113. package/dist/src/__tests__/codex-adapter.test.d.ts.map +0 -1
  114. package/dist/src/__tests__/codex-adapter.test.js +0 -224
  115. package/dist/src/__tests__/codex-adapter.test.js.map +0 -1
  116. package/dist/src/__tests__/config.test.d.ts +0 -2
  117. package/dist/src/__tests__/config.test.d.ts.map +0 -1
  118. package/dist/src/__tests__/config.test.js +0 -60
  119. package/dist/src/__tests__/config.test.js.map +0 -1
  120. package/dist/src/__tests__/cursor-adapter.test.d.ts +0 -2
  121. package/dist/src/__tests__/cursor-adapter.test.d.ts.map +0 -1
  122. package/dist/src/__tests__/cursor-adapter.test.js +0 -69
  123. package/dist/src/__tests__/cursor-adapter.test.js.map +0 -1
  124. package/dist/src/__tests__/custom-agent-flow.test.d.ts +0 -2
  125. package/dist/src/__tests__/custom-agent-flow.test.d.ts.map +0 -1
  126. package/dist/src/__tests__/custom-agent-flow.test.js +0 -244
  127. package/dist/src/__tests__/custom-agent-flow.test.js.map +0 -1
  128. package/dist/src/__tests__/daemon-autostart.test.d.ts +0 -2
  129. package/dist/src/__tests__/daemon-autostart.test.d.ts.map +0 -1
  130. package/dist/src/__tests__/daemon-autostart.test.js +0 -60
  131. package/dist/src/__tests__/daemon-autostart.test.js.map +0 -1
  132. package/dist/src/__tests__/e2e-relay.d.ts +0 -19
  133. package/dist/src/__tests__/e2e-relay.d.ts.map +0 -1
  134. package/dist/src/__tests__/e2e-relay.js +0 -256
  135. package/dist/src/__tests__/e2e-relay.js.map +0 -1
  136. package/dist/src/__tests__/model-discovery.test.d.ts +0 -2
  137. package/dist/src/__tests__/model-discovery.test.d.ts.map +0 -1
  138. package/dist/src/__tests__/model-discovery.test.js +0 -47
  139. package/dist/src/__tests__/model-discovery.test.js.map +0 -1
  140. package/dist/src/__tests__/model-switching.test.d.ts +0 -2
  141. package/dist/src/__tests__/model-switching.test.d.ts.map +0 -1
  142. package/dist/src/__tests__/model-switching.test.js +0 -253
  143. package/dist/src/__tests__/model-switching.test.js.map +0 -1
  144. package/dist/src/__tests__/native-fusion-parsers.test.d.ts +0 -2
  145. package/dist/src/__tests__/native-fusion-parsers.test.d.ts.map +0 -1
  146. package/dist/src/__tests__/native-fusion-parsers.test.js +0 -216
  147. package/dist/src/__tests__/native-fusion-parsers.test.js.map +0 -1
  148. package/dist/src/__tests__/native-fusion-service.test.d.ts +0 -2
  149. package/dist/src/__tests__/native-fusion-service.test.d.ts.map +0 -1
  150. package/dist/src/__tests__/native-fusion-service.test.js +0 -157
  151. package/dist/src/__tests__/native-fusion-service.test.js.map +0 -1
  152. package/dist/src/__tests__/native-session-sync.test.d.ts +0 -2
  153. package/dist/src/__tests__/native-session-sync.test.d.ts.map +0 -1
  154. package/dist/src/__tests__/native-session-sync.test.js +0 -198
  155. package/dist/src/__tests__/native-session-sync.test.js.map +0 -1
  156. package/dist/src/__tests__/pair-qr.test.d.ts +0 -2
  157. package/dist/src/__tests__/pair-qr.test.d.ts.map +0 -1
  158. package/dist/src/__tests__/pair-qr.test.js +0 -13
  159. package/dist/src/__tests__/pair-qr.test.js.map +0 -1
  160. package/dist/src/__tests__/pi-context.test.d.ts +0 -2
  161. package/dist/src/__tests__/pi-context.test.d.ts.map +0 -1
  162. package/dist/src/__tests__/pi-context.test.js +0 -261
  163. package/dist/src/__tests__/pi-context.test.js.map +0 -1
  164. package/dist/src/__tests__/session-manager.test.d.ts +0 -2
  165. package/dist/src/__tests__/session-manager.test.d.ts.map +0 -1
  166. package/dist/src/__tests__/session-manager.test.js +0 -592
  167. package/dist/src/__tests__/session-manager.test.js.map +0 -1
  168. package/dist/src/__tests__/session-store.test.d.ts +0 -2
  169. package/dist/src/__tests__/session-store.test.d.ts.map +0 -1
  170. package/dist/src/__tests__/session-store.test.js +0 -106
  171. package/dist/src/__tests__/session-store.test.js.map +0 -1
  172. package/dist/src/agents/adapter.d.ts.map +0 -1
  173. package/dist/src/agents/adapter.js.map +0 -1
  174. package/dist/src/agents/claude.d.ts.map +0 -1
  175. package/dist/src/agents/claude.js.map +0 -1
  176. package/dist/src/agents/codex.d.ts.map +0 -1
  177. package/dist/src/agents/codex.js.map +0 -1
  178. package/dist/src/agents/command-spec.d.ts.map +0 -1
  179. package/dist/src/agents/command-spec.js.map +0 -1
  180. package/dist/src/agents/cursor.d.ts.map +0 -1
  181. package/dist/src/agents/cursor.js.map +0 -1
  182. package/dist/src/agents/custom.d.ts.map +0 -1
  183. package/dist/src/agents/custom.js.map +0 -1
  184. package/dist/src/agents/detect.d.ts.map +0 -1
  185. package/dist/src/agents/detect.js.map +0 -1
  186. package/dist/src/agents/gemini.d.ts.map +0 -1
  187. package/dist/src/agents/gemini.js.map +0 -1
  188. package/dist/src/agents/model-registry/cache.d.ts.map +0 -1
  189. package/dist/src/agents/model-registry/cache.js.map +0 -1
  190. package/dist/src/agents/model-registry/discovery.d.ts.map +0 -1
  191. package/dist/src/agents/model-registry/discovery.js.map +0 -1
  192. package/dist/src/agents/model-registry/parsers.d.ts.map +0 -1
  193. package/dist/src/agents/model-registry/parsers.js.map +0 -1
  194. package/dist/src/agents/model-registry/runner.d.ts.map +0 -1
  195. package/dist/src/agents/model-registry/runner.js.map +0 -1
  196. package/dist/src/agents/model-registry/service.d.ts.map +0 -1
  197. package/dist/src/agents/model-registry/service.js.map +0 -1
  198. package/dist/src/agents/model-registry/types.d.ts.map +0 -1
  199. package/dist/src/agents/model-registry/types.js.map +0 -1
  200. package/dist/src/agents/model-registry.d.ts.map +0 -1
  201. package/dist/src/agents/model-registry.js.map +0 -1
  202. package/dist/src/agents/openclaw.d.ts.map +0 -1
  203. package/dist/src/agents/openclaw.js.map +0 -1
  204. package/dist/src/agents/pi.d.ts.map +0 -1
  205. package/dist/src/agents/pi.js.map +0 -1
  206. package/dist/src/commands/agent.d.ts.map +0 -1
  207. package/dist/src/commands/agent.js.map +0 -1
  208. package/dist/src/commands/daemon.d.ts.map +0 -1
  209. package/dist/src/commands/daemon.js.map +0 -1
  210. package/dist/src/commands/pair-qr.d.ts.map +0 -1
  211. package/dist/src/commands/pair-qr.js.map +0 -1
  212. package/dist/src/commands/pair.d.ts.map +0 -1
  213. package/dist/src/commands/pair.js.map +0 -1
  214. package/dist/src/commands/upgrade.d.ts.map +0 -1
  215. package/dist/src/commands/upgrade.js.map +0 -1
  216. package/dist/src/config/index.d.ts.map +0 -1
  217. package/dist/src/config/index.js.map +0 -1
  218. package/dist/src/fs/handler.d.ts.map +0 -1
  219. package/dist/src/fs/handler.js.map +0 -1
  220. package/dist/src/fs/multimodal.d.ts +0 -5
  221. package/dist/src/fs/multimodal.d.ts.map +0 -1
  222. package/dist/src/fs/multimodal.js +0 -39
  223. package/dist/src/fs/multimodal.js.map +0 -1
  224. package/dist/src/fs/security.d.ts.map +0 -1
  225. package/dist/src/fs/security.js.map +0 -1
  226. package/dist/src/index.d.ts.map +0 -1
  227. package/dist/src/index.js.map +0 -1
  228. package/dist/src/log-reporter.d.ts.map +0 -1
  229. package/dist/src/log-reporter.js.map +0 -1
  230. package/dist/src/native-fusion/parsers.d.ts.map +0 -1
  231. package/dist/src/native-fusion/parsers.js.map +0 -1
  232. package/dist/src/native-fusion/service.d.ts.map +0 -1
  233. package/dist/src/native-fusion/service.js.map +0 -1
  234. package/dist/src/native-fusion/state.d.ts.map +0 -1
  235. package/dist/src/native-fusion/state.js.map +0 -1
  236. package/dist/src/native-fusion/types.d.ts.map +0 -1
  237. package/dist/src/native-fusion/types.js.map +0 -1
  238. package/dist/src/native-sync/discover.d.ts +0 -6
  239. package/dist/src/native-sync/discover.d.ts.map +0 -1
  240. package/dist/src/native-sync/discover.js +0 -69
  241. package/dist/src/native-sync/discover.js.map +0 -1
  242. package/dist/src/native-sync/parsers.d.ts +0 -3
  243. package/dist/src/native-sync/parsers.d.ts.map +0 -1
  244. package/dist/src/native-sync/parsers.js +0 -373
  245. package/dist/src/native-sync/parsers.js.map +0 -1
  246. package/dist/src/native-sync/service.d.ts +0 -16
  247. package/dist/src/native-sync/service.d.ts.map +0 -1
  248. package/dist/src/native-sync/service.js +0 -95
  249. package/dist/src/native-sync/service.js.map +0 -1
  250. package/dist/src/native-sync/state.d.ts +0 -6
  251. package/dist/src/native-sync/state.d.ts.map +0 -1
  252. package/dist/src/native-sync/state.js +0 -34
  253. package/dist/src/native-sync/state.js.map +0 -1
  254. package/dist/src/native-sync/types.d.ts +0 -23
  255. package/dist/src/native-sync/types.d.ts.map +0 -1
  256. package/dist/src/native-sync/types.js +0 -4
  257. package/dist/src/native-sync/types.js.map +0 -1
  258. package/dist/src/region.d.ts.map +0 -1
  259. package/dist/src/region.js.map +0 -1
  260. package/dist/src/relay/client.d.ts.map +0 -1
  261. package/dist/src/relay/client.js.map +0 -1
  262. package/dist/src/session/handlers/agents.d.ts.map +0 -1
  263. package/dist/src/session/handlers/agents.js.map +0 -1
  264. package/dist/src/session/handlers/chat.d.ts.map +0 -1
  265. package/dist/src/session/handlers/chat.js.map +0 -1
  266. package/dist/src/session/handlers/control.d.ts.map +0 -1
  267. package/dist/src/session/handlers/control.js.map +0 -1
  268. package/dist/src/session/handlers/fs.d.ts.map +0 -1
  269. package/dist/src/session/handlers/fs.js.map +0 -1
  270. package/dist/src/session/handlers/queue.d.ts +0 -4
  271. package/dist/src/session/handlers/queue.d.ts.map +0 -1
  272. package/dist/src/session/handlers/queue.js +0 -66
  273. package/dist/src/session/handlers/queue.js.map +0 -1
  274. package/dist/src/session/manager.d.ts.map +0 -1
  275. package/dist/src/session/manager.js.map +0 -1
  276. package/dist/src/session/store.d.ts.map +0 -1
  277. package/dist/src/session/store.js.map +0 -1
  278. package/dist/src/session/types.d.ts.map +0 -1
  279. package/dist/src/session/types.js.map +0 -1
  280. package/dist/src/upgrade/engine.d.ts.map +0 -1
  281. package/dist/src/upgrade/engine.js.map +0 -1
  282. package/dist/tsconfig.tsbuildinfo +0 -1
@@ -1,4 +1,7 @@
1
- import { spawnSync } from 'node:child_process';
1
+ // @arch docs/architecture/cli/windows-agent-launch.md
2
+ // @test src/__tests__/command-spec.test.ts
3
+ import { spawn, spawnSync } from 'node:child_process';
4
+ import path from 'node:path';
2
5
  const BUILTIN_COMMANDS = {
3
6
  claude: [
4
7
  { command: 'claude', args: [], display: 'claude' },
@@ -22,33 +25,272 @@ const BUILTIN_COMMANDS = {
22
25
  };
23
26
  const availabilityCache = new Map();
24
27
  const resolvedCache = new Map();
28
+ const pathLookupCache = new Map();
29
+ const wslAvailabilityCache = new Map();
25
30
  export function resetCommandSpecCache() {
26
31
  availabilityCache.clear();
27
32
  resolvedCache.clear();
33
+ pathLookupCache.clear();
34
+ wslAvailabilityCache.clear();
28
35
  }
29
- export function commandExists(command) {
30
- if (availabilityCache.has(command)) {
31
- return availabilityCache.get(command) ?? false;
36
+ export function getProcessPlatform() {
37
+ return process.platform;
38
+ }
39
+ function splitLines(text) {
40
+ return text
41
+ .split(/\r?\n/)
42
+ .map((line) => line.trim())
43
+ .filter(Boolean);
44
+ }
45
+ function lookupCommandPaths(command) {
46
+ if (pathLookupCache.has(command)) {
47
+ return pathLookupCache.get(command) ?? [];
32
48
  }
33
- const lookup = process.platform === 'win32' ? 'where' : 'which';
49
+ const lookup = getProcessPlatform() === 'win32' ? 'where' : 'which';
34
50
  const result = spawnSync(lookup, [command], {
35
- stdio: 'ignore',
51
+ encoding: 'utf-8',
52
+ stdio: ['ignore', 'pipe', 'pipe'],
36
53
  timeout: 3000,
37
54
  });
38
- const exists = result.status === 0;
55
+ const paths = result.status === 0 ? splitLines(result.stdout ?? '') : [];
56
+ pathLookupCache.set(command, paths);
57
+ return paths;
58
+ }
59
+ function getWindowsShellPath() {
60
+ return process.env.ComSpec || 'cmd.exe';
61
+ }
62
+ function isWindowsNativeBinary(filePath) {
63
+ const ext = path.extname(filePath).toLowerCase();
64
+ return ext === '.exe' || ext === '.com';
65
+ }
66
+ function isWindowsCmdShim(filePath) {
67
+ const ext = path.extname(filePath).toLowerCase();
68
+ return ext === '.cmd' || ext === '.bat';
69
+ }
70
+ function quoteCmdArg(text) {
71
+ return `"${text.replace(/"/g, '""')}"`;
72
+ }
73
+ function quotePosixArg(text) {
74
+ return `'${text.replace(/'/g, `'\\''`)}'`;
75
+ }
76
+ export function windowsPathToWsl(input) {
77
+ if (!input)
78
+ return undefined;
79
+ const normalized = input.replace(/\//g, '\\');
80
+ const driveMatch = normalized.match(/^([A-Za-z]):\\(.*)$/);
81
+ if (driveMatch) {
82
+ const [, drive, rest] = driveMatch;
83
+ const suffix = rest.replace(/\\/g, '/');
84
+ return `/mnt/${drive.toLowerCase()}/${suffix}`;
85
+ }
86
+ if (normalized.startsWith('\\\\wsl$\\')) {
87
+ const remainder = normalized.replace(/^\\\\wsl\$\\[^\\]+\\?/, '');
88
+ return `/${remainder.replace(/\\/g, '/')}`;
89
+ }
90
+ if (input.startsWith('/'))
91
+ return input;
92
+ return undefined;
93
+ }
94
+ function resolveArbitraryWindowsCommand(command) {
95
+ const normalized = command.trim();
96
+ if (!normalized) {
97
+ throw new Error('Command string is empty');
98
+ }
99
+ const hasExplicitPath = /[\\/]/.test(normalized) || /^[A-Za-z]:/.test(normalized);
100
+ if (hasExplicitPath) {
101
+ if (isWindowsCmdShim(normalized))
102
+ return { kind: 'cmd-shim', path: normalized };
103
+ return { kind: 'direct', path: normalized };
104
+ }
105
+ const paths = lookupCommandPaths(normalized);
106
+ const native = paths.find(isWindowsNativeBinary);
107
+ if (native)
108
+ return { kind: 'direct', path: native };
109
+ const shim = paths.find(isWindowsCmdShim);
110
+ if (shim)
111
+ return { kind: 'cmd-shim', path: shim };
112
+ return { kind: 'direct', path: normalized };
113
+ }
114
+ function canUseWslBridge(command) {
115
+ if (wslAvailabilityCache.has(command)) {
116
+ return wslAvailabilityCache.get(command) ?? false;
117
+ }
118
+ const wslPath = lookupCommandPaths('wsl.exe')[0] ?? lookupCommandPaths('wsl')[0];
119
+ if (!wslPath) {
120
+ wslAvailabilityCache.set(command, false);
121
+ return false;
122
+ }
123
+ const result = spawnSync(wslPath, ['-e', 'sh', '-lc', `command -v ${quotePosixArg(command)} >/dev/null 2>&1`], {
124
+ stdio: 'ignore',
125
+ timeout: 5000,
126
+ });
127
+ const ok = result.status === 0;
128
+ wslAvailabilityCache.set(command, ok);
129
+ return ok;
130
+ }
131
+ export function commandExists(command) {
132
+ if (availabilityCache.has(command)) {
133
+ return availabilityCache.get(command) ?? false;
134
+ }
135
+ const exists = lookupCommandPaths(command).length > 0 || (getProcessPlatform() === 'win32' && canUseWslBridge(command));
39
136
  availabilityCache.set(command, exists);
40
137
  return exists;
41
138
  }
139
+ function resolveWindowsBuiltinCommand(candidate) {
140
+ const paths = lookupCommandPaths(candidate.command);
141
+ const native = paths.find(isWindowsNativeBinary);
142
+ if (native) {
143
+ return { ...candidate, kind: 'native', path: native };
144
+ }
145
+ const shim = paths.find(isWindowsCmdShim);
146
+ if (shim) {
147
+ return { ...candidate, kind: 'cmd-shim', path: shim };
148
+ }
149
+ if (canUseWslBridge(candidate.command)) {
150
+ const wslPath = lookupCommandPaths('wsl.exe')[0] ?? lookupCommandPaths('wsl')[0];
151
+ if (wslPath) {
152
+ return { ...candidate, kind: 'wsl-bridge', path: wslPath };
153
+ }
154
+ }
155
+ return null;
156
+ }
42
157
  export function resolveBuiltinCommand(type) {
43
158
  if (resolvedCache.has(type)) {
44
159
  return resolvedCache.get(type) ?? null;
45
160
  }
46
- const resolved = BUILTIN_COMMANDS[type].find((candidate) => commandExists(candidate.command)) ?? null;
161
+ const resolved = BUILTIN_COMMANDS[type]
162
+ .map((candidate) => {
163
+ if (getProcessPlatform() === 'win32') {
164
+ return resolveWindowsBuiltinCommand(candidate);
165
+ }
166
+ const commandPath = lookupCommandPaths(candidate.command)[0];
167
+ return commandPath ? { ...candidate, kind: 'native', path: commandPath } : null;
168
+ })
169
+ .find(Boolean) ?? null;
47
170
  resolvedCache.set(type, resolved);
48
171
  return resolved;
49
172
  }
173
+ export function buildLaunchSpec(spec, runtimeArgs, cwd) {
174
+ if (spec.kind === 'native') {
175
+ return {
176
+ command: spec.path,
177
+ args: [...spec.args, ...runtimeArgs],
178
+ cwd,
179
+ };
180
+ }
181
+ if (spec.kind === 'cmd-shim') {
182
+ const commandLine = [spec.path, ...spec.args, ...runtimeArgs].map(quoteCmdArg).join(' ');
183
+ return {
184
+ command: getWindowsShellPath(),
185
+ args: ['/d', '/s', '/c', `"${commandLine}"`],
186
+ cwd,
187
+ };
188
+ }
189
+ const wslCwd = cwd ? windowsPathToWsl(cwd) : undefined;
190
+ if (cwd && !wslCwd) {
191
+ throw new Error(`Cannot map Windows path to WSL workDir: ${cwd}`);
192
+ }
193
+ const shellCommand = [
194
+ wslCwd ? `cd ${quotePosixArg(wslCwd)}` : '',
195
+ `exec ${[spec.command, ...spec.args, ...runtimeArgs].map(quotePosixArg).join(' ')}`,
196
+ ].filter(Boolean).join(' && ');
197
+ return {
198
+ command: spec.path,
199
+ args: ['-e', 'sh', '-lc', shellCommand],
200
+ cwd: undefined,
201
+ };
202
+ }
203
+ export function spawnResolvedCommand(spec, runtimeArgs, options = {}) {
204
+ const launch = buildLaunchSpec(spec, runtimeArgs, options.cwd);
205
+ return spawn(launch.command, launch.args, {
206
+ ...options,
207
+ cwd: launch.cwd,
208
+ ...(getProcessPlatform() === 'win32' && spec.kind === 'cmd-shim'
209
+ ? { windowsVerbatimArguments: true }
210
+ : {}),
211
+ });
212
+ }
213
+ export function spawnResolvedCommandSync(spec, runtimeArgs, options = {}) {
214
+ const launch = buildLaunchSpec(spec, runtimeArgs, options.cwd);
215
+ return spawnSync(launch.command, launch.args, {
216
+ ...options,
217
+ cwd: launch.cwd,
218
+ ...(getProcessPlatform() === 'win32' && spec.kind === 'cmd-shim'
219
+ ? { windowsVerbatimArguments: true }
220
+ : {}),
221
+ });
222
+ }
223
+ export function parseCommandString(command) {
224
+ const args = [];
225
+ let current = '';
226
+ let inSingle = false;
227
+ let inDouble = false;
228
+ for (const ch of command) {
229
+ if (ch === "'" && !inDouble) {
230
+ inSingle = !inSingle;
231
+ continue;
232
+ }
233
+ if (ch === '"' && !inSingle) {
234
+ inDouble = !inDouble;
235
+ continue;
236
+ }
237
+ if (ch === ' ' && !inSingle && !inDouble) {
238
+ if (current) {
239
+ args.push(current);
240
+ current = '';
241
+ }
242
+ continue;
243
+ }
244
+ current += ch;
245
+ }
246
+ if (current)
247
+ args.push(current);
248
+ return args;
249
+ }
250
+ export function buildCommandStringLaunchSpec(commandString, runtimeArgs, cwd) {
251
+ const parts = parseCommandString(commandString);
252
+ const bin = parts[0];
253
+ if (!bin) {
254
+ throw new Error('Command string is empty');
255
+ }
256
+ const baseArgs = parts.slice(1);
257
+ if (getProcessPlatform() !== 'win32') {
258
+ return {
259
+ command: bin,
260
+ args: [...baseArgs, ...runtimeArgs],
261
+ cwd,
262
+ };
263
+ }
264
+ const invocation = resolveArbitraryWindowsCommand(bin);
265
+ if (invocation.kind === 'cmd-shim') {
266
+ return {
267
+ command: getWindowsShellPath(),
268
+ args: ['/d', '/s', '/c', `"${[invocation.path, ...baseArgs, ...runtimeArgs].map(quoteCmdArg).join(' ')}"`],
269
+ cwd,
270
+ };
271
+ }
272
+ return {
273
+ command: invocation.path,
274
+ args: [...baseArgs, ...runtimeArgs],
275
+ cwd,
276
+ };
277
+ }
278
+ export function spawnCommandString(commandString, runtimeArgs, options = {}) {
279
+ const launch = buildCommandStringLaunchSpec(commandString, runtimeArgs, options.cwd);
280
+ const parts = parseCommandString(commandString);
281
+ const invocation = getProcessPlatform() === 'win32' && parts[0]
282
+ ? resolveArbitraryWindowsCommand(parts[0])
283
+ : null;
284
+ return spawn(launch.command, launch.args, {
285
+ ...options,
286
+ cwd: launch.cwd,
287
+ ...(getProcessPlatform() === 'win32' && invocation?.kind === 'cmd-shim'
288
+ ? { windowsVerbatimArguments: true }
289
+ : {}),
290
+ });
291
+ }
50
292
  export function getCommandVersion(spec, flag = '--version') {
51
- const result = spawnSync(spec.command, [...spec.args, flag], {
293
+ const result = spawnResolvedCommandSync(spec, [flag], {
52
294
  encoding: 'utf-8',
53
295
  stdio: ['ignore', 'pipe', 'pipe'],
54
296
  timeout: 5000,
@@ -59,4 +301,3 @@ export function getCommandVersion(spec, flag = '--version') {
59
301
  const match = text.match(/\d+\.\d+[\w.-]*/);
60
302
  return match?.[0];
61
303
  }
62
- //# sourceMappingURL=command-spec.js.map
@@ -20,4 +20,3 @@ export declare class CursorAdapter extends AgentAdapter {
20
20
  private emitTextDelta;
21
21
  private emitFinalResultDelta;
22
22
  }
23
- //# sourceMappingURL=cursor.d.ts.map
@@ -1,10 +1,9 @@
1
1
  // @arch docs/architecture/cli/agent-adapters.md
2
2
  // @test src/__tests__/cursor-adapter.test.ts
3
- import { spawn } from 'node:child_process';
4
3
  import { createInterface } from 'node:readline';
5
4
  import { randomUUID } from 'node:crypto';
6
5
  import { AgentAdapter, registerAgent } from './adapter.js';
7
- import { resolveBuiltinCommand } from './command-spec.js';
6
+ import { resolveBuiltinCommand, spawnResolvedCommand } from './command-spec.js';
8
7
  export class CursorAdapter extends AgentAdapter {
9
8
  type = 'cursor';
10
9
  process = null;
@@ -58,7 +57,7 @@ export class CursorAdapter extends AgentAdapter {
58
57
  this.emit('error', new Error('Cursor Agent CLI not found. Expected "agent" or "cursor agent".'));
59
58
  return;
60
59
  }
61
- const proc = spawn(spec.command, [...spec.args, ...args], {
60
+ const proc = spawnResolvedCommand(spec, args, {
62
61
  cwd: this.workDir ?? undefined,
63
62
  stdio: ['ignore', 'pipe', 'pipe'],
64
63
  env: { ...process.env },
@@ -247,4 +246,3 @@ export class CursorAdapter extends AgentAdapter {
247
246
  }
248
247
  }
249
248
  registerAgent('cursor', () => new CursorAdapter());
250
- //# sourceMappingURL=cursor.js.map
@@ -26,11 +26,5 @@ export declare class CustomAgentAdapter extends AgentAdapter {
26
26
  private attachOutputHandlers;
27
27
  private handleProtocolEvent;
28
28
  private emitEvent;
29
- /**
30
- * Splits `this.command` into argv, supporting quoted strings.
31
- * e.g. `python /path/to/agent.py` → ['python', '/path/to/agent.py']
32
- */
33
- private buildCommandArgs;
34
29
  }
35
30
  export declare function registerCustomAgent(name: string, entry: CustomAgentEntry): void;
36
- //# sourceMappingURL=custom.d.ts.map
@@ -1,8 +1,8 @@
1
1
  // @arch docs/architecture/cli/agent-adapters.md#custom-agents
2
- import { spawn } from 'node:child_process';
3
2
  import { createInterface } from 'node:readline';
4
3
  import { randomUUID } from 'node:crypto';
5
4
  import { AgentAdapter, registerAgent } from './adapter.js';
5
+ import { spawnCommandString } from './command-spec.js';
6
6
  export class CustomAgentAdapter extends AgentAdapter {
7
7
  type;
8
8
  command;
@@ -65,15 +65,14 @@ export class CustomAgentAdapter extends AgentAdapter {
65
65
  // ─── Spawn mode ───────────────────────────────────────────────────────────
66
66
  async runSpawn(text, modelId) {
67
67
  await this.killSpawnProcess();
68
- const args = this.buildCommandArgs();
69
- args.push('/run', '--workdir', this.workDir ?? process.cwd());
68
+ const args = ['/run', '--workdir', this.workDir ?? process.cwd()];
70
69
  if (this.sessionId)
71
70
  args.push('--session', this.sessionId);
72
71
  if (this.agentSessionId)
73
72
  args.push('--resume', this.agentSessionId);
74
73
  if (modelId)
75
74
  args.push('--model', modelId);
76
- const proc = spawn(args[0], args.slice(1), {
75
+ const proc = spawnCommandString(this.command, args, {
77
76
  cwd: this.workDir ?? undefined,
78
77
  stdio: ['pipe', 'pipe', 'pipe'],
79
78
  env: { ...process.env },
@@ -99,9 +98,7 @@ export class CustomAgentAdapter extends AgentAdapter {
99
98
  }
100
99
  // ─── Stdio mode ───────────────────────────────────────────────────────────
101
100
  async startStdioProcess() {
102
- const args = this.buildCommandArgs();
103
- args.push('/start', '--workdir', this.workDir ?? process.cwd());
104
- const proc = spawn(args[0], args.slice(1), {
101
+ const proc = spawnCommandString(this.command, ['/start', '--workdir', this.workDir ?? process.cwd()], {
105
102
  cwd: this.workDir ?? undefined,
106
103
  stdio: ['pipe', 'pipe', 'pipe'],
107
104
  env: { ...process.env },
@@ -206,41 +203,8 @@ export class CustomAgentAdapter extends AgentAdapter {
206
203
  const event = { ...partial, runId: this.runId, seq: this.seq++ };
207
204
  this.emit('agentEvent', event);
208
205
  }
209
- // ─── Helpers ──────────────────────────────────────────────────────────────
210
- /**
211
- * Splits `this.command` into argv, supporting quoted strings.
212
- * e.g. `python /path/to/agent.py` → ['python', '/path/to/agent.py']
213
- */
214
- buildCommandArgs() {
215
- const args = [];
216
- let current = '';
217
- let inSingle = false;
218
- let inDouble = false;
219
- for (const ch of this.command) {
220
- if (ch === "'" && !inDouble) {
221
- inSingle = !inSingle;
222
- continue;
223
- }
224
- if (ch === '"' && !inSingle) {
225
- inDouble = !inDouble;
226
- continue;
227
- }
228
- if (ch === ' ' && !inSingle && !inDouble) {
229
- if (current) {
230
- args.push(current);
231
- current = '';
232
- }
233
- continue;
234
- }
235
- current += ch;
236
- }
237
- if (current)
238
- args.push(current);
239
- return args;
240
- }
241
206
  }
242
207
  export function registerCustomAgent(name, entry) {
243
208
  const agentType = `custom:${name}`;
244
209
  registerAgent(agentType, () => new CustomAgentAdapter(name, entry));
245
210
  }
246
- //# sourceMappingURL=custom.js.map
@@ -7,4 +7,3 @@ export type DetectedAgent = {
7
7
  models?: ModelInfo[];
8
8
  };
9
9
  export declare function detectAgents(): DetectedAgent[];
10
- //# sourceMappingURL=detect.d.ts.map
@@ -44,4 +44,3 @@ export function detectAgents() {
44
44
  }
45
45
  return detected;
46
46
  }
47
- //# sourceMappingURL=detect.js.map
@@ -15,4 +15,3 @@ export declare class GeminiAdapter extends AgentAdapter {
15
15
  private emitEvent;
16
16
  private killProcess;
17
17
  }
18
- //# sourceMappingURL=gemini.d.ts.map
@@ -1,7 +1,7 @@
1
- import { spawn } from 'node:child_process';
2
1
  import { createInterface } from 'node:readline';
3
2
  import { randomUUID } from 'node:crypto';
4
3
  import { AgentAdapter, registerAgent } from './adapter.js';
4
+ import { resolveBuiltinCommand, spawnResolvedCommand } from './command-spec.js';
5
5
  function num(v) {
6
6
  return typeof v === 'number' && Number.isFinite(v) ? v : undefined;
7
7
  }
@@ -64,7 +64,12 @@ export class GeminiAdapter extends AgentAdapter {
64
64
  await this.killProcess();
65
65
  }
66
66
  spawnAndParse(args) {
67
- const proc = spawn('gemini', args, {
67
+ const spec = resolveBuiltinCommand('gemini');
68
+ if (!spec) {
69
+ this.emit('error', new Error('Command "gemini" not found. Is Gemini CLI installed?'));
70
+ return;
71
+ }
72
+ const proc = spawnResolvedCommand(spec, args, {
68
73
  cwd: this.workDir ?? undefined,
69
74
  stdio: ['ignore', 'pipe', 'pipe'],
70
75
  env: { ...process.env },
@@ -165,4 +170,3 @@ export class GeminiAdapter extends AgentAdapter {
165
170
  }
166
171
  }
167
172
  registerAgent('gemini', () => new GeminiAdapter());
168
- //# sourceMappingURL=gemini.js.map
@@ -2,4 +2,3 @@ import { type CacheEntry, type CacheFile } from './types.js';
2
2
  export declare function readCache(): CacheFile;
3
3
  export declare function writeCache(cache: CacheFile): void;
4
4
  export declare function isCacheFresh(entry: CacheEntry | undefined, version?: string): boolean;
5
- //# sourceMappingURL=cache.d.ts.map
@@ -35,4 +35,3 @@ export function isCacheFresh(entry, version) {
35
35
  return false;
36
36
  return Date.now() - entry.refreshedAt < CACHE_TTL_MS;
37
37
  }
38
- //# sourceMappingURL=cache.js.map
@@ -2,4 +2,3 @@ import type { ModelInfo } from '@shennian/wire';
2
2
  import type { DetectedAgent } from '../detect.js';
3
3
  import { type DiscoveryContext } from './types.js';
4
4
  export declare function discoverModelsForAgent(agent: DetectedAgent, context: DiscoveryContext): Promise<ModelInfo[]>;
5
- //# sourceMappingURL=discovery.d.ts.map
@@ -1,75 +1,118 @@
1
1
  // @arch docs/architecture/cli/model-discovery.md
2
2
  // @test src/__tests__/model-switching.test.ts
3
- import { resolveBuiltinCommand } from '../command-spec.js';
4
- import { parseClaudeModels, parseCodexModels, parseCursorModels, parseGeminiModels, parseOpenClawModels } from './parsers.js';
5
- import { runCommand, runPtyCommand } from './runner.js';
3
+ import { createInterface } from 'node:readline';
4
+ import { resolveBuiltinCommand, spawnResolvedCommand } from '../command-spec.js';
5
+ import { fallbackClaudeAliasModels, fallbackGeminiModels, parseCodexAppServerModels, parseCursorModels, parseOpenClawModels, } from './parsers.js';
6
+ import { runResolvedCommand } from './runner.js';
6
7
  import { DISCOVERY_WORKDIR } from './types.js';
8
+ function sendAppServerRpc(proc, pending, id, method, params, timeoutMs) {
9
+ if (!proc.stdin)
10
+ return Promise.reject(new Error('codex app-server stdin unavailable'));
11
+ return new Promise((resolve, reject) => {
12
+ const timer = setTimeout(() => {
13
+ pending.delete(id);
14
+ reject(new Error(`codex app-server request timed out: ${method}`));
15
+ }, timeoutMs);
16
+ pending.set(id, { resolve, reject, timer });
17
+ proc.stdin.write(`${JSON.stringify({ id, method, params })}\n`, (error) => {
18
+ if (!error)
19
+ return;
20
+ clearTimeout(timer);
21
+ pending.delete(id);
22
+ reject(error);
23
+ });
24
+ });
25
+ }
26
+ async function discoverCodexModelsViaAppServer(spec) {
27
+ const proc = spawnResolvedCommand(spec, ['app-server', '--listen', 'stdio://'], {
28
+ cwd: DISCOVERY_WORKDIR,
29
+ stdio: ['pipe', 'pipe', 'pipe'],
30
+ env: { ...process.env, NO_COLOR: '1' },
31
+ });
32
+ const pending = new Map();
33
+ let seq = 1;
34
+ const rl = createInterface({ input: proc.stdout });
35
+ rl.on('line', (line) => {
36
+ if (!line.trim())
37
+ return;
38
+ let msg;
39
+ try {
40
+ msg = JSON.parse(line);
41
+ }
42
+ catch {
43
+ return;
44
+ }
45
+ if (msg.id == null)
46
+ return;
47
+ const request = pending.get(msg.id);
48
+ if (!request)
49
+ return;
50
+ clearTimeout(request.timer);
51
+ pending.delete(msg.id);
52
+ if (msg.error) {
53
+ request.reject(new Error(msg.error.message || `codex app-server error ${msg.error.code ?? ''}`.trim()));
54
+ }
55
+ else {
56
+ request.resolve(msg.result);
57
+ }
58
+ });
59
+ try {
60
+ await sendAppServerRpc(proc, pending, seq++, 'initialize', {
61
+ clientInfo: { name: 'shennian', title: 'Shennian', version: '0.0.0' },
62
+ capabilities: { experimentalApi: true },
63
+ }, 10_000);
64
+ const [modelList, configRead] = await Promise.all([
65
+ sendAppServerRpc(proc, pending, seq++, 'model/list', {}, 15_000),
66
+ sendAppServerRpc(proc, pending, seq++, 'config/read', {}, 15_000).catch(() => null),
67
+ ]);
68
+ const config = typeof configRead === 'object' && configRead !== null && 'config' in configRead
69
+ ? configRead.config
70
+ : undefined;
71
+ return parseCodexAppServerModels({
72
+ ...(typeof modelList === 'object' && modelList !== null ? modelList : {}),
73
+ config,
74
+ });
75
+ }
76
+ finally {
77
+ for (const [id, request] of pending) {
78
+ clearTimeout(request.timer);
79
+ request.reject(new Error('codex app-server stopped'));
80
+ pending.delete(id);
81
+ }
82
+ proc.kill('SIGTERM');
83
+ setTimeout(() => proc.kill('SIGKILL'), 1000).unref();
84
+ }
85
+ }
7
86
  async function discoverCursorModels() {
8
87
  const spec = resolveBuiltinCommand('cursor');
9
88
  if (!spec)
10
89
  return [];
11
- const result = await runCommand(spec.command, [...spec.args, '--list-models']);
90
+ const result = await runResolvedCommand(spec, ['--list-models']);
12
91
  return parseCursorModels(result.stdout);
13
92
  }
14
93
  async function discoverOpenClawModels() {
15
94
  const spec = resolveBuiltinCommand('openclaw');
16
95
  if (!spec)
17
96
  return [];
18
- const result = await runCommand(spec.command, [...spec.args, 'models', 'list', '--json']);
97
+ const result = await runResolvedCommand(spec, ['models', 'list', '--json']);
19
98
  return parseOpenClawModels(result.stdout);
20
99
  }
21
100
  async function discoverClaudeModels() {
22
- const spec = resolveBuiltinCommand('claude');
23
- if (!spec)
101
+ if (!resolveBuiltinCommand('claude'))
24
102
  return [];
25
- const runDiscovery = async (startupArgs) => runPtyCommand(spec, {
26
- startupArgs,
27
- readyPatterns: [/[>❯]/, /claude/i],
28
- closePatterns: [/esc/i, /confirm/i, /default/i],
29
- timeoutMs: 12_000,
30
- });
31
- const primaryRaw = await runDiscovery(['--bare', '--dangerously-skip-permissions']);
32
- const primaryModels = parseClaudeModels(primaryRaw);
33
- if (primaryModels.length > 0)
34
- return primaryModels;
35
- const clean = primaryRaw.toLowerCase();
36
- const bareUnsupported = clean.includes('--bare') &&
37
- (clean.includes('unknown option') ||
38
- clean.includes('unknown argument') ||
39
- clean.includes('unexpected argument') ||
40
- clean.includes('unrecognized option'));
41
- if (!bareUnsupported)
42
- return primaryModels;
43
- const fallbackRaw = await runDiscovery(['--dangerously-skip-permissions']);
44
- return parseClaudeModels(fallbackRaw);
103
+ return fallbackClaudeAliasModels();
45
104
  }
46
105
  async function discoverCodexModels() {
47
106
  const spec = resolveBuiltinCommand('codex');
48
107
  if (!spec)
49
108
  return [];
50
- const raw = await runPtyCommand(spec, {
51
- startupArgs: ['--no-alt-screen', '-C', DISCOVERY_WORKDIR],
52
- preOpenPromptPatterns: [/update available!/i, /skip until next version/i, /release notes:/i],
53
- preOpenPromptInput: '\u001b[B\r',
54
- readyPatterns: [/(?:^|\s)\/model\b/i, /codex/i],
55
- closePatterns: [/enter to select/i, /dismiss/i, /select model/i],
56
- timeoutMs: 45_000,
57
- scrollAfterOpenMs: 2500,
58
- scrollCount: 15,
59
- scrollIntervalMs: 500,
60
- });
61
- return parseCodexModels(raw);
109
+ const appServerModels = await discoverCodexModelsViaAppServer(spec).catch(() => []);
110
+ return appServerModels;
62
111
  }
63
112
  async function discoverGeminiModels() {
64
- const spec = resolveBuiltinCommand('gemini');
65
- if (!spec)
113
+ if (!resolveBuiltinCommand('gemini'))
66
114
  return [];
67
- const raw = await runPtyCommand(spec, {
68
- readyPatterns: [/[>❯]/, /gemini/i],
69
- closePatterns: [/enter to select/i, /select model/i, /\besc\b/i],
70
- timeoutMs: 16_000,
71
- });
72
- return parseGeminiModels(raw);
115
+ return fallbackGeminiModels();
73
116
  }
74
117
  async function discoverPiModels(context) {
75
118
  if (!context.serverUrl || !context.authToken)
@@ -116,4 +159,3 @@ export async function discoverModelsForAgent(agent, context) {
116
159
  }
117
160
  return discoverBuiltinModels(agent.type, context);
118
161
  }
119
- //# sourceMappingURL=discovery.js.map
@@ -3,6 +3,9 @@ export declare function stripAnsi(text: string): string;
3
3
  export declare function parseCursorModels(raw: string): ModelInfo[];
4
4
  export declare function parseOpenClawModels(raw: string): ModelInfo[];
5
5
  export declare function parseClaudeModels(raw: string): ModelInfo[];
6
+ export declare function parseClaudeBinaryModels(raw: string): ModelInfo[];
7
+ export declare function fallbackClaudeAliasModels(): ModelInfo[];
6
8
  export declare function parseCodexModels(raw: string): ModelInfo[];
9
+ export declare function parseCodexAppServerModels(raw: unknown): ModelInfo[];
7
10
  export declare function parseGeminiModels(raw: string): ModelInfo[];
8
- //# sourceMappingURL=parsers.d.ts.map
11
+ export declare function fallbackGeminiModels(): ModelInfo[];