@bahulam/code 0.1.11 → 0.1.12
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/package.json +1 -1
- package/src/auth/tarang-auth.mjs +313 -0
- package/src/commands/agent.mjs +7 -7
- package/src/config/cli-args.mjs +16 -0
- package/src/core/background-tasks.mjs +186 -0
- package/src/core/headless.mjs +54 -3
- package/src/core/local-agent.mjs +10 -1
- package/src/core/risk-tier.mjs +1 -0
- package/src/core/stream-client.mjs +95 -15
- package/src/core/tool-executor.mjs +219 -15
- package/src/local-service/agent-relay.mjs +1 -1
- package/src/local-service/server.mjs +116 -14
- package/src/orchestration/approval.mjs +30 -0
- package/src/orchestration/completion-triggers.mjs +40 -0
- package/src/orchestration/dispatch.mjs +118 -0
- package/src/orchestration/events.mjs +19 -0
- package/src/orchestration/graph.mjs +126 -0
- package/src/orchestration/node-runner.mjs +193 -0
- package/src/orchestration/runner.mjs +200 -0
- package/src/plugins/executor.mjs +2 -2
- package/src/plugins/manifest.mjs +27 -27
- package/src/plugins/preflight.mjs +8 -8
- package/src/terminal/agents.mjs +8 -3
- package/src/terminal/main.mjs +8 -2
- package/src/terminal/repl-render.mjs +65 -10
- package/src/terminal/repl-state.mjs +4 -2
- package/src/terminal/repl.mjs +572 -96
- package/src/tools/agent.mjs +6 -2
- package/src/tools/registry.mjs +88 -4
- package/src/ui/slash-commands.mjs +1 -1
- package/src/ui/sub-agent.mjs +14 -8
|
@@ -34,8 +34,8 @@ import * as queue from '../ui/render-queue.mjs';
|
|
|
34
34
|
// queue active) → coalesced last-wins status that can never interleave
|
|
35
35
|
// with content. Legacy dock path and bare-TTY inPlace stay as fallbacks
|
|
36
36
|
// until their write-sites migrate onto the queue too.
|
|
37
|
-
// Max
|
|
38
|
-
const SUB_AGENT_WINDOW_ROWS =
|
|
37
|
+
// Max live-window lines under the spinner during a sub-agent run.
|
|
38
|
+
const SUB_AGENT_WINDOW_ROWS = 8;
|
|
39
39
|
|
|
40
40
|
function statusWidth() {
|
|
41
41
|
return Math.max(8, (process.stderr.columns || process.stdout.columns || 120) - 1);
|
|
@@ -49,6 +49,18 @@ function fitStatusLines(lines) {
|
|
|
49
49
|
return (Array.isArray(lines) ? lines : [lines]).map(fitStatusLine);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
function subAgentWindowLines(win) {
|
|
53
|
+
if (win?.groups instanceof Map && win.groups.size) {
|
|
54
|
+
const lines = [];
|
|
55
|
+
for (const group of win.groups.values()) {
|
|
56
|
+
if (group?.header) lines.push(group.header);
|
|
57
|
+
for (const line of group?.lines || []) lines.push(line);
|
|
58
|
+
}
|
|
59
|
+
return lines;
|
|
60
|
+
}
|
|
61
|
+
return (win?.lines || []).slice(-SUB_AGENT_WINDOW_ROWS);
|
|
62
|
+
}
|
|
63
|
+
|
|
52
64
|
function presentStatus(rendered) {
|
|
53
65
|
// Watch panel override: when active, render the watch panel entries as a
|
|
54
66
|
// multi-line status block instead of the normal spinner/status line.
|
|
@@ -69,10 +81,11 @@ function presentStatus(rendered) {
|
|
|
69
81
|
const fitted = fitStatusLine(rendered);
|
|
70
82
|
if (queue.isActive()) {
|
|
71
83
|
const win = runtime.subAgentWindow;
|
|
72
|
-
|
|
84
|
+
const subAgentLines = subAgentWindowLines(win);
|
|
85
|
+
if (win?.active && subAgentLines.length) {
|
|
73
86
|
queue.statusBlock([
|
|
74
87
|
fitted,
|
|
75
|
-
...fitStatusLines(
|
|
88
|
+
...fitStatusLines(subAgentLines.map(l => ` ${c.dim(l)}`)),
|
|
76
89
|
]);
|
|
77
90
|
return;
|
|
78
91
|
}
|
|
@@ -95,7 +108,7 @@ export function pushSubAgentWindowLine(line) {
|
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
export function setSubAgentWindowActive(active) {
|
|
98
|
-
runtime.subAgentWindow = { active: Boolean(active), lines: [] };
|
|
111
|
+
runtime.subAgentWindow = { active: Boolean(active), lines: [], groups: new Map() };
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
/**
|
|
@@ -109,6 +122,25 @@ export function rebuildSubAgentWindow(lines) {
|
|
|
109
122
|
const win = runtime.subAgentWindow;
|
|
110
123
|
if (!win?.active) return;
|
|
111
124
|
win.lines = Array.isArray(lines) ? lines.slice() : [];
|
|
125
|
+
win.groups = new Map();
|
|
126
|
+
repaintSpinnerStatus();
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function rebuildSubAgentWindowGroups(groups) {
|
|
130
|
+
const win = runtime.subAgentWindow;
|
|
131
|
+
if (!win?.active) return;
|
|
132
|
+
win.groups = new Map();
|
|
133
|
+
win.lines = [];
|
|
134
|
+
for (const group of Array.isArray(groups) ? groups : []) {
|
|
135
|
+
const key = group?.runId || group?.key || group?.label;
|
|
136
|
+
if (!key) continue;
|
|
137
|
+
win.groups.set(key, {
|
|
138
|
+
runId: group.runId || null,
|
|
139
|
+
label: group.label || 'sub-agent',
|
|
140
|
+
header: group.header || group.label || 'sub-agent',
|
|
141
|
+
lines: Array.isArray(group.lines) ? group.lines.slice() : [],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
112
144
|
repaintSpinnerStatus();
|
|
113
145
|
}
|
|
114
146
|
|
|
@@ -308,11 +340,27 @@ export function renderToolCall(data) {
|
|
|
308
340
|
const args = data?.args || {};
|
|
309
341
|
const indent = subAgentIndent();
|
|
310
342
|
const callId = data?.call_id || data?._callId || `${tool}:${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
343
|
+
const fromSubAgent = Boolean(data?.internal || data?.sub_agent || data?.sub_agent_label || data?.sub_agent_run_id);
|
|
311
344
|
|
|
312
345
|
// If a previous head is still pending (no result yet), flush it as a
|
|
313
346
|
// regular two-line shape before starting the next one.
|
|
314
347
|
flushPendingHead();
|
|
315
348
|
|
|
349
|
+
// Sub-agent live window (queue mode): inner tool calls stream into the
|
|
350
|
+
// fixed-height status block instead of appending transcript lines. Keep
|
|
351
|
+
// this ahead of explore-collapse so parallel explores do not merge into
|
|
352
|
+
// one global read/search spinner.
|
|
353
|
+
if (fromSubAgent && queue.isActive() && runtime.subAgentWindow?.active) {
|
|
354
|
+
recordCard({ id: callId, tool, args, startedAt: Date.now() });
|
|
355
|
+
session.toolCounts[tool] = (session.toolCounts[tool] || 0) + 1;
|
|
356
|
+
const label = readToolLabel(tool, { args });
|
|
357
|
+
const runId = data?.run_id || data?.sub_agent_run_id || '';
|
|
358
|
+
const runSuffix = runId ? ` run ${String(runId).slice(0, 8)}` : '';
|
|
359
|
+
const lane = data?.sub_agent_label ? `[${data.sub_agent_label}${runSuffix}] ` : '';
|
|
360
|
+
pushSubAgentWindowLine(label ? `${lane}→ ${tool} · ${label}` : `${lane}→ ${tool}`);
|
|
361
|
+
return; // the spinner tick paints the window block
|
|
362
|
+
}
|
|
363
|
+
|
|
316
364
|
// ── Explore-run collapse ────────────────────────────────────────────────
|
|
317
365
|
// For list/read/search/index tools, skip the per-call head entirely and
|
|
318
366
|
// update a single animated summary spinner. The transcript stays clean;
|
|
@@ -328,9 +376,8 @@ export function renderToolCall(data) {
|
|
|
328
376
|
return;
|
|
329
377
|
}
|
|
330
378
|
|
|
331
|
-
//
|
|
332
|
-
//
|
|
333
|
-
// card is still recorded so /expand, /last, and `d` show full detail.
|
|
379
|
+
// Legacy sub-agent live window fallback for events without explicit
|
|
380
|
+
// sub-agent metadata.
|
|
334
381
|
if (queue.isActive() && runtime.subAgentWindow?.active && inSubAgentBlock()) {
|
|
335
382
|
recordCard({ id: callId, tool, args, startedAt: Date.now() });
|
|
336
383
|
session.toolCounts[tool] = (session.toolCounts[tool] || 0) + 1;
|
|
@@ -410,6 +457,14 @@ export function renderToolResult(data, eventType = 'tool_result') {
|
|
|
410
457
|
indent: gutter,
|
|
411
458
|
columns: process.stderr.columns || 120,
|
|
412
459
|
});
|
|
460
|
+
const fromSubAgent = Boolean(data?.internal || data?.sub_agent || data?.sub_agent_label || data?.sub_agent_run_id);
|
|
461
|
+
|
|
462
|
+
// Sub-agent live window: the call line is already streaming in the
|
|
463
|
+
// status block; the result stays card-only (close card summarizes). This
|
|
464
|
+
// must run before explore-collapse for read/search tools used by explores.
|
|
465
|
+
if (fromSubAgent && queue.isActive() && runtime.subAgentWindow?.active) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
413
468
|
|
|
414
469
|
// Explore tools: the call already updated the summary spinner. Refresh
|
|
415
470
|
// the "latest" hint with the result's file if we have one, and skip the
|
|
@@ -421,8 +476,8 @@ export function renderToolResult(data, eventType = 'tool_result') {
|
|
|
421
476
|
return;
|
|
422
477
|
}
|
|
423
478
|
|
|
424
|
-
//
|
|
425
|
-
//
|
|
479
|
+
// Legacy sub-agent live window fallback for events without explicit
|
|
480
|
+
// sub-agent metadata.
|
|
426
481
|
if (queue.isActive() && runtime.subAgentWindow?.active && inSubAgentBlock()) {
|
|
427
482
|
return;
|
|
428
483
|
}
|
|
@@ -43,7 +43,8 @@ export const runtime = {
|
|
|
43
43
|
|
|
44
44
|
// Explore-run collapse (read/list/search/index bursts as concise progress).
|
|
45
45
|
exploreRun: { counts: {}, recent: [], lineActive: false, lastPrintedSummary: '', lastPrintedTotal: 0, lastPrintedAt: 0 },
|
|
46
|
-
foldedSubAgentTools: null, //
|
|
46
|
+
foldedSubAgentTools: null, // current folded sub-agent tool bucket
|
|
47
|
+
foldedSubAgentToolMap: new Map(), // run-aware buckets for parallel sub-agents
|
|
47
48
|
|
|
48
49
|
// Animated spinner state (single shared interval; text/frame drive inPlace).
|
|
49
50
|
spinInterval: null,
|
|
@@ -61,7 +62,7 @@ export const runtime = {
|
|
|
61
62
|
// its inner tool calls stream into a fixed-height status block (last
|
|
62
63
|
// N lines under the spinner) instead of appending to the transcript.
|
|
63
64
|
// Full detail stays on the recorded cards (/expand, /last, `d`).
|
|
64
|
-
subAgentWindow: { active: false, lines: [] },
|
|
65
|
+
subAgentWindow: { active: false, lines: [], groups: new Map() },
|
|
65
66
|
|
|
66
67
|
// PRD-092: Watch panel — toggled by /watch. When active, the spinner
|
|
67
68
|
// area renders a compact agent-activity summary instead of the spinner.
|
|
@@ -106,6 +107,7 @@ export const session = {
|
|
|
106
107
|
lastTurnDuration: 0,
|
|
107
108
|
toolCounts: {}, // per-tool histogram (mission report)
|
|
108
109
|
subAgentCounts: {}, // per-sub-agent histogram (mission report)
|
|
110
|
+
activeSubAgentRuns: new Map(), // run_id -> active sub-agent lane
|
|
109
111
|
savedUsd: 0, // total sub-agent cost (for "saved by routing")
|
|
110
112
|
lastTask: '', // most recent user prompt (mission report title)
|
|
111
113
|
lastReasoning: '', // captured from agent for /why
|