@bahulam/code 0.1.6 → 0.1.8
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/LICENSE +1 -1
- package/NOTICE +6 -6
- package/README.md +11 -18
- package/package.json +11 -11
- package/src/agents/loader.mjs +1 -1
- package/src/agents/workflow_loader.mjs +2 -2
- package/src/auth/{tarang-auth.mjs → bahulam-auth.mjs} +4 -3
- package/src/commands/agent.mjs +3 -3
- package/src/commands/device.mjs +2 -2
- package/src/commands/pair.mjs +2 -2
- package/src/commands/remote.mjs +3 -3
- package/src/commands/workflow.mjs +5 -5
- package/src/config/env.mjs +9 -2
- package/src/config/memory-loader.mjs +1 -1
- package/src/config/model-catalog-default.json +4 -3
- package/src/config/model-catalog.mjs +2 -0
- package/src/config/settings.mjs +2 -2
- package/src/context/prose-chunker.mjs +162 -5
- package/src/core/agent-loop.mjs +17 -0
- package/src/core/attachments.mjs +66 -4
- package/src/core/backend-url.mjs +11 -12
- package/src/core/bundled-runtime.mjs +1 -1
- package/src/core/callback-client.mjs +1 -1
- package/src/core/headless.mjs +18 -4
- package/src/core/jsonl-writer.mjs +18 -18
- package/src/core/lint-resolver.mjs +472 -0
- package/src/core/local-agent.mjs +40 -8
- package/src/core/local-store.mjs +5 -1
- package/src/core/mode-selector.mjs +1 -1
- package/src/core/output-filter.mjs +22 -26
- package/src/core/pricing.mjs +10 -3
- package/src/core/project-artifacts.mjs +3 -3
- package/src/core/project-context-loader.mjs +9 -9
- package/src/core/settings-sync.mjs +1 -1
- package/src/core/stagnation.mjs +61 -1
- package/src/core/stream-client.mjs +13 -8
- package/src/core/system-prompt.mjs +2 -2
- package/src/core/tool-executor.mjs +178 -84
- package/src/daemon/http-dashboard.mjs +400 -0
- package/src/daemon/session-core.mjs +1 -0
- package/src/local-service/agent-relay.mjs +868 -0
- package/src/local-service/approval-bridge.mjs +222 -0
- package/src/local-service/browser.mjs +24 -0
- package/src/local-service/command.mjs +155 -0
- package/src/local-service/file-access.mjs +393 -0
- package/src/local-service/machine.mjs +86 -0
- package/src/local-service/paths.mjs +29 -0
- package/src/local-service/preview-converters.mjs +260 -0
- package/src/local-service/server.mjs +2644 -0
- package/src/local-service/session-store.mjs +221 -0
- package/src/mcp/client.mjs +4 -4
- package/src/onboarding/preflight.mjs +2 -2
- package/src/terminal/agents.mjs +2 -2
- package/src/terminal/analytics.mjs +2 -6
- package/src/terminal/ansi.mjs +11 -3
- package/src/terminal/main.mjs +43 -17
- package/src/terminal/model-catalog-display.mjs +111 -0
- package/src/terminal/repl-format.mjs +4 -1
- package/src/terminal/repl-model-form.mjs +81 -14
- package/src/terminal/repl-render.mjs +37 -7
- package/src/terminal/repl-resume.mjs +2 -2
- package/src/terminal/repl-state.mjs +12 -0
- package/src/terminal/repl.mjs +248 -70
- package/src/terminal/tool-display.mjs +32 -0
- package/src/terminal/watch-state.mjs +118 -0
- package/src/tools/agent.mjs +2 -2
- package/src/tools/analyze-image.mjs +158 -0
- package/src/tools/bash.mjs +11 -9
- package/src/tools/generate-image.mjs +411 -0
- package/src/tools/lint.mjs +24 -43
- package/src/tools/project-overview.mjs +12 -12
- package/src/tools/registry.mjs +4 -0
- package/src/ui/formatter.mjs +2 -2
- package/src/ui/icons.mjs +2 -0
- package/src/ui/input-dock.mjs +7 -7
- package/src/ui/palette.mjs +1 -1
- package/src/ui/slash-commands.mjs +4 -6
- package/src/ui/spinner.mjs +1 -1
- package/src/ui/term.mjs +2 -6
- package/src/ui/tool-card.mjs +81 -6
- package/pulse/app/activity/page.tsx +0 -190
- package/pulse/app/api/activity/route.ts +0 -138
- package/pulse/app/api/benchmark/route.ts +0 -113
- package/pulse/app/api/benchmarks/route.ts +0 -195
- package/pulse/app/api/costs/route.ts +0 -88
- package/pulse/app/api/export/route.ts +0 -77
- package/pulse/app/api/history/route.ts +0 -11
- package/pulse/app/api/import/route.ts +0 -31
- package/pulse/app/api/memory/route.ts +0 -50
- package/pulse/app/api/plans/route.ts +0 -9
- package/pulse/app/api/projects/[slug]/route.ts +0 -96
- package/pulse/app/api/projects/route.ts +0 -121
- package/pulse/app/api/sessions/[id]/replay/route.ts +0 -20
- package/pulse/app/api/sessions/[id]/route.ts +0 -31
- package/pulse/app/api/sessions/route.ts +0 -112
- package/pulse/app/api/settings/route.ts +0 -14
- package/pulse/app/api/stats/route.ts +0 -143
- package/pulse/app/api/todos/route.ts +0 -9
- package/pulse/app/api/tools/route.ts +0 -160
- package/pulse/app/benchmarks/page.tsx +0 -224
- package/pulse/app/costs/page.tsx +0 -179
- package/pulse/app/export/page.tsx +0 -465
- package/pulse/app/favicon.ico +0 -0
- package/pulse/app/globals.css +0 -263
- package/pulse/app/help/page.tsx +0 -143
- package/pulse/app/history/page.tsx +0 -157
- package/pulse/app/layout.tsx +0 -46
- package/pulse/app/memory/page.tsx +0 -365
- package/pulse/app/overview-client.tsx +0 -393
- package/pulse/app/page.tsx +0 -14
- package/pulse/app/plans/page.tsx +0 -308
- package/pulse/app/projects/[slug]/page.tsx +0 -390
- package/pulse/app/projects/page.tsx +0 -110
- package/pulse/app/sessions/[id]/page.tsx +0 -243
- package/pulse/app/sessions/page.tsx +0 -39
- package/pulse/app/settings/page.tsx +0 -188
- package/pulse/app/todos/page.tsx +0 -211
- package/pulse/app/tools/page.tsx +0 -249
- package/pulse/cli.js +0 -164
- package/pulse/components/activity/day-of-week-chart.tsx +0 -35
- package/pulse/components/activity/streak-card.tsx +0 -36
- package/pulse/components/costs/cache-efficiency-panel.tsx +0 -76
- package/pulse/components/costs/cost-by-project-chart.tsx +0 -48
- package/pulse/components/costs/cost-over-time-chart.tsx +0 -95
- package/pulse/components/costs/model-token-table.tsx +0 -60
- package/pulse/components/global-search.tsx +0 -193
- package/pulse/components/keyboard-nav-provider.tsx +0 -23
- package/pulse/components/layout/bottom-nav.tsx +0 -53
- package/pulse/components/layout/client-layout.tsx +0 -31
- package/pulse/components/layout/sidebar-context.tsx +0 -50
- package/pulse/components/layout/sidebar.tsx +0 -183
- package/pulse/components/layout/top-bar.tsx +0 -121
- package/pulse/components/overview/activity-heatmap.tsx +0 -107
- package/pulse/components/overview/conversation-table.tsx +0 -148
- package/pulse/components/overview/model-breakdown-donut.tsx +0 -95
- package/pulse/components/overview/peak-hours-chart.tsx +0 -87
- package/pulse/components/overview/project-activity-donut.tsx +0 -96
- package/pulse/components/overview/stat-card.tsx +0 -102
- package/pulse/components/overview/usage-over-time-chart.tsx +0 -166
- package/pulse/components/projects/project-card.tsx +0 -175
- package/pulse/components/sessions/replay/assistant-markdown.tsx +0 -94
- package/pulse/components/sessions/replay/compaction-card.tsx +0 -25
- package/pulse/components/sessions/replay/session-sidebar.tsx +0 -231
- package/pulse/components/sessions/replay/token-accumulation-chart.tsx +0 -98
- package/pulse/components/sessions/replay/tool-call-badge.tsx +0 -127
- package/pulse/components/sessions/replay/turn-cards.tsx +0 -220
- package/pulse/components/sessions/replay/user-tool-result.tsx +0 -158
- package/pulse/components/sessions/session-badges.tsx +0 -49
- package/pulse/components/sessions/session-table.tsx +0 -299
- package/pulse/components/theme-provider.tsx +0 -44
- package/pulse/components/tools/feature-adoption-table.tsx +0 -58
- package/pulse/components/tools/mcp-server-panel.tsx +0 -45
- package/pulse/components/tools/tool-ranking-chart.tsx +0 -57
- package/pulse/components/tools/version-history-table.tsx +0 -32
- package/pulse/components/ui/alert.tsx +0 -66
- package/pulse/components/ui/badge.tsx +0 -48
- package/pulse/components/ui/breadcrumb.tsx +0 -109
- package/pulse/components/ui/button.tsx +0 -64
- package/pulse/components/ui/calendar.tsx +0 -220
- package/pulse/components/ui/card.tsx +0 -92
- package/pulse/components/ui/command.tsx +0 -158
- package/pulse/components/ui/dialog.tsx +0 -158
- package/pulse/components/ui/input.tsx +0 -21
- package/pulse/components/ui/popover.tsx +0 -89
- package/pulse/components/ui/progress.tsx +0 -31
- package/pulse/components/ui/select.tsx +0 -190
- package/pulse/components/ui/separator.tsx +0 -28
- package/pulse/components/ui/sheet.tsx +0 -143
- package/pulse/components/ui/skeleton.tsx +0 -13
- package/pulse/components/ui/table.tsx +0 -116
- package/pulse/components/ui/tabs.tsx +0 -91
- package/pulse/components/ui/tooltip.tsx +0 -57
- package/pulse/components/use-global-keyboard-nav.ts +0 -79
- package/pulse/components.json +0 -23
- package/pulse/eslint.config.mjs +0 -18
- package/pulse/lib/bahulam-paths.ts +0 -23
- package/pulse/lib/claude-reader.ts +0 -592
- package/pulse/lib/decode.ts +0 -129
- package/pulse/lib/pricing.ts +0 -102
- package/pulse/lib/replay-parser.ts +0 -165
- package/pulse/lib/tool-categories.ts +0 -140
- package/pulse/lib/utils.ts +0 -6
- package/pulse/next-env.d.ts +0 -6
- package/pulse/next.config.ts +0 -16
- package/pulse/package.json +0 -45
- package/pulse/postcss.config.mjs +0 -7
- package/pulse/public/activity.png +0 -0
- package/pulse/public/cc-lens.png +0 -0
- package/pulse/public/command-k.png +0 -0
- package/pulse/public/costs.png +0 -0
- package/pulse/public/dashboard-dark.png +0 -0
- package/pulse/public/dashboard-white.png +0 -0
- package/pulse/public/export.png +0 -0
- package/pulse/public/file.svg +0 -1
- package/pulse/public/globe.svg +0 -1
- package/pulse/public/next.svg +0 -1
- package/pulse/public/projects.png +0 -0
- package/pulse/public/session-chat.png +0 -0
- package/pulse/public/todos.png +0 -0
- package/pulse/public/tools.png +0 -0
- package/pulse/public/vercel.svg +0 -1
- package/pulse/public/window.svg +0 -1
- package/pulse/tsconfig.json +0 -34
- package/pulse/types/claude.ts +0 -294
|
@@ -8,8 +8,15 @@
|
|
|
8
8
|
* mode on, redraw in place with cursor-up + erase-down, restore on exit.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { c } from './ansi.mjs';
|
|
11
|
+
import { c, stripAnsi } from './ansi.mjs';
|
|
12
12
|
import { fitAnsiLine, writeOverlayFrame, eraseOverlayFrame } from './repl-format.mjs';
|
|
13
|
+
import {
|
|
14
|
+
cacheProfileLabel,
|
|
15
|
+
formatCategoryBadge,
|
|
16
|
+
isImageGenerationModel,
|
|
17
|
+
modelCategory,
|
|
18
|
+
modelDisplayCategory,
|
|
19
|
+
} from './model-catalog-display.mjs';
|
|
13
20
|
|
|
14
21
|
const DEFAULT_SENTINEL = '__default__';
|
|
15
22
|
|
|
@@ -20,10 +27,33 @@ function creditBadge(row) {
|
|
|
20
27
|
return `~${credits < 10 ? credits.toFixed(1) : String(Math.round(credits))} cr/M`;
|
|
21
28
|
}
|
|
22
29
|
|
|
30
|
+
function formatTokenLimit(value, label) {
|
|
31
|
+
const n = Number(value);
|
|
32
|
+
if (!Number.isFinite(n) || n <= 0) return '';
|
|
33
|
+
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1).replace(/\.0$/, '')}M ${label}`;
|
|
34
|
+
if (n >= 1_000) return `${Math.round(n / 1_000)}K ${label}`;
|
|
35
|
+
return `${Math.round(n)} ${label}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function optionRowsForRole(catalog, row) {
|
|
39
|
+
const curated = (catalog || []).filter(m => m?.harness_validated && m?.id);
|
|
40
|
+
const group = String(row?.optionGroup || 'text').toLowerCase();
|
|
41
|
+
if (group === 'image_analysis') {
|
|
42
|
+
return curated.filter(m => (
|
|
43
|
+
['image', 'multimodal'].includes(modelCategory(m))
|
|
44
|
+
&& !isImageGenerationModel(m)
|
|
45
|
+
));
|
|
46
|
+
}
|
|
47
|
+
if (group === 'image_generation') {
|
|
48
|
+
return curated.filter(m => modelCategory(m) === 'image' && isImageGenerationModel(m));
|
|
49
|
+
}
|
|
50
|
+
return curated.filter(m => ['text', 'chat'].includes(modelCategory(m)));
|
|
51
|
+
}
|
|
52
|
+
|
|
23
53
|
/**
|
|
24
54
|
* @param {object} opts
|
|
25
55
|
* @param {object|null} opts.rl readline instance to pause/resume
|
|
26
|
-
* @param {Array} opts.roles [{ role, label, current, defaultLabel }]
|
|
56
|
+
* @param {Array} opts.roles [{ role, label, description, current, defaultLabel, optionGroup }]
|
|
27
57
|
* @param {Array} opts.catalog raw /api/models rows (may be empty)
|
|
28
58
|
* @param {Array} [opts.fallbackIds] model ids to cycle when no curated catalog
|
|
29
59
|
* @param {string} [opts.unavailableNote] why the catalog is missing (shown in header)
|
|
@@ -33,25 +63,24 @@ export async function pickModelOverridesForm({ rl, roles, catalog, fallbackIds,
|
|
|
33
63
|
if (!process.stdin.isTTY) return null;
|
|
34
64
|
if (rl) rl.pause();
|
|
35
65
|
|
|
36
|
-
const
|
|
37
|
-
const usingFallback =
|
|
38
|
-
const
|
|
39
|
-
? [...new Set((fallbackIds || []).filter(Boolean))]
|
|
40
|
-
: curated.map(m => m.id);
|
|
41
|
-
const baseOptions = [DEFAULT_SENTINEL, ...optionIds];
|
|
42
|
-
const byId = new Map(curated.map(m => [m.id, m]));
|
|
66
|
+
const catalogRows = (catalog || []).filter(m => m?.harness_validated && m?.id);
|
|
67
|
+
const usingFallback = catalogRows.length === 0;
|
|
68
|
+
const byId = new Map(catalogRows.map(m => [m.id, m]));
|
|
43
69
|
|
|
44
70
|
// Per-row option list; a current override that isn't in the curated list
|
|
45
71
|
// is appended so it stays visible and selectable.
|
|
46
72
|
const rows = roles.map(r => {
|
|
47
|
-
|
|
73
|
+
const optionIds = usingFallback
|
|
74
|
+
? [...new Set((fallbackIds || []).filter(Boolean))]
|
|
75
|
+
: optionRowsForRole(catalogRows, r).map(m => m.id);
|
|
76
|
+
let opts = [DEFAULT_SENTINEL, ...optionIds];
|
|
48
77
|
let idx = 0;
|
|
49
78
|
if (r.current) {
|
|
50
|
-
const found =
|
|
79
|
+
const found = opts.indexOf(r.current);
|
|
51
80
|
if (found >= 0) {
|
|
52
81
|
idx = found;
|
|
53
82
|
} else {
|
|
54
|
-
opts = [...
|
|
83
|
+
opts = [...opts, r.current];
|
|
55
84
|
idx = opts.length - 1;
|
|
56
85
|
}
|
|
57
86
|
}
|
|
@@ -76,8 +105,38 @@ export async function pickModelOverridesForm({ rl, roles, catalog, fallbackIds,
|
|
|
76
105
|
return `${c.brand(value)}${badge ? ` ${c.dim(badge)}` : ''}${flag}`;
|
|
77
106
|
};
|
|
78
107
|
|
|
108
|
+
const valueDescription = (row) => {
|
|
109
|
+
const value = row.opts[row.idx];
|
|
110
|
+
if (value === DEFAULT_SENTINEL) {
|
|
111
|
+
return row.description || 'backend default for this role';
|
|
112
|
+
}
|
|
113
|
+
const meta = byId.get(value);
|
|
114
|
+
if (!meta) {
|
|
115
|
+
return usingFallback ? 'backend configured model' : 'custom override outside curated catalog';
|
|
116
|
+
}
|
|
117
|
+
const label = String(meta.label || '').trim();
|
|
118
|
+
const parts = [];
|
|
119
|
+
if (label && label !== value) parts.push(c.white(label));
|
|
120
|
+
if (meta.provider) parts.push(c.dim(String(meta.provider)));
|
|
121
|
+
const category = modelDisplayCategory(meta);
|
|
122
|
+
if (category) parts.push(formatCategoryBadge(category));
|
|
123
|
+
const context = formatTokenLimit(meta.context_length, 'ctx');
|
|
124
|
+
if (context) parts.push(c.dim(context));
|
|
125
|
+
const output = formatTokenLimit(meta.max_output, 'out');
|
|
126
|
+
if (output) parts.push(c.dim(output));
|
|
127
|
+
if (meta.supports_tools) parts.push(c.green('tools'));
|
|
128
|
+
if (meta.supports_reasoning) parts.push(c.yellow('reasoning'));
|
|
129
|
+
const cache = cacheProfileLabel(meta.cache_profile);
|
|
130
|
+
if (cache) parts.push(c.cyan(cache));
|
|
131
|
+
return parts.join(c.dim(' · '));
|
|
132
|
+
};
|
|
133
|
+
|
|
79
134
|
const render = () => {
|
|
80
135
|
const cols = Math.max(60, process.stderr.columns || 120);
|
|
136
|
+
const labelWidth = Math.min(
|
|
137
|
+
18,
|
|
138
|
+
Math.max(14, ...rows.map(row => stripAnsi(String(row.label || row.role)).length)),
|
|
139
|
+
);
|
|
81
140
|
const lines = [];
|
|
82
141
|
lines.push(` ${c.bold('Models')} ${c.dim('· session overrides · curated platform catalog')}`);
|
|
83
142
|
if (usingFallback) {
|
|
@@ -87,9 +146,17 @@ export async function pickModelOverridesForm({ rl, roles, catalog, fallbackIds,
|
|
|
87
146
|
lines.push('');
|
|
88
147
|
rows.forEach((row, i) => {
|
|
89
148
|
const marker = i === cursor ? c.brand('▸') : ' ';
|
|
90
|
-
const rawLabel = String(row.label || row.role).padEnd(
|
|
149
|
+
const rawLabel = String(row.label || row.role).padEnd(labelWidth, ' ');
|
|
91
150
|
const label = i === cursor ? c.brand(rawLabel) : rawLabel;
|
|
92
|
-
|
|
151
|
+
const prefix = ` ${marker} ${label} ${c.dim('‹')} `;
|
|
152
|
+
const suffix = ` ${c.dim('›')}`;
|
|
153
|
+
const descText = valueDescription(row);
|
|
154
|
+
const descMaxCols = Math.max(0, Math.min(72, cols - stripAnsi(prefix + suffix).length - 24));
|
|
155
|
+
const desc = descText && descMaxCols > 12
|
|
156
|
+
? ` ${fitAnsiLine(descText, descMaxCols)}`
|
|
157
|
+
: '';
|
|
158
|
+
const maxValueCols = Math.max(18, cols - stripAnsi(prefix + suffix + desc).length - 1);
|
|
159
|
+
lines.push(fitAnsiLine(`${prefix}${fitAnsiLine(valueLabel(row), maxValueCols)}${suffix}${desc}`, cols - 1));
|
|
93
160
|
});
|
|
94
161
|
lines.push('');
|
|
95
162
|
lines.push(fitAnsiLine(` ${c.dim('↑↓ role · ←→ model · Enter apply · c defaults · Esc cancel')}`, cols - 1));
|
|
@@ -21,6 +21,7 @@ import { paint } from '../ui/palette.mjs';
|
|
|
21
21
|
import { runtime, session } from './repl-state.mjs';
|
|
22
22
|
import { fitAnsiLine } from './repl-format.mjs';
|
|
23
23
|
import { exploreCategory, isExploreTool } from './repl-explore.mjs';
|
|
24
|
+
import { watchState } from './watch-state.mjs';
|
|
24
25
|
import {
|
|
25
26
|
clearPinnedStatus,
|
|
26
27
|
drawPinnedStatus,
|
|
@@ -36,21 +37,50 @@ import * as queue from '../ui/render-queue.mjs';
|
|
|
36
37
|
// Max inner-tool lines shown under the spinner during a sub-agent run.
|
|
37
38
|
const SUB_AGENT_WINDOW_ROWS = 7;
|
|
38
39
|
|
|
40
|
+
function statusWidth() {
|
|
41
|
+
return Math.max(8, (process.stderr.columns || process.stdout.columns || 120) - 1);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function fitStatusLine(line) {
|
|
45
|
+
return fitAnsiLine(String(line ?? '').replace(/[\r\n]+/g, ' '), statusWidth());
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function fitStatusLines(lines) {
|
|
49
|
+
return (Array.isArray(lines) ? lines : [lines]).map(fitStatusLine);
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
function presentStatus(rendered) {
|
|
53
|
+
// Watch panel override: when active, render the watch panel entries as a
|
|
54
|
+
// multi-line status block instead of the normal spinner/status line.
|
|
55
|
+
if (watchState.active) {
|
|
56
|
+
const lines = watchState.visible();
|
|
57
|
+
if (lines.length) {
|
|
58
|
+
const fitted = fitStatusLines(lines);
|
|
59
|
+
if (queue.isActive()) {
|
|
60
|
+
queue.statusBlock(fitted);
|
|
61
|
+
} else if (isInputDockMounted()) {
|
|
62
|
+
drawPinnedStatus(fitted.join('\n'));
|
|
63
|
+
} else {
|
|
64
|
+
inPlace(fitted.join('\n'));
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const fitted = fitStatusLine(rendered);
|
|
40
70
|
if (queue.isActive()) {
|
|
41
71
|
const win = runtime.subAgentWindow;
|
|
42
72
|
if (win?.active && win.lines.length) {
|
|
43
73
|
queue.statusBlock([
|
|
44
|
-
|
|
45
|
-
...win.lines.slice(-SUB_AGENT_WINDOW_ROWS).map(l => ` ${c.dim(l)}`),
|
|
74
|
+
fitted,
|
|
75
|
+
...fitStatusLines(win.lines.slice(-SUB_AGENT_WINDOW_ROWS).map(l => ` ${c.dim(l)}`)),
|
|
46
76
|
]);
|
|
47
77
|
return;
|
|
48
78
|
}
|
|
49
|
-
queue.status(
|
|
79
|
+
queue.status(fitted);
|
|
50
80
|
return;
|
|
51
81
|
}
|
|
52
|
-
if (isInputDockMounted()) { drawPinnedStatus(
|
|
53
|
-
inPlace(
|
|
82
|
+
if (isInputDockMounted()) { drawPinnedStatus(fitted); return; }
|
|
83
|
+
inPlace(fitted);
|
|
54
84
|
}
|
|
55
85
|
|
|
56
86
|
/** Push a line into the live sub-agent tool window (dedup consecutive). */
|
|
@@ -103,7 +133,7 @@ import { safeCwd } from './repl-utils.mjs';
|
|
|
103
133
|
import { transcriptHeader, transcriptLine } from '../ui/transcript-block.mjs';
|
|
104
134
|
|
|
105
135
|
export function blockSeparatorMode() {
|
|
106
|
-
return String(process.env.
|
|
136
|
+
return String(process.env.BAHULAM_BLOCK_SEPARATOR || 'space').toLowerCase();
|
|
107
137
|
}
|
|
108
138
|
|
|
109
139
|
export function renderBlockBoundary(nextBlock, { compactSame = false } = {}) {
|
|
@@ -361,7 +391,7 @@ export function renderToolResult(data, eventType = 'tool_result') {
|
|
|
361
391
|
|
|
362
392
|
if (data._blocked) session.blockedOps++;
|
|
363
393
|
|
|
364
|
-
const { text, tone: t } = summarizeResult(tool, data);
|
|
394
|
+
const { text, tone: t } = summarizeResult(tool, data, data.args || {});
|
|
365
395
|
// Em dash reads more like prose than a system arrow.
|
|
366
396
|
const arrow = shellResultTool(tool)
|
|
367
397
|
? `${paint.text.dim('result')} ${paint.text.dim('—')}`
|
|
@@ -33,7 +33,7 @@ import {
|
|
|
33
33
|
writeOverlayFrame,
|
|
34
34
|
eraseOverlayFrame,
|
|
35
35
|
} from './repl-format.mjs';
|
|
36
|
-
import {
|
|
36
|
+
import { BahulamStreamClient } from '../core/stream-client.mjs';
|
|
37
37
|
import { getRecentSessions, getSessionDetail, buildResumeHistory, combineResumeSummaries } from '../core/local-store.mjs';
|
|
38
38
|
import { decideResumeMode, projectedTokensForChoice, formatTokens as formatCtxTokens } from '../core/resume-mode.mjs';
|
|
39
39
|
import { applyCompactSummary, localCompactSummary, parseCompactTailCount, prepareCompactHistory } from '../core/compact-history.mjs';
|
|
@@ -504,7 +504,7 @@ export async function summarizeResumeTranscript({
|
|
|
504
504
|
};
|
|
505
505
|
}
|
|
506
506
|
try {
|
|
507
|
-
const client = new
|
|
507
|
+
const client = new BahulamStreamClient({
|
|
508
508
|
baseUrl: creds.backendUrl,
|
|
509
509
|
token: creds.token,
|
|
510
510
|
toolExecutor,
|
|
@@ -62,6 +62,10 @@ export const runtime = {
|
|
|
62
62
|
// N lines under the spinner) instead of appending to the transcript.
|
|
63
63
|
// Full detail stays on the recorded cards (/expand, /last, `d`).
|
|
64
64
|
subAgentWindow: { active: false, lines: [] },
|
|
65
|
+
|
|
66
|
+
// PRD-092: Watch panel — toggled by /watch. When active, the spinner
|
|
67
|
+
// area renders a compact agent-activity summary instead of the spinner.
|
|
68
|
+
watchPanelActive: false,
|
|
65
69
|
};
|
|
66
70
|
|
|
67
71
|
// Full session state for the current CLI process. Set by the REPL loop
|
|
@@ -73,6 +77,13 @@ export const session = {
|
|
|
73
77
|
startTime: Date.now(),
|
|
74
78
|
inputTokens: 0,
|
|
75
79
|
outputTokens: 0,
|
|
80
|
+
// Per-turn context indicator for the dock strip. Updated at each
|
|
81
|
+
// AGENT_COMPLETE from the backend's usage.total_input_tokens (the
|
|
82
|
+
// cumulative input the primary agent sent this turn across all its
|
|
83
|
+
// internal inferences). Rough proxy for "how big is the prompt right
|
|
84
|
+
// now" — approximates what the NEXT user turn will pay before any
|
|
85
|
+
// growth. Reset by /new.
|
|
86
|
+
lastTurnInputTokens: 0,
|
|
76
87
|
toolCalls: 0, // primary-agent tool calls in the current turn
|
|
77
88
|
subAgentToolCalls: 0,// forwarded internal sub-agent tool calls in the current turn
|
|
78
89
|
totalToolCalls: 0, // across all turns
|
|
@@ -85,6 +96,7 @@ export const session = {
|
|
|
85
96
|
user: null, // { github_username, email, role }
|
|
86
97
|
model: null, // from backend user profile
|
|
87
98
|
modelLimits: {}, // role -> {model, context_length, max_output, source}
|
|
99
|
+
subAgentModels: {}, // role -> model from backend session_info
|
|
88
100
|
blockedOps: 0, // safety guardrail blocks
|
|
89
101
|
delegations: [], // agent delegation events: { from, to, time }
|
|
90
102
|
phases: [], // phase history: { name, time }
|