@cleocode/adapters 2026.9.20 → 2026.9.21
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.
- package/dist/cant-context.d.ts +7 -5
- package/dist/cant-context.d.ts.map +1 -1
- package/dist/index.js +501 -328
- package/dist/index.js.map +3 -3
- package/dist/providers/claude-code/adapter.d.ts.map +1 -1
- package/dist/providers/claude-code/spawn.d.ts +2 -2
- package/dist/providers/claude-code/spawn.d.ts.map +1 -1
- package/dist/providers/claude-sdk/spawn.d.ts +1 -1
- package/dist/providers/codex/adapter.d.ts.map +1 -1
- package/dist/providers/codex/spawn.d.ts +1 -1
- package/dist/providers/codex/spawn.d.ts.map +1 -1
- package/dist/providers/gemini-cli/adapter.d.ts.map +1 -1
- package/dist/providers/gemini-cli/spawn.d.ts +1 -1
- package/dist/providers/gemini-cli/spawn.d.ts.map +1 -1
- package/dist/providers/kimi/adapter.d.ts.map +1 -1
- package/dist/providers/kimi/spawn.d.ts.map +1 -1
- package/dist/providers/opencode/adapter.d.ts.map +1 -1
- package/dist/providers/opencode/spawn.d.ts +3 -2
- package/dist/providers/opencode/spawn.d.ts.map +1 -1
- package/dist/providers/pi/adapter.d.ts +1 -1
- package/dist/providers/pi/adapter.d.ts.map +1 -1
- package/dist/providers/pi/spawn.d.ts +3 -3
- package/dist/providers/pi/spawn.d.ts.map +1 -1
- package/dist/providers/shared/agent-spawn-wrapper.d.ts +5 -0
- package/dist/providers/shared/agent-spawn-wrapper.d.ts.map +1 -1
- package/dist/providers/shared/cli-spawn.d.ts +28 -0
- package/dist/providers/shared/cli-spawn.d.ts.map +1 -0
- package/dist/providers/shared/credentials.d.ts +2 -2
- package/dist/providers/shared/credentials.d.ts.map +1 -1
- package/dist/providers/shared/prompt-file.d.ts +32 -0
- package/dist/providers/shared/prompt-file.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/__tests__/agent-spawn-wrapper-win32.test.ts +42 -0
- package/src/__tests__/cant-context.test.ts +89 -37
- package/src/__tests__/cli-spawn-win32.test.ts +105 -0
- package/src/__tests__/spawn-prompt-file.test.ts +37 -0
- package/src/cant-context.ts +11 -15
- package/src/providers/claude-code/adapter.ts +6 -11
- package/src/providers/claude-code/spawn.ts +11 -25
- package/src/providers/claude-sdk/spawn.ts +1 -1
- package/src/providers/codex/adapter.ts +6 -11
- package/src/providers/codex/spawn.ts +17 -31
- package/src/providers/gemini-cli/adapter.ts +6 -11
- package/src/providers/gemini-cli/spawn.ts +13 -18
- package/src/providers/kimi/adapter.ts +6 -11
- package/src/providers/kimi/spawn.ts +3 -11
- package/src/providers/opencode/__tests__/spawn-prompt-delivery.test.ts +123 -0
- package/src/providers/opencode/adapter.ts +6 -11
- package/src/providers/opencode/spawn.ts +23 -25
- package/src/providers/pi/adapter.ts +8 -18
- package/src/providers/pi/spawn.ts +15 -33
- package/src/providers/shared/__tests__/credentials-cleo-home.test.ts +42 -0
- package/src/providers/shared/agent-spawn-wrapper.ts +22 -2
- package/src/providers/shared/cli-spawn.ts +41 -0
- package/src/providers/shared/credentials.ts +6 -5
- 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;
|
|
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
|
|
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
|
|
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;
|
|
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
|
-
* -
|
|
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;
|
|
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
|
|
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;
|
|
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;
|
|
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
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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
|
|
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
|
|
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;
|
|
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 `
|
|
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;
|
|
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 `
|
|
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
|
|
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
|
|
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;
|
|
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;
|
|
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.
|
|
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.
|
|
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;
|
|
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.
|
|
3
|
+
"version": "2026.9.21",
|
|
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.
|
|
19
|
-
"@cleocode/contracts": "2026.9.
|
|
20
|
-
"@cleocode/paths": "2026.9.
|
|
18
|
+
"@cleocode/caamp": "2026.9.21",
|
|
19
|
+
"@cleocode/contracts": "2026.9.21",
|
|
20
|
+
"@cleocode/paths": "2026.9.21"
|
|
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.
|
|
33
|
+
"@cleocode/playbooks": "2026.9.21"
|
|
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:
|
|
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 {
|
|
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('
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
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', () => {
|