aiden-runtime 4.1.5 → 4.6.0
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/README.md +265 -847
- package/dist/api/server.js +32 -5
- package/dist/cli/v4/aidenCLI.js +536 -152
- package/dist/cli/v4/callbacks.js +170 -0
- package/dist/cli/v4/chatSession.js +245 -3
- package/dist/cli/v4/commands/_runtimeToggleHelpers.js +94 -0
- package/dist/cli/v4/commands/browserDepth.js +45 -0
- package/dist/cli/v4/commands/cron.js +264 -0
- package/dist/cli/v4/commands/daemon.js +541 -0
- package/dist/cli/v4/commands/daemonStatus.js +253 -0
- package/dist/cli/v4/commands/fanout.js +42 -59
- package/dist/cli/v4/commands/help.js +13 -0
- package/dist/cli/v4/commands/index.js +35 -1
- package/dist/cli/v4/commands/mcp.js +80 -54
- package/dist/cli/v4/commands/plannerGuard.js +53 -0
- package/dist/cli/v4/commands/recovery.js +122 -0
- package/dist/cli/v4/commands/runs.js +223 -0
- package/dist/cli/v4/commands/sandbox.js +48 -0
- package/dist/cli/v4/commands/spawnPause.js +93 -0
- package/dist/cli/v4/commands/suggestions.js +68 -0
- package/dist/cli/v4/commands/tce.js +41 -0
- package/dist/cli/v4/commands/trigger.js +378 -0
- package/dist/cli/v4/commands/update.js +95 -3
- package/dist/cli/v4/daemonAgentBuilder.js +145 -0
- package/dist/cli/v4/defaultSoul.js +1 -1
- package/dist/cli/v4/display/capabilityCard.js +26 -0
- package/dist/cli/v4/display.js +18 -8
- package/dist/cli/v4/replyRenderer.js +31 -23
- package/dist/cli/v4/updateBootPrompt.js +170 -0
- package/dist/core/playwrightBridge.js +129 -0
- package/dist/core/v4/aidenAgent.js +527 -5
- package/dist/core/v4/browserState.js +436 -0
- package/dist/core/v4/checkpoint.js +79 -0
- package/dist/core/v4/daemon/bootstrap.js +651 -0
- package/dist/core/v4/daemon/cleanShutdown.js +154 -0
- package/dist/core/v4/daemon/cron/cronBridge.js +126 -0
- package/dist/core/v4/daemon/cron/cronEmitter.js +173 -0
- package/dist/core/v4/daemon/cron/migration.js +199 -0
- package/dist/core/v4/daemon/cron/misfirePolicy.js +115 -0
- package/dist/core/v4/daemon/daemonConfig.js +90 -0
- package/dist/core/v4/daemon/db/connection.js +106 -0
- package/dist/core/v4/daemon/db/migrations.js +362 -0
- package/dist/core/v4/daemon/db/schema/v1.spec.js +18 -0
- package/dist/core/v4/daemon/dispatcher/agentRunner.js +98 -0
- package/dist/core/v4/daemon/dispatcher/budgetGate.js +127 -0
- package/dist/core/v4/daemon/dispatcher/daemonApproval.js +113 -0
- package/dist/core/v4/daemon/dispatcher/dailyBudgetTracker.js +120 -0
- package/dist/core/v4/daemon/dispatcher/dispatcher.js +389 -0
- package/dist/core/v4/daemon/dispatcher/fireRateLimiter.js +113 -0
- package/dist/core/v4/daemon/dispatcher/index.js +53 -0
- package/dist/core/v4/daemon/dispatcher/promptTemplate.js +95 -0
- package/dist/core/v4/daemon/dispatcher/realAgentRunner.js +356 -0
- package/dist/core/v4/daemon/dispatcher/resolveModel.js +93 -0
- package/dist/core/v4/daemon/dispatcher/sessionId.js +93 -0
- package/dist/core/v4/daemon/drain.js +156 -0
- package/dist/core/v4/daemon/eventLoopLag.js +73 -0
- package/dist/core/v4/daemon/health.js +159 -0
- package/dist/core/v4/daemon/idempotencyStore.js +204 -0
- package/dist/core/v4/daemon/index.js +179 -0
- package/dist/core/v4/daemon/instanceTracker.js +99 -0
- package/dist/core/v4/daemon/resourceRegistry.js +150 -0
- package/dist/core/v4/daemon/restartCode.js +32 -0
- package/dist/core/v4/daemon/restartFailureCounter.js +77 -0
- package/dist/core/v4/daemon/runStore.js +144 -0
- package/dist/core/v4/daemon/runtimeLock.js +167 -0
- package/dist/core/v4/daemon/signals.js +50 -0
- package/dist/core/v4/daemon/supervisor.js +272 -0
- package/dist/core/v4/daemon/triggerBus.js +279 -0
- package/dist/core/v4/daemon/triggers/email/allowlist.js +70 -0
- package/dist/core/v4/daemon/triggers/email/automatedSender.js +78 -0
- package/dist/core/v4/daemon/triggers/email/bodyExtractor.js +0 -0
- package/dist/core/v4/daemon/triggers/email/emailSeenStore.js +99 -0
- package/dist/core/v4/daemon/triggers/email/emailSpec.js +107 -0
- package/dist/core/v4/daemon/triggers/email/imapConnection.js +211 -0
- package/dist/core/v4/daemon/triggers/email/index.js +332 -0
- package/dist/core/v4/daemon/triggers/email/seenUids.js +60 -0
- package/dist/core/v4/daemon/triggers/fileObservationsStore.js +93 -0
- package/dist/core/v4/daemon/triggers/fileWatcher.js +253 -0
- package/dist/core/v4/daemon/triggers/fileWatcherSpec.js +88 -0
- package/dist/core/v4/daemon/triggers/fsIdentity.js +42 -0
- package/dist/core/v4/daemon/triggers/globMatcher.js +100 -0
- package/dist/core/v4/daemon/triggers/reconcile.js +206 -0
- package/dist/core/v4/daemon/triggers/settleStat.js +81 -0
- package/dist/core/v4/daemon/triggers/webhook.js +376 -0
- package/dist/core/v4/daemon/triggers/webhookDeliveriesStore.js +109 -0
- package/dist/core/v4/daemon/triggers/webhookIdempotency.js +72 -0
- package/dist/core/v4/daemon/triggers/webhookRateLimit.js +56 -0
- package/dist/core/v4/daemon/triggers/webhookSpec.js +76 -0
- package/dist/core/v4/daemon/triggers/webhookVerifier.js +128 -0
- package/dist/core/v4/daemon/types.js +15 -0
- package/dist/core/v4/dockerSession.js +461 -0
- package/dist/core/v4/dryRun.js +117 -0
- package/dist/core/v4/failureClassifier.js +779 -0
- package/dist/core/v4/providerFallback.js +35 -2
- package/dist/core/v4/recoveryReport.js +449 -0
- package/dist/core/v4/runtimeToggles.js +214 -0
- package/dist/core/v4/sandboxConfig.js +285 -0
- package/dist/core/v4/sandboxFs.js +316 -0
- package/dist/core/v4/selfimprovement/recoveryStore.js +307 -0
- package/dist/core/v4/selfimprovement/signatureBuilder.js +158 -0
- package/dist/core/v4/subagent/childBuilder.js +391 -0
- package/dist/core/v4/subagent/fanout.js +75 -51
- package/dist/core/v4/subagent/spawnPause.js +191 -0
- package/dist/core/v4/subagent/spawnSubAgent.js +310 -0
- package/dist/core/v4/suggestionCatalog.js +41 -0
- package/dist/core/v4/suggestionEngine.js +210 -0
- package/dist/core/v4/toolRegistry.js +37 -3
- package/dist/core/v4/turnState.js +587 -0
- package/dist/core/v4/update/checkUpdate.js +63 -3
- package/dist/core/v4/update/installMethodDetect.js +115 -0
- package/dist/core/v4/update/registryClient.js +121 -0
- package/dist/core/v4/update/skipState.js +75 -0
- package/dist/core/v4/verifier.js +448 -0
- package/dist/core/version.js +1 -1
- package/dist/moat/plannerGuard.js +29 -0
- package/dist/providers/v4/anthropicAdapter.js +31 -3
- package/dist/providers/v4/chatCompletionsAdapter.js +26 -3
- package/dist/providers/v4/codexResponsesAdapter.js +25 -2
- package/dist/providers/v4/ollamaPromptToolsAdapter.js +57 -2
- package/dist/tools/v4/browser/_observer.js +224 -0
- package/dist/tools/v4/browser/browserBlocker.js +396 -0
- package/dist/tools/v4/browser/browserClick.js +18 -1
- package/dist/tools/v4/browser/browserClose.js +18 -1
- package/dist/tools/v4/browser/browserExtract.js +5 -1
- package/dist/tools/v4/browser/browserFill.js +17 -1
- package/dist/tools/v4/browser/browserGetUrl.js +5 -1
- package/dist/tools/v4/browser/browserNavigate.js +16 -1
- package/dist/tools/v4/browser/browserScreenshot.js +5 -1
- package/dist/tools/v4/browser/browserScroll.js +18 -1
- package/dist/tools/v4/browser/browserType.js +17 -1
- package/dist/tools/v4/browser/captchaCheck.js +5 -1
- package/dist/tools/v4/executeCode.js +1 -0
- package/dist/tools/v4/files/fileCopy.js +56 -2
- package/dist/tools/v4/files/fileDelete.js +38 -1
- package/dist/tools/v4/files/fileList.js +12 -1
- package/dist/tools/v4/files/fileMove.js +59 -2
- package/dist/tools/v4/files/filePatch.js +43 -1
- package/dist/tools/v4/files/fileRead.js +12 -1
- package/dist/tools/v4/files/fileWrite.js +41 -1
- package/dist/tools/v4/index.js +88 -61
- package/dist/tools/v4/memory/memoryAdd.js +14 -0
- package/dist/tools/v4/memory/memoryRemove.js +14 -0
- package/dist/tools/v4/memory/memoryReplace.js +15 -0
- package/dist/tools/v4/memory/sessionSummary.js +12 -0
- package/dist/tools/v4/process/processKill.js +19 -0
- package/dist/tools/v4/process/processList.js +1 -0
- package/dist/tools/v4/process/processLogRead.js +1 -0
- package/dist/tools/v4/process/processSpawn.js +13 -0
- package/dist/tools/v4/process/processWait.js +1 -0
- package/dist/tools/v4/sessions/recallSession.js +1 -0
- package/dist/tools/v4/sessions/sessionList.js +1 -0
- package/dist/tools/v4/sessions/sessionSearch.js +1 -0
- package/dist/tools/v4/skills/lookupToolSchema.js +7 -0
- package/dist/tools/v4/skills/skillManage.js +13 -0
- package/dist/tools/v4/skills/skillView.js +1 -0
- package/dist/tools/v4/skills/skillsList.js +1 -0
- package/dist/tools/v4/subagent/spawnSubAgentTool.js +334 -0
- package/dist/tools/v4/subagent/subagentFanout.js +54 -1
- package/dist/tools/v4/system/aidenSelfUpdate.js +16 -0
- package/dist/tools/v4/system/appClose.js +13 -0
- package/dist/tools/v4/system/appInput.js +13 -0
- package/dist/tools/v4/system/appLaunch.js +13 -0
- package/dist/tools/v4/system/clipboardRead.js +1 -0
- package/dist/tools/v4/system/clipboardWrite.js +14 -0
- package/dist/tools/v4/system/mediaKey.js +12 -0
- package/dist/tools/v4/system/mediaSessions.js +1 -0
- package/dist/tools/v4/system/mediaTransport.js +13 -0
- package/dist/tools/v4/system/naturalEvents.js +1 -0
- package/dist/tools/v4/system/nowPlaying.js +1 -0
- package/dist/tools/v4/system/osProcessList.js +1 -0
- package/dist/tools/v4/system/screenshot.js +1 -0
- package/dist/tools/v4/system/systemInfo.js +1 -0
- package/dist/tools/v4/system/volumeSet.js +17 -0
- package/dist/tools/v4/terminal/shellExec.js +81 -9
- package/dist/tools/v4/web/deepResearch.js +1 -0
- package/dist/tools/v4/web/openUrl.js +1 -0
- package/dist/tools/v4/web/webFetch.js +1 -0
- package/dist/tools/v4/web/webPage.js +1 -0
- package/dist/tools/v4/web/webSearch.js +1 -0
- package/dist/tools/v4/web/youtubeSearch.js +1 -0
- package/package.json +13 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/plannerGuard.ts — v4.6 Phase 2M.
|
|
10
|
+
*
|
|
11
|
+
* `/planner-guard on|off|status` — flip the keyword-based per-turn
|
|
12
|
+
* tool narrower (`moat/plannerGuard.ts`) live, no restart needed.
|
|
13
|
+
*
|
|
14
|
+
* Default: OFF. Smart models (GPT-5.5, Claude Sonnet 4.5+, Opus)
|
|
15
|
+
* select tools fine from the full catalog every turn, the way the
|
|
16
|
+
* reference multi-agent systems do. Per-turn narrowing was a
|
|
17
|
+
* v4.1-era workaround for smaller local models that got overwhelmed
|
|
18
|
+
* by 50+ tool schemas — opt in for that case via env (set
|
|
19
|
+
* `AIDEN_PLANNER_GUARD=1` at boot) or this slash command.
|
|
20
|
+
*
|
|
21
|
+
* Persists to `runtime_toggles.planner_guard` in config.yaml when
|
|
22
|
+
* a ConfigManager is wired (the normal REPL path). Env var
|
|
23
|
+
* `AIDEN_PLANNER_GUARD` always wins over both — see runtimeToggles.ts.
|
|
24
|
+
*
|
|
25
|
+
* Mirrors `/sandbox`, `/tce`, `/browser-depth`, `/suggestions`
|
|
26
|
+
* verbatim — same helpers, same output shape.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.plannerGuard = void 0;
|
|
30
|
+
const _runtimeToggleHelpers_1 = require("./_runtimeToggleHelpers");
|
|
31
|
+
exports.plannerGuard = {
|
|
32
|
+
name: 'planner-guard',
|
|
33
|
+
description: 'Toggle keyword-based per-turn tool narrowing (default OFF, opt-in).',
|
|
34
|
+
category: 'system',
|
|
35
|
+
icon: '🧭',
|
|
36
|
+
handler: async (ctx) => {
|
|
37
|
+
const sub = (0, _runtimeToggleHelpers_1.parseSubcommand)(ctx.args[0]);
|
|
38
|
+
if (sub === 'on') {
|
|
39
|
+
await (0, _runtimeToggleHelpers_1.flip)('planner_guard', true, ctx);
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
if (sub === 'off') {
|
|
43
|
+
await (0, _runtimeToggleHelpers_1.flip)('planner_guard', false, ctx);
|
|
44
|
+
return {};
|
|
45
|
+
}
|
|
46
|
+
if (sub === 'status') {
|
|
47
|
+
(0, _runtimeToggleHelpers_1.printStatus)('planner_guard', ctx);
|
|
48
|
+
return {};
|
|
49
|
+
}
|
|
50
|
+
ctx.display.printError('Usage: /planner-guard on|off|status');
|
|
51
|
+
return {};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/recovery.ts — v4.6 Phase 3b.
|
|
10
|
+
*
|
|
11
|
+
* `/recovery list [limit]` — top N recurring failure patterns
|
|
12
|
+
* `/recovery show <signature>` — details for one signature + reports
|
|
13
|
+
* `/recovery clear <signature>` — operator says "fixed; stop counting"
|
|
14
|
+
*
|
|
15
|
+
* Backed by the v7 `failure_signatures` + `recovery_reports` tables
|
|
16
|
+
* via the `RecoveryStore` singleton (initialised at REPL/daemon/MCP
|
|
17
|
+
* boot). All three sub-actions degrade cleanly when the store isn't
|
|
18
|
+
* initialised — print a non-fatal error and return.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.recovery = void 0;
|
|
22
|
+
const recoveryStore_1 = require("../../../core/v4/selfimprovement/recoveryStore");
|
|
23
|
+
/** Format a wall-clock ms timestamp as a compact UTC label. */
|
|
24
|
+
function formatTs(ms) {
|
|
25
|
+
return new Date(ms).toISOString().slice(0, 19) + 'Z';
|
|
26
|
+
}
|
|
27
|
+
/** Right-pad to width; truncate with ellipsis when too long. */
|
|
28
|
+
function pad(value, width) {
|
|
29
|
+
const s = String(value);
|
|
30
|
+
if (s.length === width)
|
|
31
|
+
return s;
|
|
32
|
+
if (s.length < width)
|
|
33
|
+
return s + ' '.repeat(width - s.length);
|
|
34
|
+
return s.slice(0, Math.max(0, width - 1)) + '…';
|
|
35
|
+
}
|
|
36
|
+
exports.recovery = {
|
|
37
|
+
name: 'recovery',
|
|
38
|
+
description: 'Inspect recurring failure patterns + recoveries (v4.6 Phase 3b).',
|
|
39
|
+
category: 'system',
|
|
40
|
+
icon: '🩹',
|
|
41
|
+
handler: async (ctx) => {
|
|
42
|
+
const action = (ctx.args[0] ?? 'list').toLowerCase();
|
|
43
|
+
const store = (0, recoveryStore_1.getRecoveryStore)();
|
|
44
|
+
if (!store) {
|
|
45
|
+
ctx.display.printError('recovery: recovery store not initialised — daemon DB unavailable?');
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
if (action === 'list') {
|
|
49
|
+
const limitArg = ctx.args[1];
|
|
50
|
+
const parsed = limitArg !== undefined ? Number.parseInt(limitArg, 10) : NaN;
|
|
51
|
+
const limit = Number.isFinite(parsed) && parsed > 0 ? parsed : 10;
|
|
52
|
+
const rows = store.listTopFailures(limit);
|
|
53
|
+
if (rows.length === 0) {
|
|
54
|
+
ctx.display.write('No recurring failures recorded yet.\n');
|
|
55
|
+
ctx.display.dim(' TCE writes failure signatures on classify; recoveries on failure→success transition.');
|
|
56
|
+
return {};
|
|
57
|
+
}
|
|
58
|
+
ctx.display.write(`${pad('signature', 50)} ${pad('occur', 6)} ${pad('recov', 6)} last_strategy\n`);
|
|
59
|
+
for (const r of rows) {
|
|
60
|
+
ctx.display.write(`${pad(r.signature, 50)} ${pad(r.occurrences, 6)} ${pad(r.recoveredCount, 6)} ${r.lastRecoveryStrategy ?? '-'}\n`);
|
|
61
|
+
}
|
|
62
|
+
ctx.display.write(`\n${rows.length} signature${rows.length === 1 ? '' : 's'} shown\n`);
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
if (action === 'show') {
|
|
66
|
+
const sig = ctx.args[1];
|
|
67
|
+
if (!sig) {
|
|
68
|
+
ctx.display.printError('Usage: /recovery show <signature>');
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
const row = store.getBySignature(sig);
|
|
72
|
+
if (!row) {
|
|
73
|
+
ctx.display.printError(`recovery: signature not found: ${sig}`);
|
|
74
|
+
return {};
|
|
75
|
+
}
|
|
76
|
+
ctx.display.write(`signature: ${row.signature}\n`);
|
|
77
|
+
ctx.display.write(`tool_name: ${row.toolName}\n`);
|
|
78
|
+
ctx.display.write(`failure_category: ${row.failureCategory}\n`);
|
|
79
|
+
ctx.display.write(`occurrences: ${row.occurrences}\n`);
|
|
80
|
+
ctx.display.write(`recovered_count: ${row.recoveredCount}\n`);
|
|
81
|
+
ctx.display.write(`first_seen: ${formatTs(row.firstSeenAt)}\n`);
|
|
82
|
+
ctx.display.write(`last_seen: ${formatTs(row.lastSeenAt)}\n`);
|
|
83
|
+
const reports = store.listReportsForSignature(row.id, 20);
|
|
84
|
+
if (reports.length === 0) {
|
|
85
|
+
ctx.display.dim(' (no recovery reports yet for this signature)');
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
ctx.display.write(`\nrecovery reports (${reports.length}, newest first):\n`);
|
|
89
|
+
for (const r of reports) {
|
|
90
|
+
ctx.display.write(` [${formatTs(r.createdAt)}] strategy=${r.successfulStrategy}`);
|
|
91
|
+
if (r.failedAttempts !== undefined) {
|
|
92
|
+
ctx.display.write(` failed=${r.failedAttempts}`);
|
|
93
|
+
}
|
|
94
|
+
if (r.sessionId)
|
|
95
|
+
ctx.display.write(` session=${r.sessionId}`);
|
|
96
|
+
ctx.display.write('\n');
|
|
97
|
+
if (r.notes)
|
|
98
|
+
ctx.display.dim(` ${r.notes}`);
|
|
99
|
+
if (r.verification)
|
|
100
|
+
ctx.display.dim(` verified: ${r.verification}`);
|
|
101
|
+
}
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
if (action === 'clear') {
|
|
105
|
+
const sig = ctx.args[1];
|
|
106
|
+
if (!sig) {
|
|
107
|
+
ctx.display.printError('Usage: /recovery clear <signature>');
|
|
108
|
+
return {};
|
|
109
|
+
}
|
|
110
|
+
const ok = store.clearSignature(sig);
|
|
111
|
+
if (ok) {
|
|
112
|
+
ctx.display.write(`recovery: cleared signature ${sig}\n`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
ctx.display.printError(`recovery: signature not found: ${sig}`);
|
|
116
|
+
}
|
|
117
|
+
return {};
|
|
118
|
+
}
|
|
119
|
+
ctx.display.printError('Usage: /recovery list [limit] | show <signature> | clear <signature>');
|
|
120
|
+
return {};
|
|
121
|
+
},
|
|
122
|
+
};
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/runs.ts — v4.5 Phase 6: `aiden runs` command set.
|
|
10
|
+
*
|
|
11
|
+
* Surfaces the daemon's `runs` + `run_events` tables (Phase 1
|
|
12
|
+
* runStore) so operators can inspect daemon-fired turn history
|
|
13
|
+
* outside the REPL.
|
|
14
|
+
*
|
|
15
|
+
* Subcommands:
|
|
16
|
+
* list — recent runs; optional --limit / --source / --status filters
|
|
17
|
+
* show — full run row + all run_events for one runId
|
|
18
|
+
* interrupt — request cancellation of a running turn (Q-P6-4a:
|
|
19
|
+
* SIGUSR1 + marker file pattern)
|
|
20
|
+
* stats — aggregate counts by status + mean duration
|
|
21
|
+
*
|
|
22
|
+
* The `interrupt` path writes
|
|
23
|
+
* `~/.aiden/daemon/interrupt-<runId>.req` and signals the daemon
|
|
24
|
+
* via SIGUSR1. The dispatcher polls the marker directory on each
|
|
25
|
+
* lease-renew tick (~60s) and cancels runs whose marker exists.
|
|
26
|
+
* This matches the existing SIGUSR1 → exit 75 restart contract
|
|
27
|
+
* and keeps cancellation signal-driven rather than DB-poll.
|
|
28
|
+
*/
|
|
29
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
30
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
31
|
+
};
|
|
32
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
+
exports.runRunsSubcommand = runRunsSubcommand;
|
|
34
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
35
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
36
|
+
const daemon_1 = require("../../../core/v4/daemon");
|
|
37
|
+
const paths_1 = require("../../../core/v4/paths");
|
|
38
|
+
const noopOut = (s) => { process.stdout.write(s); };
|
|
39
|
+
const noopErr = (s) => { process.stderr.write(s); };
|
|
40
|
+
async function runRunsSubcommand(action, args, argv, opts = {}) {
|
|
41
|
+
const out = opts.writeOut ?? noopOut;
|
|
42
|
+
const err = opts.writeErr ?? noopErr;
|
|
43
|
+
const aidenRoot = (0, paths_1.resolveAidenRoot)();
|
|
44
|
+
const db = (0, daemon_1.openDaemonDb)((0, daemon_1.daemonDbPath)(aidenRoot));
|
|
45
|
+
const runStore = (0, daemon_1.createRunStore)({ db });
|
|
46
|
+
switch (action) {
|
|
47
|
+
case 'list': return cmdList(runStore, argv, out);
|
|
48
|
+
case 'show': return cmdShow(runStore, args[0], out, err);
|
|
49
|
+
case 'interrupt': return cmdInterrupt(args[0], aidenRoot, out, err);
|
|
50
|
+
case 'stats': return cmdStats(db, out);
|
|
51
|
+
default:
|
|
52
|
+
err(`Unknown runs action: ${action}\n`);
|
|
53
|
+
err('Actions: list, show <runId>, interrupt <runId>, stats\n');
|
|
54
|
+
return 2;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// ── list ──────────────────────────────────────────────────────────────────
|
|
58
|
+
function cmdList(runStore, argv, out) {
|
|
59
|
+
const allowedStatuses = new Set([
|
|
60
|
+
'queued', 'running', 'completed', 'failed', 'cancelled', 'interrupted',
|
|
61
|
+
]);
|
|
62
|
+
const status = argv.status && allowedStatuses.has(argv.status)
|
|
63
|
+
? argv.status
|
|
64
|
+
: undefined;
|
|
65
|
+
// v4.6 Phase 2Q-B — default `topLevelOnly: true` hides children.
|
|
66
|
+
// `--include-children` flag (parsed by the CLI argv layer into
|
|
67
|
+
// `includeChildren: true`) flips the predicate to drop the IS NULL
|
|
68
|
+
// filter so child rows appear inline with parents.
|
|
69
|
+
const includeChildren = argv.includeChildren === true;
|
|
70
|
+
const rows = runStore.listRecent({
|
|
71
|
+
limit: argv.limit ?? 50,
|
|
72
|
+
status,
|
|
73
|
+
source: argv.source,
|
|
74
|
+
sessionIdPrefix: argv.trigger,
|
|
75
|
+
topLevelOnly: !includeChildren,
|
|
76
|
+
});
|
|
77
|
+
if (rows.length === 0) {
|
|
78
|
+
out('No runs match the filter.\n');
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
out(`${'runId'.padEnd(6)} ${'status'.padEnd(11)} ${'finish'.padEnd(11)} ${'started'.padEnd(20)} sessionId\n`);
|
|
82
|
+
for (const r of rows) {
|
|
83
|
+
const started = new Date(r.startedAt).toISOString().slice(0, 19) + 'Z';
|
|
84
|
+
const finish = r.finishReason ?? '-';
|
|
85
|
+
// v4.6 Phase 2Q-B — child-count badge. Only relevant for the
|
|
86
|
+
// top-level view (when --include-children is OFF). Skipped on
|
|
87
|
+
// the flat view to avoid double-counting visual weight: in flat
|
|
88
|
+
// mode the children are already on screen as their own rows.
|
|
89
|
+
let badge = '';
|
|
90
|
+
if (!includeChildren) {
|
|
91
|
+
const { total, completed } = runStore.countChildren(r.id);
|
|
92
|
+
if (total > 0) {
|
|
93
|
+
badge = ` (${total} ${total === 1 ? 'child' : 'children'}, ${completed} OK)`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
out(`${String(r.id).padEnd(6)} ${r.status.padEnd(11)} ${finish.padEnd(11)} ${started.padEnd(20)} ${r.sessionId}${badge}\n`);
|
|
97
|
+
}
|
|
98
|
+
const hint = includeChildren
|
|
99
|
+
? ' (parents + sub-agent children)'
|
|
100
|
+
: ' (top-level; use --include-children for sub-agents)';
|
|
101
|
+
out(`\n${rows.length} run${rows.length === 1 ? '' : 's'} shown${hint}\n`);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
// ── show ──────────────────────────────────────────────────────────────────
|
|
105
|
+
function cmdShow(runStore, rawId, out, err) {
|
|
106
|
+
if (!rawId) {
|
|
107
|
+
err('runs show: runId required\n');
|
|
108
|
+
return 2;
|
|
109
|
+
}
|
|
110
|
+
const runId = Number.parseInt(rawId, 10);
|
|
111
|
+
if (!Number.isFinite(runId) || runId <= 0) {
|
|
112
|
+
err(`runs show: invalid runId: ${rawId}\n`);
|
|
113
|
+
return 2;
|
|
114
|
+
}
|
|
115
|
+
const row = runStore.get(runId);
|
|
116
|
+
if (!row) {
|
|
117
|
+
err(`runs show: not found: ${runId}\n`);
|
|
118
|
+
return 1;
|
|
119
|
+
}
|
|
120
|
+
const events = runStore.listEvents(runId, 500);
|
|
121
|
+
out(JSON.stringify({
|
|
122
|
+
run: row,
|
|
123
|
+
events: events.map((e) => ({
|
|
124
|
+
ts: new Date(e.ts).toISOString(),
|
|
125
|
+
kind: e.kind,
|
|
126
|
+
payload: safeParse(e.payload),
|
|
127
|
+
})),
|
|
128
|
+
}, null, 2) + '\n');
|
|
129
|
+
return 0;
|
|
130
|
+
}
|
|
131
|
+
function safeParse(s) {
|
|
132
|
+
try {
|
|
133
|
+
return JSON.parse(s);
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return s;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// ── interrupt ─────────────────────────────────────────────────────────────
|
|
140
|
+
function cmdInterrupt(rawId, aidenRoot, out, err) {
|
|
141
|
+
if (!rawId) {
|
|
142
|
+
err('runs interrupt: runId required\n');
|
|
143
|
+
return 2;
|
|
144
|
+
}
|
|
145
|
+
const runId = Number.parseInt(rawId, 10);
|
|
146
|
+
if (!Number.isFinite(runId) || runId <= 0) {
|
|
147
|
+
err(`runs interrupt: invalid runId: ${rawId}\n`);
|
|
148
|
+
return 2;
|
|
149
|
+
}
|
|
150
|
+
const markerDir = node_path_1.default.join(aidenRoot, 'daemon', 'interrupt');
|
|
151
|
+
try {
|
|
152
|
+
node_fs_1.default.mkdirSync(markerDir, { recursive: true });
|
|
153
|
+
}
|
|
154
|
+
catch (e) {
|
|
155
|
+
err(`runs interrupt: failed to create marker dir: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
156
|
+
return 1;
|
|
157
|
+
}
|
|
158
|
+
const markerPath = node_path_1.default.join(markerDir, `${runId}.req`);
|
|
159
|
+
try {
|
|
160
|
+
node_fs_1.default.writeFileSync(markerPath, JSON.stringify({ runId, requestedAt: Date.now() }));
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
err(`runs interrupt: failed to write marker: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
164
|
+
return 1;
|
|
165
|
+
}
|
|
166
|
+
// Best-effort SIGUSR1 to the daemon. If the daemon isn't running,
|
|
167
|
+
// the marker is still there for whoever boots next — they'll find
|
|
168
|
+
// the run in `interrupted` state via the boot crash-recovery pass.
|
|
169
|
+
const lockPath = (0, daemon_1.daemonRuntimeLockPath)(aidenRoot);
|
|
170
|
+
let pid = null;
|
|
171
|
+
try {
|
|
172
|
+
if (node_fs_1.default.existsSync(lockPath)) {
|
|
173
|
+
const lines = node_fs_1.default.readFileSync(lockPath, 'utf-8').split(/\r?\n/);
|
|
174
|
+
// runtime.lock format: line 0 = instanceId, line 1 = pid, line 2 = port
|
|
175
|
+
const candidate = Number.parseInt(lines[1] ?? '', 10);
|
|
176
|
+
if (Number.isFinite(candidate))
|
|
177
|
+
pid = candidate;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch { /* noop */ }
|
|
181
|
+
if (pid !== null && process.platform !== 'win32') {
|
|
182
|
+
try {
|
|
183
|
+
process.kill(pid, 'SIGUSR1');
|
|
184
|
+
}
|
|
185
|
+
catch { /* daemon may have died; marker still wins on next boot */ }
|
|
186
|
+
}
|
|
187
|
+
out(`runs interrupt: marker written at ${markerPath}\n`);
|
|
188
|
+
if (pid !== null && process.platform !== 'win32') {
|
|
189
|
+
out(`runs interrupt: SIGUSR1 sent to daemon pid=${pid}\n`);
|
|
190
|
+
}
|
|
191
|
+
else if (process.platform === 'win32') {
|
|
192
|
+
out('runs interrupt: SIGUSR1 not available on Windows — daemon picks up marker on next renew tick\n');
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
out('runs interrupt: no live daemon found — marker will be honoured on next boot\n');
|
|
196
|
+
}
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
// ── stats ─────────────────────────────────────────────────────────────────
|
|
200
|
+
function cmdStats(db, out) {
|
|
201
|
+
const counts = db.prepare(`SELECT status, COUNT(*) AS c FROM runs GROUP BY status`).all();
|
|
202
|
+
const completed = db.prepare(`SELECT AVG(completed_at - started_at) AS mean,
|
|
203
|
+
MIN(completed_at - started_at) AS min,
|
|
204
|
+
MAX(completed_at - started_at) AS max,
|
|
205
|
+
COUNT(*) AS n
|
|
206
|
+
FROM runs
|
|
207
|
+
WHERE status = 'completed' AND completed_at IS NOT NULL`).get();
|
|
208
|
+
out('Run status counts:\n');
|
|
209
|
+
if (counts.length === 0) {
|
|
210
|
+
out(' (no runs recorded)\n');
|
|
211
|
+
}
|
|
212
|
+
for (const r of counts) {
|
|
213
|
+
out(` ${r.status.padEnd(12)} ${r.c}\n`);
|
|
214
|
+
}
|
|
215
|
+
if (completed.n > 0 && completed.mean !== null) {
|
|
216
|
+
out('\nCompleted-run duration (ms):\n');
|
|
217
|
+
out(` mean ${Math.round(completed.mean)}\n`);
|
|
218
|
+
out(` min ${completed.min}\n`);
|
|
219
|
+
out(` max ${completed.max}\n`);
|
|
220
|
+
out(` n ${completed.n}\n`);
|
|
221
|
+
}
|
|
222
|
+
return 0;
|
|
223
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/sandbox.ts — v4.5 Phase 8a.
|
|
10
|
+
*
|
|
11
|
+
* `/sandbox on|off|status` — flip the v4.4 execution sandbox
|
|
12
|
+
* (filesystem allow/deny + docker session backend + dryRun
|
|
13
|
+
* preflight) without restart. Persists to config.yaml
|
|
14
|
+
* (runtime_toggles.sandbox). Env var AIDEN_SANDBOX always wins
|
|
15
|
+
* over both — see runtimeToggles.ts for precedence rules.
|
|
16
|
+
*
|
|
17
|
+
* Q-P8a-4(a): /sandbox off flips silently. User explicitly typed
|
|
18
|
+
* the command and the status output makes the flip visible. The
|
|
19
|
+
* sandbox denylist (fs.sensitive_path) remains in effect for
|
|
20
|
+
* unmistakably dangerous paths regardless of the toggle —
|
|
21
|
+
* disabling the sandbox does NOT remove the always-on denylist.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.sandbox = void 0;
|
|
25
|
+
const _runtimeToggleHelpers_1 = require("./_runtimeToggleHelpers");
|
|
26
|
+
exports.sandbox = {
|
|
27
|
+
name: 'sandbox',
|
|
28
|
+
description: 'Toggle the v4.4 execution sandbox (file ACLs + docker tools).',
|
|
29
|
+
category: 'system',
|
|
30
|
+
icon: '🛡',
|
|
31
|
+
handler: async (ctx) => {
|
|
32
|
+
const sub = (0, _runtimeToggleHelpers_1.parseSubcommand)(ctx.args[0]);
|
|
33
|
+
if (sub === 'on') {
|
|
34
|
+
await (0, _runtimeToggleHelpers_1.flip)('sandbox', true, ctx);
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
if (sub === 'off') {
|
|
38
|
+
await (0, _runtimeToggleHelpers_1.flip)('sandbox', false, ctx);
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
if (sub === 'status') {
|
|
42
|
+
(0, _runtimeToggleHelpers_1.printStatus)('sandbox', ctx);
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
ctx.display.printError('Usage: /sandbox on|off|status');
|
|
46
|
+
return {};
|
|
47
|
+
},
|
|
48
|
+
};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/spawnPause.ts — v4.6 Phase 3A.
|
|
10
|
+
*
|
|
11
|
+
* `/spawn-pause on|off|status [reason...]` — operator kill-switch
|
|
12
|
+
* for sub-agent spawning. Backed by a file marker at
|
|
13
|
+
* `$aidenHome/spawn.paused` (see `core/v4/subagent/spawnPause.ts`)
|
|
14
|
+
* so REPL + daemon + MCP server all coordinate via the same state.
|
|
15
|
+
*
|
|
16
|
+
* /spawn-pause on — pause, no reason
|
|
17
|
+
* /spawn-pause on runaway-fanout — pause, reason="runaway-fanout"
|
|
18
|
+
* /spawn-pause on deploy window — pause, reason="deploy window"
|
|
19
|
+
* /spawn-pause off — resume
|
|
20
|
+
* /spawn-pause status — current state + reason + duration
|
|
21
|
+
*
|
|
22
|
+
* Unlike `/planner-guard`, `/sandbox`, etc., this command does NOT
|
|
23
|
+
* route through `runtimeToggles` — pause state is file-marker-
|
|
24
|
+
* backed (cross-process visibility) with first-class
|
|
25
|
+
* reason/pausedAt/pausedBy metadata that the boolean toggle surface
|
|
26
|
+
* can't carry. Mirrors plannerGuard.ts's command shape; diverges
|
|
27
|
+
* from `_runtimeToggleHelpers` because the storage backend is
|
|
28
|
+
* different.
|
|
29
|
+
*
|
|
30
|
+
* Hard contract: in-flight children are NEVER cancelled by this
|
|
31
|
+
* command. Pause affects only NEW spawns. Operators who want to
|
|
32
|
+
* stop in-flight runs use `aiden runs interrupt <runId>` (the
|
|
33
|
+
* existing per-run cancellation surface from v4.5 Phase 6).
|
|
34
|
+
*/
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.spawnPause = void 0;
|
|
37
|
+
const spawnPause_1 = require("../../../core/v4/subagent/spawnPause");
|
|
38
|
+
/** Format a duration in ms as a compact `Xs` / `Xm` / `Xh` string. */
|
|
39
|
+
function formatDuration(ms) {
|
|
40
|
+
if (ms < 1000)
|
|
41
|
+
return `${ms}ms`;
|
|
42
|
+
if (ms < 60000)
|
|
43
|
+
return `${Math.round(ms / 1000)}s`;
|
|
44
|
+
if (ms < 3600000)
|
|
45
|
+
return `${Math.round(ms / 60000)}m`;
|
|
46
|
+
return `${Math.round(ms / 3600000)}h`;
|
|
47
|
+
}
|
|
48
|
+
exports.spawnPause = {
|
|
49
|
+
name: 'spawn-pause',
|
|
50
|
+
description: 'Pause/resume sub-agent spawning (in-flight children continue).',
|
|
51
|
+
category: 'system',
|
|
52
|
+
icon: '⏸',
|
|
53
|
+
handler: async (ctx) => {
|
|
54
|
+
const action = (ctx.args[0] ?? 'status').toLowerCase();
|
|
55
|
+
const reasonArg = ctx.args.slice(1).join(' ').trim() || null;
|
|
56
|
+
let state;
|
|
57
|
+
try {
|
|
58
|
+
state = (0, spawnPause_1.getSpawnPause)();
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
ctx.display.printError('spawn-pause: not initialized — REPL boot did not wire the singleton.', e instanceof Error ? e.message : String(e));
|
|
62
|
+
return {};
|
|
63
|
+
}
|
|
64
|
+
if (action === 'on' || action === 'enable' || action === 'true' || action === '1') {
|
|
65
|
+
state.pause({ reason: reasonArg, pausedBy: 'repl' });
|
|
66
|
+
const s = state.status();
|
|
67
|
+
const reasonLine = s.reason ? ` reason: ${s.reason}\n` : '';
|
|
68
|
+
ctx.display.write(`spawn-pause: ON\n${reasonLine}`);
|
|
69
|
+
ctx.display.dim(' in-flight children continue. New spawn_sub_agent / subagent_fanout calls will reject.');
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
if (action === 'off' || action === 'disable' || action === 'false' || action === '0' || action === 'resume') {
|
|
73
|
+
state.resume();
|
|
74
|
+
ctx.display.write('spawn-pause: OFF (resumed)\n');
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
if (action === 'status' || action === '') {
|
|
78
|
+
const s = state.status();
|
|
79
|
+
if (!s.paused) {
|
|
80
|
+
ctx.display.write('spawn-pause: OFF\n');
|
|
81
|
+
return {};
|
|
82
|
+
}
|
|
83
|
+
const reasonLine = s.reason ? ` reason: ${s.reason}\n` : '';
|
|
84
|
+
const durationLine = s.durationMs !== undefined ? ` duration: ${formatDuration(s.durationMs)}\n` : '';
|
|
85
|
+
const pausedAtLine = s.pausedAt ? ` pausedAt: ${new Date(s.pausedAt).toISOString()}\n` : '';
|
|
86
|
+
const pausedByLine = s.pausedBy ? ` pausedBy: ${s.pausedBy}\n` : '';
|
|
87
|
+
ctx.display.write(`spawn-pause: ON\n${reasonLine}${durationLine}${pausedAtLine}${pausedByLine}`);
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
ctx.display.printError('Usage: /spawn-pause on [reason...] | off | status');
|
|
91
|
+
return {};
|
|
92
|
+
},
|
|
93
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/suggestions.ts — v4.5 Phase 8b.
|
|
10
|
+
*
|
|
11
|
+
* `/suggestions on|off|status` — flip the contextual capability
|
|
12
|
+
* suggestions surfaced by the suggestionEngine (Phase 8b). Reuses
|
|
13
|
+
* the Phase 8a `_runtimeToggleHelpers` since 'suggestions' is now
|
|
14
|
+
* a fourth ToggleKey on the runtimeToggles singleton.
|
|
15
|
+
*
|
|
16
|
+
* /suggestions on — re-enable tips (default).
|
|
17
|
+
* /suggestions off — silence tips for this REPL + persist to
|
|
18
|
+
* config.yaml (runtime_toggles.suggestions
|
|
19
|
+
* = false). Subsequent boots stay quiet
|
|
20
|
+
* until /suggestions on flips it back.
|
|
21
|
+
* /suggestions status — single-line state with source +
|
|
22
|
+
* fired-this-session count + budget remaining.
|
|
23
|
+
*/
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.suggestions = void 0;
|
|
26
|
+
const _runtimeToggleHelpers_1 = require("./_runtimeToggleHelpers");
|
|
27
|
+
const runtimeToggles_1 = require("../../../core/v4/runtimeToggles");
|
|
28
|
+
const suggestionEngine_1 = require("../../../core/v4/suggestionEngine");
|
|
29
|
+
exports.suggestions = {
|
|
30
|
+
name: 'suggestions',
|
|
31
|
+
description: 'Toggle contextual one-line capability tips.',
|
|
32
|
+
category: 'system',
|
|
33
|
+
icon: '💡',
|
|
34
|
+
handler: async (ctx) => {
|
|
35
|
+
const sub = (0, _runtimeToggleHelpers_1.parseSubcommand)(ctx.args[0]);
|
|
36
|
+
if (sub === 'on') {
|
|
37
|
+
await (0, _runtimeToggleHelpers_1.flip)('suggestions', true, ctx);
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
if (sub === 'off') {
|
|
41
|
+
await (0, _runtimeToggleHelpers_1.flip)('suggestions', false, ctx);
|
|
42
|
+
// Also session-dismiss so the in-process engine stops firing
|
|
43
|
+
// immediately, not just after the next REPL restart picks up
|
|
44
|
+
// the new config value.
|
|
45
|
+
try {
|
|
46
|
+
(0, suggestionEngine_1.getSuggestionEngine)().dismissAll();
|
|
47
|
+
}
|
|
48
|
+
catch { /* defensive */ }
|
|
49
|
+
return {};
|
|
50
|
+
}
|
|
51
|
+
if (sub === 'status') {
|
|
52
|
+
const tog = (0, runtimeToggles_1.getRuntimeToggles)().snapshot().suggestions;
|
|
53
|
+
const snap = (0, suggestionEngine_1.getSuggestionEngine)().snapshot();
|
|
54
|
+
const state = tog.value ? 'ON' : 'OFF';
|
|
55
|
+
const dismissTag = snap.dismissedSession && tog.value ? ' (dismissed this session)' : '';
|
|
56
|
+
ctx.display.write(`Suggestions: ${state} (source: ${tog.source})${dismissTag}\n`);
|
|
57
|
+
if (snap.firedSlots.length > 0) {
|
|
58
|
+
ctx.display.write(` fired this session: ${snap.firedSlots.join(', ')} · budget remaining: ${snap.budgetRemaining}\n`);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
ctx.display.write(` fired this session: (none) · budget remaining: ${snap.budgetRemaining}\n`);
|
|
62
|
+
}
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
ctx.display.printError('Usage: /suggestions on|off|status');
|
|
66
|
+
return {};
|
|
67
|
+
},
|
|
68
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Copyright (c) 2026 Shiva Deore (Taracod).
|
|
4
|
+
* Licensed under AGPL-3.0. See LICENSE for details.
|
|
5
|
+
*
|
|
6
|
+
* Aiden — local-first agent.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* cli/v4/commands/tce.ts — v4.5 Phase 8a.
|
|
10
|
+
*
|
|
11
|
+
* `/tce on|off|status` — flip the v4.2 Tool-Call Effort recovery
|
|
12
|
+
* pipeline (verifier + failure classifier + recovery report)
|
|
13
|
+
* without restart. Persists to config.yaml. Env var AIDEN_TCE
|
|
14
|
+
* always wins.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.tce = void 0;
|
|
18
|
+
const _runtimeToggleHelpers_1 = require("./_runtimeToggleHelpers");
|
|
19
|
+
exports.tce = {
|
|
20
|
+
name: 'tce',
|
|
21
|
+
description: 'Toggle the v4.2 Tool-Call Effort recovery pipeline.',
|
|
22
|
+
category: 'system',
|
|
23
|
+
icon: '🔁',
|
|
24
|
+
handler: async (ctx) => {
|
|
25
|
+
const sub = (0, _runtimeToggleHelpers_1.parseSubcommand)(ctx.args[0]);
|
|
26
|
+
if (sub === 'on') {
|
|
27
|
+
await (0, _runtimeToggleHelpers_1.flip)('tce', true, ctx);
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
if (sub === 'off') {
|
|
31
|
+
await (0, _runtimeToggleHelpers_1.flip)('tce', false, ctx);
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
if (sub === 'status') {
|
|
35
|
+
(0, _runtimeToggleHelpers_1.printStatus)('tce', ctx);
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
ctx.display.printError('Usage: /tce on|off|status');
|
|
39
|
+
return {};
|
|
40
|
+
},
|
|
41
|
+
};
|