Repository navigation
Expand file tree
/
Copy pathecc.js
More file actions
executable file
·343 lines (306 loc) · 9.13 KB
/
Copy pathecc.js
File metadata and controls
executable file
·343 lines (306 loc) · 9.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
#!/usr/bin/env node
const { spawnSync } = require('child_process');
const path = require('path');
const { listAvailableLanguages } = require('./lib/install-executor');
const { getComputeSponsorCopy } = require('./lib/compute-sponsor');
const { createSafeItoInvocationEnvironment, getInvocationCommand } = require('./lib/ito-environment');
const COMMANDS = {
setup: {
script: 'setup.js',
description: 'Install or update the Claude plugin with guided scope and hook choices',
},
welcome: {
script: 'welcome.js',
description: 'Show the ECC welcome artwork and community links',
},
install: {
script: 'install-apply.js',
description: 'Install ECC content, including the guided multi-harness wizard',
},
plan: {
script: 'install-plan.js',
description: 'Inspect selective-install manifests and resolved plans',
},
catalog: {
script: 'catalog.js',
description: 'Discover install profiles and component IDs',
},
consult: {
script: 'consult.js',
description: 'Recommend ECC components and profiles from a natural language query',
},
'control-pane': {
script: 'control-pane.js',
description: 'Run the local ECC2 operator control pane',
},
ito: {
script: 'ito.js',
description: 'Invoke the separately installed canonical Itô compute CLI',
},
nasiko: {
script: 'nasiko.js',
description: 'Install or inspect the optional pinned Nasiko CLI lifecycle bridge',
},
memory: {
script: 'memory.js',
description: 'Share durable context across Claude, Codex, Hermes, and other harnesses',
},
'install-plan': {
script: 'install-plan.js',
description: 'Alias for plan',
},
'list-installed': {
script: 'list-installed.js',
description: 'Inspect install-state files for the current context',
},
doctor: {
script: 'doctor.js',
description: 'Diagnose missing or drifted ECC-managed files',
},
feedback: {
script: 'feedback.js',
description: 'Open the shortest path to report a problem, feedback, or an idea',
},
repair: {
script: 'repair.js',
description: 'Restore drifted or missing ECC-managed files',
},
'auto-update': {
script: 'auto-update.js',
description: 'Pull latest ECC changes and reinstall the current managed targets',
},
status: {
script: 'status.js',
description: 'Query the ECC SQLite state store status summary',
},
'platform-audit': {
script: 'platform-audit.js',
description: 'Audit GitHub queues, discussions, roadmap, release, and security evidence',
},
'security-ioc-scan': {
script: 'ci/scan-supply-chain-iocs.js',
description: 'Scan dependency and AI-tool persistence surfaces for active supply-chain IOCs',
},
sessions: {
script: 'sessions-cli.js',
description: 'List or inspect ECC sessions from the SQLite state store',
},
'work-items': {
script: 'work-items.js',
description: 'Track linked Linear, GitHub, handoff, and manual work items',
},
'session-inspect': {
script: 'session-inspect.js',
description: 'Emit canonical ECC session snapshots from dmux or Claude history targets',
},
'loop-status': {
script: 'loop-status.js',
description: 'Inspect Claude transcripts for stale loop wakeups and pending tool results',
},
uninstall: {
script: 'uninstall.js',
description: 'Remove ECC-managed files recorded in install-state',
},
};
const PRIMARY_COMMANDS = [
'setup',
'welcome',
'install',
'plan',
'catalog',
'consult',
'control-pane',
'ito',
'nasiko',
'memory',
'list-installed',
'doctor',
'feedback',
'repair',
'auto-update',
'status',
'platform-audit',
'security-ioc-scan',
'sessions',
'work-items',
'session-inspect',
'loop-status',
'uninstall',
];
function showHelp(exitCode = 0) {
process.stdout.write(`
ECC selective-install CLI
Usage:
ecc <command> [args...]
ecc [install args...]
ecc --dry-run <command> [args...]
Commands:
${PRIMARY_COMMANDS.map(command => ` ${command.padEnd(15)} ${COMMANDS[command].description}`).join('\n')}
Compatibility:
ecc-install Legacy install entrypoint retained for existing flows
ecc [args...] Without a command, args are routed to "install"
ecc help <command> Show help for a specific command
Global Flags:
--dry-run Preview actions without executing (sets ECC_DRY_RUN=1)
Compute:
${getComputeSponsorCopy()}
Examples:
ecc setup
ecc setup --mode claude-plugin --scope user --hooks standard --yes
ecc welcome
ecc install --guided
ecc install --guided --harness claude --harness codex --harness kimi
ecc typescript
ecc install --profile developer --target claude
ecc plan --profile core --target cursor
ecc catalog profiles
ecc catalog components --family language
ecc catalog show framework:nextjs
ecc consult "security reviews"
ecc control-pane --port 8765
ecc ito login [--no-browser]
ecc ito logout
ecc ito auth
ecc ito find --gpu h200 --count 8 --nodes 1 --gpus-per-node 8 --days 30 --storage-tb 1 --start-window 2099-08-15 --max-rate 3.00 --form-factor bare_metal --contract-type reservation --fabric infiniband --region us-east-1
ecc ito status --json
ecc nasiko status --json
ecc nasiko install --version v0.1.0 --dry-run --json
ecc nasiko install --version v0.1.0 --yes --json
ecc ito evals --cluster clu_prod_example --live-sixtytwo --nodes gpu-01,gpu-02 --config-dir /absolute/path/to/qualification-config
ecc memory init
ecc memory handoff --from codex --target claude --title "Continue migration" --stdin
ecc memory search "migration blockers" --target-harness hermes
ecc list-installed --json
ecc doctor --target cursor
ecc feedback
ecc repair --dry-run
ecc auto-update --dry-run
ecc status --json
ecc status --exit-code
ecc status --markdown --write status.md
ecc platform-audit --json --allow-untracked docs/drafts/
ecc security-ioc-scan --home
ecc sessions
ecc sessions session-active --json
ecc work-items upsert linear-ecc-20 --source linear --source-id ECC-20 --title "Review control-plane contract" --status blocked
ecc work-items sync-github --repo affaan-m/ECC
ecc session-inspect claude:latest
ecc loop-status --json
ecc uninstall --target antigravity --dry-run
`);
process.exit(exitCode);
}
function resolveCommand(argv) {
const args = argv.slice(2);
if (args.length === 0) {
return { mode: 'help' };
}
if (args.includes('--dry-run')) {
process.env.ECC_DRY_RUN = '1';
}
let cmdStart = 0;
while (cmdStart < args.length && args[cmdStart] === '--dry-run') {
cmdStart++;
}
if (cmdStart >= args.length) {
return { mode: 'help' };
}
const firstArg = args[cmdStart];
const restArgs = args.slice(cmdStart + 1);
if (firstArg === '--help' || firstArg === '-h') {
return { mode: 'help' };
}
if (firstArg === 'help') {
return {
mode: 'help-command',
command: restArgs[0] || null,
};
}
if (COMMANDS[firstArg]) {
return {
mode: 'command',
command: firstArg,
args: restArgs,
};
}
const knownLegacyLanguages = listAvailableLanguages();
const shouldTreatAsImplicitInstall = (
firstArg.startsWith('-')
|| knownLegacyLanguages.includes(firstArg)
);
if (!shouldTreatAsImplicitInstall) {
throw new Error(`Unknown command: ${firstArg}`);
}
return {
mode: 'command',
command: 'install',
args,
};
}
function runCommand(commandName, args) {
const command = COMMANDS[commandName];
if (!command) {
throw new Error(`Unknown command: ${commandName}`);
}
const isItoLogin = commandName === 'ito' && getInvocationCommand(args) === 'login';
const result = spawnSync(
process.execPath,
[path.join(__dirname, command.script), ...args],
{
cwd: process.cwd(),
env: commandName === 'ito'
? {
...createSafeItoInvocationEnvironment(process.env, args, {
includeControls: true,
}),
}
: process.env,
stdio: isItoLogin || commandName === 'setup' || commandName === 'install'
? 'inherit'
: commandName === 'memory'
? ['inherit', 'pipe', 'pipe']
: ['pipe', 'pipe', 'pipe'],
encoding: 'utf8',
maxBuffer: 10 * 1024 * 1024,
}
);
if (result.error) {
throw result.error;
}
if (result.stdout) {
process.stdout.write(result.stdout);
}
if (result.stderr) {
process.stderr.write(result.stderr);
}
if (typeof result.status === 'number') {
return result.status;
}
if (result.signal) {
throw new Error(`Command "${commandName}" terminated by signal ${result.signal}`);
}
return 1;
}
function main() {
try {
const resolution = resolveCommand(process.argv);
if (resolution.mode === 'help') {
showHelp(0);
}
if (resolution.mode === 'help-command') {
if (!resolution.command) {
showHelp(0);
}
if (!COMMANDS[resolution.command]) {
throw new Error(`Unknown command: ${resolution.command}`);
}
process.exitCode = runCommand(resolution.command, ['--help']);
return;
}
process.exitCode = runCommand(resolution.command, resolution.args);
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
}
}
main();