aiden-runtime 4.8.1 → 4.9.1
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 +88 -1
- package/dist/cli/v4/aidenCLI.js +37 -6
- package/dist/cli/v4/chatSession.js +53 -13
- package/dist/cli/v4/commands/daemon.js +53 -3
- package/dist/cli/v4/commands/daemonDoctor.js +212 -0
- package/dist/cli/v4/commands/daemonStatus.js +45 -26
- package/dist/cli/v4/commands/help.js +5 -0
- package/dist/cli/v4/commands/hooks.js +466 -0
- package/dist/cli/v4/commands/hooksSlash.js +33 -0
- package/dist/cli/v4/commands/index.js +13 -1
- package/dist/cli/v4/commands/mcp.js +89 -1
- package/dist/cli/v4/commands/mcpClientInstall.js +359 -0
- package/dist/cli/v4/commands/memory.js +707 -0
- package/dist/cli/v4/commands/memorySlash.js +38 -0
- package/dist/cli/v4/commands/recovery.js +1 -1
- package/dist/cli/v4/commands/skin.js +7 -0
- package/dist/cli/v4/commands/theme.js +217 -0
- package/dist/cli/v4/commands/trigger.js +1 -1
- package/dist/cli/v4/design/tokens.js +52 -4
- package/dist/cli/v4/display.js +39 -26
- package/dist/cli/v4/replyRenderer.js +6 -5
- package/dist/cli/v4/skinEngine.js +67 -0
- package/dist/cli/v4/ui/progressBar.js +179 -0
- package/dist/cli/v4/util/closestAction.js +48 -0
- package/dist/core/v4/aidenAgent.js +45 -2
- package/dist/core/v4/daemon/api/runs.js +131 -0
- package/dist/core/v4/daemon/bootstrap.js +368 -13
- package/dist/core/v4/daemon/db/migrations.js +169 -0
- package/dist/core/v4/daemon/idempotency/runIdempotencyStore.js +128 -0
- package/dist/core/v4/daemon/incarnationStore.js +47 -0
- package/dist/core/v4/daemon/runs/attemptStore.js +67 -0
- package/dist/core/v4/daemon/runs/reclaim.js +88 -0
- package/dist/core/v4/daemon/runs/retryPolicy.js +73 -0
- package/dist/core/v4/daemon/runs/runWithRetry.js +80 -0
- package/dist/core/v4/daemon/runs/stuckAttemptWatchdog.js +72 -0
- package/dist/core/v4/daemon/spans/spanHelpers.js +272 -0
- package/dist/core/v4/daemon/spans/spanStore.js +113 -0
- package/dist/core/v4/daemon/triggerBus.js +50 -19
- package/dist/core/v4/hooks/auditQuery.js +67 -0
- package/dist/core/v4/hooks/dispatcher.js +286 -0
- package/dist/core/v4/hooks/index.js +46 -0
- package/dist/core/v4/hooks/lifecycle.js +27 -0
- package/dist/core/v4/hooks/manifest.js +142 -0
- package/dist/core/v4/hooks/registry.js +149 -0
- package/dist/core/v4/hooks/runtime/subprocessRunner.js +188 -0
- package/dist/core/v4/hooks/toolHookGate.js +76 -0
- package/dist/core/v4/hooks/trust.js +14 -0
- package/dist/core/v4/identity/contextManager.js +83 -0
- package/dist/core/v4/identity/daemonId.js +85 -0
- package/dist/core/v4/identity/enforcement.js +103 -0
- package/dist/core/v4/identity/executionContext.js +153 -0
- package/dist/core/v4/identity/hookExecution.js +62 -0
- package/dist/core/v4/identity/httpContext.js +68 -0
- package/dist/core/v4/identity/ids.js +185 -0
- package/dist/core/v4/identity/index.js +60 -0
- package/dist/core/v4/identity/subprocessContext.js +98 -0
- package/dist/core/v4/identity/traceparent.js +114 -0
- package/dist/core/v4/logger/index.js +3 -1
- package/dist/core/v4/logger/logger.js +28 -1
- package/dist/core/v4/logger/redact.js +149 -0
- package/dist/core/v4/logger/sinks/fileSink.js +13 -0
- package/dist/core/v4/logger/sinks/stdSink.js +19 -1
- package/dist/core/v4/mcp/install/backup.js +78 -0
- package/dist/core/v4/mcp/install/clientPaths.js +90 -0
- package/dist/core/v4/mcp/install/clients.js +203 -0
- package/dist/core/v4/mcp/install/healthCheck.js +83 -0
- package/dist/core/v4/mcp/install/jsoncMerge.js +174 -0
- package/dist/core/v4/mcp/install/profiles.js +109 -0
- package/dist/core/v4/mcp/install/wslDetect.js +62 -0
- package/dist/core/v4/memory/namespaceRegistry.js +117 -0
- package/dist/core/v4/memory/projectRoot.js +76 -0
- package/dist/core/v4/memory/reviewer/index.js +162 -0
- package/dist/core/v4/memory/reviewer/pendingStore.js +136 -0
- package/dist/core/v4/memory/reviewer/prompt.js +105 -0
- package/dist/core/v4/memory/reviewer/skipRules.js +92 -0
- package/dist/core/v4/memoryManager.js +57 -10
- package/dist/core/v4/paths.js +2 -0
- package/dist/core/v4/subagent/spawnSubAgent.js +20 -7
- package/dist/core/v4/theme/bundledThemes.js +106 -0
- package/dist/core/v4/theme/themeLoader.js +160 -0
- package/dist/core/v4/theme/themeRegistry.js +97 -0
- package/dist/core/v4/theme/themeWatcher.js +95 -0
- package/dist/core/v4/toolRegistry.js +71 -8
- package/dist/core/v4/update/depWarningFilter.js +76 -0
- package/dist/core/v4/update/executeInstall.js +41 -35
- package/dist/core/v4/update/platformInstructions.js +128 -0
- package/dist/moat/approvalEngine.js +4 -0
- package/dist/moat/memoryGuard.js +8 -1
- package/dist/providers/v4/anthropicAdapter.js +10 -4
- package/dist/tools/v4/backends/local.js +19 -2
- package/dist/tools/v4/sessions/recallSession.js +6 -1
- package/package.json +3 -1
- package/plugins/aiden-plugin-chatgpt-plus/index.js +10 -1
- package/themes/default.yaml +52 -0
- package/themes/dracula.yaml +32 -0
- package/themes/light.yaml +32 -0
- package/themes/monochrome.yaml +31 -0
- package/themes/tokyo-night.yaml +32 -0
- package/dist/core/pluginSystem.js +0 -121
- package/dist/tools/v4/ui/_uiSmokeTool.js +0 -60
|
@@ -22,44 +22,63 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
22
22
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
23
|
};
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
-
exports.daemonStatus = void 0;
|
|
25
|
+
exports.daemonStatus = exports.DAEMON_SHELL_ONLY = void 0;
|
|
26
|
+
exports.dispatchDaemonSlash = dispatchDaemonSlash;
|
|
26
27
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
27
28
|
const node_os_1 = __importDefault(require("node:os"));
|
|
28
29
|
const node_path_1 = __importDefault(require("node:path"));
|
|
29
|
-
const daemon_1 = require("
|
|
30
|
+
const daemon_1 = require("./daemon");
|
|
31
|
+
const daemon_2 = require("../../../core/v4/daemon");
|
|
30
32
|
const paths_1 = require("../../../core/v4/paths");
|
|
33
|
+
/**
|
|
34
|
+
* v4.9.1 amendment — `/daemon` defaults to `doctor` and routes
|
|
35
|
+
* `doctor` / `logs` to the existing `runDaemonSubcommand`. The pure-
|
|
36
|
+
* REPL `/daemon status` (in-process snapshot) stays inline. Lifecycle
|
|
37
|
+
* ops shell-hint — they need terminal control we can't grant inside chat.
|
|
38
|
+
*/
|
|
39
|
+
exports.DAEMON_SHELL_ONLY = new Set(['install', 'uninstall', 'start', 'stop', 'restart']);
|
|
40
|
+
async function dispatchDaemonSlash(opts) {
|
|
41
|
+
const a = (opts.action || 'doctor').toLowerCase();
|
|
42
|
+
if (exports.DAEMON_SHELL_ONLY.has(a)) {
|
|
43
|
+
opts.write(`⚠ /daemon ${a} not available inside chat (requires terminal control)\n`);
|
|
44
|
+
opts.write(' Quit (/quit) and run from shell:\n\n');
|
|
45
|
+
const tail = opts.args.length > 0 ? ' ' + opts.args.join(' ') : '';
|
|
46
|
+
opts.write(` aiden daemon ${a}${tail}\n`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
if (a === 'status' && opts.paintStatus) {
|
|
50
|
+
try {
|
|
51
|
+
opts.paintStatus();
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
opts.warn(`/daemon status: failed to read state (${e instanceof Error ? e.message : String(e)})`);
|
|
55
|
+
}
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await opts.runDaemon(a, opts.args, { writeOut: opts.write, writeErr: opts.write });
|
|
59
|
+
}
|
|
31
60
|
exports.daemonStatus = {
|
|
32
61
|
name: 'daemon',
|
|
33
|
-
description: '
|
|
62
|
+
description: 'Daemon diagnostics (doctor / status / logs).',
|
|
34
63
|
category: 'system',
|
|
35
64
|
icon: '⚙',
|
|
36
65
|
handler: async (ctx) => {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
ctx.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
' aiden daemon logs');
|
|
46
|
-
return {};
|
|
47
|
-
}
|
|
48
|
-
try {
|
|
49
|
-
const snapshot = readSnapshot();
|
|
50
|
-
printSnapshot(snapshot, ctx);
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
ctx.display.warn(`/daemon status: failed to read state (${e instanceof Error ? e.message : String(e)})`);
|
|
54
|
-
}
|
|
66
|
+
await dispatchDaemonSlash({
|
|
67
|
+
action: ctx.args[0] ?? 'doctor',
|
|
68
|
+
args: ctx.args.slice(1),
|
|
69
|
+
write: (s) => ctx.display.write(s),
|
|
70
|
+
warn: (s) => ctx.display.warn(s),
|
|
71
|
+
runDaemon: daemon_1.runDaemonSubcommand,
|
|
72
|
+
paintStatus: () => printSnapshot(readSnapshot(), ctx),
|
|
73
|
+
});
|
|
55
74
|
return {};
|
|
56
75
|
},
|
|
57
76
|
};
|
|
58
77
|
// ── Snapshot collector ─────────────────────────────────────────────────────
|
|
59
78
|
function readSnapshot() {
|
|
60
79
|
const aidenRoot = (0, paths_1.resolveAidenRoot)();
|
|
61
|
-
const dbPath = (0,
|
|
62
|
-
const lockPath = (0,
|
|
80
|
+
const dbPath = (0, daemon_2.daemonDbPath)(aidenRoot);
|
|
81
|
+
const lockPath = (0, daemon_2.daemonRuntimeLockPath)(aidenRoot);
|
|
63
82
|
// ── Liveness via the in-process bootstrap handle first, then fall
|
|
64
83
|
// back to the runtime.lock PID check (covers the case where the
|
|
65
84
|
// daemon is another process and we're a REPL inspecting its db).
|
|
@@ -67,11 +86,11 @@ function readSnapshot() {
|
|
|
67
86
|
let instanceId = null;
|
|
68
87
|
let port = null;
|
|
69
88
|
let uptimeMs = null;
|
|
70
|
-
const handle = (0,
|
|
89
|
+
const handle = (0, daemon_2.getDaemonHandle)();
|
|
71
90
|
if (handle?.active && handle.instanceId) {
|
|
72
91
|
running = true;
|
|
73
92
|
instanceId = handle.instanceId;
|
|
74
|
-
port = (0,
|
|
93
|
+
port = (0, daemon_2.getDaemonConfig)().port;
|
|
75
94
|
if (handle.instanceTracker) {
|
|
76
95
|
// instanceTracker has a `getStartedAt` if exposed; otherwise
|
|
77
96
|
// derive from daemon_instances row below.
|
|
@@ -105,7 +124,7 @@ function readSnapshot() {
|
|
|
105
124
|
dailyBudget: null,
|
|
106
125
|
};
|
|
107
126
|
}
|
|
108
|
-
const db = (0,
|
|
127
|
+
const db = (0, daemon_2.openDaemonDb)(dbPath);
|
|
109
128
|
// Uptime from the instance row when we have an instanceId.
|
|
110
129
|
if (running && instanceId) {
|
|
111
130
|
try {
|
|
@@ -31,6 +31,8 @@ exports.SUBSECTION_MAP = {
|
|
|
31
31
|
providers: 'Configuration',
|
|
32
32
|
personality: 'Configuration',
|
|
33
33
|
skin: 'Configuration',
|
|
34
|
+
// v4.9.0 Slice 1a — unified theme system (parallel to /skin).
|
|
35
|
+
theme: 'Configuration',
|
|
34
36
|
streaming: 'Configuration',
|
|
35
37
|
reasoning: 'Configuration',
|
|
36
38
|
verbose: 'Configuration',
|
|
@@ -74,6 +76,9 @@ exports.SUBSECTION_MAP = {
|
|
|
74
76
|
recovery: 'System',
|
|
75
77
|
// v4.6 ONB1 slice 10 — new-user guided tour.
|
|
76
78
|
walkthrough: 'System',
|
|
79
|
+
// v4.9.1 amendment — REPL surfaces for memory + hooks (daemon already mapped).
|
|
80
|
+
memory: 'System',
|
|
81
|
+
hooks: 'System',
|
|
77
82
|
// ── Authentication ──
|
|
78
83
|
auth: 'Authentication',
|
|
79
84
|
// ── Help ──
|
|
@@ -0,0 +1,466 @@
|
|
|
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/hooks.ts — v4.9.0 Slice 12b.
|
|
10
|
+
*
|
|
11
|
+
* aiden hooks alias for `list`
|
|
12
|
+
* aiden hooks list [--json]
|
|
13
|
+
* aiden hooks show <hook_id>
|
|
14
|
+
* aiden hooks trust <hook_id> [--yes] (risk warning + y/N prompt unless --yes)
|
|
15
|
+
* aiden hooks revoke <hook_id> [--yes]
|
|
16
|
+
* aiden hooks rescan
|
|
17
|
+
* aiden hooks test <hook_id> [--event <name>] [--payload <json>]
|
|
18
|
+
* aiden hooks doctor [--json] [--fix]
|
|
19
|
+
* aiden hooks audit [--hook id] [--event n] [--since iso]
|
|
20
|
+
* [--status s] [--limit n] [--json]
|
|
21
|
+
*
|
|
22
|
+
* Doctor's `--fix` is intentionally conservative: it creates the hooks
|
|
23
|
+
* directory and runs a rescan, but NEVER auto-trusts anything (trust
|
|
24
|
+
* remains an explicit, deliberate user action).
|
|
25
|
+
*/
|
|
26
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
29
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
30
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
31
|
+
}
|
|
32
|
+
Object.defineProperty(o, k2, desc);
|
|
33
|
+
}) : (function(o, m, k, k2) {
|
|
34
|
+
if (k2 === undefined) k2 = k;
|
|
35
|
+
o[k2] = m[k];
|
|
36
|
+
}));
|
|
37
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
38
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
39
|
+
}) : function(o, v) {
|
|
40
|
+
o["default"] = v;
|
|
41
|
+
});
|
|
42
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
43
|
+
var ownKeys = function(o) {
|
|
44
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
45
|
+
var ar = [];
|
|
46
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
47
|
+
return ar;
|
|
48
|
+
};
|
|
49
|
+
return ownKeys(o);
|
|
50
|
+
};
|
|
51
|
+
return function (mod) {
|
|
52
|
+
if (mod && mod.__esModule) return mod;
|
|
53
|
+
var result = {};
|
|
54
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
55
|
+
__setModuleDefault(result, mod);
|
|
56
|
+
return result;
|
|
57
|
+
};
|
|
58
|
+
})();
|
|
59
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
60
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
61
|
+
};
|
|
62
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
63
|
+
exports.runHooksSubcommand = runHooksSubcommand;
|
|
64
|
+
const node_fs_1 = require("node:fs");
|
|
65
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
66
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
67
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
68
|
+
const paths_1 = require("../../../core/v4/paths");
|
|
69
|
+
const daemonConfig_1 = require("../../../core/v4/daemon/daemonConfig");
|
|
70
|
+
const migrations_1 = require("../../../core/v4/daemon/db/migrations");
|
|
71
|
+
const registry_1 = require("../../../core/v4/hooks/registry");
|
|
72
|
+
const trust_1 = require("../../../core/v4/hooks/trust");
|
|
73
|
+
const dispatcher_1 = require("../../../core/v4/hooks/dispatcher");
|
|
74
|
+
const auditQuery_1 = require("../../../core/v4/hooks/auditQuery");
|
|
75
|
+
const projectRoot_1 = require("../../../core/v4/memory/projectRoot");
|
|
76
|
+
const noopOut = (s) => { process.stdout.write(s); };
|
|
77
|
+
const noopErr = (s) => { process.stderr.write(s); };
|
|
78
|
+
async function runHooksSubcommand(action, args, opts = {}) {
|
|
79
|
+
const out = opts.writeOut ?? noopOut;
|
|
80
|
+
const err = opts.writeErr ?? noopErr;
|
|
81
|
+
const json = args.includes('--json');
|
|
82
|
+
const yes = args.includes('--yes');
|
|
83
|
+
const positional = args.filter((a) => !a.startsWith('--'));
|
|
84
|
+
const paths = (0, paths_1.resolveAidenPaths)(opts.rootDir ? { rootOverride: opts.rootDir } : {});
|
|
85
|
+
let db;
|
|
86
|
+
try {
|
|
87
|
+
const dbp = opts.dbPath ?? (0, daemonConfig_1.daemonDbPath)(paths.root);
|
|
88
|
+
await node_fs_1.promises.mkdir(node_path_1.default.dirname(dbp), { recursive: true });
|
|
89
|
+
db = new better_sqlite3_1.default(dbp);
|
|
90
|
+
db.pragma('foreign_keys = ON');
|
|
91
|
+
(0, migrations_1.runMigrations)(db);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
err(`hooks: cannot open daemon db: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
95
|
+
return 1;
|
|
96
|
+
}
|
|
97
|
+
const ctx = {
|
|
98
|
+
out, err, db, paths, json, yes, positional, args,
|
|
99
|
+
promptYesNo: opts.promptYesNo ?? defaultPromptYesNo,
|
|
100
|
+
};
|
|
101
|
+
const effective = action || 'list';
|
|
102
|
+
try {
|
|
103
|
+
switch (effective) {
|
|
104
|
+
case 'list': return await cmdList(ctx);
|
|
105
|
+
case 'show': return await cmdShow(ctx);
|
|
106
|
+
case 'trust': return await cmdTrust(ctx);
|
|
107
|
+
case 'revoke': return await cmdRevoke(ctx);
|
|
108
|
+
case 'rescan': return await cmdRescan(ctx);
|
|
109
|
+
case 'test': return await cmdTest(ctx);
|
|
110
|
+
case 'doctor': return await cmdDoctor(ctx);
|
|
111
|
+
case 'audit': return await cmdAudit(ctx);
|
|
112
|
+
case '--help':
|
|
113
|
+
case 'help': return cmdHelp(out);
|
|
114
|
+
default: {
|
|
115
|
+
err(`Unknown hooks action: ${effective}\n`);
|
|
116
|
+
const { closestAction } = await Promise.resolve().then(() => __importStar(require('../util/closestAction')));
|
|
117
|
+
const m = closestAction(effective, ['list', 'show', 'trust', 'revoke', 'rescan', 'test', 'doctor', 'audit']);
|
|
118
|
+
if (m)
|
|
119
|
+
err(`Did you mean: ${m}?\n\n`);
|
|
120
|
+
cmdHelp(err);
|
|
121
|
+
return 2;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
try {
|
|
127
|
+
db.close();
|
|
128
|
+
}
|
|
129
|
+
catch { /* noop */ }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function cmdHelp(w) {
|
|
133
|
+
w('Usage: aiden hooks <action> [args...] [--json] [--yes]\n\n' +
|
|
134
|
+
'Manage Aiden\'s manifest-driven hook subsystem.\n\n' +
|
|
135
|
+
'Actions:\n' +
|
|
136
|
+
' list All discovered hooks (default).\n' +
|
|
137
|
+
' show <hook_id> Hook manifest + subscriptions + recent executions.\n' +
|
|
138
|
+
' trust <hook_id> [--yes] Mark trusted + enabled (confirmation required).\n' +
|
|
139
|
+
' revoke <hook_id> [--yes] Mark revoked + disabled (confirmation required).\n' +
|
|
140
|
+
' rescan Walk hook dirs, surface new + drifted.\n' +
|
|
141
|
+
' test <hook_id> [--event N] [--payload JSON]\n' +
|
|
142
|
+
' Dry-run invocation (no counter mutation).\n' +
|
|
143
|
+
' doctor [--json] [--fix] Pre-flight diagnostics.\n' +
|
|
144
|
+
' audit [--hook id] [--event N] [--status S] [--since ISO] [--limit N] [--json]\n' +
|
|
145
|
+
' Recent hook_executions rows.\n');
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
function defaultPromptYesNo(question) {
|
|
149
|
+
return new Promise((resolve) => {
|
|
150
|
+
const rl = node_readline_1.default.createInterface({ input: process.stdin, output: process.stderr });
|
|
151
|
+
rl.question(question, (ans) => {
|
|
152
|
+
rl.close();
|
|
153
|
+
resolve(ans.trim().toLowerCase() === 'y' || ans.trim().toLowerCase() === 'yes');
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function flagValue(args, name) {
|
|
158
|
+
const i = args.indexOf(name);
|
|
159
|
+
if (i < 0 || i + 1 >= args.length)
|
|
160
|
+
return undefined;
|
|
161
|
+
return args[i + 1];
|
|
162
|
+
}
|
|
163
|
+
function hooksWithSubs(db) {
|
|
164
|
+
const hooks = db.prepare(`SELECT *, consecutive_failures FROM hooks ORDER BY name`).all();
|
|
165
|
+
return hooks.map((h) => ({
|
|
166
|
+
...h,
|
|
167
|
+
subs: db.prepare(`SELECT * FROM hook_subscriptions WHERE hook_id = ? ORDER BY event, priority DESC`).all(h.hook_id),
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
async function cmdList(ctx) {
|
|
171
|
+
const rows = hooksWithSubs(ctx.db);
|
|
172
|
+
if (ctx.json) {
|
|
173
|
+
ctx.out(JSON.stringify(rows, null, 2) + '\n');
|
|
174
|
+
return 0;
|
|
175
|
+
}
|
|
176
|
+
if (rows.length === 0) {
|
|
177
|
+
ctx.out('no hooks discovered (drop a HOOK.yaml under ~/.aiden/hooks/<name>/ then run `aiden hooks rescan`)\n');
|
|
178
|
+
return 0;
|
|
179
|
+
}
|
|
180
|
+
for (const h of rows) {
|
|
181
|
+
const stateLabel = `${h.trust_state}, ${h.enabled ? 'enabled' : 'disabled'}`;
|
|
182
|
+
ctx.out(`${h.hook_id} ${h.name.padEnd(24)} ${stateLabel.padEnd(24)} ${h.source} (${h.subs.length} subscription${h.subs.length === 1 ? '' : 's'})\n`);
|
|
183
|
+
for (const s of h.subs) {
|
|
184
|
+
ctx.out(` ${s.event.padEnd(20)} authority=${s.authority.padEnd(18)} mode=${s.mode}\n`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return 0;
|
|
188
|
+
}
|
|
189
|
+
async function cmdShow(ctx) {
|
|
190
|
+
const hookId = ctx.positional[0];
|
|
191
|
+
if (!hookId) {
|
|
192
|
+
ctx.err('show: missing <hook_id>\n');
|
|
193
|
+
return 2;
|
|
194
|
+
}
|
|
195
|
+
const h = ctx.db.prepare(`SELECT *, consecutive_failures FROM hooks WHERE hook_id = ?`).get(hookId);
|
|
196
|
+
if (!h) {
|
|
197
|
+
ctx.err(`show: hook not found: ${hookId}\n`);
|
|
198
|
+
return 1;
|
|
199
|
+
}
|
|
200
|
+
const subs = ctx.db.prepare(`SELECT * FROM hook_subscriptions WHERE hook_id = ? ORDER BY event, priority DESC`)
|
|
201
|
+
.all(hookId);
|
|
202
|
+
const grants = ctx.db.prepare(`SELECT capability, scope_json FROM hook_capability_grants WHERE hook_id = ?`)
|
|
203
|
+
.all(hookId);
|
|
204
|
+
const recent = (0, auditQuery_1.queryHookExecutions)(ctx.db, { hookId, limit: 10 });
|
|
205
|
+
if (ctx.json) {
|
|
206
|
+
ctx.out(JSON.stringify({ hook: h, subscriptions: subs, capabilities: grants, recent }, null, 2) + '\n');
|
|
207
|
+
return 0;
|
|
208
|
+
}
|
|
209
|
+
ctx.out(`Hook: ${h.name} (${h.hook_id})\n`);
|
|
210
|
+
ctx.out(` state: ${h.trust_state}, ${h.enabled ? 'enabled' : 'disabled'}\n`);
|
|
211
|
+
ctx.out(` source: ${h.source}\n`);
|
|
212
|
+
ctx.out(` manifest: ${h.manifest_path}\n`);
|
|
213
|
+
ctx.out(` hash: ${h.code_hash.slice(0, 16)}...\n`);
|
|
214
|
+
ctx.out(` consecutive failures: ${h.consecutive_failures}\n`);
|
|
215
|
+
ctx.out('Subscriptions:\n');
|
|
216
|
+
for (const s of subs) {
|
|
217
|
+
ctx.out(` ${s.event} authority=${s.authority} mode=${s.mode} priority=${s.priority}\n`);
|
|
218
|
+
ctx.out(` timeout=${s.timeout_ms}ms on_error=${s.on_error} on_timeout=${s.on_timeout}\n`);
|
|
219
|
+
if (s.matcher_json)
|
|
220
|
+
ctx.out(` matcher=${s.matcher_json}\n`);
|
|
221
|
+
}
|
|
222
|
+
if (grants.length > 0) {
|
|
223
|
+
ctx.out('Capabilities (declared, not enforced):\n');
|
|
224
|
+
for (const g of grants)
|
|
225
|
+
ctx.out(` ${g.capability} ${g.scope_json}\n`);
|
|
226
|
+
}
|
|
227
|
+
ctx.out(`Recent executions (last ${recent.length}):\n`);
|
|
228
|
+
for (const r of recent) {
|
|
229
|
+
ctx.out(` ${r.started_at} ${r.event.padEnd(20)} ${r.status.padEnd(8)} ${r.elapsed_ms}ms\n`);
|
|
230
|
+
}
|
|
231
|
+
return 0;
|
|
232
|
+
}
|
|
233
|
+
async function cmdTrust(ctx) {
|
|
234
|
+
const hookId = ctx.positional[0];
|
|
235
|
+
if (!hookId) {
|
|
236
|
+
ctx.err('trust: missing <hook_id>\n');
|
|
237
|
+
return 2;
|
|
238
|
+
}
|
|
239
|
+
const h = ctx.db.prepare(`SELECT * FROM hooks WHERE hook_id = ?`).get(hookId);
|
|
240
|
+
if (!h) {
|
|
241
|
+
ctx.err(`trust: hook not found: ${hookId}\n`);
|
|
242
|
+
return 1;
|
|
243
|
+
}
|
|
244
|
+
if (!ctx.yes) {
|
|
245
|
+
ctx.err(`Hook: ${h.name} (${h.hook_id})\n manifest: ${h.manifest_path}\n current state: ${h.trust_state}\n`);
|
|
246
|
+
ctx.err('RISK WARNING: This hook can affect tool execution. Only trust hooks you\'ve reviewed.\n');
|
|
247
|
+
const ok = await ctx.promptYesNo('Trust this hook? [y/N] ');
|
|
248
|
+
if (!ok) {
|
|
249
|
+
if (ctx.json)
|
|
250
|
+
ctx.out(JSON.stringify({ ok: false, reason: 'declined' }) + '\n');
|
|
251
|
+
else
|
|
252
|
+
ctx.err('trust: declined\n');
|
|
253
|
+
return 1;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
(0, trust_1.markTrusted)(ctx.db, hookId);
|
|
257
|
+
if (ctx.json)
|
|
258
|
+
ctx.out(JSON.stringify({ ok: true, hook_id: hookId, trust_state: 'trusted', enabled: 1 }) + '\n');
|
|
259
|
+
else
|
|
260
|
+
ctx.out(`trusted ${h.name} (${hookId})\n`);
|
|
261
|
+
return 0;
|
|
262
|
+
}
|
|
263
|
+
async function cmdRevoke(ctx) {
|
|
264
|
+
const hookId = ctx.positional[0];
|
|
265
|
+
if (!hookId) {
|
|
266
|
+
ctx.err('revoke: missing <hook_id>\n');
|
|
267
|
+
return 2;
|
|
268
|
+
}
|
|
269
|
+
const h = ctx.db.prepare(`SELECT * FROM hooks WHERE hook_id = ?`).get(hookId);
|
|
270
|
+
if (!h) {
|
|
271
|
+
ctx.err(`revoke: hook not found: ${hookId}\n`);
|
|
272
|
+
return 1;
|
|
273
|
+
}
|
|
274
|
+
if (!ctx.yes) {
|
|
275
|
+
ctx.err(`Hook: ${h.name} (${h.hook_id}) current state: ${h.trust_state}\n`);
|
|
276
|
+
const ok = await ctx.promptYesNo('Revoke this hook? [y/N] ');
|
|
277
|
+
if (!ok) {
|
|
278
|
+
if (ctx.json)
|
|
279
|
+
ctx.out(JSON.stringify({ ok: false, reason: 'declined' }) + '\n');
|
|
280
|
+
else
|
|
281
|
+
ctx.err('revoke: declined\n');
|
|
282
|
+
return 1;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
(0, trust_1.markRevoked)(ctx.db, hookId);
|
|
286
|
+
if (ctx.json)
|
|
287
|
+
ctx.out(JSON.stringify({ ok: true, hook_id: hookId, trust_state: 'revoked', enabled: 0 }) + '\n');
|
|
288
|
+
else
|
|
289
|
+
ctx.out(`revoked ${h.name} (${hookId})\n`);
|
|
290
|
+
return 0;
|
|
291
|
+
}
|
|
292
|
+
async function cmdRescan(ctx) {
|
|
293
|
+
const projectRoot = (0, projectRoot_1.findProjectRoot)(process.cwd());
|
|
294
|
+
const r = await (0, registry_1.scanAndLoadHooks)(ctx.db, { aidenRoot: ctx.paths.root, projectRoot });
|
|
295
|
+
if (ctx.json) {
|
|
296
|
+
ctx.out(JSON.stringify(r, null, 2) + '\n');
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
299
|
+
ctx.out(`scanned: loaded=${r.loaded} errored=${r.errored} drifted=${r.drifted}\n`);
|
|
300
|
+
for (const e of r.errors)
|
|
301
|
+
ctx.out(` ERR ${e.path}: ${e.message}\n`);
|
|
302
|
+
return 0;
|
|
303
|
+
}
|
|
304
|
+
async function cmdTest(ctx) {
|
|
305
|
+
const hookId = ctx.positional[0];
|
|
306
|
+
if (!hookId) {
|
|
307
|
+
ctx.err('test: missing <hook_id>\n');
|
|
308
|
+
return 2;
|
|
309
|
+
}
|
|
310
|
+
const h = ctx.db.prepare(`SELECT * FROM hooks WHERE hook_id = ?`).get(hookId);
|
|
311
|
+
if (!h) {
|
|
312
|
+
ctx.err(`test: hook not found: ${hookId}\n`);
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
// Temporarily ignore enabled/trust_state by flipping to trusted+enabled
|
|
316
|
+
// ONLY in-memory for the test dispatch? Cleaner: dispatch reads its
|
|
317
|
+
// own subs filter; we'll invoke against a synthetic event matching
|
|
318
|
+
// the hook's first subscription. The CLI is opinionated: pick the
|
|
319
|
+
// hook's first subscription as the test target.
|
|
320
|
+
const sub = ctx.db.prepare(`SELECT event FROM hook_subscriptions WHERE hook_id = ? ORDER BY priority DESC LIMIT 1`)
|
|
321
|
+
.get(hookId);
|
|
322
|
+
const event = flagValue(ctx.args, '--event') ?? sub?.event ?? 'tool.call.pre';
|
|
323
|
+
let payload = { tool_name: 'echo', synthetic: true };
|
|
324
|
+
const payloadRaw = flagValue(ctx.args, '--payload');
|
|
325
|
+
if (payloadRaw) {
|
|
326
|
+
try {
|
|
327
|
+
payload = JSON.parse(payloadRaw);
|
|
328
|
+
}
|
|
329
|
+
catch (e) {
|
|
330
|
+
ctx.err(`test: invalid --payload JSON: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
331
|
+
return 2;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
// To test even when untrusted/disabled, briefly flip state in-memory.
|
|
335
|
+
// We use a savepoint to ensure the flip is rolled back after.
|
|
336
|
+
const restoreState = h.trust_state;
|
|
337
|
+
const restoreEnabled = h.enabled;
|
|
338
|
+
ctx.db.prepare(`UPDATE hooks SET trust_state='trusted', enabled=1 WHERE hook_id=?`).run(hookId);
|
|
339
|
+
try {
|
|
340
|
+
const result = await (0, dispatcher_1.dispatchHook)(ctx.db, event, payload, { testMode: true, runId: 'test', traceId: 'test' });
|
|
341
|
+
const fired = result.fired.find((f) => f.hookId === hookId);
|
|
342
|
+
const exec = ctx.db.prepare(`SELECT * FROM hook_executions WHERE hook_id = ? ORDER BY started_at DESC LIMIT 1`).get(hookId);
|
|
343
|
+
if (ctx.json) {
|
|
344
|
+
ctx.out(JSON.stringify({ event, payload, dispatched: result, exec, fired }, null, 2) + '\n');
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
ctx.out(`Test fired ${h.name} on ${event}:\n`);
|
|
348
|
+
ctx.out(` status: ${fired?.status ?? 'n/a'}\n`);
|
|
349
|
+
ctx.out(` decision: ${fired?.decision ?? 'n/a'}\n`);
|
|
350
|
+
ctx.out(` elapsed: ${fired?.elapsedMs ?? 0}ms\n`);
|
|
351
|
+
if (exec?.error_message)
|
|
352
|
+
ctx.out(` error: ${exec.error_message}\n`);
|
|
353
|
+
if (result.decision === 'block')
|
|
354
|
+
ctx.out(` AGGREGATE: block (reason=${result.reason ?? 'n/a'})\n`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
finally {
|
|
358
|
+
ctx.db.prepare(`UPDATE hooks SET trust_state=?, enabled=? WHERE hook_id=?`).run(restoreState, restoreEnabled, hookId);
|
|
359
|
+
}
|
|
360
|
+
return 0;
|
|
361
|
+
}
|
|
362
|
+
async function cmdDoctor(ctx) {
|
|
363
|
+
const fix = ctx.args.includes('--fix');
|
|
364
|
+
const checks = [];
|
|
365
|
+
const hooksDir = node_path_1.default.join(ctx.paths.root, 'hooks');
|
|
366
|
+
// 1. hooks dir exists
|
|
367
|
+
let dirExists = false;
|
|
368
|
+
try {
|
|
369
|
+
await node_fs_1.promises.access(hooksDir);
|
|
370
|
+
dirExists = true;
|
|
371
|
+
}
|
|
372
|
+
catch { /* missing */ }
|
|
373
|
+
if (!dirExists && fix) {
|
|
374
|
+
await node_fs_1.promises.mkdir(hooksDir, { recursive: true });
|
|
375
|
+
dirExists = true;
|
|
376
|
+
}
|
|
377
|
+
checks.push({
|
|
378
|
+
name: 'hooks_dir_exists',
|
|
379
|
+
status: dirExists ? 'ok' : 'warn',
|
|
380
|
+
detail: dirExists ? hooksDir : `missing: ${hooksDir} (run with --fix to create)`,
|
|
381
|
+
fixable: !dirExists,
|
|
382
|
+
});
|
|
383
|
+
// 2. schema v12
|
|
384
|
+
const v = ctx.db.prepare(`SELECT version FROM schema_version`).get();
|
|
385
|
+
checks.push({
|
|
386
|
+
name: 'schema_v12_current',
|
|
387
|
+
status: v && v.version >= 12 ? 'ok' : 'error',
|
|
388
|
+
detail: `db schema version = ${v?.version ?? 0}, latest = ${migrations_1.LATEST_SCHEMA_VERSION}`,
|
|
389
|
+
fixable: false,
|
|
390
|
+
});
|
|
391
|
+
// 3. parseable hooks
|
|
392
|
+
const rows = (0, registry_1.listHooks)(ctx.db);
|
|
393
|
+
const drifted = rows.filter((r) => r.trust_state === 'drifted');
|
|
394
|
+
const untrusted = rows.filter((r) => r.trust_state === 'untrusted');
|
|
395
|
+
const trustedEnabled = rows.filter((r) => r.trust_state === 'trusted' && r.enabled === 1);
|
|
396
|
+
checks.push({
|
|
397
|
+
name: 'drift_count',
|
|
398
|
+
status: drifted.length === 0 ? 'ok' : 'warn',
|
|
399
|
+
detail: `${drifted.length} drifted hook(s) (re-trust to re-enable)`,
|
|
400
|
+
fixable: false,
|
|
401
|
+
});
|
|
402
|
+
checks.push({
|
|
403
|
+
name: 'untrusted_count',
|
|
404
|
+
status: untrusted.length === 0 ? 'ok' : 'warn',
|
|
405
|
+
detail: `${untrusted.length} untrusted hook(s) installed but not yet enabled`,
|
|
406
|
+
fixable: false,
|
|
407
|
+
});
|
|
408
|
+
checks.push({
|
|
409
|
+
name: 'trusted_enabled_count',
|
|
410
|
+
status: 'ok',
|
|
411
|
+
detail: `${trustedEnabled.length} trusted + enabled hook(s)`,
|
|
412
|
+
fixable: false,
|
|
413
|
+
});
|
|
414
|
+
// 4. auto-disabled last 24h — revoked + non-zero recent executions
|
|
415
|
+
const since = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
416
|
+
const recentStatus = (0, auditQuery_1.countByStatus)(ctx.db, since);
|
|
417
|
+
const recentNonOk = (recentStatus.crash ?? 0) + (recentStatus.timeout ?? 0) + (recentStatus.malformed_output ?? 0);
|
|
418
|
+
const recentRevoked = ctx.db.prepare(`SELECT COUNT(*) AS n FROM hooks WHERE trust_state='revoked' AND updated_at >= ?`).get(since);
|
|
419
|
+
checks.push({
|
|
420
|
+
name: 'auto_disabled_24h',
|
|
421
|
+
status: recentRevoked.n === 0 ? 'ok' : 'warn',
|
|
422
|
+
detail: `${recentRevoked.n} hook(s) revoked in last 24h (${recentNonOk} non-ok executions)`,
|
|
423
|
+
fixable: false,
|
|
424
|
+
});
|
|
425
|
+
// 5. high-failure-rate hooks
|
|
426
|
+
const fr = (0, auditQuery_1.failureRates)(ctx.db, 100).filter((f) => f.failureRate > 0.1);
|
|
427
|
+
checks.push({
|
|
428
|
+
name: 'high_failure_rate',
|
|
429
|
+
status: fr.length === 0 ? 'ok' : 'warn',
|
|
430
|
+
detail: fr.length === 0 ? 'no hooks > 10% failure last 100 executions' : `${fr.length} hook(s) > 10% failure: ${fr.map((r) => r.hook_id).join(', ')}`,
|
|
431
|
+
fixable: false,
|
|
432
|
+
});
|
|
433
|
+
if (ctx.json) {
|
|
434
|
+
ctx.out(JSON.stringify({ checks, fix }, null, 2) + '\n');
|
|
435
|
+
return checks.some((c) => c.status === 'error') ? 1 : 0;
|
|
436
|
+
}
|
|
437
|
+
for (const c of checks) {
|
|
438
|
+
const icon = c.status === 'ok' ? '[ok] ' : c.status === 'warn' ? '[warn] ' : '[ERR] ';
|
|
439
|
+
ctx.out(`${icon}${c.name.padEnd(24)} ${c.detail}\n`);
|
|
440
|
+
}
|
|
441
|
+
return checks.some((c) => c.status === 'error') ? 1 : 0;
|
|
442
|
+
}
|
|
443
|
+
async function cmdAudit(ctx) {
|
|
444
|
+
const limitRaw = flagValue(ctx.args, '--limit');
|
|
445
|
+
const q = {
|
|
446
|
+
hookId: flagValue(ctx.args, '--hook'),
|
|
447
|
+
event: flagValue(ctx.args, '--event'),
|
|
448
|
+
status: flagValue(ctx.args, '--status'),
|
|
449
|
+
since: flagValue(ctx.args, '--since'),
|
|
450
|
+
limit: limitRaw ? Number.parseInt(limitRaw, 10) : 50,
|
|
451
|
+
};
|
|
452
|
+
const rows = (0, auditQuery_1.queryHookExecutions)(ctx.db, q);
|
|
453
|
+
if (ctx.json) {
|
|
454
|
+
ctx.out(JSON.stringify(rows, null, 2) + '\n');
|
|
455
|
+
return 0;
|
|
456
|
+
}
|
|
457
|
+
if (rows.length === 0) {
|
|
458
|
+
ctx.out('no executions match\n');
|
|
459
|
+
return 0;
|
|
460
|
+
}
|
|
461
|
+
ctx.out(`${'started_at'.padEnd(26)} ${'hook'.padEnd(18)} ${'event'.padEnd(20)} ${'status'.padEnd(10)} ${'decision'.padEnd(10)} elapsed\n`);
|
|
462
|
+
for (const r of rows) {
|
|
463
|
+
ctx.out(`${r.started_at.padEnd(26)} ${(r.hook_name ?? r.hook_id).slice(0, 18).padEnd(18)} ${r.event.padEnd(20)} ${r.status.padEnd(10)} ${(r.decision ?? '-').padEnd(10)} ${r.elapsed_ms}ms\n`);
|
|
464
|
+
}
|
|
465
|
+
return 0;
|
|
466
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.hooks = exports.HOOKS_SHELL_ONLY = void 0;
|
|
4
|
+
exports.dispatchHooksSlash = dispatchHooksSlash;
|
|
5
|
+
const hooks_1 = require("./hooks");
|
|
6
|
+
/** Actions that need an interactive confirmation prompt. */
|
|
7
|
+
exports.HOOKS_SHELL_ONLY = new Set(['trust', 'revoke']);
|
|
8
|
+
async function dispatchHooksSlash(opts) {
|
|
9
|
+
const a = (opts.action || 'list').toLowerCase();
|
|
10
|
+
if (exports.HOOKS_SHELL_ONLY.has(a)) {
|
|
11
|
+
opts.write(`⚠ /hooks ${a} not available inside chat (needs confirmation prompt)\n`);
|
|
12
|
+
opts.write(' Quit (/quit) and run from shell:\n\n');
|
|
13
|
+
const tail = opts.args.length > 0 ? ' ' + opts.args.join(' ') : '';
|
|
14
|
+
opts.write(` aiden hooks ${a}${tail}\n`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await opts.runHooks(a, opts.args, { writeOut: opts.write, writeErr: opts.write });
|
|
18
|
+
}
|
|
19
|
+
exports.hooks = {
|
|
20
|
+
name: 'hooks',
|
|
21
|
+
description: 'Manage hooks (list / show / rescan / test / doctor / audit).',
|
|
22
|
+
category: 'system',
|
|
23
|
+
icon: '🪝',
|
|
24
|
+
handler: async (ctx) => {
|
|
25
|
+
await dispatchHooksSlash({
|
|
26
|
+
action: ctx.args[0] ?? 'list',
|
|
27
|
+
args: ctx.args.slice(1),
|
|
28
|
+
write: (s) => ctx.display.write(s),
|
|
29
|
+
runHooks: hooks_1.runHooksSubcommand,
|
|
30
|
+
});
|
|
31
|
+
return {};
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* and registers each on the global CommandRegistry at boot.
|
|
13
13
|
*/
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.allCommands = exports.walkthrough = exports.recovery = exports.spawnPause = exports.plannerGuard = exports.suggestions = exports.daemonStatus = exports.browserDepth = exports.tce = exports.sandbox = exports.update = exports.reloadSoul = exports.history = exports.show = exports.status = exports.voice = exports.channel = exports.setup = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
15
|
+
exports.allCommands = exports.hooks = exports.memory = exports.walkthrough = exports.recovery = exports.spawnPause = exports.plannerGuard = exports.suggestions = exports.daemonStatus = exports.browserDepth = exports.tce = exports.sandbox = exports.update = exports.reloadSoul = exports.history = exports.show = exports.status = exports.voice = exports.channel = exports.setup = exports.cron = exports.doctor = exports.license = exports.auth = exports.plugins = exports.streaming = exports.debugPrompt = exports.identity = exports.providers = exports.quit = exports.clear = exports.verbose = exports.reasoning = exports.reloadMcp = exports.skills = exports.theme = exports.skin = exports.yolo = exports.usage = exports.compress = exports.title = exports.save = exports.personality = exports.model = exports.tools = exports.help = void 0;
|
|
16
16
|
const help_1 = require("./help");
|
|
17
17
|
Object.defineProperty(exports, "help", { enumerable: true, get: function () { return help_1.help; } });
|
|
18
18
|
const tools_1 = require("./tools");
|
|
@@ -33,6 +33,9 @@ const yolo_1 = require("./yolo");
|
|
|
33
33
|
Object.defineProperty(exports, "yolo", { enumerable: true, get: function () { return yolo_1.yolo; } });
|
|
34
34
|
const skin_1 = require("./skin");
|
|
35
35
|
Object.defineProperty(exports, "skin", { enumerable: true, get: function () { return skin_1.skin; } });
|
|
36
|
+
// v4.9.0 Slice 1a — unified theme system.
|
|
37
|
+
const theme_1 = require("./theme");
|
|
38
|
+
Object.defineProperty(exports, "theme", { enumerable: true, get: function () { return theme_1.theme; } });
|
|
36
39
|
const skills_1 = require("./skills");
|
|
37
40
|
Object.defineProperty(exports, "skills", { enumerable: true, get: function () { return skills_1.skills; } });
|
|
38
41
|
const reloadMcp_1 = require("./reloadMcp");
|
|
@@ -103,6 +106,11 @@ Object.defineProperty(exports, "recovery", { enumerable: true, get: function ()
|
|
|
103
106
|
// ONB1 slice 10 — new-user guided tour.
|
|
104
107
|
const walkthrough_1 = require("./walkthrough");
|
|
105
108
|
Object.defineProperty(exports, "walkthrough", { enumerable: true, get: function () { return walkthrough_1.walkthrough; } });
|
|
109
|
+
// v4.9.1 amendment — REPL slash surfaces for memory + hooks (mirrors CLI).
|
|
110
|
+
const memorySlash_1 = require("./memorySlash");
|
|
111
|
+
Object.defineProperty(exports, "memory", { enumerable: true, get: function () { return memorySlash_1.memory; } });
|
|
112
|
+
const hooksSlash_1 = require("./hooksSlash");
|
|
113
|
+
Object.defineProperty(exports, "hooks", { enumerable: true, get: function () { return hooksSlash_1.hooks; } });
|
|
106
114
|
/** All built-in system commands, in canonical order. */
|
|
107
115
|
exports.allCommands = [
|
|
108
116
|
help_1.help,
|
|
@@ -119,6 +127,7 @@ exports.allCommands = [
|
|
|
119
127
|
usage_1.usage,
|
|
120
128
|
yolo_1.yolo,
|
|
121
129
|
skin_1.skin,
|
|
130
|
+
theme_1.theme,
|
|
122
131
|
skills_1.skills,
|
|
123
132
|
plugins_1.plugins,
|
|
124
133
|
auth_1.auth,
|
|
@@ -154,6 +163,9 @@ exports.allCommands = [
|
|
|
154
163
|
recovery_1.recovery,
|
|
155
164
|
// ONB1 slice 10 — new-user guided tour.
|
|
156
165
|
walkthrough_1.walkthrough,
|
|
166
|
+
// v4.9.1 amendment — REPL slash surfaces mirroring CLI subcommands.
|
|
167
|
+
memorySlash_1.memory,
|
|
168
|
+
hooksSlash_1.hooks,
|
|
157
169
|
clear_1.clear,
|
|
158
170
|
quit_1.quit,
|
|
159
171
|
];
|