@ekkos/cli 1.3.1 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/capture/jsonl-rewriter.d.ts +1 -1
- package/dist/capture/jsonl-rewriter.js +3 -3
- package/dist/capture/transcript-repair.d.ts +2 -2
- package/dist/capture/transcript-repair.js +2 -2
- package/dist/commands/claw.d.ts +13 -0
- package/dist/commands/claw.js +253 -0
- package/dist/commands/dashboard.js +742 -118
- package/dist/commands/doctor.d.ts +3 -3
- package/dist/commands/doctor.js +6 -79
- package/dist/commands/gemini.d.ts +19 -0
- package/dist/commands/gemini.js +193 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +56 -41
- package/dist/commands/run.d.ts +0 -1
- package/dist/commands/run.js +288 -263
- package/dist/commands/scan.d.ts +21 -0
- package/dist/commands/scan.js +386 -0
- package/dist/commands/status.d.ts +4 -1
- package/dist/commands/status.js +165 -27
- package/dist/commands/swarm-dashboard.js +156 -28
- package/dist/commands/swarm.d.ts +1 -1
- package/dist/commands/swarm.js +1 -1
- package/dist/commands/test-claude.d.ts +2 -2
- package/dist/commands/test-claude.js +3 -3
- package/dist/deploy/index.d.ts +0 -2
- package/dist/deploy/index.js +0 -2
- package/dist/deploy/settings.d.ts +6 -5
- package/dist/deploy/settings.js +64 -16
- package/dist/deploy/skills.js +1 -2
- package/dist/index.js +86 -96
- package/dist/lib/usage-parser.d.ts +1 -1
- package/dist/lib/usage-parser.js +9 -6
- package/dist/local/index.d.ts +14 -0
- package/dist/local/index.js +28 -0
- package/dist/local/local-embeddings.d.ts +49 -0
- package/dist/local/local-embeddings.js +232 -0
- package/dist/local/offline-fallback.d.ts +44 -0
- package/dist/local/offline-fallback.js +159 -0
- package/dist/local/sqlite-store.d.ts +126 -0
- package/dist/local/sqlite-store.js +393 -0
- package/dist/local/sync-engine.d.ts +42 -0
- package/dist/local/sync-engine.js +223 -0
- package/dist/utils/platform.d.ts +5 -1
- package/dist/utils/platform.js +24 -4
- package/dist/utils/proxy-url.d.ts +21 -0
- package/dist/utils/proxy-url.js +34 -0
- package/dist/utils/state.d.ts +1 -1
- package/dist/utils/state.js +11 -3
- package/dist/utils/templates.js +1 -1
- package/package.json +11 -4
- package/templates/CLAUDE.md +49 -107
- package/dist/agent/daemon.d.ts +0 -130
- package/dist/agent/daemon.js +0 -606
- package/dist/agent/health-check.d.ts +0 -35
- package/dist/agent/health-check.js +0 -243
- package/dist/agent/pty-runner.d.ts +0 -53
- package/dist/agent/pty-runner.js +0 -190
- package/dist/commands/agent.d.ts +0 -50
- package/dist/commands/agent.js +0 -544
- package/dist/commands/setup-remote.d.ts +0 -20
- package/dist/commands/setup-remote.js +0 -582
- package/dist/utils/verify-remote-terminal.d.ts +0 -10
- package/dist/utils/verify-remote-terminal.js +0 -415
- package/templates/README.md +0 -378
- package/templates/claude-plugins/PHASE2_COMPLETION.md +0 -346
- package/templates/claude-plugins/PLUGIN_PROPOSALS.md +0 -1776
- package/templates/claude-plugins/README.md +0 -587
- package/templates/claude-plugins/agents/code-reviewer.json +0 -14
- package/templates/claude-plugins/agents/debug-detective.json +0 -15
- package/templates/claude-plugins/agents/git-companion.json +0 -14
- package/templates/claude-plugins/blog-manager/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/blog-manager/commands/blog.md +0 -691
- package/templates/claude-plugins/golden-loop-monitor/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/golden-loop-monitor/commands/loop-status.md +0 -434
- package/templates/claude-plugins/learning-tracker/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/learning-tracker/commands/my-patterns.md +0 -282
- package/templates/claude-plugins/memory-lens/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/memory-lens/commands/memory-search.md +0 -181
- package/templates/claude-plugins/pattern-coach/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/pattern-coach/commands/forge.md +0 -365
- package/templates/claude-plugins/project-schema-validator/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins/project-schema-validator/commands/validate-schema.md +0 -582
- package/templates/claude-plugins-admin/AGENT_TEAM_PROPOSALS.md +0 -819
- package/templates/claude-plugins-admin/README.md +0 -446
- package/templates/claude-plugins-admin/autonomous-admin-agent/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/autonomous-admin-agent/commands/agent.md +0 -595
- package/templates/claude-plugins-admin/backend-agent/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/backend-agent/commands/backend.md +0 -798
- package/templates/claude-plugins-admin/deploy-guardian/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/deploy-guardian/commands/deploy.md +0 -554
- package/templates/claude-plugins-admin/frontend-agent/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/frontend-agent/commands/frontend.md +0 -881
- package/templates/claude-plugins-admin/mcp-server-manager/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/mcp-server-manager/commands/mcp.md +0 -85
- package/templates/claude-plugins-admin/memory-system-monitor/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/memory-system-monitor/commands/memory-health.md +0 -569
- package/templates/claude-plugins-admin/qa-agent/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/qa-agent/commands/qa.md +0 -863
- package/templates/claude-plugins-admin/tech-lead-agent/.claude-plugin/plugin.json +0 -8
- package/templates/claude-plugins-admin/tech-lead-agent/commands/lead.md +0 -732
- package/templates/commands/continue.md +0 -47
- package/templates/cursor-rules/ekkos-memory.md +0 -127
- package/templates/ekkos-manifest.json +0 -223
- package/templates/helpers/json-parse.cjs +0 -101
- package/templates/hooks-node/lib/state.js +0 -187
- package/templates/hooks-node/stop.js +0 -416
- package/templates/hooks-node/user-prompt-submit.js +0 -337
- package/templates/plan-template.md +0 -306
- package/templates/rules/00-hooks-contract.mdc +0 -89
- package/templates/rules/30-ekkos-core.mdc +0 -188
- package/templates/rules/31-ekkos-messages.mdc +0 -78
- package/templates/shared/hooks-enabled.json +0 -22
- package/templates/shared/session-words.json +0 -45
- package/templates/skills/ekkOS_Deep_Recall/Skill.md +0 -282
- package/templates/skills/ekkOS_Learn/Skill.md +0 -265
- package/templates/skills/ekkOS_Memory_First/Skill.md +0 -206
- package/templates/skills/ekkOS_Plan_Assist/Skill.md +0 -302
- package/templates/skills/ekkOS_Preferences/Skill.md +0 -247
- package/templates/skills/ekkOS_Reflect/Skill.md +0 -257
- package/templates/skills/ekkOS_Safety/Skill.md +0 -265
- package/templates/skills/ekkOS_Schema/Skill.md +0 -251
- package/templates/skills/ekkOS_Summary/Skill.md +0 -257
- package/templates/spec-template.md +0 -159
- package/templates/windsurf-rules/ekkos-memory.md +0 -127
- package/templates/windsurf-skills/README.md +0 -58
- package/templates/windsurf-skills/ekkos-continue/SKILL.md +0 -81
- package/templates/windsurf-skills/ekkos-golden-loop/SKILL.md +0 -225
- package/templates/windsurf-skills/ekkos-insights/SKILL.md +0 -138
- package/templates/windsurf-skills/ekkos-recall/SKILL.md +0 -96
- package/templates/windsurf-skills/ekkos-safety/SKILL.md +0 -89
- package/templates/windsurf-skills/ekkos-vault/SKILL.md +0 -86
|
@@ -87,7 +87,7 @@ export declare function getEvictionStats(): {
|
|
|
87
87
|
lastEviction?: string;
|
|
88
88
|
};
|
|
89
89
|
/**
|
|
90
|
-
* Get evicted content for retrieval
|
|
90
|
+
* Get evicted content for retrieval
|
|
91
91
|
*/
|
|
92
92
|
export declare function getEvictedContent(limit?: number): Array<{
|
|
93
93
|
timestamp: string;
|
|
@@ -283,7 +283,7 @@ function truncateToolResult(line) {
|
|
|
283
283
|
return line;
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
// Evicted content store
|
|
286
|
+
// Evicted content store
|
|
287
287
|
const EVICTED_STORE = path.join(os.homedir(), '.ekkos', 'evicted-context.jsonl');
|
|
288
288
|
const EKKOS_CAPTURE_ENDPOINT = 'https://mcp.ekkos.dev/api/v1/context/evict';
|
|
289
289
|
const EKKOS_API_URL = process.env.EKKOS_API_URL || 'https://mcp.ekkos.dev';
|
|
@@ -716,7 +716,7 @@ function evictToTarget(filePath, currentPercent, sessionId, sessionName) {
|
|
|
716
716
|
debugLog('EVICTION_NOOP', 'No lines to evict or truncate');
|
|
717
717
|
return { success: true, evicted: 0, truncated: 0, newPercent: currentPercent };
|
|
718
718
|
}
|
|
719
|
-
// Save evicted content
|
|
719
|
+
// Save evicted content
|
|
720
720
|
const evictedLines = lines.filter(l => toRemove.has(l.index)).map(l => l.raw);
|
|
721
721
|
const evictedIndices = lines.filter(l => toRemove.has(l.index)).map(l => l.index);
|
|
722
722
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -1346,7 +1346,7 @@ function getEvictionStats() {
|
|
|
1346
1346
|
}
|
|
1347
1347
|
}
|
|
1348
1348
|
/**
|
|
1349
|
-
* Get evicted content for retrieval
|
|
1349
|
+
* Get evicted content for retrieval
|
|
1350
1350
|
*/
|
|
1351
1351
|
function getEvictedContent(limit = 10) {
|
|
1352
1352
|
try {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Transcript Repair - Handles orphan tool_result recovery
|
|
3
3
|
*
|
|
4
|
-
* When
|
|
4
|
+
* When orphan tool_results are detected (tool_result without
|
|
5
5
|
* matching tool_use), this module repairs the transcript:
|
|
6
6
|
*
|
|
7
7
|
* 1. ROLLBACK (preferred): Restore from backup if valid
|
|
8
8
|
* 2. SURGICAL REPAIR (fallback): Remove orphan tool_result lines
|
|
9
9
|
*
|
|
10
|
-
* This closes the loop:
|
|
10
|
+
* This closes the loop: orphan detected → ekkos-cli repairs → transcript clean
|
|
11
11
|
*/
|
|
12
12
|
type RepairAction = 'none' | 'rollback' | 'surgical_repair' | 'failed';
|
|
13
13
|
export interface RepairResult {
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Transcript Repair - Handles orphan tool_result recovery
|
|
4
4
|
*
|
|
5
|
-
* When
|
|
5
|
+
* When orphan tool_results are detected (tool_result without
|
|
6
6
|
* matching tool_use), this module repairs the transcript:
|
|
7
7
|
*
|
|
8
8
|
* 1. ROLLBACK (preferred): Restore from backup if valid
|
|
9
9
|
* 2. SURGICAL REPAIR (fallback): Remove orphan tool_result lines
|
|
10
10
|
*
|
|
11
|
-
* This closes the loop:
|
|
11
|
+
* This closes the loop: orphan detected → ekkos-cli repairs → transcript clean
|
|
12
12
|
*/
|
|
13
13
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
14
|
if (k2 === undefined) k2 = k;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface ClawStatusOptions {
|
|
2
|
+
json?: boolean;
|
|
3
|
+
proxyUrl?: string;
|
|
4
|
+
model?: string;
|
|
5
|
+
workspace?: string;
|
|
6
|
+
}
|
|
7
|
+
interface ClawUpgradeOptions extends ClawStatusOptions {
|
|
8
|
+
apply?: boolean;
|
|
9
|
+
force?: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function clawStatus(options?: ClawStatusOptions): Promise<void>;
|
|
12
|
+
export declare function clawUpgrade(options?: ClawUpgradeOptions): Promise<void>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.clawStatus = clawStatus;
|
|
7
|
+
exports.clawUpgrade = clawUpgrade;
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const os_1 = require("os");
|
|
11
|
+
const path_1 = require("path");
|
|
12
|
+
const net_1 = __importDefault(require("net"));
|
|
13
|
+
const OPENCLAW_CONFIG_PATH = (0, path_1.join)((0, os_1.homedir)(), '.openclaw', 'openclaw.json');
|
|
14
|
+
const DEFAULT_PROXY_URL = process.env.EKKOS_CLAW_PROXY_URL || 'https://proxy.ekkos.dev';
|
|
15
|
+
const DEFAULT_MODEL = process.env.EKKOS_CLAW_MODEL || 'ekkos-proxy/claude-sonnet-4-6';
|
|
16
|
+
const DEFAULT_WORKSPACE_PATH = process.env.EKKOS_CLAW_WORKSPACE || '/Volumes/Dev_Disk/openclaw/workspace';
|
|
17
|
+
function isRecord(value) {
|
|
18
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
19
|
+
}
|
|
20
|
+
function readConfig() {
|
|
21
|
+
if (!(0, fs_1.existsSync)(OPENCLAW_CONFIG_PATH))
|
|
22
|
+
return null;
|
|
23
|
+
try {
|
|
24
|
+
const raw = (0, fs_1.readFileSync)(OPENCLAW_CONFIG_PATH, 'utf-8');
|
|
25
|
+
const parsed = JSON.parse(raw);
|
|
26
|
+
return isRecord(parsed) ? parsed : null;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function ensureObject(parent, key) {
|
|
33
|
+
const current = parent[key];
|
|
34
|
+
if (isRecord(current))
|
|
35
|
+
return current;
|
|
36
|
+
const next = {};
|
|
37
|
+
parent[key] = next;
|
|
38
|
+
return next;
|
|
39
|
+
}
|
|
40
|
+
function timestampForBackup() {
|
|
41
|
+
return new Date().toISOString().replace(/[:.]/g, '-');
|
|
42
|
+
}
|
|
43
|
+
async function isPortListening(port, host = '127.0.0.1', timeoutMs = 1000) {
|
|
44
|
+
return new Promise((resolve) => {
|
|
45
|
+
const socket = new net_1.default.Socket();
|
|
46
|
+
let done = false;
|
|
47
|
+
const finish = (value) => {
|
|
48
|
+
if (done)
|
|
49
|
+
return;
|
|
50
|
+
done = true;
|
|
51
|
+
socket.destroy();
|
|
52
|
+
resolve(value);
|
|
53
|
+
};
|
|
54
|
+
socket.setTimeout(timeoutMs);
|
|
55
|
+
socket.once('connect', () => finish(true));
|
|
56
|
+
socket.once('timeout', () => finish(false));
|
|
57
|
+
socket.once('error', () => finish(false));
|
|
58
|
+
socket.connect(port, host);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
async function isHttpReachable(url, timeoutMs = 1400) {
|
|
62
|
+
const controller = new AbortController();
|
|
63
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
64
|
+
try {
|
|
65
|
+
const response = await fetch(url, {
|
|
66
|
+
method: 'GET',
|
|
67
|
+
signal: controller.signal,
|
|
68
|
+
});
|
|
69
|
+
return response.ok || response.status < 500;
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
finally {
|
|
75
|
+
clearTimeout(timeout);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function collectStatus(options = {}) {
|
|
79
|
+
const expectedProxy = options.proxyUrl || DEFAULT_PROXY_URL;
|
|
80
|
+
const expectedModel = options.model || DEFAULT_MODEL;
|
|
81
|
+
const workspacePath = options.workspace || DEFAULT_WORKSPACE_PATH;
|
|
82
|
+
const config = readConfig();
|
|
83
|
+
const configFound = config !== null;
|
|
84
|
+
const configValid = configFound && isRecord(config);
|
|
85
|
+
const gatewayPort = Number(config?.gateway?.port || 18789);
|
|
86
|
+
const listenerActive = await isPortListening(gatewayPort);
|
|
87
|
+
const uiReachable = await isHttpReachable(`http://127.0.0.1:${gatewayPort}/`);
|
|
88
|
+
const workspaceExists = (0, fs_1.existsSync)(workspacePath);
|
|
89
|
+
let primaryModel = null;
|
|
90
|
+
let ekkosProxyBaseUrl = null;
|
|
91
|
+
let ekkosProxyApi = null;
|
|
92
|
+
if (configValid && config) {
|
|
93
|
+
const agents = config.agents;
|
|
94
|
+
const defaults = isRecord(agents?.defaults) ? agents?.defaults : undefined;
|
|
95
|
+
const model = isRecord(defaults?.model) ? defaults?.model : undefined;
|
|
96
|
+
if (typeof model?.primary === 'string')
|
|
97
|
+
primaryModel = model.primary;
|
|
98
|
+
const models = isRecord(config.models) ? config.models : undefined;
|
|
99
|
+
const providers = isRecord(models?.providers) ? models?.providers : undefined;
|
|
100
|
+
const ekkosProxy = isRecord(providers?.['ekkos-proxy']) ? providers?.['ekkos-proxy'] : undefined;
|
|
101
|
+
if (typeof ekkosProxy?.baseUrl === 'string')
|
|
102
|
+
ekkosProxyBaseUrl = ekkosProxy.baseUrl;
|
|
103
|
+
if (typeof ekkosProxy?.api === 'string')
|
|
104
|
+
ekkosProxyApi = ekkosProxy.api;
|
|
105
|
+
}
|
|
106
|
+
const warnings = [];
|
|
107
|
+
if (!configFound)
|
|
108
|
+
warnings.push(`Missing OpenClaw config: ${OPENCLAW_CONFIG_PATH}`);
|
|
109
|
+
if (configFound && !configValid)
|
|
110
|
+
warnings.push(`Invalid JSON in: ${OPENCLAW_CONFIG_PATH}`);
|
|
111
|
+
if (!listenerActive)
|
|
112
|
+
warnings.push(`No listener on 127.0.0.1:${gatewayPort}`);
|
|
113
|
+
if (!uiReachable)
|
|
114
|
+
warnings.push(`OpenClaw UI check failed: http://127.0.0.1:${gatewayPort}/`);
|
|
115
|
+
if (!workspaceExists)
|
|
116
|
+
warnings.push(`Workspace not found: ${workspacePath}`);
|
|
117
|
+
if (primaryModel !== expectedModel)
|
|
118
|
+
warnings.push(`Primary model is '${primaryModel ?? 'unset'}' (expected '${expectedModel}')`);
|
|
119
|
+
if (ekkosProxyBaseUrl !== expectedProxy)
|
|
120
|
+
warnings.push(`ekkos-proxy baseUrl is '${ekkosProxyBaseUrl ?? 'unset'}' (expected '${expectedProxy}')`);
|
|
121
|
+
if (ekkosProxyApi !== 'anthropic-messages')
|
|
122
|
+
warnings.push(`ekkos-proxy api is '${ekkosProxyApi ?? 'unset'}' (expected 'anthropic-messages')`);
|
|
123
|
+
return {
|
|
124
|
+
timestamp: new Date().toISOString(),
|
|
125
|
+
configPath: OPENCLAW_CONFIG_PATH,
|
|
126
|
+
configFound,
|
|
127
|
+
configValid,
|
|
128
|
+
gatewayPort,
|
|
129
|
+
listenerActive,
|
|
130
|
+
uiReachable,
|
|
131
|
+
primaryModel,
|
|
132
|
+
ekkosProxyBaseUrl,
|
|
133
|
+
ekkosProxyApi,
|
|
134
|
+
workspacePath,
|
|
135
|
+
workspaceExists,
|
|
136
|
+
warnings,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function printStatus(report) {
|
|
140
|
+
const ok = (value) => (value ? chalk_1.default.green('yes') : chalk_1.default.red('no'));
|
|
141
|
+
console.log('');
|
|
142
|
+
console.log(chalk_1.default.cyan.bold('ekkOS_Claw Status'));
|
|
143
|
+
console.log(chalk_1.default.gray(` checked: ${report.timestamp}`));
|
|
144
|
+
console.log('');
|
|
145
|
+
console.log(` OpenClaw config: ${ok(report.configFound && report.configValid)} ${chalk_1.default.gray(report.configPath)}`);
|
|
146
|
+
console.log(` Listener active: ${ok(report.listenerActive)} ${chalk_1.default.gray(`127.0.0.1:${report.gatewayPort}`)}`);
|
|
147
|
+
console.log(` UI reachable: ${ok(report.uiReachable)} ${chalk_1.default.gray(`http://127.0.0.1:${report.gatewayPort}/`)}`);
|
|
148
|
+
console.log(` Workspace exists: ${ok(report.workspaceExists)} ${chalk_1.default.gray(report.workspacePath)}`);
|
|
149
|
+
console.log(` Primary model: ${chalk_1.default.white(report.primaryModel || 'unset')}`);
|
|
150
|
+
console.log(` ekkos-proxy URL: ${chalk_1.default.white(report.ekkosProxyBaseUrl || 'unset')}`);
|
|
151
|
+
console.log(` ekkos-proxy API: ${chalk_1.default.white(report.ekkosProxyApi || 'unset')}`);
|
|
152
|
+
console.log('');
|
|
153
|
+
if (report.warnings.length > 0) {
|
|
154
|
+
console.log(chalk_1.default.yellow('Warnings:'));
|
|
155
|
+
for (const warning of report.warnings) {
|
|
156
|
+
console.log(chalk_1.default.yellow(` - ${warning}`));
|
|
157
|
+
}
|
|
158
|
+
console.log('');
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(chalk_1.default.green('Integration looks healthy.'));
|
|
162
|
+
console.log('');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function planUpgrade(config, options) {
|
|
166
|
+
const nextConfig = JSON.parse(JSON.stringify(config));
|
|
167
|
+
const changes = [];
|
|
168
|
+
const proxyUrl = options.proxyUrl || DEFAULT_PROXY_URL;
|
|
169
|
+
const modelName = options.model || DEFAULT_MODEL;
|
|
170
|
+
const models = ensureObject(nextConfig, 'models');
|
|
171
|
+
const providers = ensureObject(models, 'providers');
|
|
172
|
+
const existingProvider = isRecord(providers['ekkos-proxy']) ? providers['ekkos-proxy'] : {};
|
|
173
|
+
const nextProvider = { ...existingProvider };
|
|
174
|
+
if (nextProvider.baseUrl !== proxyUrl) {
|
|
175
|
+
changes.push(`models.providers.ekkos-proxy.baseUrl -> ${proxyUrl}`);
|
|
176
|
+
nextProvider.baseUrl = proxyUrl;
|
|
177
|
+
}
|
|
178
|
+
if (nextProvider.api !== 'anthropic-messages') {
|
|
179
|
+
changes.push(`models.providers.ekkos-proxy.api -> anthropic-messages`);
|
|
180
|
+
nextProvider.api = 'anthropic-messages';
|
|
181
|
+
}
|
|
182
|
+
const desiredProviderModels = ['claude-sonnet-4-6', 'claude-opus-4-6'];
|
|
183
|
+
const providerModels = Array.isArray(nextProvider.models)
|
|
184
|
+
? nextProvider.models.filter((v) => typeof v === 'string')
|
|
185
|
+
: [];
|
|
186
|
+
const mergedProviderModels = Array.from(new Set([...providerModels, ...desiredProviderModels]));
|
|
187
|
+
if (mergedProviderModels.length !== providerModels.length) {
|
|
188
|
+
changes.push(`models.providers.ekkos-proxy.models += ${desiredProviderModels.join(', ')}`);
|
|
189
|
+
}
|
|
190
|
+
nextProvider.models = mergedProviderModels;
|
|
191
|
+
providers['ekkos-proxy'] = nextProvider;
|
|
192
|
+
const agents = ensureObject(nextConfig, 'agents');
|
|
193
|
+
const defaults = ensureObject(agents, 'defaults');
|
|
194
|
+
const model = ensureObject(defaults, 'model');
|
|
195
|
+
if (model.primary !== modelName) {
|
|
196
|
+
changes.push(`agents.defaults.model.primary -> ${modelName}`);
|
|
197
|
+
model.primary = modelName;
|
|
198
|
+
}
|
|
199
|
+
return { nextConfig, changes };
|
|
200
|
+
}
|
|
201
|
+
async function clawStatus(options = {}) {
|
|
202
|
+
const report = await collectStatus(options);
|
|
203
|
+
if (options.json) {
|
|
204
|
+
console.log(JSON.stringify(report, null, 2));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
printStatus(report);
|
|
208
|
+
}
|
|
209
|
+
async function clawUpgrade(options = {}) {
|
|
210
|
+
const config = readConfig();
|
|
211
|
+
if (!config) {
|
|
212
|
+
console.error(chalk_1.default.red(`OpenClaw config missing or invalid: ${OPENCLAW_CONFIG_PATH}`));
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
const { nextConfig, changes } = planUpgrade(config, options);
|
|
216
|
+
const reportBefore = await collectStatus(options);
|
|
217
|
+
if (options.json) {
|
|
218
|
+
console.log(JSON.stringify({
|
|
219
|
+
apply: !!options.apply,
|
|
220
|
+
force: !!options.force,
|
|
221
|
+
changes,
|
|
222
|
+
before: reportBefore,
|
|
223
|
+
}, null, 2));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(chalk_1.default.cyan.bold('ekkOS_Claw Upgrade (foundation)'));
|
|
228
|
+
console.log('');
|
|
229
|
+
if (changes.length === 0) {
|
|
230
|
+
console.log(chalk_1.default.green('No config changes needed. OpenClaw already points to ekkOS proxy.'));
|
|
231
|
+
console.log('');
|
|
232
|
+
printStatus(reportBefore);
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
console.log(chalk_1.default.cyan('Planned changes:'));
|
|
236
|
+
for (const change of changes) {
|
|
237
|
+
console.log(` - ${change}`);
|
|
238
|
+
}
|
|
239
|
+
console.log('');
|
|
240
|
+
if (!options.apply) {
|
|
241
|
+
console.log(chalk_1.default.yellow('Dry run only. Re-run with --apply to write config changes.'));
|
|
242
|
+
console.log('');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const backupPath = `${OPENCLAW_CONFIG_PATH}.bak.${timestampForBackup()}`;
|
|
246
|
+
(0, fs_1.copyFileSync)(OPENCLAW_CONFIG_PATH, backupPath);
|
|
247
|
+
(0, fs_1.writeFileSync)(OPENCLAW_CONFIG_PATH, `${JSON.stringify(nextConfig, null, 2)}\n`, 'utf-8');
|
|
248
|
+
console.log(chalk_1.default.green(`Updated ${OPENCLAW_CONFIG_PATH}`));
|
|
249
|
+
console.log(chalk_1.default.gray(`Backup written: ${backupPath}`));
|
|
250
|
+
console.log('');
|
|
251
|
+
const reportAfter = await collectStatus(options);
|
|
252
|
+
printStatus(reportAfter);
|
|
253
|
+
}
|