@cleocode/adapters 2026.9.20 → 2026.9.22

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 (56) hide show
  1. package/dist/cant-context.d.ts +7 -5
  2. package/dist/cant-context.d.ts.map +1 -1
  3. package/dist/index.js +505 -330
  4. package/dist/index.js.map +3 -3
  5. package/dist/providers/claude-code/adapter.d.ts.map +1 -1
  6. package/dist/providers/claude-code/spawn.d.ts +2 -2
  7. package/dist/providers/claude-code/spawn.d.ts.map +1 -1
  8. package/dist/providers/claude-sdk/spawn.d.ts +1 -1
  9. package/dist/providers/codex/adapter.d.ts.map +1 -1
  10. package/dist/providers/codex/spawn.d.ts +1 -1
  11. package/dist/providers/codex/spawn.d.ts.map +1 -1
  12. package/dist/providers/gemini-cli/adapter.d.ts.map +1 -1
  13. package/dist/providers/gemini-cli/spawn.d.ts +1 -1
  14. package/dist/providers/gemini-cli/spawn.d.ts.map +1 -1
  15. package/dist/providers/kimi/adapter.d.ts.map +1 -1
  16. package/dist/providers/kimi/spawn.d.ts.map +1 -1
  17. package/dist/providers/opencode/adapter.d.ts.map +1 -1
  18. package/dist/providers/opencode/spawn.d.ts +3 -2
  19. package/dist/providers/opencode/spawn.d.ts.map +1 -1
  20. package/dist/providers/pi/adapter.d.ts +1 -1
  21. package/dist/providers/pi/adapter.d.ts.map +1 -1
  22. package/dist/providers/pi/spawn.d.ts +3 -3
  23. package/dist/providers/pi/spawn.d.ts.map +1 -1
  24. package/dist/providers/shared/agent-spawn-wrapper.d.ts +5 -0
  25. package/dist/providers/shared/agent-spawn-wrapper.d.ts.map +1 -1
  26. package/dist/providers/shared/cli-spawn.d.ts +28 -0
  27. package/dist/providers/shared/cli-spawn.d.ts.map +1 -0
  28. package/dist/providers/shared/credentials.d.ts +2 -2
  29. package/dist/providers/shared/credentials.d.ts.map +1 -1
  30. package/dist/providers/shared/prompt-file.d.ts +32 -0
  31. package/dist/providers/shared/prompt-file.d.ts.map +1 -0
  32. package/package.json +5 -5
  33. package/src/__tests__/agent-spawn-wrapper-win32.test.ts +42 -0
  34. package/src/__tests__/cant-context.test.ts +89 -37
  35. package/src/__tests__/cli-spawn-win32.test.ts +105 -0
  36. package/src/__tests__/spawn-prompt-file.test.ts +37 -0
  37. package/src/cant-context.ts +11 -15
  38. package/src/providers/claude-code/adapter.ts +6 -11
  39. package/src/providers/claude-code/spawn.ts +11 -25
  40. package/src/providers/claude-sdk/spawn.ts +1 -1
  41. package/src/providers/codex/adapter.ts +6 -11
  42. package/src/providers/codex/spawn.ts +17 -31
  43. package/src/providers/gemini-cli/adapter.ts +6 -11
  44. package/src/providers/gemini-cli/spawn.ts +13 -18
  45. package/src/providers/kimi/adapter.ts +6 -11
  46. package/src/providers/kimi/spawn.ts +3 -11
  47. package/src/providers/opencode/__tests__/spawn-prompt-delivery.test.ts +123 -0
  48. package/src/providers/opencode/adapter.ts +6 -11
  49. package/src/providers/opencode/spawn.ts +23 -25
  50. package/src/providers/pi/adapter.ts +8 -18
  51. package/src/providers/pi/spawn.ts +15 -33
  52. package/src/providers/shared/__tests__/credentials-cleo-home.test.ts +42 -0
  53. package/src/providers/shared/agent-spawn-wrapper.ts +22 -2
  54. package/src/providers/shared/cli-spawn.ts +41 -0
  55. package/src/providers/shared/credentials.ts +6 -5
  56. package/src/providers/shared/prompt-file.ts +44 -0
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAI7D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,iBAAiB;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA6B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,sBAAsB,CAAC;IAC9B;;;;;;OAMG;IACH,KAAK,EAAE,oBAAoB,CAAC;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,yBAAyB,CAAC;IACnC,mEAAmE;IACnE,KAAK,EAAE,sBAAsB,CAAC;IAC9B,+EAA+E;IAC/E,cAAc,EAAE,gCAAgC,CAAC;IACjD,wDAAwD;IACxD,SAAS,EAAE,2BAA2B,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,EAAE,0BAA0B,CAAC;IAErC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAY5B;;;;;;;;OAQG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyCjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,gCAAgC,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAC;AAE7D;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAkB,YAAW,mBAAmB;IAC3D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,iBAAiB;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA6B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,sBAAsB,CAAC;IAC9B;;;;;;OAMG;IACH,KAAK,EAAE,oBAAoB,CAAC;IAC5B,+EAA+E;IAC/E,OAAO,EAAE,yBAAyB,CAAC;IACnC,mEAAmE;IACnE,KAAK,EAAE,sBAAsB,CAAC;IAC9B,+EAA+E;IAC/E,cAAc,EAAE,gCAAgC,CAAC;IACjD,wDAAwD;IACxD,SAAS,EAAE,2BAA2B,CAAC;IACvC,2EAA2E;IAC3E,QAAQ,EAAE,0BAA0B,CAAC;IAErC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAY5B;;;;;;;;OAQG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAuCjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -24,7 +24,7 @@ import type { AdapterSpawnProvider, SpawnContext, SpawnResult } from '@cleocode/
24
24
  * @remarks
25
25
  * The provider uses `--allow-insecure --no-upgrade-check` flags to
26
26
  * ensure the Claude CLI starts without interactive prompts. Prompts are
27
- * written to temporary files under `/tmp/` and cleaned up after the
27
+ * written to temporary files under a private temp directory (`os.tmpdir()`) and cleaned up after the
28
28
  * child process exits. Processes are tracked by instance ID in an
29
29
  * in-memory map and verified via `kill(pid, 0)` liveness checks.
30
30
  */
@@ -34,7 +34,7 @@ export declare class ClaudeCodeSpawnProvider implements AdapterSpawnProvider {
34
34
  /**
35
35
  * Check if the Claude CLI is available in PATH.
36
36
  *
37
- * @returns true if `claude` is found via `which`
37
+ * @returns true if `claude` is found on PATH (PATHEXT-aware on Windows)
38
38
  */
39
39
  canSpawn(): Promise<boolean>;
40
40
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EACV,oBAAoB,EAEpB,YAAY,EACZ,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAgB7B;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAwB,YAAW,oBAAoB;IAClE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IASlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA2IxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAuB3C;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlD;;;;;;;OAOG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAIpC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/claude-code/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EACV,oBAAoB,EAEpB,YAAY,EACZ,WAAW,EACZ,MAAM,qBAAqB,CAAC;AAgB7B;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAwB,YAAW,oBAAoB;IAClE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAoIxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAuB3C;;;;;;;;;;;;OAYG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBlD;;;;;;;OAOG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;CAIpC"}
@@ -46,7 +46,7 @@ export declare class ClaudeSDKSpawnProvider implements AdapterSpawnProvider {
46
46
  *
47
47
  * Uses 3-tier key resolution so the provider works with:
48
48
  * - `ANTHROPIC_API_KEY` environment variable (explicit)
49
- * - `~/.local/share/cleo/anthropic-key` (user-stored via cleo config)
49
+ * - `<getCleoHome()>/anthropic-key` (user-stored via cleo config)
50
50
  * - Claude Code OAuth token (zero-config for Claude Code users)
51
51
  *
52
52
  * @returns `true` when any Anthropic credential is available
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAIpD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,mBAAmB;IACtD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,WAAW;IACtB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,WAAW;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAW/B;IAEF,6CAA6C;IAC7C,KAAK,EAAE,iBAAiB,CAAC;IACzB,uDAAuD;IACvD,OAAO,EAAE,oBAAoB,CAAC;IAE9B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,YAAa,YAAW,mBAAmB;IACtD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,WAAW;IACtB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,WAAW;IACxB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAW/B;IAEF,6CAA6C;IAC7C,KAAK,EAAE,iBAAiB,CAAC;IACzB,uDAAuD;IACvD,OAAO,EAAE,oBAAoB,CAAC;IAE9B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAmCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -47,7 +47,7 @@ export declare class CodexSpawnProvider implements AdapterSpawnProvider {
47
47
  /**
48
48
  * Check if the Codex CLI is available in PATH.
49
49
  *
50
- * @returns `true` if `codex` is found via `which`
50
+ * @returns `true` if `codex` is found on PATH (PATHEXT-aware on Windows)
51
51
  */
52
52
  canSpawn(): Promise<boolean>;
53
53
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAY3F;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAclC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAqFxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/codex/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAa3F;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAUlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA4ExD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini-cli/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAIxD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAiB,YAAW,mBAAmB;IAC1D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAsB/B;IAEF,6CAA6C;IAC7C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,uDAAuD;IACvD,OAAO,EAAE,wBAAwB,CAAC;IAElC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini-cli/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAExD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAiB,YAAW,mBAAmB;IAC1D,kCAAkC;IAClC,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,gBAAgB;IAC7B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAsB/B;IAEF,6CAA6C;IAC7C,KAAK,EAAE,qBAAqB,CAAC;IAC7B,uDAAuD;IACvD,OAAO,EAAE,wBAAwB,CAAC;IAElC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAmCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -48,7 +48,7 @@ export declare class GeminiCliSpawnProvider implements AdapterSpawnProvider {
48
48
  /**
49
49
  * Check if the Gemini CLI is available in PATH.
50
50
  *
51
- * @returns `true` if `gemini` is found via `which`
51
+ * @returns `true` if `gemini` is found on PATH (PATHEXT-aware on Windows)
52
52
  */
53
53
  canSpawn(): Promise<boolean>;
54
54
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini-cli/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAe3F;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAuB,YAAW,oBAAoB;IACjE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAclC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA8ExD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/gemini-cli/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAe3F;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,sBAAuB,YAAW,oBAAoB;IACjE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAUlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA8ExD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/kimi/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAInD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAY,YAAW,mBAAmB;IACrD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,UAAU;IACrB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,UAAU;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAW/B;IAEF,4DAA4D;IAC5D,KAAK,EAAE,gBAAgB,CAAC;IACxB,uDAAuD;IACvD,OAAO,EAAE,mBAAmB,CAAC;IAE7B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAqCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/kimi/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAY,YAAW,mBAAmB;IACrD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,UAAU;IACrB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,UAAU;IACvB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CAW/B;IAEF,4DAA4D;IAC5D,KAAK,EAAE,gBAAgB,CAAC;IACxB,uDAAuD;IACvD,OAAO,EAAE,mBAAmB,CAAC;IAE7B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAO5B;;;;;OAKG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;;;OAMG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK9B;;;;;;;;;;OAUG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAmCjD;;;OAGG;IACH,aAAa,IAAI,OAAO;IAIxB;;;OAGG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/kimi/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AA8D3F;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,oBAAoB;IAC5D,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAiC;IAElE;;;;;;;;OAQG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAYlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAkGxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAU3C;;;;;;;;OAQG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGnD"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/kimi/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAwD3F;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,iBAAkB,YAAW,oBAAoB;IAC5D,kCAAkC;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAiC;IAElE;;;;;;;;OAQG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAYlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAkGxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAU3C;;;;;;;;OAQG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGnD"}
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAInD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,YAAW,mBAAmB;IACzD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,cAAc;IACzB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,cAAc;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA0B/B;IAEF,0EAA0E;IAC1E,KAAK,EAAE,oBAAoB,CAAC;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,qBAAqB,CAAC;IAC7B,iEAAiE;IACjE,OAAO,EAAE,uBAAuB,CAAC;IAEjC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAQ5B;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IA2CjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEnD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,YAAW,mBAAmB;IACzD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,cAAc;IACzB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,cAAc;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA0B/B;IAEF,0EAA0E;IAC1E,KAAK,EAAE,oBAAoB,CAAC;IAC5B,0EAA0E;IAC1E,KAAK,EAAE,qBAAqB,CAAC;IAC7B,iEAAiE;IACjE,OAAO,EAAE,uBAAuB,CAAC;IAEjC,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAQ5B;;;;;;;OAOG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAyCjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -42,7 +42,8 @@ export declare function buildOpenCodeAgentMarkdown(description: string, instruct
42
42
  *
43
43
  * Spawns detached OpenCode CLI processes for subagent execution.
44
44
  * Each spawn ensures a CLEO subagent definition exists, then runs
45
- * `opencode run --format json --agent <name> --title <title> <prompt>`
45
+ * `opencode run --format json --agent <name> --title <title>` with the
46
+ * prompt piped on stdin (never in argv, T12619)
46
47
  * as a detached, unref'd child process.
47
48
  *
48
49
  * @remarks
@@ -58,7 +59,7 @@ export declare class OpenCodeSpawnProvider implements AdapterSpawnProvider {
58
59
  /**
59
60
  * Check if the OpenCode CLI is available in PATH.
60
61
  *
61
- * @returns true if `opencode` is found via `which`
62
+ * @returns true if `opencode` is found on PATH (PATHEXT-aware on Windows)
62
63
  */
63
64
  canSpawn(): Promise<boolean>;
64
65
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAkB3F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAY5F;AA+CD;;;;;;;;;;;;;;GAcG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IASlC;;;;;;;;;OASG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA+ExD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/opencode/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAkB3F;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAY5F;AA+CD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,qBAAsB,YAAW,oBAAoB;IAChE,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;OAIG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAIlC;;;;;;;;;OASG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAmFxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
@@ -84,7 +84,7 @@ export declare class PiAdapter implements CLEOProviderAdapter {
84
84
  *
85
85
  * Checks:
86
86
  * 1. Adapter has been initialized
87
- * 2. Pi CLI is available (via PI_CLI_PATH or `which pi`)
87
+ * 2. Pi CLI is available (via PI_CLI_PATH or a PATH search for `pi`)
88
88
  * 3. Pi global state root (~/.pi/agent/ or PI_CODING_AGENT_DIR) exists
89
89
  *
90
90
  * @returns Health status with details about each check
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/pi/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAOH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAwB7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,SAAU,YAAW,mBAAmB;IACnD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,QAAQ;IACnB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,QAAQ;IACrB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA0B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,cAAc,CAAC;IACtB,oEAAoE;IACpE,KAAK,EAAE,eAAe,CAAC;IACvB,iEAAiE;IACjE,OAAO,EAAE,iBAAiB,CAAC;IAE3B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAQ5B;;;;;;OAMG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAwDjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/providers/pi/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAsB7C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,SAAU,YAAW,mBAAmB;IACnD,kCAAkC;IAClC,QAAQ,CAAC,EAAE,QAAQ;IACnB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,QAAQ;IACrB,8BAA8B;IAC9B,QAAQ,CAAC,OAAO,WAAW;IAE3B,+CAA+C;IAC/C,YAAY,EAAE,mBAAmB,CA0B/B;IAEF,8DAA8D;IAC9D,KAAK,EAAE,cAAc,CAAC;IACtB,oEAAoE;IACpE,KAAK,EAAE,eAAe,CAAC;IACvB,iEAAiE;IACjE,OAAO,EAAE,iBAAiB,CAAC;IAE3B,oEAAoE;IACpE,OAAO,CAAC,UAAU,CAAuB;IACzC,kDAAkD;IAClD,OAAO,CAAC,WAAW,CAAS;;IAQ5B;;;;;;OAMG;IACG,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ9B;;;;;;;;;OASG;IACG,WAAW,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAiDjD;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,IAAI;CAG/B"}
@@ -7,7 +7,7 @@
7
7
  * subagent processes with prompts written to temporary files. Processes
8
8
  * run detached and are tracked by PID for listing and termination.
9
9
  *
10
- * Pi detection: `PI_CLI_PATH` env var or `which pi`.
10
+ * Pi detection: `PI_CLI_PATH` env var or a PATH search for `pi`.
11
11
  *
12
12
  * @task T553
13
13
  */
@@ -20,7 +20,7 @@ import type { AdapterSpawnProvider, SpawnContext, SpawnResult } from '@cleocode/
20
20
  * prompt file as the primary argument as a detached, unref'd child process.
21
21
  *
22
22
  * @remarks
23
- * Prompts are written to temporary files under `/tmp/` and cleaned up
23
+ * Prompts are written to temporary files under a private temp directory (`os.tmpdir()`) and cleaned up
24
24
  * after the child process exits. Processes are tracked by instance ID in
25
25
  * an in-memory map and verified via `kill(pid, 0)` liveness checks.
26
26
  * All failures are best-effort and non-blocking.
@@ -31,7 +31,7 @@ export declare class PiSpawnProvider implements AdapterSpawnProvider {
31
31
  /**
32
32
  * Check if the Pi CLI is available.
33
33
  *
34
- * Checks `PI_CLI_PATH` env var first, then tries `which pi`.
34
+ * Checks `PI_CLI_PATH` env var first, then searches PATH for `pi`.
35
35
  *
36
36
  * @returns true if the Pi CLI is accessible
37
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/pi/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAsB3F;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,YAAW,oBAAoB;IAC1D,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAelC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAuExD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/pi/spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAuB3F;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,YAAW,oBAAoB;IAC1D,mDAAmD;IACnD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;;;OAMG;IACG,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;IAOlC;;;;;;;;OAQG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IA8DxD;;;;;;;OAOG;IACG,WAAW,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;IAqB3C;;;;;;;OAOG;IACG,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWnD"}
@@ -51,6 +51,11 @@ export interface AgentSpawnArgs {
51
51
  command: string;
52
52
  /** Full argument list. */
53
53
  args: string[];
54
+ /**
55
+ * Set (`true`) only when win32 launches a `.cmd`/`.bat` CLI through
56
+ * cmd.exe; pass it to `spawn` so the pre-quoted line is not re-quoted.
57
+ */
58
+ windowsVerbatimArguments?: boolean;
54
59
  /**
55
60
  * Ownership handle to persist in the session tracking record.
56
61
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-spawn-wrapper.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/agent-spawn-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,KAAK,EAAwB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAMrF,kFAAkF;AAClF,eAAO,MAAM,UAAU,EAAG,YAAqB,CAAC;AAmChD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAElE;AAyBD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;;OAIG;IACH,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,MAAM,GACf,cAAc,CAmEhB"}
1
+ {"version":3,"file":"agent-spawn-wrapper.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/agent-spawn-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,KAAK,EAAwB,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAOrF,kFAAkF;AAClF,eAAO,MAAM,UAAU,EAAG,YAAqB,CAAC;AAmChD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAElE;AAyBD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC;;;;OAIG;IACH,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAMD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,CAAC,EAAE,MAAM,GACf,cAAc,CAiFhB"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Spawn a provider CLI the same way on every platform.
3
+ *
4
+ * On Windows an npm-installed CLI (`codex`, `gemini`, `opencode`, `pi`) is a
5
+ * `.cmd` shim. Node's bare-name lookup only tries `.exe`/`.com`, and Node
6
+ * refuses to spawn a `.cmd` without a shell (CVE-2024-27980), so a bare
7
+ * `spawn('codex', …)` failed there. {@link resolveSpawnInvocation} spawns the
8
+ * absolute path, routing batch files through cmd.exe with injection-safe
9
+ * quoting. POSIX is unchanged.
10
+ *
11
+ * @task T12618
12
+ */
13
+ import { type ChildProcess, type SpawnOptions } from 'node:child_process';
14
+ /**
15
+ * Spawn `command args` without a user-visible shell on any platform.
16
+ *
17
+ * @param command - CLI name or path, e.g. `codex` or `PI_CLI_PATH`.
18
+ * @param args - Literal arguments; never interpreted by a shell.
19
+ * @param options - Spawn options (cwd, stdio, detached, env).
20
+ * @returns The child process.
21
+ * @throws When a win32 batch-file argument contains a line break.
22
+ * @example
23
+ * ```ts
24
+ * const child = spawnCli('codex', ['--full-auto', promptFile], { detached: true, stdio: 'ignore' });
25
+ * ```
26
+ */
27
+ export declare function spawnCli(command: string, args: readonly string[], options: SpawnOptions): ChildProcess;
28
+ //# sourceMappingURL=cli-spawn.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-spawn.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/cli-spawn.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,YAAY,EAAS,MAAM,oBAAoB,CAAC;AAGjF;;;;;;;;;;;;GAYG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,YAAY,GACpB,YAAY,CAOd"}
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * ## Resolution tiers (first non-empty match wins)
10
10
  * 1. `ANTHROPIC_API_KEY` environment variable
11
- * 2. `~/.local/share/cleo/anthropic-key` (XDG-aware legacy flat-key file)
11
+ * 2. `<getCleoHome()>/anthropic-key` (legacy flat-key file)
12
12
  * 3. `~/.claude/.credentials.json` OAuth bearer token
13
13
  *
14
14
  * Call-sites use the same `resolveCredentials('anthropic').apiKey` pattern
@@ -38,7 +38,7 @@ export interface ResolvedCredential {
38
38
  *
39
39
  * Resolution order (first non-empty match wins):
40
40
  * 1. `ANTHROPIC_API_KEY` environment variable
41
- * 2. `~/.local/share/cleo/anthropic-key` (XDG-aware stored key)
41
+ * 2. `<getCleoHome()>/anthropic-key` (stored key)
42
42
  * 3. `~/.claude/.credentials.json` Claude Code OAuth token
43
43
  *
44
44
  * Never throws — all filesystem errors are caught and treated as "not found".
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAWH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,kBAAkB,CA6B7E"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAYH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,6EAA6E;IAC7E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAMD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,WAAW,GAAG,kBAAkB,CA6B7E"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Private temp files for spawn-adapter prompts.
3
+ *
4
+ * Prompts used to be written to a literal `/tmp/<provider>-spawn-<id>.txt`.
5
+ * Windows has no `/tmp`, so every spawn failed there, and on macOS the path
6
+ * ignored `$TMPDIR` and the per-user sandbox temp. Each prompt now lives in a
7
+ * fresh `mkdtemp` directory under `os.tmpdir()`, removed with the file (T12606).
8
+ *
9
+ * @task T12606
10
+ */
11
+ /**
12
+ * Write a prompt to `prompt.txt` inside a new private temp directory.
13
+ *
14
+ * @param prefix - Directory-name prefix identifying the provider, e.g. `claude-spawn`.
15
+ * @param prompt - Prompt text.
16
+ * @returns Absolute path of the written prompt file.
17
+ * @example
18
+ * ```ts
19
+ * const file = await writeSpawnPromptFile('codex-spawn', prompt);
20
+ * // …spawn the child with `file`, then on exit:
21
+ * await removeSpawnPromptFile(file);
22
+ * ```
23
+ */
24
+ export declare function writeSpawnPromptFile(prefix: string, prompt: string): Promise<string>;
25
+ /**
26
+ * Remove a prompt file written by {@link writeSpawnPromptFile} and its directory.
27
+ * Never throws: cleanup failure must not mask the spawn outcome.
28
+ *
29
+ * @param file - Path returned by {@link writeSpawnPromptFile}.
30
+ */
31
+ export declare function removeSpawnPromptFile(file: string): Promise<void>;
32
+ //# sourceMappingURL=prompt-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-file.d.ts","sourceRoot":"","sources":["../../../src/providers/shared/prompt-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;;;;;;;;;GAYG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK1F;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleocode/adapters",
3
- "version": "2026.9.20",
3
+ "version": "2026.9.22",
4
4
  "description": "Unified provider adapters for CLEO (Claude Code, OpenCode, Cursor)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,9 +15,9 @@
15
15
  "@ai-sdk/anthropic": "^3.0.69",
16
16
  "@ai-sdk/openai": "^2.0.53",
17
17
  "ai": "^6.0.168",
18
- "@cleocode/caamp": "2026.9.20",
19
- "@cleocode/contracts": "2026.9.20",
20
- "@cleocode/paths": "2026.9.20"
18
+ "@cleocode/caamp": "2026.9.22",
19
+ "@cleocode/paths": "2026.9.22",
20
+ "@cleocode/contracts": "2026.9.22"
21
21
  },
22
22
  "license": "MIT",
23
23
  "engines": {
@@ -30,7 +30,7 @@
30
30
  "devDependencies": {
31
31
  "@types/node": "^24.3.0",
32
32
  "vitest": "^4.1.4",
33
- "@cleocode/playbooks": "2026.9.20"
33
+ "@cleocode/playbooks": "2026.9.22"
34
34
  },
35
35
  "repository": {
36
36
  "type": "git",
@@ -0,0 +1,42 @@
1
+ /**
2
+ * T12604 — agent spawns must not route through `sh` on Windows.
3
+ *
4
+ * `buildAgentSpawnArgs` wrapped the agent binary in `sh -c 'ulimit -c 0; …'`
5
+ * whenever systemd-run was absent, so no agent could be spawned on Windows.
6
+ */
7
+
8
+ import { afterEach, describe, expect, it } from 'vitest';
9
+ import {
10
+ _forceSystemdRunAvailable,
11
+ buildAgentSpawnArgs,
12
+ } from '../providers/shared/agent-spawn-wrapper.js';
13
+
14
+ const realPlatform = process.platform;
15
+
16
+ function setPlatform(value: NodeJS.Platform): void {
17
+ Object.defineProperty(process, 'platform', { value, configurable: true });
18
+ }
19
+
20
+ afterEach(() => {
21
+ setPlatform(realPlatform);
22
+ _forceSystemdRunAvailable(false);
23
+ });
24
+
25
+ describe('buildAgentSpawnArgs pgid fallback per platform (T12604)', () => {
26
+ it('spawns the agent binary directly on win32', () => {
27
+ setPlatform('win32');
28
+ _forceSystemdRunAvailable(false);
29
+ const built = buildAgentSpawnArgs('claude', ['--print', 'prompt.txt'], 'T1');
30
+ expect(built.command).toBe('claude');
31
+ expect(built.args).toEqual(['--print', 'prompt.txt']);
32
+ expect(built.ownership.mode).toBe('pgid');
33
+ });
34
+
35
+ it('keeps ulimit core suppression on POSIX', () => {
36
+ setPlatform('linux');
37
+ _forceSystemdRunAvailable(false);
38
+ const built = buildAgentSpawnArgs('claude', ['--print'], 'T1');
39
+ expect(built.command).toBe('sh');
40
+ expect(built.args.slice(0, 2)).toEqual(['-c', 'ulimit -c 0; exec "$@"']);
41
+ });
42
+ });
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Tests cover:
5
5
  * - discoverCantFiles: finds .cant files, handles missing dirs
6
- * - resolveThreeTierPaths: XDG-compliant paths with env var overrides
6
+ * - resolveThreeTierPaths: tiers resolve through @cleocode/paths on every platform
7
7
  * - discoverCantFilesMultiTier: 3-tier merge with override semantics
8
8
  * - readMemoryBridge: reads file, handles missing/empty
9
9
  * - buildMemoryBridgeBlock: wraps content in labeled section
@@ -14,9 +14,10 @@
14
14
  */
15
15
 
16
16
  import { mkdirSync, rmSync, writeFileSync } from 'node:fs';
17
- import { tmpdir } from 'node:os';
17
+ import { homedir, tmpdir } from 'node:os';
18
18
  import { join } from 'node:path';
19
- import { afterEach, beforeEach, describe, expect, it } from 'vitest';
19
+ import { getCleoHome } from '@cleocode/paths';
20
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
20
21
 
21
22
  import {
22
23
  buildCantEnrichedPrompt,
@@ -24,6 +25,7 @@ import {
24
25
  buildMentalModelInjection,
25
26
  discoverCantFiles,
26
27
  discoverCantFilesMultiTier,
28
+ readIdentityFile,
27
29
  readMemoryBridge,
28
30
  resolveThreeTierPaths,
29
31
  } from '../cant-context.js';
@@ -68,33 +70,81 @@ describe('discoverCantFiles', () => {
68
70
  // ---------------------------------------------------------------------------
69
71
 
70
72
  describe('resolveThreeTierPaths', () => {
73
+ const PLATFORM = Object.getOwnPropertyDescriptor(process, 'platform');
74
+
75
+ function stubPlatform(platform: NodeJS.Platform): void {
76
+ Object.defineProperty(process, 'platform', { value: platform, configurable: true });
77
+ }
78
+
79
+ beforeEach(() => {
80
+ vi.stubEnv('CLEO_HOME', undefined);
81
+ vi.stubEnv('CLEO_CONFIG_HOME', undefined);
82
+ });
83
+
84
+ afterEach(() => {
85
+ if (PLATFORM) Object.defineProperty(process, 'platform', PLATFORM);
86
+ vi.unstubAllEnvs();
87
+ });
88
+
71
89
  it('returns project tier pointing to .cleo/cant/', () => {
72
90
  const paths = resolveThreeTierPaths('/my/project');
73
91
  expect(paths.project).toBe(join('/my/project', '.cleo', 'cant'));
74
92
  });
75
93
 
76
- it('respects XDG_DATA_HOME for global tier', () => {
77
- const originalXdg = process.env['XDG_DATA_HOME'];
78
- process.env['XDG_DATA_HOME'] = '/custom/data';
79
- try {
80
- const paths = resolveThreeTierPaths('/my/project');
81
- expect(paths.global).toBe(join('/custom/data', 'cleo', 'cant'));
82
- } finally {
83
- if (originalXdg) process.env['XDG_DATA_HOME'] = originalXdg;
84
- else delete process.env['XDG_DATA_HOME'];
85
- }
86
- });
87
-
88
- it('respects XDG_CONFIG_HOME for user tier', () => {
89
- const originalXdg = process.env['XDG_CONFIG_HOME'];
90
- process.env['XDG_CONFIG_HOME'] = '/custom/config';
91
- try {
92
- const paths = resolveThreeTierPaths('/my/project');
93
- expect(paths.user).toBe(join('/custom/config', 'cleo', 'cant'));
94
- } finally {
95
- if (originalXdg) process.env['XDG_CONFIG_HOME'] = originalXdg;
96
- else delete process.env['XDG_CONFIG_HOME'];
97
- }
94
+ it('global tier is <getCleoHome()>/cant and user tier is <CLEO config>/cant', () => {
95
+ vi.stubEnv('CLEO_HOME', '/opt/cleo-data');
96
+ vi.stubEnv('CLEO_CONFIG_HOME', '/opt/cleo-config');
97
+ const paths = resolveThreeTierPaths('/my/project');
98
+ expect(paths.global).toBe(join('/opt/cleo-data', 'cant'));
99
+ expect(paths.user).toBe(join('/opt/cleo-config', 'cant'));
100
+ });
101
+
102
+ it('macOS: global and user tiers are under ~/Library, not the XDG dirs (T12602)', () => {
103
+ stubPlatform('darwin');
104
+ vi.stubEnv('XDG_DATA_HOME', '/custom/data');
105
+ vi.stubEnv('XDG_CONFIG_HOME', '/custom/config');
106
+ const paths = resolveThreeTierPaths('/my/project');
107
+ expect(paths.global).toBe(join(getCleoHome(), 'cant'));
108
+ expect(paths.global).toBe(join(homedir(), 'Library', 'Application Support', 'cleo', 'cant'));
109
+ expect(paths.user).toBe(join(homedir(), 'Library', 'Preferences', 'cleo', 'cant'));
110
+ });
111
+
112
+ it('Windows: global tier is under %LOCALAPPDATA% (T12602)', () => {
113
+ stubPlatform('win32');
114
+ vi.stubEnv('LOCALAPPDATA', 'C:\\Users\\me\\AppData\\Local');
115
+ vi.stubEnv('XDG_DATA_HOME', '/custom/data');
116
+ const paths = resolveThreeTierPaths('/my/project');
117
+ expect(paths.global).toBe(join(getCleoHome(), 'cant'));
118
+ expect(paths.global.startsWith('C:\\Users\\me\\AppData\\Local')).toBe(true);
119
+ });
120
+
121
+ it('Linux: honours XDG_DATA_HOME and XDG_CONFIG_HOME', () => {
122
+ stubPlatform('linux');
123
+ vi.stubEnv('XDG_DATA_HOME', '/custom/data');
124
+ vi.stubEnv('XDG_CONFIG_HOME', '/custom/config');
125
+ const paths = resolveThreeTierPaths('/my/project');
126
+ expect(paths.global).toBe(join('/custom/data', 'cleo', 'cant'));
127
+ expect(paths.user).toBe(join('/custom/config', 'cleo', 'cant'));
128
+ });
129
+ });
130
+
131
+ // ---------------------------------------------------------------------------
132
+ // readIdentityFile — global tier (T12602)
133
+ // ---------------------------------------------------------------------------
134
+
135
+ describe('readIdentityFile', () => {
136
+ afterEach(() => {
137
+ vi.unstubAllEnvs();
138
+ });
139
+
140
+ it('reads the global CLEOOS-IDENTITY.md from getCleoHome(), not $XDG_DATA_HOME/cleo', () => {
141
+ const cleoHome = join(tempDir, 'cleo-home');
142
+ mkdirSync(cleoHome, { recursive: true });
143
+ writeFileSync(join(cleoHome, 'CLEOOS-IDENTITY.md'), 'global identity');
144
+ vi.stubEnv('CLEO_HOME', cleoHome);
145
+ vi.stubEnv('XDG_DATA_HOME', join(tempDir, 'empty-xdg'));
146
+
147
+ expect(readIdentityFile(join(tempDir, 'project'))).toBe('global identity');
98
148
  });
99
149
  });
100
150
 
@@ -103,22 +153,24 @@ describe('resolveThreeTierPaths', () => {
103
153
  // ---------------------------------------------------------------------------
104
154
 
105
155
  describe('discoverCantFilesMultiTier', () => {
106
- let origXdgData: string | undefined;
107
- let origXdgConfig: string | undefined;
108
-
109
156
  beforeEach(() => {
110
- // Override XDG paths so global/user tiers point to empty temp subdirs
111
- origXdgData = process.env['XDG_DATA_HOME'];
112
- origXdgConfig = process.env['XDG_CONFIG_HOME'];
113
- process.env['XDG_DATA_HOME'] = join(tempDir, 'xdg-data');
114
- process.env['XDG_CONFIG_HOME'] = join(tempDir, 'xdg-config');
157
+ // Point the global/user tiers at empty temp subdirs on every platform.
158
+ vi.stubEnv('CLEO_HOME', join(tempDir, 'cleo-home'));
159
+ vi.stubEnv('CLEO_CONFIG_HOME', join(tempDir, 'cleo-config'));
115
160
  });
116
161
 
117
162
  afterEach(() => {
118
- if (origXdgData) process.env['XDG_DATA_HOME'] = origXdgData;
119
- else delete process.env['XDG_DATA_HOME'];
120
- if (origXdgConfig) process.env['XDG_CONFIG_HOME'] = origXdgConfig;
121
- else delete process.env['XDG_CONFIG_HOME'];
163
+ vi.unstubAllEnvs();
164
+ });
165
+
166
+ it('discovers files from the global tier under getCleoHome() (T12602)', () => {
167
+ const globalCant = join(tempDir, 'cleo-home', 'cant');
168
+ mkdirSync(globalCant, { recursive: true });
169
+ writeFileSync(join(globalCant, 'global.cant'), 'team: global');
170
+
171
+ const result = discoverCantFilesMultiTier(tempDir);
172
+ expect(result.stats.global).toBe(1);
173
+ expect(result.files).toEqual([join(globalCant, 'global.cant')]);
122
174
  });
123
175
 
124
176
  it('discovers files from project tier', () => {