@cleocode/adapters 2026.4.0 → 2026.4.3
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/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +724 -630
- package/dist/index.js.map +3 -3
- package/dist/providers/claude-code/adapter.d.ts +21 -1
- package/dist/providers/claude-code/adapter.d.ts.map +1 -1
- package/dist/providers/claude-code/context-monitor.d.ts +11 -0
- package/dist/providers/claude-code/context-monitor.d.ts.map +1 -1
- package/dist/providers/claude-code/hooks.d.ts +7 -0
- package/dist/providers/claude-code/hooks.d.ts.map +1 -1
- package/dist/providers/claude-code/index.d.ts +16 -1
- package/dist/providers/claude-code/index.d.ts.map +1 -1
- package/dist/providers/claude-code/install.d.ts +10 -18
- package/dist/providers/claude-code/install.d.ts.map +1 -1
- package/dist/providers/claude-code/paths.d.ts +8 -0
- package/dist/providers/claude-code/paths.d.ts.map +1 -1
- package/dist/providers/claude-code/spawn.d.ts +7 -0
- package/dist/providers/claude-code/spawn.d.ts.map +1 -1
- package/dist/providers/claude-code/statusline.d.ts +44 -0
- package/dist/providers/claude-code/statusline.d.ts.map +1 -1
- package/dist/providers/claude-code/task-sync.d.ts +8 -0
- package/dist/providers/claude-code/task-sync.d.ts.map +1 -1
- package/dist/providers/claude-code/transport.d.ts +11 -0
- package/dist/providers/claude-code/transport.d.ts.map +1 -1
- package/dist/providers/codex/adapter.d.ts +14 -1
- package/dist/providers/codex/adapter.d.ts.map +1 -1
- package/dist/providers/codex/hooks.d.ts +6 -0
- package/dist/providers/codex/hooks.d.ts.map +1 -1
- package/dist/providers/codex/index.d.ts +16 -1
- package/dist/providers/codex/index.d.ts.map +1 -1
- package/dist/providers/codex/install.d.ts +8 -17
- package/dist/providers/codex/install.d.ts.map +1 -1
- package/dist/providers/cursor/adapter.d.ts +15 -1
- package/dist/providers/cursor/adapter.d.ts.map +1 -1
- package/dist/providers/cursor/hooks.d.ts +7 -0
- package/dist/providers/cursor/hooks.d.ts.map +1 -1
- package/dist/providers/cursor/index.d.ts +16 -1
- package/dist/providers/cursor/index.d.ts.map +1 -1
- package/dist/providers/cursor/install.d.ts +10 -17
- package/dist/providers/cursor/install.d.ts.map +1 -1
- package/dist/providers/gemini-cli/adapter.d.ts +15 -1
- package/dist/providers/gemini-cli/adapter.d.ts.map +1 -1
- package/dist/providers/gemini-cli/hooks.d.ts +7 -0
- package/dist/providers/gemini-cli/hooks.d.ts.map +1 -1
- package/dist/providers/gemini-cli/index.d.ts +16 -1
- package/dist/providers/gemini-cli/index.d.ts.map +1 -1
- package/dist/providers/gemini-cli/install.d.ts +8 -17
- package/dist/providers/gemini-cli/install.d.ts.map +1 -1
- package/dist/providers/kimi/adapter.d.ts +15 -2
- package/dist/providers/kimi/adapter.d.ts.map +1 -1
- package/dist/providers/kimi/hooks.d.ts +6 -0
- package/dist/providers/kimi/hooks.d.ts.map +1 -1
- package/dist/providers/kimi/index.d.ts +16 -1
- package/dist/providers/kimi/index.d.ts.map +1 -1
- package/dist/providers/kimi/install.d.ts +7 -22
- package/dist/providers/kimi/install.d.ts.map +1 -1
- package/dist/providers/opencode/adapter.d.ts +17 -1
- package/dist/providers/opencode/adapter.d.ts.map +1 -1
- package/dist/providers/opencode/hooks.d.ts +9 -0
- package/dist/providers/opencode/hooks.d.ts.map +1 -1
- package/dist/providers/opencode/index.d.ts +16 -1
- package/dist/providers/opencode/index.d.ts.map +1 -1
- package/dist/providers/opencode/install.d.ts +8 -17
- package/dist/providers/opencode/install.d.ts.map +1 -1
- package/dist/providers/opencode/spawn.d.ts +23 -1
- package/dist/providers/opencode/spawn.d.ts.map +1 -1
- package/dist/providers/shared/transcript-reader.d.ts +15 -0
- package/dist/providers/shared/transcript-reader.d.ts.map +1 -1
- package/dist/registry.d.ts +54 -2
- package/dist/registry.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/__tests__/claude-code-adapter.test.js +21 -30
- package/src/__tests__/claude-code-adapter.test.js.map +1 -1
- package/src/__tests__/claude-code-adapter.test.ts +21 -32
- package/src/__tests__/cursor-adapter.test.js +25 -29
- package/src/__tests__/cursor-adapter.test.js.map +1 -1
- package/src/__tests__/cursor-adapter.test.ts +26 -33
- package/src/__tests__/opencode-adapter.test.js +47 -46
- package/src/__tests__/opencode-adapter.test.js.map +1 -1
- package/src/__tests__/opencode-adapter.test.ts +51 -49
- package/src/index.ts +9 -1
- package/src/providers/claude-code/__tests__/adapter.test.js +50 -23
- package/src/providers/claude-code/__tests__/adapter.test.js.map +1 -1
- package/src/providers/claude-code/__tests__/adapter.test.ts +52 -23
- package/src/providers/claude-code/adapter.ts +22 -2
- package/src/providers/claude-code/context-monitor.ts +11 -0
- package/src/providers/claude-code/hooks.ts +7 -0
- package/src/providers/claude-code/index.ts +16 -1
- package/src/providers/claude-code/install.ts +15 -96
- package/src/providers/claude-code/manifest.json +1 -1
- package/src/providers/claude-code/paths.ts +8 -0
- package/src/providers/claude-code/spawn.ts +7 -0
- package/src/providers/claude-code/statusline.ts +44 -0
- package/src/providers/claude-code/task-sync.ts +8 -0
- package/src/providers/claude-code/transport.ts +11 -0
- package/src/providers/codex/adapter.ts +15 -2
- package/src/providers/codex/hooks.ts +6 -0
- package/src/providers/codex/index.ts +16 -1
- package/src/providers/codex/install.ts +17 -81
- package/src/providers/codex/manifest.json +1 -1
- package/src/providers/cursor/__tests__/adapter.test.js +37 -12
- package/src/providers/cursor/__tests__/adapter.test.js.map +1 -1
- package/src/providers/cursor/__tests__/adapter.test.ts +43 -12
- package/src/providers/cursor/adapter.ts +16 -2
- package/src/providers/cursor/hooks.ts +7 -0
- package/src/providers/cursor/index.ts +16 -1
- package/src/providers/cursor/install.ts +23 -88
- package/src/providers/cursor/manifest.json +1 -1
- package/src/providers/gemini-cli/adapter.ts +16 -2
- package/src/providers/gemini-cli/hooks.ts +7 -0
- package/src/providers/gemini-cli/index.ts +16 -1
- package/src/providers/gemini-cli/install.ts +17 -81
- package/src/providers/gemini-cli/manifest.json +1 -1
- package/src/providers/kimi/adapter.ts +16 -3
- package/src/providers/kimi/hooks.ts +6 -0
- package/src/providers/kimi/index.ts +16 -1
- package/src/providers/kimi/install.ts +16 -86
- package/src/providers/kimi/manifest.json +1 -1
- package/src/providers/opencode/__tests__/adapter.test.js +48 -35
- package/src/providers/opencode/__tests__/adapter.test.js.map +1 -1
- package/src/providers/opencode/__tests__/adapter.test.ts +49 -34
- package/src/providers/opencode/adapter.ts +18 -2
- package/src/providers/opencode/hooks.ts +9 -0
- package/src/providers/opencode/index.ts +16 -1
- package/src/providers/opencode/install.ts +17 -90
- package/src/providers/opencode/manifest.json +1 -1
- package/src/providers/opencode/spawn.ts +23 -1
- package/src/providers/shared/transcript-reader.ts +15 -0
- package/src/registry.ts +54 -2
- package/dist/providers/claude-code/adapter.js +0 -165
- package/dist/providers/claude-code/adapter.js.map +0 -1
- package/dist/providers/claude-code/context-monitor.js +0 -148
- package/dist/providers/claude-code/context-monitor.js.map +0 -1
- package/dist/providers/claude-code/hooks.js +0 -279
- package/dist/providers/claude-code/hooks.js.map +0 -1
- package/dist/providers/claude-code/index.js +0 -26
- package/dist/providers/claude-code/index.js.map +0 -1
- package/dist/providers/claude-code/install.js +0 -234
- package/dist/providers/claude-code/install.js.map +0 -1
- package/dist/providers/claude-code/paths.js +0 -33
- package/dist/providers/claude-code/paths.js.map +0 -1
- package/dist/providers/claude-code/spawn.js +0 -164
- package/dist/providers/claude-code/spawn.js.map +0 -1
- package/dist/providers/claude-code/statusline.js +0 -86
- package/dist/providers/claude-code/statusline.js.map +0 -1
- package/dist/providers/claude-code/task-sync.js +0 -111
- package/dist/providers/claude-code/task-sync.js.map +0 -1
- package/dist/providers/claude-code/transport.js +0 -18
- package/dist/providers/claude-code/transport.js.map +0 -1
- package/dist/providers/codex/adapter.js +0 -134
- package/dist/providers/codex/adapter.js.map +0 -1
- package/dist/providers/codex/hooks.js +0 -107
- package/dist/providers/codex/hooks.js.map +0 -1
- package/dist/providers/codex/index.js +0 -24
- package/dist/providers/codex/index.js.map +0 -1
- package/dist/providers/codex/install.js +0 -183
- package/dist/providers/codex/install.js.map +0 -1
- package/dist/providers/cursor/adapter.js +0 -138
- package/dist/providers/cursor/adapter.js.map +0 -1
- package/dist/providers/cursor/hooks.js +0 -201
- package/dist/providers/cursor/hooks.js.map +0 -1
- package/dist/providers/cursor/index.js +0 -21
- package/dist/providers/cursor/index.js.map +0 -1
- package/dist/providers/cursor/install.js +0 -238
- package/dist/providers/cursor/install.js.map +0 -1
- package/dist/providers/cursor/spawn.js +0 -59
- package/dist/providers/cursor/spawn.js.map +0 -1
- package/dist/providers/gemini-cli/adapter.js +0 -145
- package/dist/providers/gemini-cli/adapter.js.map +0 -1
- package/dist/providers/gemini-cli/hooks.js +0 -121
- package/dist/providers/gemini-cli/hooks.js.map +0 -1
- package/dist/providers/gemini-cli/index.js +0 -24
- package/dist/providers/gemini-cli/index.js.map +0 -1
- package/dist/providers/gemini-cli/install.js +0 -183
- package/dist/providers/gemini-cli/install.js.map +0 -1
- package/dist/providers/kimi/adapter.js +0 -133
- package/dist/providers/kimi/adapter.js.map +0 -1
- package/dist/providers/kimi/hooks.js +0 -73
- package/dist/providers/kimi/hooks.js.map +0 -1
- package/dist/providers/kimi/index.js +0 -24
- package/dist/providers/kimi/index.js.map +0 -1
- package/dist/providers/kimi/install.js +0 -189
- package/dist/providers/kimi/install.js.map +0 -1
- package/dist/providers/opencode/adapter.js +0 -151
- package/dist/providers/opencode/adapter.js.map +0 -1
- package/dist/providers/opencode/hooks.js +0 -197
- package/dist/providers/opencode/hooks.js.map +0 -1
- package/dist/providers/opencode/index.js +0 -22
- package/dist/providers/opencode/index.js.map +0 -1
- package/dist/providers/opencode/install.js +0 -180
- package/dist/providers/opencode/install.js.map +0 -1
- package/dist/providers/opencode/spawn.js +0 -219
- package/dist/providers/opencode/spawn.js.map +0 -1
- package/dist/providers/shared/transcript-reader.js +0 -109
- package/dist/providers/shared/transcript-reader.js.map +0 -1
- package/dist/registry.js +0 -55
- package/dist/registry.js.map +0 -1
- package/src/__tests__/claude-code-adapter.test.d.ts +0 -10
- package/src/__tests__/cursor-adapter.test.d.ts +0 -10
- package/src/__tests__/opencode-adapter.test.d.ts +0 -10
- package/src/index.d.ts +0 -35
- package/src/index.d.ts.map +0 -1
- package/src/index.js +0 -13
- package/src/index.js.map +0 -1
- package/src/providers/claude-code/__tests__/adapter.test.d.ts +0 -7
- package/src/providers/claude-code/adapter.d.ts +0 -79
- package/src/providers/claude-code/adapter.d.ts.map +0 -1
- package/src/providers/claude-code/adapter.js +0 -154
- package/src/providers/claude-code/adapter.js.map +0 -1
- package/src/providers/claude-code/context-monitor.d.ts +0 -24
- package/src/providers/claude-code/context-monitor.d.ts.map +0 -1
- package/src/providers/claude-code/context-monitor.js +0 -148
- package/src/providers/claude-code/context-monitor.js.map +0 -1
- package/src/providers/claude-code/hooks.d.ts +0 -59
- package/src/providers/claude-code/hooks.d.ts.map +0 -1
- package/src/providers/claude-code/hooks.js +0 -77
- package/src/providers/claude-code/hooks.js.map +0 -1
- package/src/providers/claude-code/index.d.ts +0 -28
- package/src/providers/claude-code/index.d.ts.map +0 -1
- package/src/providers/claude-code/index.js +0 -26
- package/src/providers/claude-code/index.js.map +0 -1
- package/src/providers/claude-code/install.d.ts +0 -75
- package/src/providers/claude-code/install.d.ts.map +0 -1
- package/src/providers/claude-code/install.js +0 -234
- package/src/providers/claude-code/install.js.map +0 -1
- package/src/providers/claude-code/paths.d.ts +0 -24
- package/src/providers/claude-code/paths.d.ts.map +0 -1
- package/src/providers/claude-code/paths.js +0 -33
- package/src/providers/claude-code/paths.js.map +0 -1
- package/src/providers/claude-code/spawn.d.ts +0 -60
- package/src/providers/claude-code/spawn.d.ts.map +0 -1
- package/src/providers/claude-code/spawn.js +0 -164
- package/src/providers/claude-code/spawn.js.map +0 -1
- package/src/providers/claude-code/statusline.d.ts +0 -23
- package/src/providers/claude-code/statusline.d.ts.map +0 -1
- package/src/providers/claude-code/statusline.js +0 -86
- package/src/providers/claude-code/statusline.js.map +0 -1
- package/src/providers/claude-code/task-sync.js +0 -122
- package/src/providers/claude-code/task-sync.js.map +0 -1
- package/src/providers/claude-code/transport.d.ts +0 -14
- package/src/providers/claude-code/transport.d.ts.map +0 -1
- package/src/providers/claude-code/transport.js +0 -18
- package/src/providers/claude-code/transport.js.map +0 -1
- package/src/providers/cursor/__tests__/adapter.test.d.ts +0 -7
- package/src/providers/cursor/adapter.d.ts +0 -66
- package/src/providers/cursor/adapter.d.ts.map +0 -1
- package/src/providers/cursor/adapter.js +0 -124
- package/src/providers/cursor/adapter.js.map +0 -1
- package/src/providers/cursor/hooks.d.ts +0 -48
- package/src/providers/cursor/hooks.d.ts.map +0 -1
- package/src/providers/cursor/hooks.js +0 -55
- package/src/providers/cursor/hooks.js.map +0 -1
- package/src/providers/cursor/index.d.ts +0 -19
- package/src/providers/cursor/index.d.ts.map +0 -1
- package/src/providers/cursor/index.js +0 -21
- package/src/providers/cursor/index.js.map +0 -1
- package/src/providers/cursor/install.d.ts +0 -94
- package/src/providers/cursor/install.d.ts.map +0 -1
- package/src/providers/cursor/install.js +0 -238
- package/src/providers/cursor/install.js.map +0 -1
- package/src/providers/cursor/spawn.d.ts +0 -50
- package/src/providers/cursor/spawn.d.ts.map +0 -1
- package/src/providers/cursor/spawn.js +0 -59
- package/src/providers/cursor/spawn.js.map +0 -1
- package/src/providers/opencode/__tests__/adapter.test.d.ts +0 -7
- package/src/providers/opencode/adapter.d.ts +0 -71
- package/src/providers/opencode/adapter.d.ts.map +0 -1
- package/src/providers/opencode/adapter.js +0 -144
- package/src/providers/opencode/adapter.js.map +0 -1
- package/src/providers/opencode/hooks.d.ts +0 -66
- package/src/providers/opencode/hooks.d.ts.map +0 -1
- package/src/providers/opencode/hooks.js +0 -89
- package/src/providers/opencode/hooks.js.map +0 -1
- package/src/providers/opencode/index.d.ts +0 -20
- package/src/providers/opencode/index.d.ts.map +0 -1
- package/src/providers/opencode/index.js +0 -22
- package/src/providers/opencode/index.js.map +0 -1
- package/src/providers/opencode/install.d.ts +0 -65
- package/src/providers/opencode/install.d.ts.map +0 -1
- package/src/providers/opencode/install.js +0 -180
- package/src/providers/opencode/install.js.map +0 -1
- package/src/providers/opencode/spawn.d.ts +0 -75
- package/src/providers/opencode/spawn.d.ts.map +0 -1
- package/src/providers/opencode/spawn.js +0 -219
- package/src/providers/opencode/spawn.js.map +0 -1
- package/src/registry.d.ts +0 -36
- package/src/registry.d.ts.map +0 -1
- package/src/registry.js +0 -55
- package/src/registry.js.map +0 -1
|
@@ -2,66 +2,53 @@
|
|
|
2
2
|
* OpenCode Install Provider
|
|
3
3
|
*
|
|
4
4
|
* Handles CLEO installation into OpenCode environments:
|
|
5
|
-
* - Registers CLEO MCP server in .opencode/config.json
|
|
6
5
|
* - Ensures AGENTS.md has CLEO @-references
|
|
7
6
|
*
|
|
8
7
|
* @task T5240
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
|
-
import { existsSync,
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
11
|
import { join } from 'node:path';
|
|
13
12
|
import type { AdapterInstallProvider, InstallOptions, InstallResult } from '@cleocode/contracts';
|
|
14
13
|
|
|
15
14
|
/** Lines that should appear in AGENTS.md to reference CLEO. */
|
|
16
15
|
const INSTRUCTION_REFERENCES = ['@~/.cleo/templates/CLEO-INJECTION.md', '@.cleo/memory-bridge.md'];
|
|
17
16
|
|
|
18
|
-
/** MCP server registration key used in OpenCode config. */
|
|
19
|
-
const MCP_SERVER_KEY = 'cleo';
|
|
20
|
-
|
|
21
17
|
/**
|
|
22
18
|
* Install provider for OpenCode.
|
|
23
19
|
*
|
|
24
20
|
* Manages CLEO's integration with OpenCode by:
|
|
25
|
-
* 1.
|
|
26
|
-
*
|
|
21
|
+
* 1. Ensuring AGENTS.md contains @-references to CLEO instruction files
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Installation is idempotent -- running install multiple times on the same
|
|
25
|
+
* project produces the same result. Only AGENTS.md is managed; OpenCode's
|
|
26
|
+
* plugin system is handled separately by the hook provider.
|
|
27
27
|
*/
|
|
28
28
|
export class OpenCodeInstallProvider implements AdapterInstallProvider {
|
|
29
|
-
private installedProjectDir: string | null = null;
|
|
30
|
-
|
|
31
29
|
/**
|
|
32
30
|
* Install CLEO into an OpenCode project.
|
|
33
31
|
*
|
|
34
|
-
* @param options - Installation options including project directory
|
|
32
|
+
* @param options - Installation options including project directory
|
|
35
33
|
* @returns Result describing what was installed
|
|
36
34
|
*/
|
|
37
35
|
async install(options: InstallOptions): Promise<InstallResult> {
|
|
38
|
-
const { projectDir
|
|
36
|
+
const { projectDir } = options;
|
|
39
37
|
const installedAt = new Date().toISOString();
|
|
40
38
|
let instructionFileUpdated = false;
|
|
41
|
-
let mcpRegistered = false;
|
|
42
39
|
const details: Record<string, unknown> = {};
|
|
43
40
|
|
|
44
|
-
// Step 1:
|
|
45
|
-
if (mcpServerPath) {
|
|
46
|
-
mcpRegistered = this.registerMcpServer(projectDir, mcpServerPath);
|
|
47
|
-
if (mcpRegistered) {
|
|
48
|
-
details.mcpConfigPath = join(projectDir, '.opencode', 'config.json');
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Step 2: Ensure AGENTS.md has @-references
|
|
41
|
+
// Step 1: Ensure AGENTS.md has @-references
|
|
53
42
|
instructionFileUpdated = this.updateInstructionFile(projectDir);
|
|
54
43
|
if (instructionFileUpdated) {
|
|
55
44
|
details.instructionFile = join(projectDir, 'AGENTS.md');
|
|
56
45
|
}
|
|
57
46
|
|
|
58
|
-
this.installedProjectDir = projectDir;
|
|
59
|
-
|
|
60
47
|
return {
|
|
61
48
|
success: true,
|
|
62
49
|
installedAt,
|
|
63
50
|
instructionFileUpdated,
|
|
64
|
-
mcpRegistered,
|
|
51
|
+
mcpRegistered: false,
|
|
65
52
|
details,
|
|
66
53
|
};
|
|
67
54
|
}
|
|
@@ -69,44 +56,21 @@ export class OpenCodeInstallProvider implements AdapterInstallProvider {
|
|
|
69
56
|
/**
|
|
70
57
|
* Uninstall CLEO from the current OpenCode project.
|
|
71
58
|
*
|
|
72
|
-
* Removes the MCP server registration from .opencode/config.json.
|
|
73
59
|
* Does not remove AGENTS.md references (they are harmless if CLEO is not present).
|
|
74
60
|
*/
|
|
75
|
-
async uninstall(): Promise<void> {
|
|
76
|
-
if (!this.installedProjectDir) return;
|
|
77
|
-
|
|
78
|
-
const configPath = join(this.installedProjectDir, '.opencode', 'config.json');
|
|
79
|
-
if (existsSync(configPath)) {
|
|
80
|
-
try {
|
|
81
|
-
const raw = readFileSync(configPath, 'utf-8');
|
|
82
|
-
const config = JSON.parse(raw) as Record<string, unknown>;
|
|
83
|
-
const mcpServers = config.mcpServers as Record<string, unknown> | undefined;
|
|
84
|
-
if (mcpServers && MCP_SERVER_KEY in mcpServers) {
|
|
85
|
-
delete mcpServers[MCP_SERVER_KEY];
|
|
86
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
87
|
-
}
|
|
88
|
-
} catch {
|
|
89
|
-
// Ignore errors during uninstall
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
this.installedProjectDir = null;
|
|
94
|
-
}
|
|
61
|
+
async uninstall(): Promise<void> {}
|
|
95
62
|
|
|
96
63
|
/**
|
|
97
64
|
* Check whether CLEO is installed in the current environment.
|
|
98
65
|
*
|
|
99
|
-
* Checks for
|
|
100
|
-
* Returns true if the CLEO MCP server entry is found.
|
|
66
|
+
* Checks for CLEO references in AGENTS.md.
|
|
101
67
|
*/
|
|
102
68
|
async isInstalled(): Promise<boolean> {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
if (existsSync(configPath)) {
|
|
69
|
+
const agentsMdPath = join(process.cwd(), 'AGENTS.md');
|
|
70
|
+
if (existsSync(agentsMdPath)) {
|
|
106
71
|
try {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
if (mcpServers && MCP_SERVER_KEY in mcpServers) {
|
|
72
|
+
const content = readFileSync(agentsMdPath, 'utf-8');
|
|
73
|
+
if (INSTRUCTION_REFERENCES.some((ref) => content.includes(ref))) {
|
|
110
74
|
return true;
|
|
111
75
|
}
|
|
112
76
|
} catch {
|
|
@@ -128,43 +92,6 @@ export class OpenCodeInstallProvider implements AdapterInstallProvider {
|
|
|
128
92
|
this.updateInstructionFile(projectDir);
|
|
129
93
|
}
|
|
130
94
|
|
|
131
|
-
/**
|
|
132
|
-
* Register the CLEO MCP server in .opencode/config.json.
|
|
133
|
-
*
|
|
134
|
-
* OpenCode stores its MCP server configuration in .opencode/config.json
|
|
135
|
-
* under the mcpServers key.
|
|
136
|
-
*
|
|
137
|
-
* @returns true if registration was performed or updated
|
|
138
|
-
*/
|
|
139
|
-
private registerMcpServer(projectDir: string, mcpServerPath: string): boolean {
|
|
140
|
-
const openCodeDir = join(projectDir, '.opencode');
|
|
141
|
-
const configPath = join(openCodeDir, 'config.json');
|
|
142
|
-
let config: Record<string, unknown> = {};
|
|
143
|
-
|
|
144
|
-
mkdirSync(openCodeDir, { recursive: true });
|
|
145
|
-
|
|
146
|
-
if (existsSync(configPath)) {
|
|
147
|
-
try {
|
|
148
|
-
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
149
|
-
} catch {
|
|
150
|
-
// Start fresh on parse error
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!config.mcpServers || typeof config.mcpServers !== 'object') {
|
|
155
|
-
config.mcpServers = {};
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const mcpServers = config.mcpServers as Record<string, unknown>;
|
|
159
|
-
mcpServers[MCP_SERVER_KEY] = {
|
|
160
|
-
command: 'node',
|
|
161
|
-
args: [mcpServerPath],
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', 'utf-8');
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
95
|
/**
|
|
169
96
|
* Update AGENTS.md with CLEO @-references.
|
|
170
97
|
*
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"supportedHookEvents": ["onSessionStart", "onSessionEnd", "onToolStart", "onToolComplete", "onError", "onPromptSubmit"],
|
|
11
11
|
"supportsSpawn": true,
|
|
12
12
|
"supportsInstall": true,
|
|
13
|
-
"supportsMcp":
|
|
13
|
+
"supportsMcp": false,
|
|
14
14
|
"supportsInstructionFiles": true,
|
|
15
15
|
"instructionFilePattern": "AGENTS.md",
|
|
16
16
|
"supportsContextMonitor": false,
|
|
@@ -38,9 +38,24 @@ interface TrackedProcess {
|
|
|
38
38
|
* OpenCode agents are defined as markdown files with YAML frontmatter
|
|
39
39
|
* in the .opencode/agent/ directory.
|
|
40
40
|
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* The generated markdown uses YAML frontmatter with `mode: subagent`
|
|
43
|
+
* and `hidden: true` so the agent does not appear in OpenCode's
|
|
44
|
+
* interactive agent selection menu.
|
|
45
|
+
*
|
|
41
46
|
* @param description - Agent description for frontmatter
|
|
42
47
|
* @param instructions - Markdown instructions body
|
|
43
|
-
* @returns Complete agent definition markdown
|
|
48
|
+
* @returns Complete agent definition markdown with YAML frontmatter
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { buildOpenCodeAgentMarkdown } from '@cleocode/adapters/providers/opencode/spawn';
|
|
53
|
+
*
|
|
54
|
+
* const md = buildOpenCodeAgentMarkdown(
|
|
55
|
+
* 'CLEO task executor',
|
|
56
|
+
* '# Subagent\n\nExecute the delegated task.',
|
|
57
|
+
* );
|
|
58
|
+
* ```
|
|
44
59
|
*/
|
|
45
60
|
export function buildOpenCodeAgentMarkdown(description: string, instructions: string): string {
|
|
46
61
|
const normalizedDesc = description.replace(/\s+/g, ' ').trim();
|
|
@@ -103,6 +118,13 @@ async function ensureSubagentDefinition(workingDirectory: string): Promise<strin
|
|
|
103
118
|
* Each spawn ensures a CLEO subagent definition exists, then runs
|
|
104
119
|
* `opencode run --format json --agent <name> --title <title> <prompt>`
|
|
105
120
|
* as a detached, unref'd child process.
|
|
121
|
+
*
|
|
122
|
+
* @remarks
|
|
123
|
+
* Before spawning, the provider ensures a `cleo-subagent` agent definition
|
|
124
|
+
* exists in `.opencode/agent/`. If the definition cannot be created, it
|
|
125
|
+
* falls back to the built-in `general` agent. Processes are tracked by
|
|
126
|
+
* instance ID in an in-memory map and verified via `kill(pid, 0)` liveness
|
|
127
|
+
* checks.
|
|
106
128
|
*/
|
|
107
129
|
export class OpenCodeSpawnProvider implements AdapterSpawnProvider {
|
|
108
130
|
/** Map of instance IDs to tracked process info. */
|
|
@@ -82,11 +82,26 @@ function parseTranscriptLines(raw: string): TranscriptTurn[] {
|
|
|
82
82
|
* - No JSON/JSONL files are present
|
|
83
83
|
* - The most recent file contains no parseable turns
|
|
84
84
|
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* This utility is shared by Gemini CLI and Codex CLI hook providers which
|
|
87
|
+
* both store session data in the same flat JSON/JSONL format. Only the
|
|
88
|
+
* most recent file is read to keep memory usage bounded.
|
|
89
|
+
*
|
|
85
90
|
* @param providerDir - Absolute path to the provider's session directory
|
|
86
91
|
* (e.g. `~/.gemini` or `~/.codex`).
|
|
87
92
|
* @returns A plain-text transcript with lines of the form `role: content`,
|
|
88
93
|
* or `null` if no transcript could be extracted.
|
|
89
94
|
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* import { readLatestTranscript } from '../shared/transcript-reader.js';
|
|
98
|
+
*
|
|
99
|
+
* const transcript = await readLatestTranscript('/home/user/.gemini');
|
|
100
|
+
* if (transcript) {
|
|
101
|
+
* console.log(transcript);
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
90
105
|
* @task T161
|
|
91
106
|
* @epic T134
|
|
92
107
|
*/
|
package/src/registry.ts
CHANGED
|
@@ -11,18 +11,37 @@ import { readFileSync } from 'node:fs';
|
|
|
11
11
|
import { dirname, join, resolve } from 'node:path';
|
|
12
12
|
import { fileURLToPath } from 'node:url';
|
|
13
13
|
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Minimal manifest shape for provider discovery.
|
|
16
|
+
*
|
|
17
|
+
* @remarks
|
|
18
|
+
* Each provider adapter ships a `manifest.json` in its directory under
|
|
19
|
+
* `providers/`. The registry reads these at startup to populate the
|
|
20
|
+
* adapter discovery surface. The shape is intentionally minimal -- only
|
|
21
|
+
* the fields needed for dynamic loading and detection are required.
|
|
22
|
+
*/
|
|
15
23
|
export interface AdapterManifest {
|
|
24
|
+
/** Unique provider identifier (e.g. "claude-code", "cursor"). */
|
|
16
25
|
id: string;
|
|
26
|
+
/** Human-readable display name for the provider. */
|
|
17
27
|
name: string;
|
|
28
|
+
/** Semantic version of the adapter. */
|
|
18
29
|
version: string;
|
|
30
|
+
/** Short description of what the provider integrates with. */
|
|
19
31
|
description: string;
|
|
32
|
+
/** Provider slug used for directory lookups. */
|
|
20
33
|
provider: string;
|
|
34
|
+
/** Relative path to the adapter's entry point module. */
|
|
21
35
|
entryPoint: string;
|
|
36
|
+
/** Capability flags declared by the adapter. */
|
|
22
37
|
capabilities: Record<string, unknown>;
|
|
38
|
+
/** Patterns used to auto-detect the provider in a project. */
|
|
23
39
|
detectionPatterns: Array<{
|
|
40
|
+
/** Detection strategy type (e.g. "file", "env"). */
|
|
24
41
|
type: string;
|
|
42
|
+
/** Glob or regex pattern to match. */
|
|
25
43
|
pattern: string;
|
|
44
|
+
/** Human-readable explanation of this detection rule. */
|
|
26
45
|
description: string;
|
|
27
46
|
}>;
|
|
28
47
|
}
|
|
@@ -33,7 +52,22 @@ const PROVIDER_IDS = ['claude-code', 'opencode', 'cursor'] as const;
|
|
|
33
52
|
/**
|
|
34
53
|
* Get the manifests for all bundled provider adapters.
|
|
35
54
|
*
|
|
36
|
-
* @
|
|
55
|
+
* @remarks
|
|
56
|
+
* Scans the known provider directories for `manifest.json` files.
|
|
57
|
+
* Providers whose manifests cannot be loaded (missing or malformed)
|
|
58
|
+
* are silently skipped.
|
|
59
|
+
*
|
|
60
|
+
* @returns Array of adapter manifests for successfully loaded providers
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { getProviderManifests } from '@cleocode/adapters';
|
|
65
|
+
*
|
|
66
|
+
* const manifests = getProviderManifests();
|
|
67
|
+
* for (const m of manifests) {
|
|
68
|
+
* console.log(`${m.id}: ${m.name} v${m.version}`);
|
|
69
|
+
* }
|
|
70
|
+
* ```
|
|
37
71
|
*/
|
|
38
72
|
export function getProviderManifests(): AdapterManifest[] {
|
|
39
73
|
const manifests: AdapterManifest[] = [];
|
|
@@ -56,6 +90,24 @@ export function getProviderManifests(): AdapterManifest[] {
|
|
|
56
90
|
* Discover all available provider adapters.
|
|
57
91
|
*
|
|
58
92
|
* Returns a map of provider ID to adapter factory function.
|
|
93
|
+
*
|
|
94
|
+
* @remarks
|
|
95
|
+
* Each factory lazily imports the provider module and constructs a new
|
|
96
|
+
* adapter instance. This avoids loading all provider code upfront and
|
|
97
|
+
* keeps startup fast.
|
|
98
|
+
*
|
|
99
|
+
* @returns Map of provider ID to async factory function that creates an adapter instance
|
|
100
|
+
*
|
|
101
|
+
* @example
|
|
102
|
+
* ```typescript
|
|
103
|
+
* import { discoverProviders } from '@cleocode/adapters';
|
|
104
|
+
*
|
|
105
|
+
* const providers = await discoverProviders();
|
|
106
|
+
* const factory = providers.get('claude-code');
|
|
107
|
+
* if (factory) {
|
|
108
|
+
* const adapter = await factory();
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
59
111
|
*/
|
|
60
112
|
export async function discoverProviders(): Promise<Map<string, () => Promise<unknown>>> {
|
|
61
113
|
const providers = new Map<string, () => Promise<unknown>>();
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code Adapter
|
|
3
|
-
*
|
|
4
|
-
* Main CLEOProviderAdapter implementation for Anthropic's Claude Code CLI.
|
|
5
|
-
* Provides spawn, hooks, and install capabilities for CLEO integration.
|
|
6
|
-
*
|
|
7
|
-
* @task T5240
|
|
8
|
-
*/
|
|
9
|
-
import { exec } from 'node:child_process';
|
|
10
|
-
import { existsSync } from 'node:fs';
|
|
11
|
-
import { homedir } from 'node:os';
|
|
12
|
-
import { join } from 'node:path';
|
|
13
|
-
import { promisify } from 'node:util';
|
|
14
|
-
import { ClaudeCodeContextMonitorProvider } from './context-monitor.js';
|
|
15
|
-
import { ClaudeCodeHookProvider } from './hooks.js';
|
|
16
|
-
import { ClaudeCodeInstallProvider } from './install.js';
|
|
17
|
-
import { ClaudeCodePathProvider } from './paths.js';
|
|
18
|
-
import { ClaudeCodeSpawnProvider } from './spawn.js';
|
|
19
|
-
import { ClaudeCodeTaskSyncProvider } from './task-sync.js';
|
|
20
|
-
import { ClaudeCodeTransportProvider } from './transport.js';
|
|
21
|
-
const execAsync = promisify(exec);
|
|
22
|
-
/**
|
|
23
|
-
* CLEO provider adapter for Anthropic Claude Code CLI.
|
|
24
|
-
*
|
|
25
|
-
* Bridges CLEO's adapter system with Claude Code's native capabilities:
|
|
26
|
-
* - Hooks: Maps Claude Code events (SessionStart, PostToolUse, etc.) to CAAMP events
|
|
27
|
-
* - Spawn: Launches subagent processes via the `claude` CLI
|
|
28
|
-
* - Install: Registers MCP server, instruction files, and brain observation plugin
|
|
29
|
-
*/
|
|
30
|
-
export class ClaudeCodeAdapter {
|
|
31
|
-
id = 'claude-code';
|
|
32
|
-
name = 'Claude Code';
|
|
33
|
-
version = '1.0.0';
|
|
34
|
-
capabilities = {
|
|
35
|
-
supportsHooks: true,
|
|
36
|
-
// 14/16 canonical events — derived from getProviderHookProfile('claude-code') in CAAMP 1.9.1.
|
|
37
|
-
// PreModel and PostModel are not supported by Claude Code.
|
|
38
|
-
supportedHookEvents: [
|
|
39
|
-
'SessionStart',
|
|
40
|
-
'SessionEnd',
|
|
41
|
-
'PromptSubmit',
|
|
42
|
-
'ResponseComplete',
|
|
43
|
-
'PreToolUse',
|
|
44
|
-
'PostToolUse',
|
|
45
|
-
'PostToolUseFailure',
|
|
46
|
-
'PermissionRequest',
|
|
47
|
-
'SubagentStart',
|
|
48
|
-
'SubagentStop',
|
|
49
|
-
'PreCompact',
|
|
50
|
-
'PostCompact',
|
|
51
|
-
'Notification',
|
|
52
|
-
'ConfigChange',
|
|
53
|
-
],
|
|
54
|
-
supportsSpawn: true,
|
|
55
|
-
supportsInstall: true,
|
|
56
|
-
supportsMcp: true,
|
|
57
|
-
supportsInstructionFiles: true,
|
|
58
|
-
instructionFilePattern: 'CLAUDE.md',
|
|
59
|
-
supportsContextMonitor: true,
|
|
60
|
-
supportsStatusline: true,
|
|
61
|
-
supportsProviderPaths: true,
|
|
62
|
-
supportsTransport: true,
|
|
63
|
-
supportsTaskSync: true,
|
|
64
|
-
};
|
|
65
|
-
hooks;
|
|
66
|
-
spawn;
|
|
67
|
-
install;
|
|
68
|
-
paths;
|
|
69
|
-
contextMonitor;
|
|
70
|
-
transport;
|
|
71
|
-
taskSync;
|
|
72
|
-
projectDir = null;
|
|
73
|
-
initialized = false;
|
|
74
|
-
constructor() {
|
|
75
|
-
this.hooks = new ClaudeCodeHookProvider();
|
|
76
|
-
this.spawn = new ClaudeCodeSpawnProvider();
|
|
77
|
-
this.install = new ClaudeCodeInstallProvider();
|
|
78
|
-
this.paths = new ClaudeCodePathProvider();
|
|
79
|
-
this.contextMonitor = new ClaudeCodeContextMonitorProvider();
|
|
80
|
-
this.transport = new ClaudeCodeTransportProvider();
|
|
81
|
-
this.taskSync = new ClaudeCodeTaskSyncProvider();
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Initialize the adapter for a given project directory.
|
|
85
|
-
*
|
|
86
|
-
* Validates the environment by checking for the Claude CLI
|
|
87
|
-
* and Claude Code configuration directory.
|
|
88
|
-
*
|
|
89
|
-
* @param projectDir - Root directory of the project
|
|
90
|
-
*/
|
|
91
|
-
async initialize(projectDir) {
|
|
92
|
-
this.projectDir = projectDir;
|
|
93
|
-
this.initialized = true;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Dispose the adapter and clean up resources.
|
|
97
|
-
*
|
|
98
|
-
* Unregisters hooks and releases any tracked state.
|
|
99
|
-
*/
|
|
100
|
-
async dispose() {
|
|
101
|
-
if (this.hooks.isRegistered()) {
|
|
102
|
-
await this.hooks.unregisterNativeHooks();
|
|
103
|
-
}
|
|
104
|
-
this.initialized = false;
|
|
105
|
-
this.projectDir = null;
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* Run a health check to verify Claude Code is accessible.
|
|
109
|
-
*
|
|
110
|
-
* Checks:
|
|
111
|
-
* 1. Adapter has been initialized
|
|
112
|
-
* 2. Claude CLI is available in PATH
|
|
113
|
-
* 3. ~/.claude/ configuration directory exists
|
|
114
|
-
*
|
|
115
|
-
* @returns Health status with details about each check
|
|
116
|
-
*/
|
|
117
|
-
async healthCheck() {
|
|
118
|
-
const details = {};
|
|
119
|
-
if (!this.initialized) {
|
|
120
|
-
return {
|
|
121
|
-
healthy: false,
|
|
122
|
-
provider: this.id,
|
|
123
|
-
details: { error: 'Adapter not initialized' },
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
// Check Claude CLI availability
|
|
127
|
-
let cliAvailable = false;
|
|
128
|
-
try {
|
|
129
|
-
const { stdout } = await execAsync('which claude');
|
|
130
|
-
cliAvailable = stdout.trim().length > 0;
|
|
131
|
-
details.cliPath = stdout.trim();
|
|
132
|
-
}
|
|
133
|
-
catch {
|
|
134
|
-
details.cliAvailable = false;
|
|
135
|
-
}
|
|
136
|
-
// Check for Claude Code config directory
|
|
137
|
-
const claudeConfigDir = join(homedir(), '.claude');
|
|
138
|
-
const configExists = existsSync(claudeConfigDir);
|
|
139
|
-
details.configDirExists = configExists;
|
|
140
|
-
// Check for CLAUDE_CODE_ENTRYPOINT env var
|
|
141
|
-
const entrypointSet = process.env.CLAUDE_CODE_ENTRYPOINT !== undefined;
|
|
142
|
-
details.entrypointEnvSet = entrypointSet;
|
|
143
|
-
// Healthy if CLI is available (primary requirement)
|
|
144
|
-
const healthy = cliAvailable;
|
|
145
|
-
details.cliAvailable = cliAvailable;
|
|
146
|
-
return {
|
|
147
|
-
healthy,
|
|
148
|
-
provider: this.id,
|
|
149
|
-
details,
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Check whether the adapter has been initialized.
|
|
154
|
-
*/
|
|
155
|
-
isInitialized() {
|
|
156
|
-
return this.initialized;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Get the project directory this adapter was initialized with.
|
|
160
|
-
*/
|
|
161
|
-
getProjectDir() {
|
|
162
|
-
return this.projectDir;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
//# sourceMappingURL=adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/providers/claude-code/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Claude Code context monitor provider.
|
|
3
|
-
*
|
|
4
|
-
* Implements AdapterContextMonitorProvider for Claude Code's context window
|
|
5
|
-
* tracking and statusline integration.
|
|
6
|
-
*
|
|
7
|
-
* @task T5240
|
|
8
|
-
*/
|
|
9
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
10
|
-
import { mkdir } from 'node:fs/promises';
|
|
11
|
-
import { homedir } from 'node:os';
|
|
12
|
-
import { dirname, join } from 'node:path';
|
|
13
|
-
import { ClaudeCodePathProvider } from './paths.js';
|
|
14
|
-
/** Thresholds for context window status levels. */
|
|
15
|
-
const THRESHOLDS = {
|
|
16
|
-
WARNING: 50,
|
|
17
|
-
CAUTION: 70,
|
|
18
|
-
CRITICAL: 85,
|
|
19
|
-
EMERGENCY: 95,
|
|
20
|
-
};
|
|
21
|
-
function getContextStatusFromPercentage(percentage) {
|
|
22
|
-
if (percentage >= THRESHOLDS.EMERGENCY)
|
|
23
|
-
return 'emergency';
|
|
24
|
-
if (percentage >= THRESHOLDS.CRITICAL)
|
|
25
|
-
return 'critical';
|
|
26
|
-
if (percentage >= THRESHOLDS.CAUTION)
|
|
27
|
-
return 'caution';
|
|
28
|
-
if (percentage >= THRESHOLDS.WARNING)
|
|
29
|
-
return 'warning';
|
|
30
|
-
return 'ok';
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Context monitor provider for Claude Code.
|
|
34
|
-
*
|
|
35
|
-
* Processes context window JSON from Claude Code and writes state files
|
|
36
|
-
* for statusline display. Also provides statusline configuration
|
|
37
|
-
* and setup instructions specific to Claude Code's settings.json.
|
|
38
|
-
*/
|
|
39
|
-
export class ClaudeCodeContextMonitorProvider {
|
|
40
|
-
pathProvider = new ClaudeCodePathProvider();
|
|
41
|
-
async processContextInput(input, cwd) {
|
|
42
|
-
const typed = input;
|
|
43
|
-
const contextSize = typed.context_window?.context_window_size ?? 200000;
|
|
44
|
-
const usage = typed.context_window?.current_usage;
|
|
45
|
-
if (!usage)
|
|
46
|
-
return '-- no data';
|
|
47
|
-
const inputTokens = usage.input_tokens ?? 0;
|
|
48
|
-
const outputTokens = usage.output_tokens ?? 0;
|
|
49
|
-
const cacheCreate = usage.cache_creation_input_tokens ?? 0;
|
|
50
|
-
const totalTokens = inputTokens + outputTokens + cacheCreate;
|
|
51
|
-
const percentage = Math.floor((totalTokens * 100) / contextSize);
|
|
52
|
-
const status = getContextStatusFromPercentage(percentage);
|
|
53
|
-
// Write state file if CLEO dir exists
|
|
54
|
-
const cleoDir = cwd ? join(cwd, '.cleo') : '.cleo';
|
|
55
|
-
if (existsSync(cleoDir)) {
|
|
56
|
-
const stateDir = join(cleoDir, 'context-states');
|
|
57
|
-
const statePath = join(stateDir, '.context-state.json');
|
|
58
|
-
const state = {
|
|
59
|
-
$schema: 'https://cleo-dev.com/schemas/v1/context-state.schema.json',
|
|
60
|
-
version: '1.0.0',
|
|
61
|
-
timestamp: new Date().toISOString().replace(/\.\d{3}Z$/, 'Z'),
|
|
62
|
-
staleAfterMs: 5000,
|
|
63
|
-
contextWindow: {
|
|
64
|
-
maxTokens: contextSize,
|
|
65
|
-
currentTokens: totalTokens,
|
|
66
|
-
percentage,
|
|
67
|
-
breakdown: {
|
|
68
|
-
inputTokens,
|
|
69
|
-
outputTokens,
|
|
70
|
-
cacheCreationTokens: cacheCreate,
|
|
71
|
-
cacheReadTokens: usage.cache_read_input_tokens ?? 0,
|
|
72
|
-
},
|
|
73
|
-
},
|
|
74
|
-
thresholds: {
|
|
75
|
-
warning: THRESHOLDS.WARNING,
|
|
76
|
-
caution: THRESHOLDS.CAUTION,
|
|
77
|
-
critical: THRESHOLDS.CRITICAL,
|
|
78
|
-
emergency: THRESHOLDS.EMERGENCY,
|
|
79
|
-
},
|
|
80
|
-
status,
|
|
81
|
-
cleoSessionId: '',
|
|
82
|
-
};
|
|
83
|
-
try {
|
|
84
|
-
await mkdir(dirname(statePath), { recursive: true });
|
|
85
|
-
writeFileSync(statePath, JSON.stringify(state, null, 2));
|
|
86
|
-
}
|
|
87
|
-
catch {
|
|
88
|
-
// Non-fatal
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return `${percentage}% | ${totalTokens}/${contextSize}`;
|
|
92
|
-
}
|
|
93
|
-
checkStatuslineIntegration() {
|
|
94
|
-
const settingsPath = this.pathProvider.getSettingsPath();
|
|
95
|
-
if (!settingsPath || !existsSync(settingsPath))
|
|
96
|
-
return 'no_settings';
|
|
97
|
-
try {
|
|
98
|
-
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
|
|
99
|
-
const statusLine = settings.statusLine;
|
|
100
|
-
if (!statusLine?.type)
|
|
101
|
-
return 'not_configured';
|
|
102
|
-
if (statusLine.type !== 'command')
|
|
103
|
-
return 'custom_no_cleo';
|
|
104
|
-
const cmd = statusLine.command ?? '';
|
|
105
|
-
if (cmd.includes('context-monitor.sh') ||
|
|
106
|
-
cmd.includes('cleo-statusline') ||
|
|
107
|
-
cmd.includes('.context-state.json') ||
|
|
108
|
-
cmd.includes('context-states')) {
|
|
109
|
-
return 'configured';
|
|
110
|
-
}
|
|
111
|
-
const scriptPath = cmd.startsWith('~') ? cmd.replace('~', homedir()) : cmd;
|
|
112
|
-
if (existsSync(scriptPath)) {
|
|
113
|
-
try {
|
|
114
|
-
const content = readFileSync(scriptPath, 'utf-8');
|
|
115
|
-
if (content.includes('context-state.json'))
|
|
116
|
-
return 'configured';
|
|
117
|
-
}
|
|
118
|
-
catch {
|
|
119
|
-
/* unreadable */
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
return 'custom_no_cleo';
|
|
123
|
-
}
|
|
124
|
-
catch {
|
|
125
|
-
return 'no_settings';
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
getStatuslineConfig() {
|
|
129
|
-
return {
|
|
130
|
-
statusLine: {
|
|
131
|
-
type: 'command',
|
|
132
|
-
command: join(homedir(), '.cleo', 'lib', 'session', 'context-monitor.sh'),
|
|
133
|
-
},
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
getSetupInstructions() {
|
|
137
|
-
const settingsPath = this.pathProvider.getSettingsPath() ?? '~/.claude/settings.json';
|
|
138
|
-
return [
|
|
139
|
-
'To enable context monitoring, add to your Claude Code settings:',
|
|
140
|
-
`File: ${settingsPath}`,
|
|
141
|
-
'',
|
|
142
|
-
JSON.stringify(this.getStatuslineConfig(), null, 2),
|
|
143
|
-
'',
|
|
144
|
-
'This enables real-time context window tracking in the CLI.',
|
|
145
|
-
].join('\n');
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
//# sourceMappingURL=context-monitor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-monitor.js","sourceRoot":"","sources":["../../../src/providers/claude-code/context-monitor.ts"],"names":[],"mappings":"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"}
|