@ouro.bot/cli 0.1.0-alpha.302 → 0.1.0-alpha.303
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.json
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
|
|
3
3
|
"versions": [
|
|
4
|
+
{
|
|
5
|
+
"version": "0.1.0-alpha.303",
|
|
6
|
+
"changes": [
|
|
7
|
+
"feat(cli): overhaul CLI help and error handling. `ouro --help` now shows commands grouped into 9 categories (Lifecycle, Agents, Chat, Tasks, Habits, Friends, Auth, Internal, System) instead of a flat wall of text. `ouro help <command>` and `ouro <command> --help` show per-command help with description, usage syntax, subcommands, and an example. Unknown commands get Levenshtein-based typo suggestions when distance <= 2 (e.g., `ouro stauts` -> `Did you mean 'status'?`). `ouro up` now prints progress messages: 'Checking for updates...' -> 'Installing <version>...' or 'Up to date.' -> 'Starting daemon...'. New command metadata registry in `src/heart/daemon/cli-help.ts` covers 32 commands. 50+ new tests at 100% coverage on all new code."
|
|
8
|
+
]
|
|
9
|
+
},
|
|
4
10
|
{
|
|
5
11
|
"version": "0.1.0-alpha.302",
|
|
6
12
|
"changes": [
|
|
@@ -66,6 +66,7 @@ const auth_flow_1 = require("../auth/auth-flow");
|
|
|
66
66
|
const ouro_version_manager_1 = require("../versioning/ouro-version-manager");
|
|
67
67
|
const cli_parse_1 = require("./cli-parse");
|
|
68
68
|
const cli_parse_2 = require("./cli-parse");
|
|
69
|
+
const cli_help_1 = require("./cli-help");
|
|
69
70
|
const cli_render_1 = require("./cli-render");
|
|
70
71
|
const cli_defaults_1 = require("./cli-defaults");
|
|
71
72
|
const doctor_1 = require("./doctor");
|
|
@@ -647,7 +648,7 @@ function resolveClonePath(options, checkExists, deps) {
|
|
|
647
648
|
// ── Main CLI execution ──
|
|
648
649
|
async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDeps)()) {
|
|
649
650
|
if (args.length === 1 && (args[0] === "--help" || args[0] === "-h")) {
|
|
650
|
-
const text = (0,
|
|
651
|
+
const text = (0, cli_help_1.getGroupedHelp)();
|
|
651
652
|
deps.writeStdout(text);
|
|
652
653
|
return text;
|
|
653
654
|
}
|
|
@@ -725,6 +726,13 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
725
726
|
message: "ouro CLI command invoked",
|
|
726
727
|
meta: { kind: command.kind },
|
|
727
728
|
});
|
|
729
|
+
if (command.kind === "help") {
|
|
730
|
+
const text = command.command
|
|
731
|
+
? ((0, cli_help_1.getCommandHelp)(command.command) ?? `Unknown command: ${command.command}\n\n${(0, cli_help_1.getGroupedHelp)()}`)
|
|
732
|
+
: (0, cli_help_1.getGroupedHelp)();
|
|
733
|
+
deps.writeStdout(text);
|
|
734
|
+
return text;
|
|
735
|
+
}
|
|
728
736
|
if (command.kind === "bluebubbles.replay") {
|
|
729
737
|
const { replayBlueBubblesMessage, formatBlueBubblesReplayText } = await Promise.resolve().then(() => __importStar(require("../../senses/bluebubbles/replay")));
|
|
730
738
|
const replay = await replayBlueBubblesMessage({
|
|
@@ -773,10 +781,12 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
773
781
|
const linkedVersionBeforeUp = deps.getCurrentCliVersion?.() ?? null;
|
|
774
782
|
// ── versioned CLI update check ──
|
|
775
783
|
if (deps.checkForCliUpdate) {
|
|
784
|
+
deps.writeStdout("checking for updates...");
|
|
776
785
|
let pendingReExec = false;
|
|
777
786
|
try {
|
|
778
787
|
const updateResult = await deps.checkForCliUpdate();
|
|
779
788
|
if (updateResult.available && updateResult.latestVersion) {
|
|
789
|
+
deps.writeStdout(`installing ${updateResult.latestVersion}...`);
|
|
780
790
|
/* v8 ignore next -- fallback: getCurrentCliVersion always injected in tests @preserve */
|
|
781
791
|
const currentVersion = linkedVersionBeforeUp ?? "unknown";
|
|
782
792
|
await deps.installCliVersion(updateResult.latestVersion);
|
|
@@ -804,6 +814,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
804
814
|
if (pendingReExec) {
|
|
805
815
|
deps.reExecFromNewVersion(args);
|
|
806
816
|
}
|
|
817
|
+
else {
|
|
818
|
+
deps.writeStdout("up to date.");
|
|
819
|
+
}
|
|
807
820
|
}
|
|
808
821
|
await performSystemSetup(deps);
|
|
809
822
|
// Track whether we've already printed the "ouro updated to" message
|
|
@@ -873,6 +886,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
873
886
|
const count = agents.length;
|
|
874
887
|
deps.writeStdout(`updated ${count} agent${count === 1 ? "" : "s"} to runtime ${to}${fromStr}`);
|
|
875
888
|
}
|
|
889
|
+
deps.writeStdout("starting daemon...");
|
|
876
890
|
const daemonResult = await ensureDaemonRunning(deps);
|
|
877
891
|
deps.writeStdout(daemonResult.message);
|
|
878
892
|
// Persist boot startup AFTER daemon is running — bootstrap is safe now
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* CLI help system — command registry, grouped help output, and per-command help.
|
|
4
|
+
*
|
|
5
|
+
* Pure data + formatting: no side effects, no daemon communication.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.COMMAND_REGISTRY = void 0;
|
|
9
|
+
exports.levenshteinDistance = levenshteinDistance;
|
|
10
|
+
exports.suggestCommand = suggestCommand;
|
|
11
|
+
exports.getGroupedHelp = getGroupedHelp;
|
|
12
|
+
exports.getCommandHelp = getCommandHelp;
|
|
13
|
+
// ── Registry ──
|
|
14
|
+
exports.COMMAND_REGISTRY = {
|
|
15
|
+
up: {
|
|
16
|
+
category: "Lifecycle",
|
|
17
|
+
description: "Start the ouro daemon (default command)",
|
|
18
|
+
usage: "ouro [up]",
|
|
19
|
+
example: "ouro up",
|
|
20
|
+
},
|
|
21
|
+
stop: {
|
|
22
|
+
category: "Lifecycle",
|
|
23
|
+
description: "Stop the running daemon",
|
|
24
|
+
usage: "ouro stop",
|
|
25
|
+
example: "ouro stop",
|
|
26
|
+
},
|
|
27
|
+
down: {
|
|
28
|
+
category: "Lifecycle",
|
|
29
|
+
description: "Stop the running daemon (alias for stop)",
|
|
30
|
+
usage: "ouro down",
|
|
31
|
+
example: "ouro down",
|
|
32
|
+
},
|
|
33
|
+
status: {
|
|
34
|
+
category: "Lifecycle",
|
|
35
|
+
description: "Show daemon status",
|
|
36
|
+
usage: "ouro status",
|
|
37
|
+
example: "ouro status",
|
|
38
|
+
},
|
|
39
|
+
logs: {
|
|
40
|
+
category: "Lifecycle",
|
|
41
|
+
description: "View or prune daemon logs",
|
|
42
|
+
usage: "ouro logs [prune]",
|
|
43
|
+
example: "ouro logs",
|
|
44
|
+
subcommands: ["prune"],
|
|
45
|
+
},
|
|
46
|
+
dev: {
|
|
47
|
+
category: "Lifecycle",
|
|
48
|
+
description: "Start daemon in development mode from a local repo",
|
|
49
|
+
usage: "ouro dev [--repo-path <path>] [--clone [--clone-path <path>]]",
|
|
50
|
+
example: "ouro dev --repo-path ~/code/ouroboros",
|
|
51
|
+
},
|
|
52
|
+
hatch: {
|
|
53
|
+
category: "Lifecycle",
|
|
54
|
+
description: "Create a new agent",
|
|
55
|
+
usage: "ouro hatch [--agent <name>] [--human <name>] [--provider <provider>]",
|
|
56
|
+
example: "ouro hatch --agent Sprout --human Ari --provider anthropic",
|
|
57
|
+
},
|
|
58
|
+
rollback: {
|
|
59
|
+
category: "Lifecycle",
|
|
60
|
+
description: "Roll back to a previous CLI version",
|
|
61
|
+
usage: "ouro rollback [<version>]",
|
|
62
|
+
example: "ouro rollback 0.1.0-alpha.250",
|
|
63
|
+
},
|
|
64
|
+
versions: {
|
|
65
|
+
category: "Lifecycle",
|
|
66
|
+
description: "List installed CLI versions",
|
|
67
|
+
usage: "ouro versions",
|
|
68
|
+
example: "ouro versions",
|
|
69
|
+
},
|
|
70
|
+
doctor: {
|
|
71
|
+
category: "Lifecycle",
|
|
72
|
+
description: "Run diagnostic checks on the ouro installation",
|
|
73
|
+
usage: "ouro doctor",
|
|
74
|
+
example: "ouro doctor",
|
|
75
|
+
},
|
|
76
|
+
outlook: {
|
|
77
|
+
category: "Agents",
|
|
78
|
+
description: "Show the agent's current outlook",
|
|
79
|
+
usage: "ouro outlook [--json]",
|
|
80
|
+
example: "ouro outlook --json",
|
|
81
|
+
},
|
|
82
|
+
whoami: {
|
|
83
|
+
category: "Agents",
|
|
84
|
+
description: "Show current agent identity info",
|
|
85
|
+
usage: "ouro whoami [--agent <name>]",
|
|
86
|
+
example: "ouro whoami",
|
|
87
|
+
},
|
|
88
|
+
config: {
|
|
89
|
+
category: "Agents",
|
|
90
|
+
description: "View or change agent configuration",
|
|
91
|
+
usage: "ouro config <subcommand> --agent <name>",
|
|
92
|
+
example: "ouro config models --agent ouroboros",
|
|
93
|
+
subcommands: ["model", "models"],
|
|
94
|
+
},
|
|
95
|
+
changelog: {
|
|
96
|
+
category: "Agents",
|
|
97
|
+
description: "View the agent changelog",
|
|
98
|
+
usage: "ouro changelog [--from <version>] [--agent <name>]",
|
|
99
|
+
example: "ouro changelog --from 0.1.0-alpha.250",
|
|
100
|
+
},
|
|
101
|
+
chat: {
|
|
102
|
+
category: "Chat",
|
|
103
|
+
description: "Open an interactive chat session with an agent",
|
|
104
|
+
usage: "ouro chat <agent>",
|
|
105
|
+
example: "ouro chat ouroboros",
|
|
106
|
+
},
|
|
107
|
+
msg: {
|
|
108
|
+
category: "Chat",
|
|
109
|
+
description: "Send a single message to an agent",
|
|
110
|
+
usage: "ouro msg --to <agent> [--session <id>] [--task <ref>] <message>",
|
|
111
|
+
example: "ouro msg --to ouroboros hello there",
|
|
112
|
+
},
|
|
113
|
+
task: {
|
|
114
|
+
category: "Tasks",
|
|
115
|
+
description: "Manage agent tasks",
|
|
116
|
+
usage: "ouro task <subcommand> [--agent <name>]",
|
|
117
|
+
example: "ouro task board",
|
|
118
|
+
subcommands: ["board", "create", "update", "show", "actionable", "deps", "sessions", "fix"],
|
|
119
|
+
},
|
|
120
|
+
poke: {
|
|
121
|
+
category: "Tasks",
|
|
122
|
+
description: "Poke an agent about a task or habit",
|
|
123
|
+
usage: "ouro poke <agent> --task <task-id> | --habit <name>",
|
|
124
|
+
example: "ouro poke ouroboros --task abc123",
|
|
125
|
+
},
|
|
126
|
+
reminder: {
|
|
127
|
+
category: "Tasks",
|
|
128
|
+
description: "Create reminders for an agent",
|
|
129
|
+
usage: "ouro reminder create <title> --body <body> [--at <iso>] [--cadence <interval>]",
|
|
130
|
+
example: "ouro reminder create standup --body 'daily standup' --cadence '1d'",
|
|
131
|
+
subcommands: ["create"],
|
|
132
|
+
},
|
|
133
|
+
habit: {
|
|
134
|
+
category: "Habits",
|
|
135
|
+
description: "Manage agent habits",
|
|
136
|
+
usage: "ouro habit <subcommand> [--agent <name>]",
|
|
137
|
+
example: "ouro habit list",
|
|
138
|
+
subcommands: ["list", "create", "poke"],
|
|
139
|
+
},
|
|
140
|
+
friend: {
|
|
141
|
+
category: "Friends",
|
|
142
|
+
description: "Manage agent friends and identity links",
|
|
143
|
+
usage: "ouro friend <subcommand> [--agent <name>]",
|
|
144
|
+
example: "ouro friend list",
|
|
145
|
+
subcommands: ["list", "show", "create", "update", "link", "unlink"],
|
|
146
|
+
},
|
|
147
|
+
link: {
|
|
148
|
+
category: "Friends",
|
|
149
|
+
description: "Link an external identity to an agent friend",
|
|
150
|
+
usage: "ouro link <agent> --friend <id> --provider <provider> --external-id <eid>",
|
|
151
|
+
example: "ouro link ouroboros --friend f1 --provider aad --external-id user@example.com",
|
|
152
|
+
},
|
|
153
|
+
auth: {
|
|
154
|
+
category: "Auth",
|
|
155
|
+
description: "Set up, verify, or switch agent credentials",
|
|
156
|
+
usage: "ouro auth [verify|switch] --agent <name> [--provider <provider>]",
|
|
157
|
+
example: "ouro auth --agent ouroboros",
|
|
158
|
+
subcommands: ["verify", "switch"],
|
|
159
|
+
},
|
|
160
|
+
thoughts: {
|
|
161
|
+
category: "Internal",
|
|
162
|
+
description: "View agent inner dialog thoughts",
|
|
163
|
+
usage: "ouro thoughts [--last <n>] [--json] [--follow] [--agent <name>]",
|
|
164
|
+
example: "ouro thoughts --last 5 --follow",
|
|
165
|
+
},
|
|
166
|
+
inner: {
|
|
167
|
+
category: "Internal",
|
|
168
|
+
description: "Show inner dialog status",
|
|
169
|
+
usage: "ouro inner [--agent <name>]",
|
|
170
|
+
example: "ouro inner",
|
|
171
|
+
},
|
|
172
|
+
attention: {
|
|
173
|
+
category: "Internal",
|
|
174
|
+
description: "View agent attention items",
|
|
175
|
+
usage: "ouro attention [show <id>|history] [--agent <name>]",
|
|
176
|
+
example: "ouro attention history",
|
|
177
|
+
subcommands: ["show", "history"],
|
|
178
|
+
},
|
|
179
|
+
session: {
|
|
180
|
+
category: "Internal",
|
|
181
|
+
description: "Manage agent sessions",
|
|
182
|
+
usage: "ouro session list [--agent <name>]",
|
|
183
|
+
example: "ouro session list",
|
|
184
|
+
subcommands: ["list"],
|
|
185
|
+
},
|
|
186
|
+
mcp: {
|
|
187
|
+
category: "System",
|
|
188
|
+
description: "Interact with MCP servers",
|
|
189
|
+
usage: "ouro mcp <subcommand>",
|
|
190
|
+
example: "ouro mcp list",
|
|
191
|
+
subcommands: ["list", "call"],
|
|
192
|
+
},
|
|
193
|
+
"mcp-serve": {
|
|
194
|
+
category: "System",
|
|
195
|
+
description: "Start an MCP server for dev tool integration",
|
|
196
|
+
usage: "ouro mcp-serve --agent <name> [--friend <id>]",
|
|
197
|
+
example: "ouro mcp-serve --agent ouroboros",
|
|
198
|
+
},
|
|
199
|
+
setup: {
|
|
200
|
+
category: "System",
|
|
201
|
+
description: "Register MCP server and hooks for a dev tool",
|
|
202
|
+
usage: "ouro setup --tool <claude-code|codex> --agent <name>",
|
|
203
|
+
example: "ouro setup --tool claude-code --agent ouroboros",
|
|
204
|
+
},
|
|
205
|
+
hook: {
|
|
206
|
+
category: "System",
|
|
207
|
+
description: "Fire a dev tool lifecycle hook",
|
|
208
|
+
usage: "ouro hook <event> --agent <name>",
|
|
209
|
+
example: "ouro hook session-start --agent ouroboros",
|
|
210
|
+
},
|
|
211
|
+
bluebubbles: {
|
|
212
|
+
category: "System",
|
|
213
|
+
description: "BlueBubbles integration commands",
|
|
214
|
+
usage: "ouro bluebubbles replay --agent <name> --message-guid <guid> [--event-type <type>] [--json]",
|
|
215
|
+
example: "ouro bluebubbles replay --agent ouroboros --message-guid abc123",
|
|
216
|
+
subcommands: ["replay"],
|
|
217
|
+
},
|
|
218
|
+
};
|
|
219
|
+
// ── Levenshtein distance ──
|
|
220
|
+
function levenshteinDistance(a, b) {
|
|
221
|
+
if (a.length === 0)
|
|
222
|
+
return b.length;
|
|
223
|
+
if (b.length === 0)
|
|
224
|
+
return a.length;
|
|
225
|
+
const matrix = [];
|
|
226
|
+
for (let i = 0; i <= a.length; i++) {
|
|
227
|
+
matrix[i] = [i];
|
|
228
|
+
}
|
|
229
|
+
for (let j = 0; j <= b.length; j++) {
|
|
230
|
+
matrix[0][j] = j;
|
|
231
|
+
}
|
|
232
|
+
for (let i = 1; i <= a.length; i++) {
|
|
233
|
+
for (let j = 1; j <= b.length; j++) {
|
|
234
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
235
|
+
matrix[i][j] = Math.min(matrix[i - 1][j] + 1, // deletion
|
|
236
|
+
matrix[i][j - 1] + 1, // insertion
|
|
237
|
+
matrix[i - 1][j - 1] + cost);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return matrix[a.length][b.length];
|
|
241
|
+
}
|
|
242
|
+
// ── Command suggestion ──
|
|
243
|
+
function suggestCommand(input) {
|
|
244
|
+
if (!input)
|
|
245
|
+
return null;
|
|
246
|
+
let bestMatch = null;
|
|
247
|
+
let bestDistance = Infinity;
|
|
248
|
+
for (const name of Object.keys(exports.COMMAND_REGISTRY)) {
|
|
249
|
+
const distance = levenshteinDistance(input, name);
|
|
250
|
+
if (distance < bestDistance) {
|
|
251
|
+
bestDistance = distance;
|
|
252
|
+
bestMatch = name;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return bestDistance <= 2 ? bestMatch : null;
|
|
256
|
+
}
|
|
257
|
+
// ── Category display order ──
|
|
258
|
+
const CATEGORY_ORDER = [
|
|
259
|
+
"Lifecycle",
|
|
260
|
+
"Agents",
|
|
261
|
+
"Chat",
|
|
262
|
+
"Tasks",
|
|
263
|
+
"Habits",
|
|
264
|
+
"Friends",
|
|
265
|
+
"Auth",
|
|
266
|
+
"Internal",
|
|
267
|
+
"System",
|
|
268
|
+
];
|
|
269
|
+
// ── Grouped help output ──
|
|
270
|
+
function getGroupedHelp() {
|
|
271
|
+
const lines = ["Usage: ouro <command> [options]", ""];
|
|
272
|
+
for (const category of CATEGORY_ORDER) {
|
|
273
|
+
lines.push(` ${category}:`);
|
|
274
|
+
for (const [name, entry] of Object.entries(exports.COMMAND_REGISTRY)) {
|
|
275
|
+
if (entry.category === category) {
|
|
276
|
+
lines.push(` ${name.padEnd(16)} ${entry.description}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
lines.push("");
|
|
280
|
+
}
|
|
281
|
+
lines.push("Run 'ouro help <command>' for details on a specific command.");
|
|
282
|
+
return lines.join("\n");
|
|
283
|
+
}
|
|
284
|
+
// ── Per-command help ──
|
|
285
|
+
function getCommandHelp(name) {
|
|
286
|
+
const entry = exports.COMMAND_REGISTRY[name];
|
|
287
|
+
if (!entry)
|
|
288
|
+
return null;
|
|
289
|
+
const lines = [
|
|
290
|
+
`${name} - ${entry.description}`,
|
|
291
|
+
"",
|
|
292
|
+
`Usage: ${entry.usage}`,
|
|
293
|
+
];
|
|
294
|
+
if (entry.subcommands && entry.subcommands.length > 0) {
|
|
295
|
+
lines.push("");
|
|
296
|
+
lines.push("Subcommands:");
|
|
297
|
+
for (const sub of entry.subcommands) {
|
|
298
|
+
lines.push(` ${sub}`);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (entry.example) {
|
|
302
|
+
lines.push("");
|
|
303
|
+
lines.push(`Example: ${entry.example}`);
|
|
304
|
+
}
|
|
305
|
+
return lines.join("\n");
|
|
306
|
+
}
|
|
@@ -13,6 +13,7 @@ exports.usage = usage;
|
|
|
13
13
|
exports.parseMcpServeCommand = parseMcpServeCommand;
|
|
14
14
|
exports.parseOuroCommand = parseOuroCommand;
|
|
15
15
|
const types_1 = require("../../mind/friends/types");
|
|
16
|
+
const cli_help_1 = require("./cli-help");
|
|
16
17
|
// ── Shared helpers ──
|
|
17
18
|
function extractAgentFlag(args) {
|
|
18
19
|
const idx = args.indexOf("--agent");
|
|
@@ -686,6 +687,14 @@ function parseOuroCommand(args) {
|
|
|
686
687
|
const [head, second] = args;
|
|
687
688
|
if (!head)
|
|
688
689
|
return { kind: "daemon.up" };
|
|
690
|
+
// ── help command ──
|
|
691
|
+
if (head === "help") {
|
|
692
|
+
return second ? { kind: "help", command: second } : { kind: "help" };
|
|
693
|
+
}
|
|
694
|
+
// ── per-command --help ──
|
|
695
|
+
if (args.includes("--help")) {
|
|
696
|
+
return { kind: "help", command: head };
|
|
697
|
+
}
|
|
689
698
|
if (head === "--agent" && second) {
|
|
690
699
|
return parseOuroCommand(args.slice(2));
|
|
691
700
|
}
|
|
@@ -807,5 +816,7 @@ function parseOuroCommand(args) {
|
|
|
807
816
|
return { kind: "doctor" };
|
|
808
817
|
if (head === "bluebubbles")
|
|
809
818
|
return parseBlueBubblesCommand(args.slice(1));
|
|
810
|
-
|
|
819
|
+
const suggestion = (0, cli_help_1.suggestCommand)(head);
|
|
820
|
+
const hint = suggestion ? ` Did you mean '${suggestion}'?` : "";
|
|
821
|
+
throw new Error(`Unknown command '${args.join(" ")}'.${hint}\n${usage()}`);
|
|
811
822
|
}
|
|
@@ -59,9 +59,10 @@ const DISPATCH_EXEMPT_PATTERNS = [
|
|
|
59
59
|
"repertoire/tools-config",
|
|
60
60
|
"repertoire/tools-base",
|
|
61
61
|
// CLI sub-modules: cli-exec.ts is the router with emitNervesEvent calls;
|
|
62
|
-
// cli-parse and cli-
|
|
62
|
+
// cli-parse, cli-render, and cli-help are pure functions/data with no side effects.
|
|
63
63
|
"daemon/cli-parse",
|
|
64
64
|
"daemon/cli-render",
|
|
65
|
+
"daemon/cli-help",
|
|
65
66
|
// Shared utility modules: pure helpers consumed by modules that own observability.
|
|
66
67
|
"arc/json-store",
|
|
67
68
|
"repertoire/api-client",
|