delimit-cli 4.7.2 → 4.7.4
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/CHANGELOG.md +15 -0
- package/README.md +37 -2
- package/bin/delimit-cli.js +152 -1
- package/bin/delimit-setup.js +88 -6
- package/bin/delimit.js +10 -25
- package/gateway/ai/backends/governance_bridge.py +52 -0
- package/gateway/ai/backends/repo_bridge.py +12 -0
- package/gateway/ai/backends/tools_infra.py +43 -1
- package/gateway/ai/cli_contract.py +12 -0
- package/gateway/ai/custom_gemini_repl.py +80 -0
- package/gateway/ai/delimit_daemon.py +8 -0
- package/gateway/ai/gemini_vertex_shim.py +38 -0
- package/gateway/ai/license_core.cpython-310-x86_64-linux-gnu.so +0 -0
- package/gateway/ai/release_sync.py +43 -8
- package/gateway/ai/route_daemon.py +98 -0
- package/gateway/ai/server.py +71 -1
- package/gateway/ai/session_phoenix.py +101 -136
- package/gateway/ai/supabase_sync.py +58 -0
- package/gateway/ai/swarm.py +2 -0
- package/gateway/ai/tui.py +81 -0
- package/gateway/core/ci_formatter.py +89 -61
- package/gateway/core/diff_engine_v2.py +208 -627
- package/gateway/core/explainer.py +67 -34
- package/lib/ai-sbom-engine.js +1 -0
- package/lib/auth-setup.js +10 -1
- package/lib/chat-repl.js +244 -0
- package/lib/cross-model-hooks.js +111 -0
- package/lib/timeline-engine.js +60 -0
- package/lib/wrap-engine.js +67 -11
- package/package.json +1 -1
- package/server.json +2 -2
package/lib/wrap-engine.js
CHANGED
|
@@ -172,6 +172,31 @@ function loadOrCreateHmacKey() {
|
|
|
172
172
|
return key;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
+
|
|
176
|
+
function getNextModelInChain(currentModel) {
|
|
177
|
+
const homedir = os.homedir();
|
|
178
|
+
const modelsPath = path.join(homedir, '.delimit', 'models.json');
|
|
179
|
+
if (!fs.existsSync(modelsPath)) return null;
|
|
180
|
+
|
|
181
|
+
try {
|
|
182
|
+
const models = JSON.parse(fs.readFileSync(modelsPath, 'utf-8'));
|
|
183
|
+
// Normalize currentModel (it might be a path)
|
|
184
|
+
const base = path.basename(currentModel).toLowerCase();
|
|
185
|
+
|
|
186
|
+
// Find which chain contains the current model
|
|
187
|
+
// Using 'default' chain for prototype
|
|
188
|
+
const chain = models.fallbacks?.default || [];
|
|
189
|
+
const idx = chain.findIndex(m => m.toLowerCase() === base);
|
|
190
|
+
if (idx !== -1 && idx < chain.length - 1) {
|
|
191
|
+
return chain[idx + 1];
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
|
|
175
200
|
function signAttestation(bundle) {
|
|
176
201
|
const key = loadOrCreateHmacKey();
|
|
177
202
|
return crypto.createHmac('sha256', key).update(canonicalize(bundle)).digest('hex');
|
|
@@ -251,6 +276,8 @@ function suggestHandoff(rawCmd) {
|
|
|
251
276
|
aider: ['claude', 'codex', 'gemini'],
|
|
252
277
|
codex: ['claude', 'gemini', 'cursor'],
|
|
253
278
|
gemini: ['claude', 'codex', 'cursor'],
|
|
279
|
+
antigravity: ['claude', 'codex', 'gemini'],
|
|
280
|
+
agy: ['claude', 'codex', 'gemini'],
|
|
254
281
|
};
|
|
255
282
|
const key = Object.keys(fallbacks).find(k => base.includes(k));
|
|
256
283
|
if (!key) return null;
|
|
@@ -309,6 +336,7 @@ async function runWrap(rawCmd, options = {}) {
|
|
|
309
336
|
attest = true,
|
|
310
337
|
cwd = process.cwd(),
|
|
311
338
|
maxTimeSeconds = 0, // LED-1052: 0 disables kill switch
|
|
339
|
+
autoPhoenix = false, // LED-3013: automatic model switching
|
|
312
340
|
} = options;
|
|
313
341
|
|
|
314
342
|
const repoRoot = getRepoRoot(cwd);
|
|
@@ -333,20 +361,48 @@ async function runWrap(rawCmd, options = {}) {
|
|
|
333
361
|
const beforeDirty = isGitRepo ? getDirtyFiles(repoRoot) : [];
|
|
334
362
|
const startedAt = new Date().toISOString();
|
|
335
363
|
|
|
336
|
-
// Execute the wrapped command
|
|
337
|
-
// The wrapped command runs in the user's shell so `claude -p "..."` / `cursor edit` / etc. work natively.
|
|
338
|
-
// LED-1052: if maxTimeSeconds > 0, use async spawnWithKillSwitch; otherwise spawnSync for back-compat.
|
|
364
|
+
// Execute the wrapped command (with Auto-Phoenix retry loop)
|
|
339
365
|
let wrappedExit;
|
|
340
366
|
let killedByTimeout = false;
|
|
341
367
|
let killSignal = null;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
368
|
+
let currentCmd = [...rawCmd];
|
|
369
|
+
let attempts = 0;
|
|
370
|
+
const maxAttempts = autoPhoenix ? 3 : 1;
|
|
371
|
+
const chalk = require('chalk');
|
|
372
|
+
|
|
373
|
+
while (attempts < maxAttempts) {
|
|
374
|
+
attempts++;
|
|
375
|
+
if (attempts > 1) {
|
|
376
|
+
console.log(chalk.blue(`\n Auto-Phoenix: Retrying with next model (Attempt ${attempts}/${maxAttempts})...`));
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (maxTimeSeconds > 0) {
|
|
380
|
+
const res = await spawnWithKillSwitch(currentCmd[0], currentCmd.slice(1), { cwd: repoRoot, shell: false }, maxTimeSeconds);
|
|
381
|
+
wrappedExit = res.status;
|
|
382
|
+
killedByTimeout = res.killed_by_timeout;
|
|
383
|
+
killSignal = res.signal || null;
|
|
384
|
+
} else {
|
|
385
|
+
const child = spawnSync(currentCmd[0], currentCmd.slice(1), { cwd: repoRoot, stdio: 'inherit', shell: false });
|
|
386
|
+
wrappedExit = child.status ?? 1;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (wrappedExit === 0) break;
|
|
390
|
+
if (!autoPhoenix) break;
|
|
391
|
+
|
|
392
|
+
// Migration logic
|
|
393
|
+
const nextModel = getNextModelInChain(currentCmd[0]);
|
|
394
|
+
if (!nextModel) break;
|
|
395
|
+
|
|
396
|
+
console.log(chalk.yellow(`\n ⚠ Task failed (exit ${wrappedExit}). Auto-Phoenix initiating migration...`));
|
|
397
|
+
|
|
398
|
+
// 1. Capture Soul
|
|
399
|
+
runDelimitCLI(['soul-capture', '--active-task', `Auto-Phoenix migration: ${currentCmd.join(' ')}`], repoRoot);
|
|
400
|
+
|
|
401
|
+
// 2. Update command for next iteration
|
|
402
|
+
console.log(chalk.green(` ✓ Migrating session to ${chalk.bold(nextModel)}...`));
|
|
403
|
+
currentCmd[0] = nextModel;
|
|
404
|
+
// In prototype, we don't automatically add --revive because we don't know the CLI arg schema of nextModel
|
|
405
|
+
// but we've logged the soul capture which the next agent can find.
|
|
350
406
|
}
|
|
351
407
|
const completedAt = new Date().toISOString();
|
|
352
408
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delimit-cli",
|
|
3
3
|
"mcpName": "io.github.delimit-ai/delimit-mcp-server",
|
|
4
|
-
"version": "4.7.
|
|
4
|
+
"version": "4.7.4",
|
|
5
5
|
"description": "Unify Claude Code, Codex, Cursor, and Gemini CLI with persistent context, governance, and multi-model debate.",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"files": [
|
package/server.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"url": "https://github.com/delimit-ai/delimit-mcp-server",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "4.
|
|
10
|
+
"version": "4.7.3",
|
|
11
11
|
"websiteUrl": "https://delimit.ai",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"identifier": "delimit-cli",
|
|
16
|
-
"version": "4.
|
|
16
|
+
"version": "4.7.3",
|
|
17
17
|
"transport": {
|
|
18
18
|
"type": "stdio"
|
|
19
19
|
}
|