@cleocode/adapters 2026.4.31 → 2026.4.35

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 (99) hide show
  1. package/dist/index.js +641 -5
  2. package/dist/index.js.map +4 -4
  3. package/dist/providers/claude-code/adapter.js +184 -0
  4. package/dist/providers/claude-code/adapter.js.map +1 -0
  5. package/dist/providers/claude-code/context-monitor.js +159 -0
  6. package/dist/providers/claude-code/context-monitor.js.map +1 -0
  7. package/dist/providers/claude-code/hooks.js +286 -0
  8. package/dist/providers/claude-code/hooks.js.map +1 -0
  9. package/dist/providers/claude-code/index.js +41 -0
  10. package/dist/providers/claude-code/index.js.map +1 -0
  11. package/dist/providers/claude-code/install.js +199 -0
  12. package/dist/providers/claude-code/install.js.map +1 -0
  13. package/dist/providers/claude-code/paths.js +41 -0
  14. package/dist/providers/claude-code/paths.js.map +1 -0
  15. package/dist/providers/claude-code/spawn.js +171 -0
  16. package/dist/providers/claude-code/spawn.js.map +1 -0
  17. package/dist/providers/claude-code/statusline.js +130 -0
  18. package/dist/providers/claude-code/statusline.js.map +1 -0
  19. package/dist/providers/claude-code/task-sync.js +119 -0
  20. package/dist/providers/claude-code/task-sync.js.map +1 -0
  21. package/dist/providers/claude-code/transport.js +29 -0
  22. package/dist/providers/claude-code/transport.js.map +1 -0
  23. package/dist/providers/codex/adapter.js +146 -0
  24. package/dist/providers/codex/adapter.js.map +1 -0
  25. package/dist/providers/codex/hooks.js +113 -0
  26. package/dist/providers/codex/hooks.js.map +1 -0
  27. package/dist/providers/codex/index.js +39 -0
  28. package/dist/providers/codex/index.js.map +1 -0
  29. package/dist/providers/codex/install.js +124 -0
  30. package/dist/providers/codex/install.js.map +1 -0
  31. package/dist/providers/cursor/adapter.js +151 -0
  32. package/dist/providers/cursor/adapter.js.map +1 -0
  33. package/dist/providers/cursor/hooks.js +208 -0
  34. package/dist/providers/cursor/hooks.js.map +1 -0
  35. package/dist/providers/cursor/index.js +36 -0
  36. package/dist/providers/cursor/index.js.map +1 -0
  37. package/dist/providers/cursor/install.js +180 -0
  38. package/dist/providers/cursor/install.js.map +1 -0
  39. package/dist/providers/cursor/spawn.js +59 -0
  40. package/dist/providers/cursor/spawn.js.map +1 -0
  41. package/dist/providers/gemini-cli/adapter.js +158 -0
  42. package/dist/providers/gemini-cli/adapter.js.map +1 -0
  43. package/dist/providers/gemini-cli/hooks.js +128 -0
  44. package/dist/providers/gemini-cli/hooks.js.map +1 -0
  45. package/dist/providers/gemini-cli/index.js +39 -0
  46. package/dist/providers/gemini-cli/index.js.map +1 -0
  47. package/dist/providers/gemini-cli/install.js +124 -0
  48. package/dist/providers/gemini-cli/install.js.map +1 -0
  49. package/dist/providers/kimi/adapter.js +145 -0
  50. package/dist/providers/kimi/adapter.js.map +1 -0
  51. package/dist/providers/kimi/hooks.js +79 -0
  52. package/dist/providers/kimi/hooks.js.map +1 -0
  53. package/dist/providers/kimi/index.js +39 -0
  54. package/dist/providers/kimi/index.js.map +1 -0
  55. package/dist/providers/kimi/install.js +124 -0
  56. package/dist/providers/kimi/install.js.map +1 -0
  57. package/dist/providers/opencode/adapter.js +166 -0
  58. package/dist/providers/opencode/adapter.js.map +1 -0
  59. package/dist/providers/opencode/hooks.js +206 -0
  60. package/dist/providers/opencode/hooks.js.map +1 -0
  61. package/dist/providers/opencode/index.js +37 -0
  62. package/dist/providers/opencode/index.js.map +1 -0
  63. package/dist/providers/opencode/install.js +115 -0
  64. package/dist/providers/opencode/install.js.map +1 -0
  65. package/dist/providers/opencode/spawn.js +241 -0
  66. package/dist/providers/opencode/spawn.js.map +1 -0
  67. package/dist/providers/pi/adapter.d.ts +102 -0
  68. package/dist/providers/pi/adapter.d.ts.map +1 -0
  69. package/dist/providers/pi/adapter.js +220 -0
  70. package/dist/providers/pi/adapter.js.map +1 -0
  71. package/dist/providers/pi/hooks.d.ts +149 -0
  72. package/dist/providers/pi/hooks.d.ts.map +1 -0
  73. package/dist/providers/pi/hooks.js +223 -0
  74. package/dist/providers/pi/hooks.js.map +1 -0
  75. package/dist/providers/pi/index.d.ts +36 -0
  76. package/dist/providers/pi/index.d.ts.map +1 -0
  77. package/dist/providers/pi/index.js +38 -0
  78. package/dist/providers/pi/index.js.map +1 -0
  79. package/dist/providers/pi/install.d.ts +68 -0
  80. package/dist/providers/pi/install.d.ts.map +1 -0
  81. package/dist/providers/pi/install.js +175 -0
  82. package/dist/providers/pi/install.js.map +1 -0
  83. package/dist/providers/pi/spawn.d.ts +68 -0
  84. package/dist/providers/pi/spawn.d.ts.map +1 -0
  85. package/dist/providers/pi/spawn.js +187 -0
  86. package/dist/providers/pi/spawn.js.map +1 -0
  87. package/dist/providers/shared/transcript-reader.js +124 -0
  88. package/dist/providers/shared/transcript-reader.js.map +1 -0
  89. package/dist/registry.d.ts.map +1 -1
  90. package/dist/registry.js +92 -0
  91. package/dist/registry.js.map +1 -0
  92. package/package.json +3 -3
  93. package/src/providers/pi/adapter.ts +240 -0
  94. package/src/providers/pi/hooks.ts +232 -0
  95. package/src/providers/pi/index.ts +41 -0
  96. package/src/providers/pi/install.ts +189 -0
  97. package/src/providers/pi/manifest.json +40 -0
  98. package/src/providers/pi/spawn.ts +207 -0
  99. package/src/registry.ts +6 -1
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * CLEO provider adapter for Pi coding agent (https://github.com/badlogic/pi-mono).
5
+ * Pi is CAAMP's first-class primary harness with 11/16 canonical hook events.
6
+ * Default export is the adapter class for dynamic loading by AdapterManager.
7
+ *
8
+ * @task T553
9
+ */
10
+ import { PiAdapter } from './adapter.js';
11
+ export { PiAdapter } from './adapter.js';
12
+ export { PiHookProvider } from './hooks.js';
13
+ export { PiInstallProvider } from './install.js';
14
+ export { PiSpawnProvider } from './spawn.js';
15
+ export default PiAdapter;
16
+ /**
17
+ * Factory function for creating Pi adapter instances.
18
+ * Used by AdapterManager's dynamic import fallback.
19
+ *
20
+ * @remarks
21
+ * This is the primary entry point for dynamic adapter loading.
22
+ * AdapterManager calls this function when it resolves the pi provider
23
+ * via its import-based discovery mechanism.
24
+ *
25
+ * @returns A new {@link PiAdapter} instance ready for initialization
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * import { createAdapter } from '@cleocode/adapters/providers/pi';
30
+ *
31
+ * const adapter = createAdapter();
32
+ * await adapter.initialize('/path/to/project');
33
+ * ```
34
+ */
35
+ export function createAdapter() {
36
+ return new PiAdapter();
37
+ }
38
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/providers/pi/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAe,SAAS,CAAC;AAEzB;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,SAAS,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Pi Install Provider
3
+ *
4
+ * Handles CLEO installation into Pi coding agent environments:
5
+ * - Ensures AGENTS.md has CLEO @-references (project and global scope)
6
+ * - Manages Pi settings.json to register CLEO extension path
7
+ *
8
+ * Pi uses AGENTS.md (not CLAUDE.md) as its instruction file. The global
9
+ * instruction file lives at `~/.pi/agent/AGENTS.md`; the project-level
10
+ * file lives at `<projectDir>/AGENTS.md`.
11
+ *
12
+ * Detection: Pi is detected by the `PI_CODING_AGENT_DIR` or `PI_HOME`
13
+ * environment variables, or by presence of `~/.pi/agent/` directory.
14
+ *
15
+ * @task T553
16
+ */
17
+ import type { AdapterInstallProvider, InstallOptions, InstallResult } from '@cleocode/contracts';
18
+ /**
19
+ * Install provider for Pi coding agent.
20
+ *
21
+ * Manages CLEO's integration with Pi by:
22
+ * 1. Ensuring project AGENTS.md contains @-references to CLEO instruction files
23
+ * 2. Ensuring global AGENTS.md (~/.pi/agent/AGENTS.md) contains @-references
24
+ *
25
+ * @remarks
26
+ * Installation is idempotent — running install multiple times on the same
27
+ * project produces the same result. Pi's AGENTS.md is auto-discovered from
28
+ * the working directory upwards, so project-level injection is the primary
29
+ * mechanism. Global injection ensures fresh sessions always load CLEO context.
30
+ */
31
+ export declare class PiInstallProvider implements AdapterInstallProvider {
32
+ /**
33
+ * Install CLEO into a Pi coding agent project.
34
+ *
35
+ * @param options - Installation options including project directory
36
+ * @returns Result describing what was installed
37
+ */
38
+ install(options: InstallOptions): Promise<InstallResult>;
39
+ /**
40
+ * Uninstall CLEO from the current Pi project.
41
+ *
42
+ * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
43
+ */
44
+ uninstall(): Promise<void>;
45
+ /**
46
+ * Check whether CLEO is installed in the current environment.
47
+ *
48
+ * Checks for CLEO references in the project AGENTS.md.
49
+ */
50
+ isInstalled(): Promise<boolean>;
51
+ /**
52
+ * Ensure AGENTS.md contains @-references to CLEO instruction files.
53
+ *
54
+ * Creates AGENTS.md if it does not exist. Appends any missing references.
55
+ *
56
+ * @param projectDir - Project root directory
57
+ */
58
+ ensureInstructionReferences(projectDir: string): Promise<void>;
59
+ /**
60
+ * Update an instruction file with CLEO @-references.
61
+ *
62
+ * @param dir - Directory containing the instruction file
63
+ * @param filename - Name of the instruction file (e.g. "AGENTS.md")
64
+ * @returns true if the file was created or modified
65
+ */
66
+ private updateInstructionFile;
67
+ }
68
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/providers/pi/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAyBjG;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAkB,YAAW,sBAAsB;IAC9D;;;;;OAKG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAiC9D;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAEhC;;;;OAIG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IA6BrC;;;;;;OAMG;IACG,2BAA2B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;CA+B9B"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Pi Install Provider
3
+ *
4
+ * Handles CLEO installation into Pi coding agent environments:
5
+ * - Ensures AGENTS.md has CLEO @-references (project and global scope)
6
+ * - Manages Pi settings.json to register CLEO extension path
7
+ *
8
+ * Pi uses AGENTS.md (not CLAUDE.md) as its instruction file. The global
9
+ * instruction file lives at `~/.pi/agent/AGENTS.md`; the project-level
10
+ * file lives at `<projectDir>/AGENTS.md`.
11
+ *
12
+ * Detection: Pi is detected by the `PI_CODING_AGENT_DIR` or `PI_HOME`
13
+ * environment variables, or by presence of `~/.pi/agent/` directory.
14
+ *
15
+ * @task T553
16
+ */
17
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
18
+ import { homedir } from 'node:os';
19
+ import { join } from 'node:path';
20
+ /** Lines that should appear in AGENTS.md to reference CLEO. */
21
+ const INSTRUCTION_REFERENCES = ['@~/.cleo/templates/CLEO-INJECTION.md', '@.cleo/memory-bridge.md'];
22
+ /**
23
+ * Resolve the Pi global state root directory.
24
+ *
25
+ * Honours `PI_CODING_AGENT_DIR` env var when set (with `~` expansion),
26
+ * then `PI_HOME`, then falls back to `~/.pi/agent`.
27
+ */
28
+ function getPiAgentDir() {
29
+ const env = process.env['PI_CODING_AGENT_DIR'];
30
+ if (env !== undefined && env.length > 0) {
31
+ if (env === '~')
32
+ return homedir();
33
+ if (env.startsWith('~/'))
34
+ return join(homedir(), env.slice(2));
35
+ return env;
36
+ }
37
+ const piHome = process.env['PI_HOME'];
38
+ if (piHome !== undefined && piHome.length > 0) {
39
+ return join(piHome, 'agent');
40
+ }
41
+ return join(homedir(), '.pi', 'agent');
42
+ }
43
+ /**
44
+ * Install provider for Pi coding agent.
45
+ *
46
+ * Manages CLEO's integration with Pi by:
47
+ * 1. Ensuring project AGENTS.md contains @-references to CLEO instruction files
48
+ * 2. Ensuring global AGENTS.md (~/.pi/agent/AGENTS.md) contains @-references
49
+ *
50
+ * @remarks
51
+ * Installation is idempotent — running install multiple times on the same
52
+ * project produces the same result. Pi's AGENTS.md is auto-discovered from
53
+ * the working directory upwards, so project-level injection is the primary
54
+ * mechanism. Global injection ensures fresh sessions always load CLEO context.
55
+ */
56
+ export class PiInstallProvider {
57
+ /**
58
+ * Install CLEO into a Pi coding agent project.
59
+ *
60
+ * @param options - Installation options including project directory
61
+ * @returns Result describing what was installed
62
+ */
63
+ async install(options) {
64
+ const { projectDir } = options;
65
+ const installedAt = new Date().toISOString();
66
+ const details = {};
67
+ // Step 1: Ensure project AGENTS.md has @-references
68
+ const projectUpdated = this.updateInstructionFile(projectDir, 'AGENTS.md');
69
+ if (projectUpdated) {
70
+ details.instructionFile = join(projectDir, 'AGENTS.md');
71
+ }
72
+ // Step 2: Ensure global AGENTS.md has @-references (best-effort)
73
+ let globalUpdated = false;
74
+ try {
75
+ const globalDir = getPiAgentDir();
76
+ globalUpdated = this.updateInstructionFile(globalDir, 'AGENTS.md');
77
+ if (globalUpdated) {
78
+ details.globalInstructionFile = join(globalDir, 'AGENTS.md');
79
+ }
80
+ }
81
+ catch {
82
+ // Global install is best-effort — never block project install
83
+ }
84
+ const instructionFileUpdated = projectUpdated || globalUpdated;
85
+ return {
86
+ success: true,
87
+ installedAt,
88
+ instructionFileUpdated,
89
+ details,
90
+ };
91
+ }
92
+ /**
93
+ * Uninstall CLEO from the current Pi project.
94
+ *
95
+ * Does not remove AGENTS.md references (they are harmless if CLEO is not present).
96
+ */
97
+ async uninstall() { }
98
+ /**
99
+ * Check whether CLEO is installed in the current environment.
100
+ *
101
+ * Checks for CLEO references in the project AGENTS.md.
102
+ */
103
+ async isInstalled() {
104
+ const agentsMdPath = join(process.cwd(), 'AGENTS.md');
105
+ if (existsSync(agentsMdPath)) {
106
+ try {
107
+ const content = readFileSync(agentsMdPath, 'utf-8');
108
+ if (INSTRUCTION_REFERENCES.some((ref) => content.includes(ref))) {
109
+ return true;
110
+ }
111
+ }
112
+ catch {
113
+ // Fall through
114
+ }
115
+ }
116
+ // Also check global AGENTS.md
117
+ try {
118
+ const globalPath = join(getPiAgentDir(), 'AGENTS.md');
119
+ if (existsSync(globalPath)) {
120
+ const content = readFileSync(globalPath, 'utf-8');
121
+ if (INSTRUCTION_REFERENCES.some((ref) => content.includes(ref))) {
122
+ return true;
123
+ }
124
+ }
125
+ }
126
+ catch {
127
+ // Fall through
128
+ }
129
+ return false;
130
+ }
131
+ /**
132
+ * Ensure AGENTS.md contains @-references to CLEO instruction files.
133
+ *
134
+ * Creates AGENTS.md if it does not exist. Appends any missing references.
135
+ *
136
+ * @param projectDir - Project root directory
137
+ */
138
+ async ensureInstructionReferences(projectDir) {
139
+ this.updateInstructionFile(projectDir, 'AGENTS.md');
140
+ }
141
+ /**
142
+ * Update an instruction file with CLEO @-references.
143
+ *
144
+ * @param dir - Directory containing the instruction file
145
+ * @param filename - Name of the instruction file (e.g. "AGENTS.md")
146
+ * @returns true if the file was created or modified
147
+ */
148
+ updateInstructionFile(dir, filename) {
149
+ const filePath = join(dir, filename);
150
+ let content = '';
151
+ let existed = false;
152
+ if (existsSync(filePath)) {
153
+ content = readFileSync(filePath, 'utf-8');
154
+ existed = true;
155
+ }
156
+ const missingRefs = INSTRUCTION_REFERENCES.filter((ref) => !content.includes(ref));
157
+ if (missingRefs.length === 0) {
158
+ return false;
159
+ }
160
+ const refsBlock = missingRefs.join('\n');
161
+ if (existed) {
162
+ // Append missing references
163
+ const separator = content.endsWith('\n') ? '' : '\n';
164
+ content = content + separator + refsBlock + '\n';
165
+ }
166
+ else {
167
+ // Create new file with references — ensure parent dir exists
168
+ mkdirSync(dir, { recursive: true });
169
+ content = refsBlock + '\n';
170
+ }
171
+ writeFileSync(filePath, content, 'utf-8');
172
+ return true;
173
+ }
174
+ }
175
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/providers/pi/install.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Pi Spawn Provider
3
+ *
4
+ * Implements AdapterSpawnProvider for Pi coding agent CLI.
5
+ *
6
+ * Uses the `pi` CLI (or the path from `PI_CLI_PATH` env var) to spawn
7
+ * subagent processes with prompts written to temporary files. Processes
8
+ * run detached and are tracked by PID for listing and termination.
9
+ *
10
+ * Pi detection: `PI_CLI_PATH` env var or `which pi`.
11
+ *
12
+ * @task T553
13
+ */
14
+ import type { AdapterSpawnProvider, SpawnContext, SpawnResult } from '@cleocode/contracts';
15
+ /**
16
+ * Spawn provider for Pi coding agent.
17
+ *
18
+ * Spawns detached Pi CLI processes for subagent execution. Each spawn
19
+ * writes its prompt to a temporary file, then runs the Pi CLI with the
20
+ * prompt file as the primary argument as a detached, unref'd child process.
21
+ *
22
+ * @remarks
23
+ * Prompts are written to temporary files under `/tmp/` and cleaned up
24
+ * after the child process exits. Processes are tracked by instance ID in
25
+ * an in-memory map and verified via `kill(pid, 0)` liveness checks.
26
+ * All failures are best-effort and non-blocking.
27
+ */
28
+ export declare class PiSpawnProvider implements AdapterSpawnProvider {
29
+ /** Map of instance IDs to tracked process info. */
30
+ private processMap;
31
+ /**
32
+ * Check if the Pi CLI is available.
33
+ *
34
+ * Checks `PI_CLI_PATH` env var first, then tries `which pi`.
35
+ *
36
+ * @returns true if the Pi CLI is accessible
37
+ */
38
+ canSpawn(): Promise<boolean>;
39
+ /**
40
+ * Spawn a subagent via Pi CLI.
41
+ *
42
+ * Writes the prompt to a temporary file and spawns a detached Pi
43
+ * process. The process runs independently of the parent.
44
+ *
45
+ * @param context - Spawn context with taskId, prompt, and options
46
+ * @returns Spawn result with instance ID and status
47
+ */
48
+ spawn(context: SpawnContext): Promise<SpawnResult>;
49
+ /**
50
+ * List currently running Pi subagent processes.
51
+ *
52
+ * Checks each tracked process via kill(pid, 0) to verify it is still alive.
53
+ * Dead processes are automatically cleaned from the tracking map.
54
+ *
55
+ * @returns Array of spawn results for running processes
56
+ */
57
+ listRunning(): Promise<SpawnResult[]>;
58
+ /**
59
+ * Terminate a running spawn by instance ID.
60
+ *
61
+ * Sends SIGTERM to the tracked process. If the process is not found
62
+ * or has already exited, this is a no-op.
63
+ *
64
+ * @param instanceId - ID of the spawn instance to terminate
65
+ */
66
+ terminate(instanceId: string): Promise<void>;
67
+ }
68
+ //# sourceMappingURL=spawn.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Pi Spawn Provider
3
+ *
4
+ * Implements AdapterSpawnProvider for Pi coding agent CLI.
5
+ *
6
+ * Uses the `pi` CLI (or the path from `PI_CLI_PATH` env var) to spawn
7
+ * subagent processes with prompts written to temporary files. Processes
8
+ * run detached and are tracked by PID for listing and termination.
9
+ *
10
+ * Pi detection: `PI_CLI_PATH` env var or `which pi`.
11
+ *
12
+ * @task T553
13
+ */
14
+ import { exec, spawn as nodeSpawn } from 'node:child_process';
15
+ import { unlink, writeFile } from 'node:fs/promises';
16
+ import { promisify } from 'node:util';
17
+ import { getErrorMessage } from '@cleocode/contracts';
18
+ const execAsync = promisify(exec);
19
+ /**
20
+ * Resolve the Pi CLI executable path.
21
+ *
22
+ * Honours `PI_CLI_PATH` env var when set, otherwise uses `pi` (expects
23
+ * the binary on PATH).
24
+ */
25
+ function getPiCliPath() {
26
+ return process.env['PI_CLI_PATH'] ?? 'pi';
27
+ }
28
+ /**
29
+ * Spawn provider for Pi coding agent.
30
+ *
31
+ * Spawns detached Pi CLI processes for subagent execution. Each spawn
32
+ * writes its prompt to a temporary file, then runs the Pi CLI with the
33
+ * prompt file as the primary argument as a detached, unref'd child process.
34
+ *
35
+ * @remarks
36
+ * Prompts are written to temporary files under `/tmp/` and cleaned up
37
+ * after the child process exits. Processes are tracked by instance ID in
38
+ * an in-memory map and verified via `kill(pid, 0)` liveness checks.
39
+ * All failures are best-effort and non-blocking.
40
+ */
41
+ export class PiSpawnProvider {
42
+ /** Map of instance IDs to tracked process info. */
43
+ processMap = new Map();
44
+ /**
45
+ * Check if the Pi CLI is available.
46
+ *
47
+ * Checks `PI_CLI_PATH` env var first, then tries `which pi`.
48
+ *
49
+ * @returns true if the Pi CLI is accessible
50
+ */
51
+ async canSpawn() {
52
+ const cliPath = getPiCliPath();
53
+ try {
54
+ if (cliPath !== 'pi') {
55
+ // Custom path — check if it exists
56
+ const { stdout } = await execAsync(`test -x "${cliPath}" && echo ok`);
57
+ return stdout.trim() === 'ok';
58
+ }
59
+ await execAsync('which pi');
60
+ return true;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
66
+ /**
67
+ * Spawn a subagent via Pi CLI.
68
+ *
69
+ * Writes the prompt to a temporary file and spawns a detached Pi
70
+ * process. The process runs independently of the parent.
71
+ *
72
+ * @param context - Spawn context with taskId, prompt, and options
73
+ * @returns Spawn result with instance ID and status
74
+ */
75
+ async spawn(context) {
76
+ const instanceId = `pi-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
77
+ const startTime = new Date().toISOString();
78
+ let tmpFile;
79
+ try {
80
+ tmpFile = `/tmp/pi-spawn-${instanceId}.txt`;
81
+ await writeFile(tmpFile, context.prompt, 'utf-8');
82
+ const cliPath = getPiCliPath();
83
+ const args = [tmpFile];
84
+ const spawnOpts = {
85
+ detached: true,
86
+ stdio: 'ignore',
87
+ };
88
+ if (context.workingDirectory) {
89
+ spawnOpts.cwd = context.workingDirectory;
90
+ }
91
+ const child = nodeSpawn(cliPath, args, spawnOpts);
92
+ child.unref();
93
+ if (child.pid) {
94
+ this.processMap.set(instanceId, {
95
+ pid: child.pid,
96
+ taskId: context.taskId,
97
+ startTime,
98
+ });
99
+ }
100
+ const capturedTmpFile = tmpFile;
101
+ child.on('exit', async () => {
102
+ this.processMap.delete(instanceId);
103
+ try {
104
+ await unlink(capturedTmpFile);
105
+ }
106
+ catch {
107
+ // Ignore cleanup errors
108
+ }
109
+ });
110
+ return {
111
+ instanceId,
112
+ taskId: context.taskId,
113
+ providerId: 'pi',
114
+ status: 'running',
115
+ startTime,
116
+ };
117
+ }
118
+ catch (error) {
119
+ console.error(`[PiSpawnProvider] Failed to spawn: ${getErrorMessage(error)}`);
120
+ if (tmpFile) {
121
+ try {
122
+ await unlink(tmpFile);
123
+ }
124
+ catch {
125
+ // Ignore cleanup errors
126
+ }
127
+ }
128
+ return {
129
+ instanceId,
130
+ taskId: context.taskId,
131
+ providerId: 'pi',
132
+ status: 'failed',
133
+ startTime,
134
+ endTime: new Date().toISOString(),
135
+ error: getErrorMessage(error),
136
+ };
137
+ }
138
+ }
139
+ /**
140
+ * List currently running Pi subagent processes.
141
+ *
142
+ * Checks each tracked process via kill(pid, 0) to verify it is still alive.
143
+ * Dead processes are automatically cleaned from the tracking map.
144
+ *
145
+ * @returns Array of spawn results for running processes
146
+ */
147
+ async listRunning() {
148
+ const running = [];
149
+ for (const [instanceId, tracked] of this.processMap.entries()) {
150
+ try {
151
+ process.kill(tracked.pid, 0);
152
+ running.push({
153
+ instanceId,
154
+ taskId: tracked.taskId,
155
+ providerId: 'pi',
156
+ status: 'running',
157
+ startTime: tracked.startTime,
158
+ });
159
+ }
160
+ catch {
161
+ this.processMap.delete(instanceId);
162
+ }
163
+ }
164
+ return running;
165
+ }
166
+ /**
167
+ * Terminate a running spawn by instance ID.
168
+ *
169
+ * Sends SIGTERM to the tracked process. If the process is not found
170
+ * or has already exited, this is a no-op.
171
+ *
172
+ * @param instanceId - ID of the spawn instance to terminate
173
+ */
174
+ async terminate(instanceId) {
175
+ const tracked = this.processMap.get(instanceId);
176
+ if (!tracked)
177
+ return;
178
+ try {
179
+ process.kill(tracked.pid, 'SIGTERM');
180
+ }
181
+ catch {
182
+ // Process may have already exited
183
+ }
184
+ this.processMap.delete(instanceId);
185
+ }
186
+ }
187
+ //# sourceMappingURL=spawn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../src/providers/pi/spawn.ts"],"names":[],"mappings":"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"}