@memnexus-ai/mx-agent-cli 0.1.208 → 0.1.209

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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * CWE-150 render-layer test (#4350 security review).
3
+ *
4
+ * renderStartupHealth() prints fleet-supplied fields (team, latest_outcome,
5
+ * warning messages) to the operator's terminal. Any worktree can POST crafted
6
+ * control sequences straight to the API with the shared token, so the render
7
+ * layer must strip them before printing. This asserts the rendered output
8
+ * contains none of the injected sequences.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=startup-health-render.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-health-render.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/startup-health-render.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * CWE-150 render-layer test (#4350 security review).
3
+ *
4
+ * renderStartupHealth() prints fleet-supplied fields (team, latest_outcome,
5
+ * warning messages) to the operator's terminal. Any worktree can POST crafted
6
+ * control sequences straight to the API with the shared token, so the render
7
+ * layer must strip them before printing. This asserts the rendered output
8
+ * contains none of the injected sequences.
9
+ */
10
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
11
+ import chalk from 'chalk';
12
+ import { renderStartupHealth } from '../commands/dashboard.js';
13
+ const ESC = String.fromCharCode(27); // \x1b
14
+ const BEL = String.fromCharCode(7); // \x07
15
+ const SCREEN_CLEAR = ESC + '[2J';
16
+ const OSC_TITLE = ESC + ']0;OWNED' + BEL;
17
+ let logged;
18
+ const origLevel = chalk.level;
19
+ beforeEach(() => {
20
+ // Disable chalk styling so the only escape sequences that could appear in the
21
+ // output are ones that leaked through from the (hostile) input fields.
22
+ chalk.level = 0;
23
+ logged = '';
24
+ vi.spyOn(console, 'log').mockImplementation((...args) => {
25
+ logged += args.map((a) => String(a)).join(' ') + '\n';
26
+ });
27
+ });
28
+ afterEach(() => {
29
+ vi.restoreAllMocks();
30
+ chalk.level = origLevel;
31
+ });
32
+ describe('renderStartupHealth — control-sequence stripping', () => {
33
+ it('renders team, outcome, and warning message with the injected sequences absent', () => {
34
+ renderStartupHealth({
35
+ window_days: 7,
36
+ generated_at: new Date().toISOString(),
37
+ teams: [
38
+ {
39
+ team: `evil${SCREEN_CLEAR}team`,
40
+ latest_outcome: `ok${OSC_TITLE}`,
41
+ latest_started_at: new Date().toISOString(),
42
+ latest_warning_count: 1,
43
+ latest_error_count: 0,
44
+ report_count: 1,
45
+ total_warning_count: 1,
46
+ total_error_count: 0,
47
+ },
48
+ ],
49
+ top_warnings: [{ message: `boom${SCREEN_CLEAR}${OSC_TITLE}bar`, count: 3 }],
50
+ });
51
+ // No ESC byte, no screen-clear, no OSC payload anywhere in the printed output.
52
+ expect(logged.includes(ESC)).toBe(false);
53
+ expect(logged.includes('[2J')).toBe(false);
54
+ expect(logged.includes('OWNED')).toBe(false);
55
+ // The benign parts of each field still render.
56
+ expect(logged).toContain('evilteam');
57
+ expect(logged).toContain('boombar');
58
+ });
59
+ });
60
+ //# sourceMappingURL=startup-health-render.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-health-render.test.js","sourceRoot":"","sources":["../../src/__tests__/startup-health-render.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAE/D,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO;AAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO;AAC3C,MAAM,YAAY,GAAG,GAAG,GAAG,KAAK,CAAC;AACjC,MAAM,SAAS,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC;AAEzC,IAAI,MAAc,CAAC;AACnB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC;AAE9B,UAAU,CAAC,GAAG,EAAE;IACd,8EAA8E;IAC9E,uEAAuE;IACvE,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC;IAChB,MAAM,GAAG,EAAE,CAAC;IACZ,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,kBAAkB,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;QACjE,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACrB,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kDAAkD,EAAE,GAAG,EAAE;IAChE,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,mBAAmB,CAAC;YAClB,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACtC,KAAK,EAAE;gBACL;oBACE,IAAI,EAAE,OAAO,YAAY,MAAM;oBAC/B,cAAc,EAAE,KAAK,SAAS,EAAE;oBAChC,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBAC3C,oBAAoB,EAAE,CAAC;oBACvB,kBAAkB,EAAE,CAAC;oBACrB,YAAY,EAAE,CAAC;oBACf,mBAAmB,EAAE,CAAC;oBACtB,iBAAiB,EAAE,CAAC;iBACrB;aACF;YACD,YAAY,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,YAAY,GAAG,SAAS,KAAK,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;QAEH,+EAA+E;QAC/E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE7C,+CAA+C;QAC/C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -10,7 +10,7 @@
10
10
  * - the console-capture tee records every print without altering output
11
11
  */
12
12
  import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
13
- import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, existsSync, rmSync, chmodSync } from 'fs';
13
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, readdirSync, existsSync, rmSync, chmodSync } from 'fs';
14
14
  import { tmpdir } from 'os';
15
15
  import { join } from 'path';
16
16
  import { startupReport, inferLevel, stripAnsi, redactUrlCredentials } from '../lib/startup-report.js';
@@ -126,6 +126,39 @@ describe('record + finalize', () => {
126
126
  expect(raw).toHaveLength(1);
127
127
  expect(JSON.parse(raw[0]).outcome).toBe('ok');
128
128
  });
129
+ it('persists messages with terminal control sequences stripped (CWE-150)', () => {
130
+ const ESC = String.fromCharCode(27);
131
+ const BEL = String.fromCharCode(7);
132
+ startupReport.setContext({ worktree: 'ctrl-wt' });
133
+ startupReport.record('warning', `boom${ESC}[2J${ESC}]0;OWNED${BEL}bar`);
134
+ startupReport.finalize('ok');
135
+ const raw = readFileSync(logPath('ctrl-wt'), 'utf-8').trim();
136
+ // The whole persisted line must be free of ESC, screen-clear, and OSC payload.
137
+ expect(raw.includes(ESC)).toBe(false);
138
+ expect(raw.includes('[2J')).toBe(false);
139
+ expect(raw.includes('OWNED')).toBe(false);
140
+ const report = JSON.parse(raw);
141
+ expect(report.entries[0].message).toBe('boombar');
142
+ });
143
+ it('spools a copy of the report for central shipping (#4350 Phase 2)', () => {
144
+ startupReport.setContext({ worktree: 'ship-wt', team: 'shipteam' });
145
+ startupReport.record('warning', 'w');
146
+ startupReport.finalize('ok');
147
+ const spool = join(home, '.mx-agent', 'logs', 'startup', 'spool');
148
+ const files = readdirSync(spool).filter((f) => f.endsWith('.json'));
149
+ expect(files).toHaveLength(1);
150
+ const spooled = JSON.parse(readFileSync(join(spool, files[0]), 'utf-8'));
151
+ expect(spooled.worktree).toBe('ship-wt');
152
+ expect(spooled.outcome).toBe('ok');
153
+ });
154
+ it('fires the ship hook once on finalize (fire-and-forget)', () => {
155
+ const hook = vi.fn();
156
+ startupReport.setShipHook(hook);
157
+ startupReport.setContext({ worktree: 'hook-wt' });
158
+ startupReport.finalize('ok');
159
+ startupReport.finalize('error'); // idempotent — hook must not fire twice
160
+ expect(hook).toHaveBeenCalledTimes(1);
161
+ });
129
162
  it('falls back to team, then "unknown", for the file name', () => {
130
163
  startupReport.setContext({ team: 'teamx' }); // no worktree
131
164
  startupReport.record('info', 'x');
@@ -1 +1 @@
1
- {"version":3,"file":"startup-report.test.js","sourceRoot":"","sources":["../../src/__tests__/startup-report.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"startup-report.test.js","sourceRoot":"","sources":["../../src/__tests__/startup-report.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Tests for the central StartupReport shipper (platform v2.58 Phase 2, #4350).
3
+ *
4
+ * Covers the spool lifecycle and never-throw discipline:
5
+ * - spoolReport writes one file; flush POSTs and deletes on 2xx
6
+ * - POST failure (non-2xx / network) leaves the file spooled
7
+ * - no token → flush skips the POST and leaves everything spooled
8
+ * - 50-file cap drops the oldest beyond 50
9
+ * - 14-day age drop happens at spool-write time
10
+ * - spoolReport never throws under a read-only spool dir
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=startup-shipper.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-shipper.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/startup-shipper.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Tests for the central StartupReport shipper (platform v2.58 Phase 2, #4350).
3
+ *
4
+ * Covers the spool lifecycle and never-throw discipline:
5
+ * - spoolReport writes one file; flush POSTs and deletes on 2xx
6
+ * - POST failure (non-2xx / network) leaves the file spooled
7
+ * - no token → flush skips the POST and leaves everything spooled
8
+ * - 50-file cap drops the oldest beyond 50
9
+ * - 14-day age drop happens at spool-write time
10
+ * - spoolReport never throws under a read-only spool dir
11
+ */
12
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
13
+ import { mkdtempSync, mkdirSync, writeFileSync, readdirSync, rmSync, chmodSync, utimesSync } from 'fs';
14
+ import { tmpdir } from 'os';
15
+ import { join } from 'path';
16
+ import { spoolReport, flushSpool, spoolDir } from '../lib/startup-shipper.js';
17
+ let home;
18
+ const OLD_HOME = process.env.HOME;
19
+ function report(over = {}) {
20
+ return JSON.stringify({
21
+ schema_version: 1,
22
+ project: 'memnexus',
23
+ team: 'platform',
24
+ worktree: 'platform-wt',
25
+ machine: 'host-a',
26
+ cli_version: '2.58.0',
27
+ outcome: 'ok',
28
+ started_at: new Date().toISOString(),
29
+ entries: [{ ts: '', level: 'warning', message: 'w' }],
30
+ ...over,
31
+ });
32
+ }
33
+ function spoolFiles() {
34
+ try {
35
+ return readdirSync(spoolDir()).filter((f) => f.endsWith('.json'));
36
+ }
37
+ catch {
38
+ return [];
39
+ }
40
+ }
41
+ beforeEach(() => {
42
+ home = mkdtempSync(join(tmpdir(), 'mx-shipper-home-'));
43
+ process.env.HOME = home;
44
+ vi.unstubAllGlobals();
45
+ });
46
+ afterEach(() => {
47
+ vi.unstubAllGlobals();
48
+ // Restore perms so cleanup can remove read-only dirs created by a test.
49
+ try {
50
+ chmodSync(spoolDir(), 0o755);
51
+ }
52
+ catch { /* ignore */ }
53
+ rmSync(home, { recursive: true, force: true });
54
+ if (OLD_HOME === undefined)
55
+ delete process.env.HOME;
56
+ else
57
+ process.env.HOME = OLD_HOME;
58
+ });
59
+ describe('spoolReport', () => {
60
+ it('writes one JSON file to the spool dir', () => {
61
+ const p = spoolReport(report());
62
+ expect(p).toBeTruthy();
63
+ expect(spoolFiles().length).toBe(1);
64
+ });
65
+ it('never throws under a read-only spool dir (returns null)', () => {
66
+ mkdirSync(spoolDir(), { recursive: true });
67
+ chmodSync(spoolDir(), 0o500); // read+execute, no write
68
+ let result = 'sentinel';
69
+ expect(() => { result = spoolReport(report()); }).not.toThrow();
70
+ // On most CI the write fails and returns null; if the platform ignores the
71
+ // mode (e.g. running as root), it may still succeed — either is acceptable
72
+ // as long as it did not throw.
73
+ expect(result === null || typeof result === 'string').toBe(true);
74
+ });
75
+ it('drops files older than 14 days at write time', () => {
76
+ mkdirSync(spoolDir(), { recursive: true });
77
+ const stale = join(spoolDir(), 'stale.json');
78
+ writeFileSync(stale, report());
79
+ const old = Date.now() / 1000 - 15 * 24 * 60 * 60; // 15 days ago
80
+ utimesSync(stale, old, old);
81
+ spoolReport(report()); // triggers the age sweep
82
+ const files = spoolFiles();
83
+ expect(files).not.toContain('stale.json');
84
+ expect(files.length).toBe(1); // only the freshly-written report remains
85
+ });
86
+ });
87
+ describe('flushSpool — POST lifecycle', () => {
88
+ it('POSTs each spooled report and deletes it on 2xx', async () => {
89
+ spoolReport(report());
90
+ spoolReport(report({ worktree: 'wt2' }));
91
+ expect(spoolFiles().length).toBe(2);
92
+ const fetchMock = vi.fn(() => Promise.resolve(new Response(JSON.stringify({ stored: 1 }), { status: 201 })));
93
+ vi.stubGlobal('fetch', fetchMock);
94
+ const res = await flushSpool({ apiUrl: 'http://obs.test', apiToken: 'tok' });
95
+ expect(fetchMock).toHaveBeenCalledTimes(2);
96
+ expect(res.shipped).toBe(2);
97
+ expect(res.remaining).toBe(0);
98
+ expect(spoolFiles().length).toBe(0);
99
+ });
100
+ it('leaves the file spooled when the POST is not 2xx', async () => {
101
+ spoolReport(report());
102
+ vi.stubGlobal('fetch', vi.fn(() => Promise.resolve(new Response('nope', { status: 500 }))));
103
+ const res = await flushSpool({ apiUrl: 'http://obs.test', apiToken: 'tok' });
104
+ expect(res.shipped).toBe(0);
105
+ expect(spoolFiles().length).toBe(1);
106
+ });
107
+ it('leaves the file spooled when the POST rejects (network error)', async () => {
108
+ spoolReport(report());
109
+ vi.stubGlobal('fetch', vi.fn(() => Promise.reject(new Error('ECONNREFUSED'))));
110
+ const res = await flushSpool({ apiUrl: 'http://obs.test', apiToken: 'tok' });
111
+ expect(res.shipped).toBe(0);
112
+ expect(spoolFiles().length).toBe(1);
113
+ });
114
+ it('skips the POST entirely when no token is configured', async () => {
115
+ spoolReport(report());
116
+ const fetchMock = vi.fn(() => Promise.resolve(new Response('', { status: 201 })));
117
+ vi.stubGlobal('fetch', fetchMock);
118
+ const res = await flushSpool({ apiUrl: 'http://obs.test', apiToken: undefined });
119
+ expect(fetchMock).not.toHaveBeenCalled();
120
+ expect(res.shipped).toBe(0);
121
+ expect(res.remaining).toBe(1);
122
+ expect(spoolFiles().length).toBe(1);
123
+ });
124
+ });
125
+ describe('flushSpool — 50-file cap', () => {
126
+ it('drops the oldest files beyond 50 before shipping', async () => {
127
+ mkdirSync(spoolDir(), { recursive: true });
128
+ // Write 55 files with strictly increasing mtimes so "oldest" is deterministic.
129
+ for (let i = 0; i < 55; i++) {
130
+ const p = join(spoolDir(), `f${String(i).padStart(3, '0')}.json`);
131
+ writeFileSync(p, report({ worktree: `wt${i}` }));
132
+ const t = Date.now() / 1000 - (55 - i) * 60; // older files first
133
+ utimesSync(p, t, t);
134
+ }
135
+ expect(spoolFiles().length).toBe(55);
136
+ const logs = [];
137
+ vi.stubGlobal('fetch', vi.fn(() => Promise.resolve(new Response('', { status: 201 }))));
138
+ const res = await flushSpool({
139
+ apiUrl: 'http://obs.test',
140
+ apiToken: 'tok',
141
+ log: (m) => logs.push(m),
142
+ });
143
+ // 5 oldest dropped, 50 shipped (and deleted on 2xx) → none remain.
144
+ expect(res.shipped).toBe(50);
145
+ expect(spoolFiles().length).toBe(0);
146
+ expect(logs.some((m) => m.includes('exceeded 50'))).toBe(true);
147
+ });
148
+ });
149
+ //# sourceMappingURL=startup-shipper.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-shipper.test.js","sourceRoot":"","sources":["../../src/__tests__/startup-shipper.test.ts"],"names":[],"mappings":"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"}
@@ -8,5 +8,26 @@ export interface DashboardOptions {
8
8
  team?: string;
9
9
  days: number;
10
10
  }
11
+ interface StartupTeamSummary {
12
+ team: string;
13
+ latest_outcome: string;
14
+ latest_started_at: string;
15
+ latest_warning_count: number;
16
+ latest_error_count: number;
17
+ report_count: number;
18
+ total_warning_count: number;
19
+ total_error_count: number;
20
+ }
21
+ interface StartupSummaryResponse {
22
+ window_days: number;
23
+ generated_at: string;
24
+ teams: StartupTeamSummary[];
25
+ top_warnings: Array<{
26
+ message: string;
27
+ count: number;
28
+ }>;
29
+ }
30
+ export declare function renderStartupHealth(summary: StartupSummaryResponse): void;
11
31
  export declare function runDashboard(options: DashboardOptions): Promise<void>;
32
+ export {};
12
33
  //# sourceMappingURL=dashboard.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAmjBD,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqD3E"}
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/commands/dashboard.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAgED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AACD,UAAU,sBAAsB;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,YAAY,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAqgBD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,sBAAsB,GAAG,IAAI,CA2DzE;AAID,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0D3E"}
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import chalk from 'chalk';
8
8
  import { getConfigValue } from '../lib/config.js';
9
+ import { stripControlSequences } from '../lib/startup-report.js';
9
10
  import { calcLineCost, getRates } from '../lib/jsonl.js';
10
11
  import { listTeams } from '../lib/catalog.js';
11
12
  import { findProjectRoot } from '../lib/worktree.js';
@@ -110,6 +111,20 @@ async function fetchTrends(apiUrl, token, weeks = 4) {
110
111
  return null;
111
112
  }
112
113
  }
114
+ async function fetchStartupSummary(apiUrl, token, days) {
115
+ try {
116
+ const url = `${apiUrl}/v1/startup-reports/summary?days=${days}`;
117
+ const res = await fetch(url, {
118
+ headers: { Authorization: `Bearer ${token}` },
119
+ });
120
+ if (!res.ok)
121
+ return null;
122
+ return (await res.json());
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
113
128
  // ── Rendering ────────────────────────────────────────────────────────────────
114
129
  function aggregate(sessions) {
115
130
  const map = new Map();
@@ -433,6 +448,55 @@ function renderTopSessions(sessions) {
433
448
  }
434
449
  console.log();
435
450
  }
451
+ export function renderStartupHealth(summary) {
452
+ if (summary.teams.length === 0 && summary.top_warnings.length === 0)
453
+ return;
454
+ // CWE-150: every field below is fleet-supplied (any worktree can POST crafted
455
+ // reports directly to the API with the shared token). Strip all terminal
456
+ // control sequences before printing so a report cannot drive the operator's
457
+ // terminal (screen clear, title set, cursor moves).
458
+ const clean = stripControlSequences;
459
+ const W = { team: 22, outcome: 12, warn: 10, err: 10, reports: 10 };
460
+ const totalW = W.team + W.outcome + W.warn + W.err + W.reports + 2;
461
+ console.log(` ${chalk.cyan.bold('Startup Health')} ${chalk.dim(`(last ${summary.window_days} day${summary.window_days === 1 ? '' : 's'})`)}`);
462
+ console.log(chalk.dim(' ' + '─'.repeat(totalW)));
463
+ const h = (s, w) => chalk.bold(s.padStart(w));
464
+ console.log(` ${chalk.bold('Team'.padEnd(W.team))}` +
465
+ `${chalk.bold('Latest'.padEnd(W.outcome))}` +
466
+ `${h('Warnings', W.warn)}${h('Errors', W.err)}${h('Reports', W.reports)}`);
467
+ console.log(chalk.dim(' ' + '─'.repeat(totalW)));
468
+ const colorOutcome = (raw) => {
469
+ const o = clean(raw);
470
+ if (o === 'ok')
471
+ return chalk.green(o);
472
+ if (o === 'refused' || o === 'hard_stop')
473
+ return chalk.red(o);
474
+ return chalk.yellow(o || '—');
475
+ };
476
+ const teams = [...summary.teams].sort((a, b) => a.team.localeCompare(b.team));
477
+ for (const t of teams) {
478
+ const warnStr = t.total_warning_count > 0 ? chalk.yellow(String(t.total_warning_count)) : chalk.dim('0');
479
+ const errStr = t.total_error_count > 0 ? chalk.red(String(t.total_error_count)) : chalk.dim('0');
480
+ // padStart is offset by chalk escape length (10) for colored cells.
481
+ console.log(` ${chalk.white(clean(t.team).padEnd(W.team))}` +
482
+ `${colorOutcome(t.latest_outcome).padEnd(W.outcome + 10)}` +
483
+ `${warnStr.padStart(W.warn + 10)}` +
484
+ `${errStr.padStart(W.err + 10)}` +
485
+ `${String(t.report_count).padStart(W.reports)}`);
486
+ }
487
+ // Most frequent warning messages fleet-wide.
488
+ if (summary.top_warnings.length > 0) {
489
+ console.log(chalk.dim(' ' + '─'.repeat(totalW)));
490
+ console.log(` ${chalk.bold('Most frequent warnings (fleet)')}`);
491
+ for (const w of summary.top_warnings.slice(0, 10)) {
492
+ const cleaned = clean(w.message);
493
+ const msg = cleaned.length > 68 ? cleaned.slice(0, 65) + '...' : cleaned;
494
+ console.log(` ${chalk.yellow(String(w.count).padStart(4))} ${chalk.dim(msg)}`);
495
+ }
496
+ }
497
+ console.log(chalk.dim(' ' + '─'.repeat(totalW)));
498
+ console.log();
499
+ }
436
500
  // ── Entry point ──────────────────────────────────────────────────────────────
437
501
  export async function runDashboard(options) {
438
502
  const apiUrl = getConfigValue('observability-api-url') ||
@@ -457,18 +521,25 @@ export async function runDashboard(options) {
457
521
  // Non-fatal: if catalog unavailable, all teams treated as iteration agents
458
522
  }
459
523
  try {
460
- const [sessions, trends] = await Promise.all([
524
+ const [sessions, trends, startupSummary] = await Promise.all([
461
525
  fetchSessions(apiUrl, token, options.days, options.team),
462
526
  fetchTrends(apiUrl, token),
527
+ fetchStartupSummary(apiUrl, token, options.days),
463
528
  ]);
464
529
  if (sessions.length === 0) {
465
530
  console.log(chalk.dim('\n No sessions found for the specified time window.\n'));
531
+ // Startup health is independent of session telemetry — show it even when
532
+ // no sessions exist yet (e.g. a fresh fleet that has only run `start`).
533
+ if (startupSummary)
534
+ renderStartupHealth(startupSummary);
466
535
  return;
467
536
  }
468
537
  const teams = aggregate(sessions);
469
538
  renderFleet(teams, options.days, trends, serviceAgents);
470
539
  renderBehavioralCompliance(teams, options.days);
471
540
  renderDelegationBreakdown(teams, options.days);
541
+ if (startupSummary)
542
+ renderStartupHealth(startupSummary);
472
543
  renderTopSessions(sessions);
473
544
  }
474
545
  catch (err) {