@namzu/cli 25.0.1 → 26.0.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +265 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +9 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/acp.d.ts.map +1 -1
  6. package/dist/commands/acp.js +5 -0
  7. package/dist/commands/acp.js.map +1 -1
  8. package/dist/commands/drain.d.ts.map +1 -1
  9. package/dist/commands/drain.js +5 -0
  10. package/dist/commands/drain.js.map +1 -1
  11. package/dist/commands/run-stream.d.ts.map +1 -1
  12. package/dist/commands/run-stream.js +5 -0
  13. package/dist/commands/run-stream.js.map +1 -1
  14. package/dist/commands/run.d.ts.map +1 -1
  15. package/dist/commands/run.js +5 -0
  16. package/dist/commands/run.js.map +1 -1
  17. package/dist/config/load.d.ts.map +1 -1
  18. package/dist/config/load.js +47 -0
  19. package/dist/config/load.js.map +1 -1
  20. package/dist/config/schema.d.ts +24 -0
  21. package/dist/config/schema.d.ts.map +1 -1
  22. package/dist/config/schema.js.map +1 -1
  23. package/dist/config/tool-result-screens.d.ts +103 -0
  24. package/dist/config/tool-result-screens.d.ts.map +1 -0
  25. package/dist/config/tool-result-screens.js +104 -0
  26. package/dist/config/tool-result-screens.js.map +1 -0
  27. package/dist/context/doctrine.d.ts +4 -2
  28. package/dist/context/doctrine.d.ts.map +1 -1
  29. package/dist/context/doctrine.js +4 -2
  30. package/dist/context/doctrine.js.map +1 -1
  31. package/dist/integrations/mcp/servers.d.ts +30 -0
  32. package/dist/integrations/mcp/servers.d.ts.map +1 -1
  33. package/dist/integrations/mcp/servers.js +32 -1
  34. package/dist/integrations/mcp/servers.js.map +1 -1
  35. package/dist/integrations/resident/session-step.d.ts.map +1 -1
  36. package/dist/integrations/resident/session-step.js +5 -0
  37. package/dist/integrations/resident/session-step.js.map +1 -1
  38. package/dist/integrations/subagents/activity.d.ts +285 -11
  39. package/dist/integrations/subagents/activity.d.ts.map +1 -1
  40. package/dist/integrations/subagents/activity.js +334 -31
  41. package/dist/integrations/subagents/activity.js.map +1 -1
  42. package/dist/integrations/subagents/replay.d.ts +46 -0
  43. package/dist/integrations/subagents/replay.d.ts.map +1 -0
  44. package/dist/integrations/subagents/replay.js +193 -0
  45. package/dist/integrations/subagents/replay.js.map +1 -0
  46. package/dist/integrations/subagents/runs.d.ts +72 -0
  47. package/dist/integrations/subagents/runs.d.ts.map +1 -0
  48. package/dist/integrations/subagents/runs.js +155 -0
  49. package/dist/integrations/subagents/runs.js.map +1 -0
  50. package/dist/integrations/subagents/runtime.d.ts +21 -0
  51. package/dist/integrations/subagents/runtime.d.ts.map +1 -1
  52. package/dist/integrations/subagents/runtime.js +134 -2
  53. package/dist/integrations/subagents/runtime.js.map +1 -1
  54. package/dist/tui/AgentExplorer.d.ts +46 -2
  55. package/dist/tui/AgentExplorer.d.ts.map +1 -1
  56. package/dist/tui/AgentExplorer.js +261 -22
  57. package/dist/tui/AgentExplorer.js.map +1 -1
  58. package/dist/tui/App.d.ts.map +1 -1
  59. package/dist/tui/App.js +456 -28
  60. package/dist/tui/App.js.map +1 -1
  61. package/dist/tui/ChoicePicker.d.ts +2 -0
  62. package/dist/tui/ChoicePicker.d.ts.map +1 -1
  63. package/dist/tui/ChoicePicker.js +3 -1
  64. package/dist/tui/ChoicePicker.js.map +1 -1
  65. package/dist/tui/Composer.d.ts +10 -7
  66. package/dist/tui/Composer.d.ts.map +1 -1
  67. package/dist/tui/Composer.js +2 -7
  68. package/dist/tui/Composer.js.map +1 -1
  69. package/dist/tui/StatusBar.d.ts +56 -10
  70. package/dist/tui/StatusBar.d.ts.map +1 -1
  71. package/dist/tui/StatusBar.js +106 -35
  72. package/dist/tui/StatusBar.js.map +1 -1
  73. package/dist/tui/agent.d.ts +46 -1
  74. package/dist/tui/agent.d.ts.map +1 -1
  75. package/dist/tui/agent.js +55 -5
  76. package/dist/tui/agent.js.map +1 -1
  77. package/dist/tui/choice-selection.d.ts +3 -1
  78. package/dist/tui/choice-selection.d.ts.map +1 -1
  79. package/dist/tui/choice-selection.js +2 -2
  80. package/dist/tui/choice-selection.js.map +1 -1
  81. package/dist/tui/permission-review.d.ts.map +1 -1
  82. package/dist/tui/permission-review.js +14 -2
  83. package/dist/tui/permission-review.js.map +1 -1
  84. package/dist/tui/slashCommands.d.ts +40 -0
  85. package/dist/tui/slashCommands.d.ts.map +1 -1
  86. package/dist/tui/slashCommands.js +62 -3
  87. package/dist/tui/slashCommands.js.map +1 -1
  88. package/dist/tui/types.d.ts +12 -0
  89. package/dist/tui/types.d.ts.map +1 -1
  90. package/package.json +3 -3
@@ -0,0 +1,193 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { RunDiskStore, readRunEventsIn, } from '@namzu/sdk';
4
+ import { SubagentActivityMonitor, } from './activity.js';
5
+ /**
6
+ * Session directories scanned when looking for a conversation's saved
7
+ * children.
8
+ *
9
+ * Each delegated child is given its OWN session directory, so the children of
10
+ * one parent run are spread across as many of them as the parent launched
11
+ * children. A long-lived project accumulates those, and a scan with no
12
+ * ceiling would grow with the whole estate rather than with the conversation
13
+ * being opened. The scan is one `readdir` per directory and stops here.
14
+ *
15
+ * It is a bound, not a policy. Entries come back in the order the filesystem
16
+ * lists them, so past this many directories WHICH children are found stops
17
+ * being predictable — which is an argument for a prune command, not a
18
+ * substitute for one.
19
+ */
20
+ const MAX_SCANNED_SESSION_DIRECTORIES = 2_000;
21
+ /**
22
+ * Children replayed into one monitor, matching the live monitor's own
23
+ * retention. Replay walks the newest first and stops at this many, so a
24
+ * conversation that delegated thousands of times opens its most recent work
25
+ * instead of its whole history.
26
+ */
27
+ const MAX_REPLAYED_CHILDREN = 80;
28
+ /**
29
+ * Every delegated child saved under one conversation's parent runs, newest
30
+ * first.
31
+ *
32
+ * Two directory shapes have to meet here. A conversation's own runs are
33
+ * `<sessionsRoot>/<sessionId>/runs/<runId>`, which is where the parent run
34
+ * ids come from after a restart has forgotten them. A child's evidence is
35
+ * `<sessionsRoot>/<childSessionId>/runs/<parentRunId>/children/<childRunId>`,
36
+ * under the child's session and not the parent's — so finding a child means
37
+ * asking every session directory whether it holds a `runs/` entry named after
38
+ * one of this conversation's runs.
39
+ *
40
+ * That ordering is deliberate: one `readdir` per session directory answers
41
+ * the question for all of that directory's children at once, where probing
42
+ * each parent run inside each session directory would multiply the two
43
+ * counts. A child session directory holds exactly one parent run id, so the
44
+ * inner listing runs only where there is something to list.
45
+ *
46
+ * READ-ONLY throughout. Nothing here creates a directory, and in particular
47
+ * nothing binds a `RunDiskStore`, which would mint the run directory it was
48
+ * asked about.
49
+ */
50
+ export async function listSavedChildren(scope) {
51
+ const parentRunIds = new Set(await directoryNames(join(scope.sessionsRoot, scope.sessionId, 'runs')));
52
+ if (parentRunIds.size === 0)
53
+ return [];
54
+ const sessionIds = await directoryNames(scope.sessionsRoot);
55
+ const found = [];
56
+ for (const sessionId of sessionIds.slice(0, MAX_SCANNED_SESSION_DIRECTORIES)) {
57
+ const runsDir = join(scope.sessionsRoot, sessionId, 'runs');
58
+ for (const runId of await directoryNames(runsDir)) {
59
+ if (!parentRunIds.has(runId))
60
+ continue;
61
+ try {
62
+ found.push(...(await RunDiskStore.listChildren(runsDir, runId)));
63
+ }
64
+ catch (error) {
65
+ // One unreadable parent directory is not a reason to report that a
66
+ // conversation delegated nothing. Named so the operator can find it.
67
+ scope.log?.warn('Saved delegated children could not be listed', {
68
+ 'namzu.subagent.replay.runs_dir': runsDir,
69
+ 'namzu.subagent.replay.parent_run_id': runId,
70
+ 'namzu.subagent.replay.error': errorMessage(error),
71
+ });
72
+ }
73
+ }
74
+ }
75
+ // Newest first so the cap keeps the most recent work, then back into launch
76
+ // order, which is the order the cockpit lists a cohort in.
77
+ found.sort((left, right) => (right.startedAt ?? 0) - (left.startedAt ?? 0));
78
+ return found.slice(0, scope.maxChildren ?? MAX_REPLAYED_CHILDREN).reverse();
79
+ }
80
+ /**
81
+ * Replays saved children into the display shape the live monitor publishes.
82
+ *
83
+ * One monitor for the whole batch, in replay mode: its bounds, its grouping
84
+ * and its projection are the live ones, and its rows carry
85
+ * {@link SubagentActivity.replayed} so no surface offers to act on work that
86
+ * finished in another process.
87
+ */
88
+ export async function replaySavedChildren(children, log) {
89
+ const monitor = new SubagentActivityMonitor({ replay: true });
90
+ for (const child of children) {
91
+ const evidence = await readChildEvidence(child, log);
92
+ monitor.replay({
93
+ agentId: child.agentId ?? child.agentName ?? child.id,
94
+ description: child.agentName ?? child.agentId ?? child.id,
95
+ ...(child.model ? { model: child.model } : {}),
96
+ runId: child.id,
97
+ // A parent run is the display group a live cohort is keyed by, and
98
+ // the batch a child belonged to is not recorded on disk. Grouping
99
+ // every saved child of one parent run together is the coarsest
100
+ // answer that is still true; splitting them by anything else would
101
+ // invent a boundary the evidence does not have.
102
+ workflowId: child.parentRunId,
103
+ batchId: `saved:${child.parentRunId}`,
104
+ ...(child.status ? { status: activityStatus(child.status) } : {}),
105
+ ...(child.totalTokens !== undefined ? { tokens: child.totalTokens } : {}),
106
+ ...(child.startedAt !== undefined ? { startedAt: child.startedAt } : {}),
107
+ ...(child.endedAt !== undefined ? { completedAt: child.endedAt } : {}),
108
+ ...(evidence.partial ? { partial: true } : {}),
109
+ }, evidence.events);
110
+ }
111
+ return monitor.getSnapshot();
112
+ }
113
+ /** Discovery and replay in one call, for a host that wants the whole list. */
114
+ export async function replaySavedChildrenFor(scope) {
115
+ return replaySavedChildren(await listSavedChildren(scope), scope.log);
116
+ }
117
+ /**
118
+ * One child's durable events, and whether all of them could be read.
119
+ *
120
+ * Read strictly first, then tolerantly. The strict pass is not about
121
+ * refusing damaged evidence — it is the only way to LEARN that the evidence
122
+ * is damaged, because the tolerant reader's whole job is to skip a torn
123
+ * record and carry on, which leaves a truncated transcript indistinguishable
124
+ * from a short one. A replay that quietly showed four rows of a forty-row run
125
+ * would be the most misleading thing this view could do, so the damage is
126
+ * reported instead: the rows that survive are shown, and the transcript says
127
+ * it is partial.
128
+ *
129
+ * A transcript that cannot be read AT ALL — an unreadable file, or a
130
+ * compaction archive beside it that the tolerant read cannot skip past
131
+ * either — is the same answer taken to its limit: no rows, and partial. It is
132
+ * not a reason to leave the child out of the listing. `run.json` still
133
+ * records what the run did and when, dropping the row would say this child
134
+ * never existed, and a row that shows the facts it has under a notice saying
135
+ * the record is incomplete is the honest version of the same information.
136
+ */
137
+ async function readChildEvidence(child, log) {
138
+ try {
139
+ return { events: await readRunEventsIn(child.dir, { integrity: 'strict' }), partial: false };
140
+ }
141
+ catch {
142
+ // Falls through to the tolerant read below.
143
+ }
144
+ try {
145
+ return { events: await readRunEventsIn(child.dir), partial: true };
146
+ }
147
+ catch (error) {
148
+ log?.warn('Saved child transcript could not be read', {
149
+ 'namzu.subagent.replay.child_dir': child.dir,
150
+ 'namzu.subagent.replay.error': errorMessage(error),
151
+ });
152
+ return { events: [], partial: true };
153
+ }
154
+ }
155
+ /**
156
+ * A saved run status as the display status the monitor projects.
157
+ *
158
+ * `running` survives as `working` rather than being rewritten to a terminal
159
+ * value: a process killed mid-run genuinely did not record an ending, and
160
+ * claiming one would be a different lie from the one this view exists to
161
+ * avoid. Nothing is attached to the row either way — `replayed` is what says
162
+ * that, on every replayed row regardless of status.
163
+ */
164
+ function activityStatus(status) {
165
+ switch (status) {
166
+ case 'idle':
167
+ return 'starting';
168
+ case 'pending':
169
+ return 'queued';
170
+ case 'running':
171
+ return 'working';
172
+ case 'completed':
173
+ return 'completed';
174
+ case 'failed':
175
+ return 'failed';
176
+ case 'cancelled':
177
+ return 'cancelled';
178
+ }
179
+ }
180
+ /** Directory entries by name; an absent directory lists as nothing. */
181
+ async function directoryNames(dir) {
182
+ try {
183
+ const entries = await readdir(dir, { withFileTypes: true });
184
+ return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
185
+ }
186
+ catch {
187
+ return [];
188
+ }
189
+ }
190
+ function errorMessage(error) {
191
+ return error instanceof Error ? error.message : String(error);
192
+ }
193
+ //# sourceMappingURL=replay.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.js","sourceRoot":"","sources":["../../../src/integrations/subagents/replay.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ import { type SubagentActivity } from './activity.js';
2
+ import { type SavedChildScope } from './replay.js';
3
+ /**
4
+ * One row of `/agents runs`: every child launched under one parent turn,
5
+ * whether that turn is still going or long settled.
6
+ *
7
+ * {@link id} is the parent run id every one of its children names —
8
+ * `workflowId` on a live {@link SubagentActivity}, `parentRunId` on a saved
9
+ * {@link import('@namzu/sdk').DelegatedChildRun} — so a row from either
10
+ * source addresses the same run the same way.
11
+ */
12
+ export interface OrchestrationRun {
13
+ readonly id: string;
14
+ readonly name: string;
15
+ readonly startedAt: number;
16
+ readonly phases: readonly string[];
17
+ readonly agentsDone: number;
18
+ readonly agentsTotal: number;
19
+ readonly tokensTotal: number;
20
+ readonly elapsedMs: number;
21
+ /**
22
+ * Read from the live monitor because at least one child is still going.
23
+ *
24
+ * Never true for a row this module read from disk: a finished run is
25
+ * reported from `run.json`, the durable record, and not from whatever the
26
+ * live monitor still happens to retain of it — see
27
+ * {@link listSavedOrchestrationRuns}.
28
+ */
29
+ readonly live: boolean;
30
+ }
31
+ /**
32
+ * Parent turns THIS PROCESS is still tracking, one row per run id that has at
33
+ * least one non-terminal child.
34
+ *
35
+ * A group every one of whose members has already settled is left out: that
36
+ * run is better read from disk, where `run.json` is the record of fact, and
37
+ * reporting it here too would be a second, competing account of a run this
38
+ * function has no fresher information about than the disk copy already has.
39
+ * Its caller is what applies that rule — see {@link listSavedOrchestrationRuns}'s
40
+ * own doc — by excluding a live id from the disk pass.
41
+ *
42
+ * The row's name is the group's own `workflow` label, an explicit annotation
43
+ * when the delegating host supplied one and the neutral default otherwise —
44
+ * the live case is the ONE place that label is trustworthy, since the
45
+ * process that would know it is the one being asked. A saved run has no such
46
+ * label to read; see {@link listSavedOrchestrationRuns} for what it reports
47
+ * instead.
48
+ */
49
+ export declare function liveOrchestrationRuns(agents: readonly SubagentActivity[], now: number): readonly OrchestrationRun[];
50
+ /**
51
+ * Finished parent turns read from disk, one row per parent run id
52
+ * {@link listSavedChildren} finds children under.
53
+ *
54
+ * Cheap by design: only `run.json` is read per child, the same evidence
55
+ * {@link listSavedChildren} already surfaces, and the parent turn's OWN
56
+ * `messages.json` for the row's name — never a child's transcript. A full
57
+ * replay (transcript included) happens once an operator actually opens one
58
+ * of these rows, not while building the list every one of them appears on.
59
+ *
60
+ * Named from the parent turn's own first words, read straight from
61
+ * `<sessionsRoot>/<sessionId>/runs/<parentRunId>/messages.json` — a saved
62
+ * child carries no `workflow` label to fall back to instead, because that
63
+ * label is display-only and reaches nowhere durable (see
64
+ * `docs/sdk/delegation-events.md`); the run that opened the turn is the
65
+ * nearest durable stand-in for what it was.
66
+ *
67
+ * Never reports a phase beyond the neutral default: a phase label is exactly
68
+ * as undurable as a workflow label, so nothing on disk can distinguish two
69
+ * saved phases from one.
70
+ */
71
+ export declare function listSavedOrchestrationRuns(scope: SavedChildScope): Promise<readonly OrchestrationRun[]>;
72
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runs.ts"],"names":[],"mappings":"AAIA,OAAO,EAGN,KAAK,gBAAgB,EAErB,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,eAAe,EAAqB,MAAM,aAAa,CAAA;AAKrE;;;;;;;;GAQG;AACH,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;;;;OAOG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CACtB;AAiCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,SAAS,gBAAgB,EAAE,EACnC,GAAG,EAAE,MAAM,GACT,SAAS,gBAAgB,EAAE,CAyB7B;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,0BAA0B,CAC/C,KAAK,EAAE,eAAe,GACpB,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CA6BtC"}
@@ -0,0 +1,155 @@
1
+ import { join } from 'node:path';
2
+ import { isTerminalStatus as isTerminalRunStatus, readRunMessagesIn } from '@namzu/sdk';
3
+ import { DEFAULT_AGENT_PHASE, DEFAULT_AGENT_WORKFLOW, } from './activity.js';
4
+ import { listSavedChildren } from './replay.js';
5
+ /** Longest a run's display name gets before it is clipped, matching a conversation title's own bound. */
6
+ const MAX_RUN_NAME_CODE_UNITS = 60;
7
+ function isTerminalActivityStatus(status) {
8
+ return status === 'completed' || status === 'failed' || status === 'cancelled';
9
+ }
10
+ function isDefined(value) {
11
+ return value !== undefined;
12
+ }
13
+ /** A phase name per distinct phase a group's members declared, in launch order. */
14
+ function orderedPhaseNames(members) {
15
+ const seen = new Set();
16
+ const ordered = [];
17
+ for (const agent of [...members].sort((left, right) => left.phaseSequence - right.phaseSequence)) {
18
+ if (seen.has(agent.phase))
19
+ continue;
20
+ seen.add(agent.phase);
21
+ ordered.push(agent.phase);
22
+ }
23
+ return ordered;
24
+ }
25
+ /** A conversation-title-style clip: one line, `MAX_RUN_NAME_CODE_UNITS` wide, or the neutral default. */
26
+ function runName(text) {
27
+ const oneLine = text?.replace(/\s+/g, ' ').trim();
28
+ if (!oneLine)
29
+ return DEFAULT_AGENT_WORKFLOW;
30
+ return oneLine.length > MAX_RUN_NAME_CODE_UNITS
31
+ ? `${oneLine.slice(0, MAX_RUN_NAME_CODE_UNITS - 1)}…`
32
+ : oneLine;
33
+ }
34
+ /**
35
+ * Parent turns THIS PROCESS is still tracking, one row per run id that has at
36
+ * least one non-terminal child.
37
+ *
38
+ * A group every one of whose members has already settled is left out: that
39
+ * run is better read from disk, where `run.json` is the record of fact, and
40
+ * reporting it here too would be a second, competing account of a run this
41
+ * function has no fresher information about than the disk copy already has.
42
+ * Its caller is what applies that rule — see {@link listSavedOrchestrationRuns}'s
43
+ * own doc — by excluding a live id from the disk pass.
44
+ *
45
+ * The row's name is the group's own `workflow` label, an explicit annotation
46
+ * when the delegating host supplied one and the neutral default otherwise —
47
+ * the live case is the ONE place that label is trustworthy, since the
48
+ * process that would know it is the one being asked. A saved run has no such
49
+ * label to read; see {@link listSavedOrchestrationRuns} for what it reports
50
+ * instead.
51
+ */
52
+ export function liveOrchestrationRuns(agents, now) {
53
+ const groups = new Map();
54
+ for (const agent of agents) {
55
+ if (agent.replayed)
56
+ continue;
57
+ const group = groups.get(agent.workflowId);
58
+ if (group)
59
+ group.push(agent);
60
+ else
61
+ groups.set(agent.workflowId, [agent]);
62
+ }
63
+ const runs = [];
64
+ for (const [id, members] of groups) {
65
+ if (members.every((agent) => isTerminalActivityStatus(agent.status)))
66
+ continue;
67
+ const startedAt = Math.min(...members.map((agent) => agent.startedAt));
68
+ runs.push({
69
+ id,
70
+ name: runName(members[0]?.workflow),
71
+ startedAt,
72
+ phases: orderedPhaseNames(members),
73
+ agentsTotal: members.length,
74
+ agentsDone: members.filter((agent) => isTerminalActivityStatus(agent.status)).length,
75
+ tokensTotal: members.reduce((sum, agent) => sum + (agent.tokens ?? 0), 0),
76
+ elapsedMs: Math.max(0, now - startedAt),
77
+ live: true,
78
+ });
79
+ }
80
+ return runs;
81
+ }
82
+ /**
83
+ * Finished parent turns read from disk, one row per parent run id
84
+ * {@link listSavedChildren} finds children under.
85
+ *
86
+ * Cheap by design: only `run.json` is read per child, the same evidence
87
+ * {@link listSavedChildren} already surfaces, and the parent turn's OWN
88
+ * `messages.json` for the row's name — never a child's transcript. A full
89
+ * replay (transcript included) happens once an operator actually opens one
90
+ * of these rows, not while building the list every one of them appears on.
91
+ *
92
+ * Named from the parent turn's own first words, read straight from
93
+ * `<sessionsRoot>/<sessionId>/runs/<parentRunId>/messages.json` — a saved
94
+ * child carries no `workflow` label to fall back to instead, because that
95
+ * label is display-only and reaches nowhere durable (see
96
+ * `docs/sdk/delegation-events.md`); the run that opened the turn is the
97
+ * nearest durable stand-in for what it was.
98
+ *
99
+ * Never reports a phase beyond the neutral default: a phase label is exactly
100
+ * as undurable as a workflow label, so nothing on disk can distinguish two
101
+ * saved phases from one.
102
+ */
103
+ export async function listSavedOrchestrationRuns(scope) {
104
+ const children = await listSavedChildren(scope);
105
+ const groups = new Map();
106
+ for (const child of children) {
107
+ const group = groups.get(child.parentRunId);
108
+ if (group)
109
+ group.push(child);
110
+ else
111
+ groups.set(child.parentRunId, [child]);
112
+ }
113
+ const runs = [];
114
+ for (const [id, members] of groups) {
115
+ const started = members.map((child) => child.startedAt).filter(isDefined);
116
+ const ended = members.map((child) => child.endedAt).filter(isDefined);
117
+ const startedAt = started.length > 0 ? Math.min(...started) : 0;
118
+ const finishedAt = ended.length > 0 ? Math.max(...ended) : startedAt;
119
+ runs.push({
120
+ id,
121
+ name: runName(await parentTurnFirstWords(scope, id)),
122
+ startedAt,
123
+ phases: [DEFAULT_AGENT_PHASE],
124
+ agentsTotal: members.length,
125
+ agentsDone: members.filter((child) => child.status !== undefined && isTerminalRunStatus(child.status)).length,
126
+ tokensTotal: members.reduce((sum, child) => sum + (child.totalTokens ?? 0), 0),
127
+ elapsedMs: Math.max(0, finishedAt - startedAt),
128
+ live: false,
129
+ });
130
+ }
131
+ return runs;
132
+ }
133
+ /**
134
+ * The opening line of the user turn that started `parentRunId`, or
135
+ * `undefined` when it cannot be read — a run still in flight has not written
136
+ * `messages.json` yet (see {@link import('@namzu/sdk').RunStore.writeMessages}),
137
+ * and an old or damaged one is not a reason to fail the whole listing.
138
+ */
139
+ async function parentTurnFirstWords(scope, parentRunId) {
140
+ try {
141
+ const runDir = join(scope.sessionsRoot, scope.sessionId, 'runs', parentRunId);
142
+ const snapshot = await readRunMessagesIn(runDir);
143
+ const messages = snapshot.kind === 'unavailable' ? [] : snapshot.messages;
144
+ const first = messages.find((message) => message.role === 'user' && message.source === undefined);
145
+ return first?.role === 'user' ? first.content : undefined;
146
+ }
147
+ catch (error) {
148
+ scope.log?.warn('A saved parent turn could not be read for its name', {
149
+ 'namzu.subagent.runs.parent_run_id': parentRunId,
150
+ 'namzu.subagent.runs.error': error instanceof Error ? error.message : String(error),
151
+ });
152
+ return undefined;
153
+ }
154
+ }
155
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../../src/integrations/subagents/runs.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,17 @@
16
16
  import { type AgentFileDefinition, type AuthorizationGateConfig, CompletionInbox, type LLMProvider, type PathBuilder, type Project, type ProjectInstructionContext, type ReactiveAgentConfig, type ReasoningEffort, type ResumeHandler, type RunEvent, type RunId, type SandboxProvider, type SessionId, type TaskScheduler, type ToolContext, type ToolDefinition, type ToolRegistryContract, type Topic } from '@namzu/sdk';
17
17
  import type { RunLimitsConfig } from '../../config/schema.js';
18
18
  import { type SubagentActivitySource } from './activity.js';
19
+ /**
20
+ * The parent's narration tool, named once.
21
+ *
22
+ * Exported because a second surface reads the name: the TUI drops the
23
+ * transcript row for a SUCCESSFUL call, since the line it wrote is already on
24
+ * screen above the rail and a row repeating it would print the sentence
25
+ * twice, the second time as protocol. A literal spelled in both places would
26
+ * drift the moment either is renamed, and the symptom would be a duplicated
27
+ * sentence rather than an error.
28
+ */
29
+ export declare const NARRATION_TOOL_NAME = "narrate_work";
19
30
  export declare const GENERAL_PURPOSE_SUBAGENT = "general-purpose";
20
31
  /**
21
32
  * The kernel's read-only delegate, with this application's doctrine under
@@ -112,6 +123,16 @@ export interface SubagentRuntime {
112
123
  /** Queue a correction for an owned task that has not finished. */
113
124
  readonly sendMessageTool: ToolDefinition;
114
125
  readonly cancelAgentTool: ToolDefinition;
126
+ /**
127
+ * Write one line of commentary above the agent rail.
128
+ *
129
+ * Registered on the PARENT's registry only, like every other tool here, and
130
+ * only by a host that has an operator watching — see `createAgentSession`.
131
+ * A child's roster is whatever the host's `buildTools()` returns, which
132
+ * never carries this one: that is what makes narration the run's own voice
133
+ * rather than a child's, and the property a test holds.
134
+ */
135
+ readonly narrationTool: ToolDefinition;
115
136
  readonly allowedAgentIds: readonly string[];
116
137
  /** Live, bounded observation of children created by this CLI session. */
117
138
  readonly activity: SubagentActivitySource;
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAGN,KAAK,mBAAmB,EAIxB,KAAK,uBAAuB,EAI5B,eAAe,EASf,KAAK,WAAW,EAEhB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,yBAAyB,EAE9B,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,aAAa,EAElB,KAAK,QAAQ,EACb,KAAK,KAAK,EACV,KAAK,eAAe,EACpB,KAAK,SAAS,EAId,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAEzB,KAAK,KAAK,EAcV,MAAM,YAAY,CAAA;AAGnB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAE7D,OAAO,EAIN,KAAK,sBAAsB,EAC3B,MAAM,eAAe,CAAA;AAItB,eAAO,MAAM,wBAAwB,oBAAoB,CAAA;AACzD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,YAAmB,CAAA;AAoChD,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;CAC7B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,eAAe,CAAA;CACjC;AAED,MAAM,WAAW,sBAAsB;IACtC,mFAAmF;IACnF,QAAQ,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,mEAAmE;IACnE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,6EAA6E;IAC7E,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAC7B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,eAAe,GAAG,SAAS,CAAA;IACtE,6EAA6E;IAC7E,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,4EAA4E;IAC5E,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAA;IAClC,iFAAiF;IACjF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,mBAAmB,GAAG,WAAW,CAAA;IAC7D,wFAAwF;IACxF,QAAQ,CAAC,aAAa,EAAE,CACvB,eAAe,CAAC,EAAE,SAAS,EAC3B,SAAS,CAAC,EAAE,cAAc,KACtB,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IACvC,QAAQ,CAAC,YAAY,CAAC,EAAE,CACvB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,EAC9D,MAAM,EAAE,WAAW,KACf,OAAO,CAAC,cAAc,CAAC,CAAA;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;IAC7E,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,MAAM,oBAAoB,CAAA;IAC/C,kFAAkF;IAClF,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAC7B,QAAQ,EAAE,WAAW,EACrB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,oBAAoB,KACvB,mBAAmB,CAAC,WAAW,CAAC,CAAA;IACrC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,uBAAuB,CAAA;IACpD;;;OAGG;IACH,QAAQ,CAAC,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,aAAa,GAAG,SAAS,CAAA;IAC1F,8EAA8E;IAC9E,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAChC,KAAK,EAAE,KAAK,KACR,CAAC,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAA;IACzD,kEAAkE;IAClE,QAAQ,CAAC,eAAe,CAAC,EAAE,eAAe,CAAA;IAC1C,sEAAsE;IACtE,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAA;IAC1C,2EAA2E;IAC3E,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,yBAAyB,CAAA;IACpE;;;;;;;;OAQG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC5C;;;;OAIG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAA;CACrD;AAED,MAAM,WAAW,eAAe;IAC/B,6DAA6D;IAC7D,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IACnD,wEAAwE;IACxE,qBAAqB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC7D,gFAAgF;IAChF,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,cAAc,CAAA;IAC5C,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAA;IAClC,6DAA6D;IAC7D,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAA;IACxC,QAAQ,CAAC,iBAAiB,EAAE,cAAc,CAAA;IAC1C,kEAAkE;IAClE,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAA;IACxC,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAA;IACxC,QAAQ,CAAC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3C,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAA;IACzC,uEAAuE;IACvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACtB;AA0DD;;;GAGG;AACH,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,sBAAsB,GAC1B,OAAO,CAAC,eAAe,CAAC,CA2zB1B"}
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/integrations/subagents/runtime.ts"],"names":[],"mappings":"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"}