agent-nuvira 2.7.0 → 2.7.2

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 (114) hide show
  1. package/dist/agents/orchestrator.d.ts.map +1 -1
  2. package/dist/agents/orchestrator.js +17 -3
  3. package/dist/agents/orchestrator.js.map +1 -1
  4. package/dist/app.js +26 -0
  5. package/dist/cli/chat.d.ts.map +1 -1
  6. package/dist/cli/chat.js +108 -2
  7. package/dist/cli/chat.js.map +1 -1
  8. package/dist/config/auth.js +18 -0
  9. package/dist/config/jwt.js +24 -0
  10. package/dist/config/keys.js +14 -0
  11. package/dist/gateway/chat-store.d.ts +32 -5
  12. package/dist/gateway/chat-store.d.ts.map +1 -1
  13. package/dist/gateway/chat-store.js +52 -6
  14. package/dist/gateway/chat-store.js.map +1 -1
  15. package/dist/gateway/registry.d.ts.map +1 -1
  16. package/dist/gateway/registry.js +54 -10
  17. package/dist/gateway/registry.js.map +1 -1
  18. package/dist/inference/model-validator.d.ts.map +1 -1
  19. package/dist/inference/model-validator.js +11 -1
  20. package/dist/inference/model-validator.js.map +1 -1
  21. package/dist/inference/tool-call-utils.d.ts +31 -0
  22. package/dist/inference/tool-call-utils.d.ts.map +1 -1
  23. package/dist/inference/tool-call-utils.js +41 -0
  24. package/dist/inference/tool-call-utils.js.map +1 -1
  25. package/dist/learning/reasoning-trace.d.ts +5 -3
  26. package/dist/learning/reasoning-trace.d.ts.map +1 -1
  27. package/dist/learning/reasoning-trace.js +2 -2
  28. package/dist/learning/reasoning-trace.js.map +1 -1
  29. package/dist/middleware/auth.js +30 -0
  30. package/dist/nlu/conversation-gate.js +1 -1
  31. package/dist/nlu/conversation-gate.js.map +1 -1
  32. package/dist/nlu/entities.d.ts.map +1 -1
  33. package/dist/nlu/entities.js +12 -0
  34. package/dist/nlu/entities.js.map +1 -1
  35. package/dist/nlu/intent.d.ts.map +1 -1
  36. package/dist/nlu/intent.js +83 -15
  37. package/dist/nlu/intent.js.map +1 -1
  38. package/dist/passport.js +34 -0
  39. package/dist/routes/auth.js +42 -0
  40. package/dist/routes/user.js +31 -0
  41. package/dist/server.js +17 -0
  42. package/dist/tools/pipeline-tool.d.ts.map +1 -1
  43. package/dist/tools/pipeline-tool.js +14 -0
  44. package/dist/tools/pipeline-tool.js.map +1 -1
  45. package/dist/tools/release-sync.d.ts +52 -16
  46. package/dist/tools/release-sync.d.ts.map +1 -1
  47. package/dist/tools/release-sync.js +143 -79
  48. package/dist/tools/release-sync.js.map +1 -1
  49. package/dist/web-dashboard/src/App.js +85 -0
  50. package/dist/web-dashboard/src/admin-auth.test.js +186 -0
  51. package/dist/web-dashboard/src/ansi.js +23 -0
  52. package/dist/web-dashboard/src/ansi.test.js +31 -0
  53. package/dist/web-dashboard/src/api-admin-auth.test.js +172 -0
  54. package/dist/web-dashboard/src/api-admin.test.js +65 -0
  55. package/dist/web-dashboard/src/api-hub.test.js +117 -0
  56. package/dist/web-dashboard/src/api.js +1421 -0
  57. package/dist/web-dashboard/src/api.test.js +51 -0
  58. package/dist/web-dashboard/src/artifacts.js +128 -0
  59. package/dist/web-dashboard/src/artifacts.test.js +139 -0
  60. package/dist/web-dashboard/src/components/AdminPanel.js +567 -0
  61. package/dist/web-dashboard/src/components/AdminPanel.test.js +288 -0
  62. package/dist/web-dashboard/src/components/AgentHub.js +1580 -0
  63. package/dist/web-dashboard/src/components/AgentHub.test.js +343 -0
  64. package/dist/web-dashboard/src/components/BedrockOnboarding.js +320 -0
  65. package/dist/web-dashboard/src/components/BenchmarkCharts.js +228 -0
  66. package/dist/web-dashboard/src/components/ChatPage.js +1586 -0
  67. package/dist/web-dashboard/src/components/ChatPage.test.js +899 -0
  68. package/dist/web-dashboard/src/components/ContactsPage.js +141 -0
  69. package/dist/web-dashboard/src/components/CostDashboard.js +105 -0
  70. package/dist/web-dashboard/src/components/DAGView.js +477 -0
  71. package/dist/web-dashboard/src/components/DAGView.test.js +147 -0
  72. package/dist/web-dashboard/src/components/EnvVarEditor.js +138 -0
  73. package/dist/web-dashboard/src/components/EvalsPage.js +73 -0
  74. package/dist/web-dashboard/src/components/EvalsPage.test.js +120 -0
  75. package/dist/web-dashboard/src/components/ExecutionHistory.js +201 -0
  76. package/dist/web-dashboard/src/components/GatewayPage.js +40 -0
  77. package/dist/web-dashboard/src/components/GatewayPage.test.js +74 -0
  78. package/dist/web-dashboard/src/components/HealthPanel.js +68 -0
  79. package/dist/web-dashboard/src/components/HistoryBrowser.js +34 -0
  80. package/dist/web-dashboard/src/components/Layout.js +50 -0
  81. package/dist/web-dashboard/src/components/Markdown.js +152 -0
  82. package/dist/web-dashboard/src/components/Markdown.test.js +126 -0
  83. package/dist/web-dashboard/src/components/MarkdownZeroDep.js +237 -0
  84. package/dist/web-dashboard/src/components/MemoryPanel.js +81 -0
  85. package/dist/web-dashboard/src/components/ModelTimeline.js +298 -0
  86. package/dist/web-dashboard/src/components/ModelsPanel.js +1484 -0
  87. package/dist/web-dashboard/src/components/ModelsPanel.test.js +460 -0
  88. package/dist/web-dashboard/src/components/Overview.js +123 -0
  89. package/dist/web-dashboard/src/components/PhaseTimeline.js +359 -0
  90. package/dist/web-dashboard/src/components/PhaseTimeline.test.js +234 -0
  91. package/dist/web-dashboard/src/components/PlatformConfigSection.js +384 -0
  92. package/dist/web-dashboard/src/components/PlatformConfigSection.test.js +106 -0
  93. package/dist/web-dashboard/src/components/PlatformsPage.js +250 -0
  94. package/dist/web-dashboard/src/components/QuotaPanel.js +159 -0
  95. package/dist/web-dashboard/src/components/QuotaPanel.test.js +85 -0
  96. package/dist/web-dashboard/src/components/RequestsPanel.js +229 -0
  97. package/dist/web-dashboard/src/components/RequestsPanel.test.js +103 -0
  98. package/dist/web-dashboard/src/components/RoutingInsightsPanel.js +938 -0
  99. package/dist/web-dashboard/src/components/RoutingInsightsPanel.test.js +339 -0
  100. package/dist/web-dashboard/src/components/RoutingWalkthrough.js +408 -0
  101. package/dist/web-dashboard/src/components/RoutingWalkthrough.test.js +209 -0
  102. package/dist/web-dashboard/src/components/TaskConsole.js +119 -0
  103. package/dist/web-dashboard/src/components/TaskConsole.test.js +123 -0
  104. package/dist/web-dashboard/src/components/TasksPage.js +256 -0
  105. package/dist/web-dashboard/src/components/TasksPage.test.js +103 -0
  106. package/dist/web-dashboard/src/components/TracePanel.js +306 -0
  107. package/dist/web-dashboard/src/components/WhatsAppPanel.js +195 -0
  108. package/dist/web-dashboard/src/components/WhatsAppPanel.test.js +122 -0
  109. package/dist/web-dashboard/src/jsonOrNull.js +37 -0
  110. package/dist/web-dashboard/src/main.js +15 -0
  111. package/dist/web-dashboard/src/mask.js +11 -0
  112. package/dist/web-dashboard/vite.config.js +23 -0
  113. package/dist/web-dashboard/vitest.config.js +15 -0
  114. package/package.json +5 -3
@@ -10,127 +10,191 @@
10
10
  * `vX.Y.Z · N tests` badge, `docs/COMMANDS.md` carries a `nuvira vX.Y.x`
11
11
  * header), and NO post-publish diff existed.
12
12
  *
13
- * Deterministic and pure at the core (`findReleaseDrift` fixture-testable):
14
- * each release-marker pattern is matched and compared against the CURRENT
15
- * version; a marker that still names an older version is a gap. Historical
16
- * "Since v1.60.x" notes are deliberately NOT markers only the three
17
- * release-marker patterns below are checked, so nothing false-positives.
13
+ * P5a.2 AUTO-FIX: detection alone left the fix to a human (or a lucky
14
+ * agent turn). Since every marker is a NARROW, version-bearing regex, the
15
+ * fix is deterministic: rewrite the stale version token, keep everything
16
+ * else byte-identical, then RE-DETECT on the result (a fix that does not
17
+ * verify is reported as failed, never silently claimed). `runReleaseSync`
18
+ * now fixes by default; `reportOnly` opts out. File writes are surgical
19
+ * (target file, matched span only) and failures are best-effort — a sync
20
+ * failure must never mark the publish failed.
21
+ *
22
+ * Deterministic and pure at the core (`findReleaseDrift` / `fixReleaseDrift`
23
+ * — fixture-testable): each release-marker pattern is matched and compared
24
+ * against the CURRENT version; a marker that still names an older version is
25
+ * a gap. Historical "Since v1.60.x" notes are deliberately NOT markers —
26
+ * only the three release-marker patterns below are checked, so nothing
27
+ * false-positives.
18
28
  *
19
29
  * Best-effort by construction: a missing/unreadable sync target, or an
20
30
  * emission failure, never throws — a sync check failure must never mark the
21
31
  * publish failed (the brief's hard rule).
22
32
  */
23
- import { readFileSync, existsSync } from 'node:fs';
33
+ import { readFileSync, writeFileSync, existsSync } from 'node:fs';
24
34
  import { join } from 'node:path';
25
35
  /** The sync targets scanned after a publish (relative to the workspace root). */
26
36
  export const SYNC_TARGETS = ['website/index.html', 'docs/COMMANDS.md'];
37
+ const RELEASE_MARKERS = [
38
+ {
39
+ kind: 'current-release',
40
+ // Marker 1 — the website's "Current release" callout.
41
+ pattern: /Current release <strong>v(\d+\.\d+\.\d+)<\/strong>/g,
42
+ render: (_full, stale, fixed) => _full.replace(`v${stale}`, `v${fixed}`),
43
+ },
44
+ {
45
+ kind: 'test-count-badge',
46
+ // Marker 2 — the arch-tier "vX.Y.Z · N tests" badge (N is comma-grouped).
47
+ pattern: /v(\d+\.\d+\.\d+) · [\d,]+ tests/g,
48
+ render: (_full, stale, fixed) => _full.replace(`v${stale}`, `v${fixed}`),
49
+ },
50
+ {
51
+ kind: 'cli-version-header',
52
+ // Marker 3 — the docs "`buff` vX.Y.x" / "`nuvira` vX.Y.x" CLI header
53
+ // (major.minor only). COMMANDS.md has used both binary names.
54
+ pattern: /`?(?:buff|nuvira)`? v(\d+\.\d+)\.x/g,
55
+ render: (_full, stale, fixed) => _full.replace(`v${stale}.x`, `v${fixed}.x`),
56
+ },
57
+ ];
58
+ /** 1-based line number of a character offset. */
59
+ function lineNumberAt(text, index) {
60
+ let line = 1;
61
+ for (let i = 0; i < index && i < text.length; i++) {
62
+ if (text[i] === '\n')
63
+ line++;
64
+ }
65
+ return line;
66
+ }
27
67
  /**
28
68
  * Pure drift detector — the testable core. Scans one file's text for the
29
69
  * release-marker patterns and returns every marker whose version does NOT
30
70
  * match the current (published) version. Never throws.
31
- *
32
- * Markers (deliberately narrow — historical notes are not markers):
33
- * 1. `Current release <strong>vX.Y.Z</strong>` → exact version
34
- * 2. `vX.Y.Z · N tests` (the arch-tier badge) → exact version
35
- * 3. `nuvira vX.Y.x` (COMMANDS.md header) → major.minor only
36
71
  */
37
72
  export function findReleaseDrift(text, file, currentVersion) {
38
73
  const gaps = [];
39
74
  const clean = currentVersion.trim().replace(/^v/, '');
40
75
  const expectedExact = `v${clean}`;
41
76
  const expectedMajorMinor = clean.split('.').slice(0, 2).join('.');
42
- // Marker 1 the website's "Current release" callout.
43
- const currentRe = /Current release <strong>v(\d+\.\d+\.\d+)<\/strong>/g;
44
- let m;
45
- while ((m = currentRe.exec(text)) !== null) {
46
- const found = m[1];
47
- if (found !== clean) {
48
- gaps.push({
49
- file,
50
- line: lineNumberAt(text, m.index),
51
- found: `v${found}`,
52
- expected: expectedExact,
53
- kind: 'current-release',
54
- });
55
- }
56
- }
57
- // Marker 2 — the arch-tier "vX.Y.Z · N tests" badge (N is comma-grouped,
58
- // e.g. "4,556 tests").
59
- const badgeRe = /v(\d+\.\d+\.\d+) · [\d,]+ tests/g;
60
- while ((m = badgeRe.exec(text)) !== null) {
61
- const found = m[1];
62
- if (found !== clean) {
63
- gaps.push({
64
- file,
65
- line: lineNumberAt(text, m.index),
66
- found: `v${found}`,
67
- expected: expectedExact,
68
- kind: 'test-count-badge',
69
- });
70
- }
71
- }
72
- // Marker 3 — the docs "`buff` vX.Y.x" / "`nuvira` vX.Y.x" CLI header
73
- // (major.minor only). COMMANDS.md has used both binary names
74
- // ("`nuvira` v1.74.x" observed live); tolerate backticked or bare.
75
- const cliRe = /`?(buff|nuvira)`? v(\d+\.\d+)\.x/g;
76
- while ((m = cliRe.exec(text)) !== null) {
77
- const found = m[2];
78
- if (found !== expectedMajorMinor) {
79
- gaps.push({
80
- file,
81
- line: lineNumberAt(text, m.index),
82
- found: `v${found}.x`,
83
- expected: `v${expectedMajorMinor}.x`,
84
- kind: 'cli-version-header',
85
- });
77
+ for (const marker of RELEASE_MARKERS) {
78
+ marker.pattern.lastIndex = 0;
79
+ let m;
80
+ while ((m = marker.pattern.exec(text)) !== null) {
81
+ const found = m[1];
82
+ const stale = marker.kind === 'cli-version-header'
83
+ ? found !== expectedMajorMinor
84
+ : found !== clean;
85
+ if (stale) {
86
+ gaps.push({
87
+ file,
88
+ line: lineNumberAt(text, m.index),
89
+ found: marker.kind === 'cli-version-header' ? `v${found}.x` : `v${found}`,
90
+ expected: marker.kind === 'cli-version-header' ? `v${expectedMajorMinor}.x` : expectedExact,
91
+ kind: marker.kind,
92
+ });
93
+ }
86
94
  }
87
95
  }
88
96
  return gaps;
89
97
  }
90
- /** 1-based line number of a character offset. */
91
- function lineNumberAt(text, index) {
92
- let line = 1;
93
- for (let i = 0; i < index && i < text.length; i++) {
94
- if (text[i] === '\n')
95
- line++;
98
+ /**
99
+ * P5a.2 — pure marker patcher. Rewrites ONLY the stale version tokens of the
100
+ * release markers in `text` to `currentVersion`; every other byte is kept.
101
+ * Deterministic: same input + version same output. Companion to
102
+ * `findReleaseDrift` (shared marker table), so anything detection would flag,
103
+ * the patcher fixes — and vice versa.
104
+ */
105
+ export function fixReleaseDrift(text, currentVersion) {
106
+ const clean = currentVersion.trim().replace(/^v/, '');
107
+ const expectedMajorMinor = clean.split('.').slice(0, 2).join('.');
108
+ let out = text;
109
+ for (const marker of RELEASE_MARKERS) {
110
+ marker.pattern.lastIndex = 0;
111
+ out = out.replace(marker.pattern, (full, stale) => {
112
+ const fixed = marker.kind === 'cli-version-header' ? expectedMajorMinor : clean;
113
+ return stale === fixed ? full : marker.render(full, stale, fixed);
114
+ });
96
115
  }
97
- return line;
116
+ return out;
98
117
  }
99
118
  /** Read a sync target's text (empty string when missing/unreadable). */
100
119
  function readTarget(root, target) {
101
120
  try {
102
121
  const p = join(root, target);
103
- return existsSync(p) ? readFileSync(p, 'utf-8') : '';
122
+ if (!existsSync(p))
123
+ return { text: '', ok: false };
124
+ return { text: readFileSync(p, 'utf-8'), ok: true };
104
125
  }
105
126
  catch {
106
- return '';
127
+ return { text: '', ok: false };
128
+ }
129
+ }
130
+ /** Write a sync target (false on any failure — reported, never thrown). */
131
+ function writeTarget(root, target, text) {
132
+ try {
133
+ writeFileSync(join(root, target), text, 'utf-8');
134
+ return true;
135
+ }
136
+ catch {
137
+ return false;
107
138
  }
108
139
  }
109
140
  /**
110
- * Run the post-publish sync check: scan every sync target under the
111
- * workspace root for stale release markers vs the published version. Emits a
112
- * structured `release:sync` event (best-effort) so a future GUI card can
113
- * render the gaps with an offer-to-fix. Returns a model-feedable summary —
114
- * never throws.
141
+ * P5a.2 — run the post-publish sync pass with AUTO-FIX. Detects drift,
142
+ * patches every stale marker, re-reads and RE-DETECTS to verify, and emits a
143
+ * structured `release:sync` event. `reportOnly: true` restores the old
144
+ * detect-only behavior. Returns a model-feedable summary — never throws.
115
145
  */
116
- export function runReleaseSync(currentVersion, ctx) {
146
+ export function runReleaseSync(currentVersion, ctx, opts) {
117
147
  const root = ctx.cwd || process.cwd();
118
148
  const clean = currentVersion.trim().replace(/^v/, '');
149
+ const reportOnly = opts?.reportOnly === true;
119
150
  const gaps = [];
151
+ const fixes = [];
152
+ const errors = [];
120
153
  for (const target of SYNC_TARGETS) {
121
- const text = readTarget(root, target);
122
- if (!text)
154
+ const read = readTarget(root, target);
155
+ if (!read.ok || !read.text)
123
156
  continue; // a missing target is not a gap — best-effort
124
- gaps.push(...findReleaseDrift(text, target, clean));
157
+ const found = findReleaseDrift(read.text, target, clean);
158
+ gaps.push(...found);
159
+ if (found.length === 0 || reportOnly)
160
+ continue;
161
+ const fixedText = fixReleaseDrift(read.text, clean);
162
+ if (!writeTarget(root, target, fixedText)) {
163
+ errors.push(`${target}: write failed (read-only checkout?) — fix manually or commit the version bump first.`);
164
+ continue;
165
+ }
166
+ // Verify: re-read the file we just wrote and re-detect. A fix that does
167
+ // not verify is reported as failed — never silently claimed as done.
168
+ const verify = readTarget(root, target);
169
+ const remaining = verify.ok ? findReleaseDrift(verify.text, target, clean) : found;
170
+ for (const gap of found) {
171
+ const stillThere = remaining.some((r) => r.kind === gap.kind && r.line === gap.line);
172
+ fixes.push({ file: gap.file, line: gap.line, kind: gap.kind, found: gap.found, expected: gap.expected, verified: !stillThere });
173
+ }
174
+ }
175
+ const fixedCount = fixes.filter((f) => f.verified).length;
176
+ const failedCount = fixes.filter((f) => !f.verified).length;
177
+ const synced = gaps.length === 0 || (reportOnly === false && failedCount === 0 && errors.length === 0);
178
+ try {
179
+ ctx.emit?.('release:sync', { version: clean, gaps, fixes, synced, reportOnly, errors });
180
+ }
181
+ catch {
182
+ /* best-effort — the text summary below still ships */
125
183
  }
126
184
  if (gaps.length === 0) {
127
- ctx.emit?.('release:sync', { version: clean, gaps: [], synced: true });
128
185
  return `✅ Release-sync: website/docs already at v${clean} — no version drift.`;
129
186
  }
130
- const lines = gaps.map((g) => ` • ${g.file}:${g.line} — ${g.kind} shows ${g.found}, should be ${g.expected}`);
131
- ctx.emit?.('release:sync', { version: clean, gaps, synced: false });
132
- return (`⚠️ Release-sync: ${gaps.length} stale release marker(s) after publishing v${clean}:\n` +
133
- lines.join('\n') +
134
- `\nOffer to fix them (ask_user → edit_file) so the website/docs stay at the release level.`);
187
+ if (reportOnly) {
188
+ const lines = gaps.map((g) => ` • ${g.file}:${g.line} ${g.kind} shows ${g.found}, should be ${g.expected}`);
189
+ return (`⚠️ Release-sync: ${gaps.length} stale release marker(s) vs v${clean}:\n` +
190
+ lines.join('\n') +
191
+ `\nOffer to fix them (ask_user → edit_file) so the website/docs stay at the release level.`);
192
+ }
193
+ const fixLines = fixes.map((f) => ` • ${f.file}:${f.line} — ${f.kind} ${f.found} → ${f.expected}${f.verified ? ' ✅' : ' ❌ verify failed'}`);
194
+ const errorLines = errors.length > 0 ? `\n⚠️ ${errors.join('\n⚠️ ')}` : '';
195
+ const status = failedCount === 0 && errors.length === 0
196
+ ? `✅ Release-sync auto-fixed ${fixedCount} stale marker(s) for v${clean} — verified by re-scan.`
197
+ : `⚠️ Release-sync: ${fixedCount} fixed, ${failedCount} failed for v${clean}:`;
198
+ return `${status}\n${fixLines.join('\n')}${errorLines}`;
135
199
  }
136
200
  //# sourceMappingURL=release-sync.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"release-sync.js","sourceRoot":"","sources":["../../src/tools/release-sync.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"release-sync.js","sourceRoot":"","sources":["../../src/tools/release-sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = App;
7
+ const react_1 = require("react");
8
+ const react_router_dom_1 = require("react-router-dom");
9
+ const api_1 = require("./api");
10
+ const Layout_1 = __importDefault(require("./components/Layout"));
11
+ const Overview_1 = __importDefault(require("./components/Overview"));
12
+ const DAGView_1 = __importDefault(require("./components/DAGView"));
13
+ const CostDashboard_1 = __importDefault(require("./components/CostDashboard"));
14
+ const BenchmarkCharts_1 = __importDefault(require("./components/BenchmarkCharts"));
15
+ const HealthPanel_1 = __importDefault(require("./components/HealthPanel"));
16
+ const ModelsPanel_1 = __importDefault(require("./components/ModelsPanel"));
17
+ const RoutingInsightsPanel_1 = __importDefault(require("./components/RoutingInsightsPanel"));
18
+ const RequestsPanel_1 = __importDefault(require("./components/RequestsPanel"));
19
+ const TracePanel_1 = __importDefault(require("./components/TracePanel"));
20
+ const AdminPanel_1 = __importDefault(require("./components/AdminPanel"));
21
+ const AgentHub_1 = __importDefault(require("./components/AgentHub"));
22
+ const TasksPage_1 = __importDefault(require("./components/TasksPage"));
23
+ const ChatPage_1 = __importDefault(require("./components/ChatPage"));
24
+ const EvalsPage_1 = __importDefault(require("./components/EvalsPage"));
25
+ const GatewayPage_1 = __importDefault(require("./components/GatewayPage"));
26
+ const PlatformsPage_1 = __importDefault(require("./components/PlatformsPage"));
27
+ const BedrockOnboarding_1 = __importDefault(require("./components/BedrockOnboarding"));
28
+ const ContactsPage_1 = __importDefault(require("./components/ContactsPage"));
29
+ const ModelTimeline_1 = __importDefault(require("./components/ModelTimeline"));
30
+ function App() {
31
+ const [data, setData] = (0, react_1.useState)(null);
32
+ const [connected, setConnected] = (0, react_1.useState)(false);
33
+ const [lastUpdated, setLastUpdated] = (0, react_1.useState)('--');
34
+ const handleData = (0, react_1.useCallback)((d) => {
35
+ setData(d);
36
+ setLastUpdated(new Date().toLocaleTimeString());
37
+ }, []);
38
+ const handleConnection = (0, react_1.useCallback)((c) => {
39
+ setConnected(c);
40
+ }, []);
41
+ (0, react_1.useEffect)(() => {
42
+ // Fetch initial data
43
+ api_1.dashboardAPI.fetchAll().then((d) => {
44
+ if (d)
45
+ handleData(d);
46
+ });
47
+ // Subscribe to SSE updates
48
+ const unsubData = api_1.dashboardAPI.subscribe(handleData);
49
+ const unsubConn = api_1.dashboardAPI.onConnectionChange(handleConnection);
50
+ api_1.dashboardAPI.connect();
51
+ return () => {
52
+ unsubData();
53
+ unsubConn();
54
+ api_1.dashboardAPI.disconnect();
55
+ };
56
+ }, [handleData, handleConnection]);
57
+ return (<Layout_1.default connected={connected} lastUpdated={lastUpdated}>
58
+ <react_router_dom_1.Routes>
59
+ {/* Phase 5 — Chat is the front door; Overview (and every other room)
60
+ stays reachable as a panel, never required. */}
61
+ <react_router_dom_1.Route path="/" element={<ChatPage_1.default />}/>
62
+ <react_router_dom_1.Route path="/overview" element={<Overview_1.default data={data}/>}/>
63
+ <react_router_dom_1.Route path="/chat" element={<react_router_dom_1.Navigate to="/" replace/>}/>
64
+ <react_router_dom_1.Route path="/dag" element={<DAGView_1.default data={data}/>}/>
65
+ <react_router_dom_1.Route path="/costs" element={<CostDashboard_1.default data={data}/>}/>
66
+ <react_router_dom_1.Route path="/benchmarks" element={<BenchmarkCharts_1.default data={data}/>}/>
67
+ <react_router_dom_1.Route path="/models" element={<ModelsPanel_1.default />}/>
68
+ <react_router_dom_1.Route path="/models/timeline" element={<ModelTimeline_1.default />}/>
69
+ <react_router_dom_1.Route path="/routing" element={<RoutingInsightsPanel_1.default data={data}/>}/>
70
+ <react_router_dom_1.Route path="/requests" element={<RequestsPanel_1.default data={data}/>}/>
71
+ <react_router_dom_1.Route path="/traces" element={<TracePanel_1.default />}/>
72
+ <react_router_dom_1.Route path="/hub" element={<AgentHub_1.default />}/>
73
+ <react_router_dom_1.Route path="/tasks" element={<TasksPage_1.default />}/>
74
+ <react_router_dom_1.Route path="/chat" element={<ChatPage_1.default />}/>
75
+ <react_router_dom_1.Route path="/evals" element={<EvalsPage_1.default data={data}/>}/>
76
+ <react_router_dom_1.Route path="/platforms" element={<PlatformsPage_1.default />}/>
77
+ <react_router_dom_1.Route path="/bedrock" element={<BedrockOnboarding_1.default canWrite={true} sessionExpired={(msg) => console.error(msg)}/>}/>
78
+ <react_router_dom_1.Route path="/contacts" element={<ContactsPage_1.default />}/>
79
+ <react_router_dom_1.Route path="/gateway" element={<GatewayPage_1.default />}/>
80
+ <react_router_dom_1.Route path="/system" element={<HealthPanel_1.default data={data}/>}/>
81
+ <react_router_dom_1.Route path="/admin" element={<AdminPanel_1.default />}/>
82
+ <react_router_dom_1.Route path="*" element={<react_router_dom_1.Navigate to="/" replace/>}/>
83
+ </react_router_dom_1.Routes>
84
+ </Layout_1.default>);
85
+ }
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * Admin-auth module tests (Sessions 18 + 19).
4
+ *
5
+ * Session 18: the user-id + password gate (scrypt, env override, Bearer
6
+ * sessions). Session 19: multi-user + RBAC roles — the credential file stores
7
+ * a users map with roles, rbac.json assignments override the stored role (CLI
8
+ * governance parity), and sessions carry the acting role. These tests pin the
9
+ * security properties: passwords never on disk, wrong passwords fail, legacy
10
+ * single-user files migrate, rbac wins over the stored role, and the last
11
+ * admin can't be removed.
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const vitest_1 = require("vitest");
15
+ const paths_1 = require("../../config/paths");
16
+ const node_fs_1 = require("node:fs");
17
+ const node_os_1 = require("node:os");
18
+ const node_path_1 = require("node:path");
19
+ const admin_auth_1 = require("./admin-auth");
20
+ (0, vitest_1.describe)('hashAdminPassword / verifyAdminPassword', () => {
21
+ (0, vitest_1.it)('round-trips a password (unique salt per hash)', () => {
22
+ const a = (0, admin_auth_1.hashAdminPassword)('s3cret-pass');
23
+ const b = (0, admin_auth_1.hashAdminPassword)('s3cret-pass');
24
+ (0, vitest_1.expect)(a.salt).not.toBe(b.salt);
25
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdminPassword)('s3cret-pass', a.salt, a.hash)).toBe(true);
26
+ });
27
+ (0, vitest_1.it)('rejects a wrong password and a wrong salt', () => {
28
+ const { salt, hash } = (0, admin_auth_1.hashAdminPassword)('right-password');
29
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdminPassword)('wrong-password', salt, hash)).toBe(false);
30
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdminPassword)('right-password', 'ffffffffffffffff', hash)).toBe(false);
31
+ });
32
+ });
33
+ (0, vitest_1.describe)('multi-user credential store (config-dir scoped)', () => {
34
+ let dir;
35
+ (0, vitest_1.beforeEach)(() => {
36
+ dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'buff-admin-auth-'));
37
+ });
38
+ (0, vitest_1.afterEach)(() => {
39
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
40
+ });
41
+ (0, vitest_1.it)('stores users with roles — passwords never on disk', () => {
42
+ const admin = (0, admin_auth_1.writeAdminUser)('admin', 'super-secret-pass', 'admin', dir);
43
+ (0, vitest_1.expect)(admin.role).toBe('admin');
44
+ const op = (0, admin_auth_1.writeAdminUser)('op', 'operator-pass-1', 'operator', dir);
45
+ (0, vitest_1.expect)(op.role).toBe('operator');
46
+ const raw = (0, node_fs_1.readFileSync)((0, node_path_1.join)(dir, 'dashboard-admin.json'), 'utf-8');
47
+ (0, vitest_1.expect)(raw).not.toContain('super-secret-pass');
48
+ (0, vitest_1.expect)(raw).not.toContain('operator-pass-1');
49
+ const users = (0, admin_auth_1.readAdminUsers)(dir);
50
+ (0, vitest_1.expect)(Object.keys(users).sort()).toEqual(['admin', 'op']);
51
+ (0, vitest_1.expect)(users.admin.role).toBe('admin');
52
+ (0, vitest_1.expect)(users.op.role).toBe('operator');
53
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'super-secret-pass', dir)).toBe(true);
54
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('op', 'operator-pass-1', dir)).toBe(true);
55
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'wrong', dir)).toBe(false);
56
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('ghost', 'super-secret-pass', dir)).toBe(false);
57
+ (0, vitest_1.expect)((0, admin_auth_1.isAdminConfigured)(dir)).toBe(true);
58
+ });
59
+ (0, vitest_1.it)('listAdminUsers excludes salt/hash; removeAdminUser deletes; countAdminRoleUsers counts admins', () => {
60
+ (0, admin_auth_1.writeAdminUser)('admin', 'admin-pass-123', 'admin', dir);
61
+ (0, admin_auth_1.writeAdminUser)('op', 'operator-pass-1', 'operator', dir);
62
+ (0, admin_auth_1.writeAdminUser)('view', 'viewer-pass-12', 'viewer', dir);
63
+ const listed = (0, admin_auth_1.listAdminUsers)(dir);
64
+ (0, vitest_1.expect)(listed).toHaveLength(3);
65
+ for (const u of listed) {
66
+ (0, vitest_1.expect)(u).not.toHaveProperty('salt');
67
+ (0, vitest_1.expect)(u).not.toHaveProperty('hash');
68
+ }
69
+ (0, vitest_1.expect)((0, admin_auth_1.countAdminRoleUsers)(dir)).toBe(1);
70
+ (0, vitest_1.expect)((0, admin_auth_1.removeAdminUser)('op', dir)).toBe(true);
71
+ (0, vitest_1.expect)((0, admin_auth_1.removeAdminUser)('op', dir)).toBe(false);
72
+ (0, vitest_1.expect)((0, admin_auth_1.listAdminUsers)(dir).map((u) => u.user)).toEqual(['admin', 'view']);
73
+ });
74
+ (0, vitest_1.it)('migrates the legacy single-user file shape to an admin user', () => {
75
+ // Session 18 shape: { user, salt, hash, createdAt } (no users wrapper).
76
+ const { salt, hash } = (0, admin_auth_1.hashAdminPassword)('legacy-pass');
77
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, 'dashboard-admin.json'), JSON.stringify({ user: 'admin', salt, hash, createdAt: 123 }), 'utf-8');
78
+ const users = (0, admin_auth_1.readAdminUsers)(dir);
79
+ (0, vitest_1.expect)(users.admin.role).toBe('admin');
80
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'legacy-pass', dir)).toBe(true);
81
+ (0, vitest_1.expect)((0, admin_auth_1.isAdminConfigured)(dir)).toBe(true);
82
+ });
83
+ (0, vitest_1.it)('a corrupt file reads as unconfigured (never throws, never downgrades to open)', () => {
84
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, 'dashboard-admin.json'), '{not json', 'utf-8');
85
+ (0, vitest_1.expect)((0, admin_auth_1.readAdminUsers)(dir)).toBeNull();
86
+ (0, vitest_1.expect)((0, admin_auth_1.isAdminConfigured)(dir)).toBe(false);
87
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'anything', dir)).toBe(false);
88
+ });
89
+ });
90
+ (0, vitest_1.describe)('roleForUser — rbac.json wins over the stored role (CLI parity)', () => {
91
+ let dir;
92
+ (0, vitest_1.beforeEach)(() => {
93
+ dir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'buff-admin-auth-'));
94
+ });
95
+ (0, vitest_1.afterEach)(() => {
96
+ (0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
97
+ });
98
+ (0, vitest_1.it)('uses the credential role when rbac.json has no assignment', () => {
99
+ (0, admin_auth_1.writeAdminUser)('op', 'operator-pass-1', 'operator', dir);
100
+ (0, vitest_1.expect)((0, admin_auth_1.roleForUser)('op', dir)).toBe('operator');
101
+ });
102
+ (0, vitest_1.it)('an rbac.json assignment overrides the stored role (a viewer in rbac is a viewer here)', () => {
103
+ (0, admin_auth_1.writeAdminUser)('op', 'operator-pass-1', 'operator', dir);
104
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(dir, 'rbac.json'), JSON.stringify({ version: 1, users: { op: { role: 'viewer', addedAt: Date.now(), via: 'local' } } }), 'utf-8');
105
+ // rbac wins: the dashboard cannot escalate a user the CLI governs as viewer.
106
+ (0, vitest_1.expect)((0, admin_auth_1.roleForUser)('op', dir)).toBe('viewer');
107
+ });
108
+ (0, vitest_1.it)('unknown users resolve to viewer (deny by default)', () => {
109
+ (0, vitest_1.expect)((0, admin_auth_1.roleForUser)('ghost', dir)).toBe('viewer');
110
+ });
111
+ });
112
+ (0, vitest_1.describe)('env override (with role)', () => {
113
+ const OLD = {
114
+ user: (0, paths_1.envBuff)('DASHBOARD_ADMIN_USER'),
115
+ pass: (0, paths_1.envBuff)('DASHBOARD_ADMIN_PASSWORD'),
116
+ role: (0, paths_1.envBuff)('DASHBOARD_ADMIN_ROLE'),
117
+ };
118
+ (0, vitest_1.afterEach)(() => {
119
+ for (const [k, v] of Object.entries(OLD)) {
120
+ if (v === undefined)
121
+ delete process.env[`BUFF_DASHBOARD_ADMIN_${k.toUpperCase()}`];
122
+ else
123
+ process.env[`BUFF_DASHBOARD_ADMIN_${k.toUpperCase()}`] = v;
124
+ }
125
+ });
126
+ (0, vitest_1.it)('password-only defaults to the admin user + admin role; env wins over the file', () => {
127
+ delete (0, paths_1.envBuff)('DASHBOARD_ADMIN_USER');
128
+ delete (0, paths_1.envBuff)('DASHBOARD_ADMIN_ROLE');
129
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_PASSWORD') = 'env-pass';
130
+ (0, vitest_1.expect)((0, admin_auth_1.envAdminOverride)()).toEqual({ user: 'admin', password: 'env-pass', role: 'admin' });
131
+ (0, vitest_1.expect)((0, admin_auth_1.isAdminConfigured)()).toBe(true);
132
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'env-pass')).toBe(true);
133
+ (0, vitest_1.expect)((0, admin_auth_1.verifyAdmin)('admin', 'file-pass')).toBe(false);
134
+ });
135
+ (0, vitest_1.it)('honors BUFF_DASHBOARD_ADMIN_ROLE and rejects an invalid one (falls back to admin)', () => {
136
+ delete (0, paths_1.envBuff)('DASHBOARD_ADMIN_USER');
137
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_PASSWORD') = 'env-pass';
138
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_ROLE') = 'operator';
139
+ (0, vitest_1.expect)((0, admin_auth_1.envAdminOverride)()?.role).toBe('operator');
140
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_ROLE') = 'superuser';
141
+ (0, vitest_1.expect)((0, admin_auth_1.envAdminOverride)()?.role).toBe('admin');
142
+ });
143
+ (0, vitest_1.it)('roleForUser honors the env override role even with NO credential file (regression — env admins are not viewers)', () => {
144
+ delete (0, paths_1.envBuff)('DASHBOARD_ADMIN_USER');
145
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_ROLE') = 'admin';
146
+ (0, paths_1.envBuff)('DASHBOARD_ADMIN_PASSWORD') = 'env-pass';
147
+ // No dashboard-admin.json exists anywhere — the env role must still apply.
148
+ (0, vitest_1.expect)((0, admin_auth_1.roleForUser)('admin')).toBe('admin');
149
+ (0, vitest_1.expect)((0, admin_auth_1.roleForUser)('someone-else')).toBe('viewer');
150
+ });
151
+ });
152
+ (0, vitest_1.describe)('AdminSessions (role-carrying)', () => {
153
+ (0, vitest_1.it)('issues and validates a token with its role, rejects garbage', () => {
154
+ const s = new admin_auth_1.AdminSessions();
155
+ const token = s.issue('admin', 'admin');
156
+ (0, vitest_1.expect)(s.validate(token)).toEqual({ user: 'admin', role: 'admin' });
157
+ (0, vitest_1.expect)(s.validate('nope')).toBeNull();
158
+ (0, vitest_1.expect)(s.validate(undefined)).toBeNull();
159
+ (0, vitest_1.expect)(s.size()).toBe(1);
160
+ });
161
+ (0, vitest_1.it)('revokes a token', () => {
162
+ const s = new admin_auth_1.AdminSessions();
163
+ const token = s.issue('op', 'operator');
164
+ (0, vitest_1.expect)(s.revoke(token)).toBe(true);
165
+ (0, vitest_1.expect)(s.validate(token)).toBeNull();
166
+ (0, vitest_1.expect)(s.size()).toBe(0);
167
+ });
168
+ (0, vitest_1.it)('rejects expired tokens and reaps them', () => {
169
+ const s = new admin_auth_1.AdminSessions();
170
+ const token = s.issue('admin', 'admin');
171
+ vitest_1.vi.useFakeTimers();
172
+ try {
173
+ vitest_1.vi.advanceTimersByTime(8 * 60 * 60 * 1000 + 1);
174
+ (0, vitest_1.expect)(s.validate(token)).toBeNull();
175
+ (0, vitest_1.expect)(s.size()).toBe(0);
176
+ }
177
+ finally {
178
+ vitest_1.vi.useRealTimers();
179
+ }
180
+ });
181
+ });
182
+ (0, vitest_1.describe)('MIN_ADMIN_PASSWORD_LENGTH', () => {
183
+ (0, vitest_1.it)('is enforced by the server-facing constant (8 chars)', () => {
184
+ (0, vitest_1.expect)(admin_auth_1.MIN_ADMIN_PASSWORD_LENGTH).toBe(8);
185
+ });
186
+ });
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ /**
3
+ * P2 — ANSI escape stripping for terminal output rendered in the dashboard.
4
+ *
5
+ * The P1 task runner streams a child process's RAW stdout/stderr — chalk
6
+ * colors, cursor-control (progress bars / spinners), and OSC window-title
7
+ * sequences all arrive intact. The task-run card must render clean text, so
8
+ * every escape sequence is removed here (pure string in → string out).
9
+ *
10
+ * Coverage:
11
+ * - CSI sequences ESC [ ... (params) (intermediates) final — `\x1b[32m`,
12
+ * `\x1b[2K` (clear line), `\x1b[1A` (cursor up), `\x1b[?25l` (hide cursor)
13
+ * - OSC sequences ESC ] ... BEL|ST — `\x1b]0;title\x07`
14
+ * - Single-char escapes — `\x1b7` etc.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.stripAnsi = stripAnsi;
18
+ const ANSI_PATTERN = /\x1b(?:\[[0-9;?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-Z\\-_])/g;
19
+ function stripAnsi(text) {
20
+ if (!text)
21
+ return '';
22
+ return text.replace(ANSI_PATTERN, '');
23
+ }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ /**
3
+ * P2 — ANSI escape stripping unit tests: the pure string→string function the
4
+ * task-run card uses to render child-process output without chalk colors,
5
+ * cursor-control, or OSC window-title sequences.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const vitest_1 = require("vitest");
9
+ const ansi_1 = require("./ansi");
10
+ (0, vitest_1.describe)('stripAnsi', () => {
11
+ (0, vitest_1.it)('removes SGR color codes (single and multi-param)', () => {
12
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b[32mgreen\x1b[0m')).toBe('green');
13
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b[38;2;255;0;0m rgb \x1b[39m')).toBe(' rgb ');
14
+ });
15
+ (0, vitest_1.it)('removes cursor-control and clear-line sequences (progress bars)', () => {
16
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b[2K\x1b[1A\x1b[2Kprogress 50%')).toBe('progress 50%');
17
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b[?25l\x1b[?25h')).toBe('');
18
+ });
19
+ (0, vitest_1.it)('removes OSC window-title sequences', () => {
20
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b]0;my title\x07content')).toBe('content');
21
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('\x1b]0;another\x1b\\tail')).toBe('tail');
22
+ });
23
+ (0, vitest_1.it)('leaves plain text untouched', () => {
24
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('plain output 123')).toBe('plain output 123');
25
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)('')).toBe('');
26
+ });
27
+ (0, vitest_1.it)('handles mixed lines with multiple sequences', () => {
28
+ const line = '\x1b[1mBOLD\x1b[22m \x1b[31mRED\x1b[0m \x1b[2Kdone';
29
+ (0, vitest_1.expect)((0, ansi_1.stripAnsi)(line)).toBe('BOLD RED done');
30
+ });
31
+ });