shipwright-cli 2.2.2 → 2.3.1

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 (151) hide show
  1. package/README.md +12 -11
  2. package/dashboard/public/index.html +224 -8
  3. package/dashboard/public/styles.css +1078 -4
  4. package/dashboard/server.ts +1100 -15
  5. package/dashboard/src/canvas/interactions.ts +74 -0
  6. package/dashboard/src/canvas/layout.ts +85 -0
  7. package/dashboard/src/canvas/overlays.ts +117 -0
  8. package/dashboard/src/canvas/particles.ts +105 -0
  9. package/dashboard/src/canvas/renderer.ts +191 -0
  10. package/dashboard/src/components/charts/bar.ts +54 -0
  11. package/dashboard/src/components/charts/donut.ts +25 -0
  12. package/dashboard/src/components/charts/pipeline-rail.ts +105 -0
  13. package/dashboard/src/components/charts/sparkline.ts +82 -0
  14. package/dashboard/src/components/header.ts +616 -0
  15. package/dashboard/src/components/modal.ts +413 -0
  16. package/dashboard/src/components/terminal.ts +144 -0
  17. package/dashboard/src/core/api.test.ts +362 -0
  18. package/dashboard/src/core/api.ts +381 -0
  19. package/dashboard/src/core/helpers.ts +118 -0
  20. package/dashboard/src/core/router.test.ts +266 -0
  21. package/dashboard/src/core/router.ts +190 -0
  22. package/dashboard/src/core/sse.ts +38 -0
  23. package/dashboard/src/core/state.test.ts +235 -0
  24. package/dashboard/src/core/state.ts +150 -0
  25. package/dashboard/src/core/ws.test.ts +216 -0
  26. package/dashboard/src/core/ws.ts +143 -0
  27. package/dashboard/src/design/icons.test.ts +105 -0
  28. package/dashboard/src/design/icons.ts +131 -0
  29. package/dashboard/src/design/tokens.test.ts +204 -0
  30. package/dashboard/src/design/tokens.ts +160 -0
  31. package/dashboard/src/main.ts +68 -0
  32. package/dashboard/src/types/api.ts +337 -0
  33. package/dashboard/src/views/activity.ts +185 -0
  34. package/dashboard/src/views/agent-cockpit.ts +236 -0
  35. package/dashboard/src/views/agents.ts +72 -0
  36. package/dashboard/src/views/fleet-map.ts +299 -0
  37. package/dashboard/src/views/insights.ts +298 -0
  38. package/dashboard/src/views/machines.ts +162 -0
  39. package/dashboard/src/views/metrics.ts +420 -0
  40. package/dashboard/src/views/overview.ts +409 -0
  41. package/dashboard/src/views/pipeline-theater.ts +219 -0
  42. package/dashboard/src/views/pipelines.ts +595 -0
  43. package/dashboard/src/views/team.ts +362 -0
  44. package/dashboard/src/views/timeline.ts +389 -0
  45. package/dashboard/tsconfig.json +21 -0
  46. package/dashboard/vitest.config.ts +27 -0
  47. package/docs/AGI-WHATS-NEXT.md +15 -15
  48. package/package.json +16 -2
  49. package/scripts/lib/helpers.sh +30 -0
  50. package/scripts/lib/pipeline-quality-checks.sh +1 -1
  51. package/scripts/lib/pipeline-stages.sh +59 -0
  52. package/scripts/sw +86 -167
  53. package/scripts/sw-activity.sh +1 -1
  54. package/scripts/sw-adaptive.sh +1 -1
  55. package/scripts/sw-adversarial.sh +1 -1
  56. package/scripts/sw-architecture-enforcer.sh +1 -1
  57. package/scripts/sw-auth.sh +14 -6
  58. package/scripts/sw-autonomous.sh +230 -13
  59. package/scripts/sw-changelog.sh +2 -2
  60. package/scripts/sw-checkpoint.sh +1 -1
  61. package/scripts/sw-ci.sh +1 -1
  62. package/scripts/sw-cleanup.sh +1 -1
  63. package/scripts/sw-code-review.sh +1 -1
  64. package/scripts/sw-connect.sh +1 -1
  65. package/scripts/sw-context.sh +1 -1
  66. package/scripts/sw-cost.sh +1 -1
  67. package/scripts/sw-daemon.sh +2 -2
  68. package/scripts/sw-dashboard.sh +1 -1
  69. package/scripts/sw-db.sh +1 -1
  70. package/scripts/sw-decompose.sh +1 -1
  71. package/scripts/sw-deps.sh +1 -1
  72. package/scripts/sw-developer-simulation.sh +1 -1
  73. package/scripts/sw-discovery.sh +1 -1
  74. package/scripts/sw-doc-fleet.sh +1 -1
  75. package/scripts/sw-docs-agent.sh +1 -1
  76. package/scripts/sw-docs.sh +1 -1
  77. package/scripts/sw-doctor.sh +8 -1
  78. package/scripts/sw-dora.sh +1 -1
  79. package/scripts/sw-durable.sh +1 -1
  80. package/scripts/sw-e2e-orchestrator.sh +1 -1
  81. package/scripts/sw-eventbus.sh +1 -1
  82. package/scripts/sw-feedback.sh +1 -1
  83. package/scripts/sw-fix.sh +6 -5
  84. package/scripts/sw-fleet-discover.sh +1 -1
  85. package/scripts/sw-fleet-viz.sh +1 -1
  86. package/scripts/sw-fleet.sh +1 -1
  87. package/scripts/sw-github-app.sh +5 -2
  88. package/scripts/sw-github-checks.sh +1 -1
  89. package/scripts/sw-github-deploy.sh +1 -1
  90. package/scripts/sw-github-graphql.sh +1 -1
  91. package/scripts/sw-guild.sh +1 -1
  92. package/scripts/sw-heartbeat.sh +1 -1
  93. package/scripts/sw-hygiene.sh +1 -1
  94. package/scripts/sw-incident.sh +1 -1
  95. package/scripts/sw-init.sh +112 -9
  96. package/scripts/sw-instrument.sh +6 -1
  97. package/scripts/sw-intelligence.sh +5 -1
  98. package/scripts/sw-jira.sh +1 -1
  99. package/scripts/sw-launchd.sh +1 -1
  100. package/scripts/sw-linear.sh +20 -9
  101. package/scripts/sw-logs.sh +1 -1
  102. package/scripts/sw-loop.sh +2 -1
  103. package/scripts/sw-memory.sh +10 -1
  104. package/scripts/sw-mission-control.sh +1 -1
  105. package/scripts/sw-model-router.sh +4 -1
  106. package/scripts/sw-otel.sh +1 -1
  107. package/scripts/sw-oversight.sh +1 -1
  108. package/scripts/sw-pipeline-composer.sh +3 -1
  109. package/scripts/sw-pipeline-vitals.sh +4 -6
  110. package/scripts/sw-pipeline.sh +4 -1
  111. package/scripts/sw-pm.sh +5 -2
  112. package/scripts/sw-pr-lifecycle.sh +1 -1
  113. package/scripts/sw-predictive.sh +4 -1
  114. package/scripts/sw-prep.sh +3 -2
  115. package/scripts/sw-ps.sh +1 -1
  116. package/scripts/sw-public-dashboard.sh +10 -4
  117. package/scripts/sw-quality.sh +1 -1
  118. package/scripts/sw-reaper.sh +1 -1
  119. package/scripts/sw-recruit.sh +16 -0
  120. package/scripts/sw-regression.sh +2 -1
  121. package/scripts/sw-release-manager.sh +1 -1
  122. package/scripts/sw-release.sh +7 -5
  123. package/scripts/sw-remote.sh +1 -1
  124. package/scripts/sw-replay.sh +1 -1
  125. package/scripts/sw-retro.sh +4 -1
  126. package/scripts/sw-scale.sh +4 -1
  127. package/scripts/sw-security-audit.sh +1 -1
  128. package/scripts/sw-self-optimize.sh +113 -1
  129. package/scripts/sw-session.sh +1 -1
  130. package/scripts/sw-setup.sh +1 -1
  131. package/scripts/sw-standup.sh +2 -1
  132. package/scripts/sw-status.sh +1 -1
  133. package/scripts/sw-strategic.sh +2 -1
  134. package/scripts/sw-stream.sh +1 -1
  135. package/scripts/sw-swarm.sh +6 -1
  136. package/scripts/sw-team-stages.sh +1 -1
  137. package/scripts/sw-templates.sh +1 -1
  138. package/scripts/sw-testgen.sh +3 -2
  139. package/scripts/sw-tmux-pipeline.sh +2 -1
  140. package/scripts/sw-tmux.sh +1 -1
  141. package/scripts/sw-trace.sh +1 -1
  142. package/scripts/sw-tracker-jira.sh +1 -0
  143. package/scripts/sw-tracker-linear.sh +1 -0
  144. package/scripts/sw-tracker.sh +1 -1
  145. package/scripts/sw-triage.sh +198 -11
  146. package/scripts/sw-upgrade.sh +1 -1
  147. package/scripts/sw-ux.sh +1 -1
  148. package/scripts/sw-webhook.sh +1 -1
  149. package/scripts/sw-widgets.sh +2 -2
  150. package/scripts/sw-worktree.sh +1 -1
  151. package/dashboard/public/app.js +0 -4422
@@ -0,0 +1,160 @@
1
+ // Design System Tokens
2
+ // Single source of truth for colors, typography, spacing, shadows, animations, and z-index.
3
+ // CSS custom properties mirror these values; Canvas2D code reads from here directly.
4
+
5
+ export const colors = {
6
+ bg: {
7
+ abyss: "#060a14",
8
+ deep: "#0a1628",
9
+ ocean: "#0d1f3c",
10
+ surface: "#132d56",
11
+ foam: "#1a3a6a",
12
+ },
13
+ accent: {
14
+ cyan: "#00d4ff",
15
+ cyanGlow: "rgba(0, 212, 255, 0.15)",
16
+ cyanDim: "rgba(0, 212, 255, 0.4)",
17
+ purple: "#7c3aed",
18
+ purpleGlow: "rgba(124, 58, 237, 0.15)",
19
+ blue: "#0066ff",
20
+ },
21
+ semantic: {
22
+ success: "#4ade80",
23
+ warning: "#fbbf24",
24
+ error: "#f43f5e",
25
+ },
26
+ text: {
27
+ primary: "#e8ecf4",
28
+ secondary: "#8899b8",
29
+ muted: "#5a6d8a",
30
+ },
31
+ } as const;
32
+
33
+ export const fonts = {
34
+ display: "'Instrument Serif', Georgia, serif",
35
+ body: "'Plus Jakarta Sans', system-ui, sans-serif",
36
+ mono: "'JetBrains Mono', 'SF Mono', monospace",
37
+ } as const;
38
+
39
+ export const typeScale = {
40
+ display: { size: 32, weight: 400, family: fonts.display },
41
+ heading: { size: 24, weight: 400, family: fonts.display },
42
+ title: { size: 20, weight: 600, family: fonts.body },
43
+ body: { size: 14, weight: 400, family: fonts.body },
44
+ caption: { size: 12, weight: 500, family: fonts.body },
45
+ tiny: { size: 11, weight: 400, family: fonts.body },
46
+ mono: { size: 13, weight: 400, family: fonts.mono },
47
+ monoSm: { size: 11, weight: 400, family: fonts.mono },
48
+ } as const;
49
+
50
+ export const spacing: Record<number, number> = {
51
+ 0: 0,
52
+ 1: 4,
53
+ 2: 8,
54
+ 3: 12,
55
+ 4: 16,
56
+ 5: 20,
57
+ 6: 24,
58
+ 8: 32,
59
+ 10: 40,
60
+ 12: 48,
61
+ 16: 64,
62
+ };
63
+
64
+ export const radius = {
65
+ sm: 4,
66
+ md: 8,
67
+ lg: 12,
68
+ xl: 16,
69
+ full: 9999,
70
+ } as const;
71
+
72
+ export const shadows = {
73
+ glow: {
74
+ cyan: "0 0 20px rgba(0, 212, 255, 0.15)",
75
+ purple: "0 0 20px rgba(124, 58, 237, 0.15)",
76
+ success: "0 0 12px rgba(74, 222, 128, 0.2)",
77
+ error: "0 0 12px rgba(244, 63, 94, 0.2)",
78
+ },
79
+ elevated: "0 8px 32px rgba(0, 0, 0, 0.4)",
80
+ } as const;
81
+
82
+ export const duration = {
83
+ fast: 150,
84
+ base: 300,
85
+ slow: 500,
86
+ glacial: 1000,
87
+ } as const;
88
+
89
+ export const easing = {
90
+ default: "ease",
91
+ smooth: "cubic-bezier(0.4, 0, 0.2, 1)",
92
+ spring: "cubic-bezier(0.34, 1.56, 0.64, 1)",
93
+ } as const;
94
+
95
+ export const zIndex = {
96
+ base: 1,
97
+ dropdown: 10,
98
+ sticky: 20,
99
+ overlay: 30,
100
+ modal: 40,
101
+ toast: 50,
102
+ } as const;
103
+
104
+ export const STAGES = [
105
+ "intake",
106
+ "plan",
107
+ "design",
108
+ "build",
109
+ "test",
110
+ "review",
111
+ "compound_quality",
112
+ "pr",
113
+ "merge",
114
+ "deploy",
115
+ "monitor",
116
+ ] as const;
117
+
118
+ export type StageName = (typeof STAGES)[number];
119
+
120
+ export const STAGE_SHORT: Record<StageName, string> = {
121
+ intake: "INT",
122
+ plan: "PLN",
123
+ design: "DSN",
124
+ build: "BLD",
125
+ test: "TST",
126
+ review: "REV",
127
+ compound_quality: "QA",
128
+ pr: "PR",
129
+ merge: "MRG",
130
+ deploy: "DPL",
131
+ monitor: "MON",
132
+ };
133
+
134
+ export const STAGE_COLORS: string[] = [
135
+ "c-cyan",
136
+ "c-blue",
137
+ "c-purple",
138
+ "c-green",
139
+ "c-amber",
140
+ "c-cyan",
141
+ "c-blue",
142
+ "c-purple",
143
+ "c-green",
144
+ "c-amber",
145
+ "c-cyan",
146
+ ];
147
+
148
+ export const STAGE_HEX: Record<StageName, string> = {
149
+ intake: "#00d4ff",
150
+ plan: "#0066ff",
151
+ design: "#7c3aed",
152
+ build: "#4ade80",
153
+ test: "#fbbf24",
154
+ review: "#00d4ff",
155
+ compound_quality: "#0066ff",
156
+ pr: "#7c3aed",
157
+ merge: "#4ade80",
158
+ deploy: "#fbbf24",
159
+ monitor: "#00d4ff",
160
+ };
@@ -0,0 +1,68 @@
1
+ // Fleet Command Dashboard - Main Entry Point
2
+ // Boots WebSocket, router, header, modals, and registers all views
3
+
4
+ import { connect } from "./core/ws";
5
+ import { store } from "./core/state";
6
+ import { setupRouter, registerView } from "./core/router";
7
+ import {
8
+ setupHeader,
9
+ renderCostTicker,
10
+ renderAlertBanner,
11
+ updateEmergencyBrakeVisibility,
12
+ updateAmbientIndicator,
13
+ detectCompletions,
14
+ } from "./components/header";
15
+ import { setupInterventionModal, setupBulkActions } from "./components/modal";
16
+
17
+ // Views
18
+ import { overviewView } from "./views/overview";
19
+ import { agentsView } from "./views/agents";
20
+ import { pipelinesView } from "./views/pipelines";
21
+ import { timelineView } from "./views/timeline";
22
+ import { activityView } from "./views/activity";
23
+ import { metricsView } from "./views/metrics";
24
+ import { machinesView } from "./views/machines";
25
+ import { insightsView } from "./views/insights";
26
+ import { teamView } from "./views/team";
27
+
28
+ // New visualization views (lazy-loaded when tabs exist)
29
+ import { fleetMapView } from "./views/fleet-map";
30
+ import { pipelineTheaterView } from "./views/pipeline-theater";
31
+ import { agentCockpitView } from "./views/agent-cockpit";
32
+
33
+ // Register all views
34
+ registerView("overview", overviewView);
35
+ registerView("agents", agentsView);
36
+ registerView("pipelines", pipelinesView);
37
+ registerView("timeline", timelineView);
38
+ registerView("activity", activityView);
39
+ registerView("metrics", metricsView);
40
+ registerView("machines", machinesView);
41
+ registerView("insights", insightsView);
42
+ registerView("team", teamView);
43
+ registerView("fleet-map", fleetMapView);
44
+ registerView("pipeline-theater", pipelineTheaterView);
45
+ registerView("agent-cockpit", agentCockpitView);
46
+
47
+ // Setup header (user menu, daemon control, emergency brake)
48
+ setupHeader();
49
+
50
+ // Setup shared modals
51
+ setupInterventionModal();
52
+ setupBulkActions();
53
+
54
+ // Setup tab routing
55
+ setupRouter();
56
+
57
+ // Subscribe to fleet state for global UI updates
58
+ store.subscribe("fleetState", (data) => {
59
+ if (!data) return;
60
+ renderCostTicker(data);
61
+ renderAlertBanner(data);
62
+ updateEmergencyBrakeVisibility(data);
63
+ updateAmbientIndicator(data);
64
+ detectCompletions(data);
65
+ });
66
+
67
+ // Connect WebSocket
68
+ connect();
@@ -0,0 +1,337 @@
1
+ // Shared TypeScript interfaces for all API responses
2
+ // These types mirror the actual shapes returned by dashboard/server.ts
3
+
4
+ export interface DaemonInfo {
5
+ running: boolean;
6
+ pid: number | null;
7
+ uptime_s: number;
8
+ maxParallel: number;
9
+ pollInterval: number;
10
+ }
11
+
12
+ export interface PipelineInfo {
13
+ issue: number;
14
+ title: string;
15
+ stage: string;
16
+ stagesDone: string[];
17
+ elapsed_s: number;
18
+ worktree?: string;
19
+ iteration: number;
20
+ maxIterations: number;
21
+ linesWritten?: number;
22
+ testsPassing?: boolean;
23
+ cost?: number;
24
+ branch?: string;
25
+ status?: string;
26
+ }
27
+
28
+ export interface QueueItem {
29
+ issue: number;
30
+ title: string;
31
+ score?: number;
32
+ estimated_cost?: number;
33
+ factors?: ScoringFactors;
34
+ }
35
+
36
+ export interface ScoringFactors {
37
+ complexity?: number;
38
+ impact?: number;
39
+ priority?: number;
40
+ age?: number;
41
+ dependency?: number;
42
+ memory?: number;
43
+ }
44
+
45
+ export interface EventItem {
46
+ ts?: string;
47
+ timestamp?: string;
48
+ type: string;
49
+ issue?: number;
50
+ issueTitle?: string;
51
+ title?: string;
52
+ duration_s?: number;
53
+ stage?: string;
54
+ result?: string;
55
+ [key: string]: unknown;
56
+ }
57
+
58
+ export interface ScaleInfo {
59
+ from?: number;
60
+ to?: number;
61
+ cpuCores?: number;
62
+ maxByCpu?: number;
63
+ maxByMem?: number;
64
+ maxByBudget?: number;
65
+ availMemGb?: number;
66
+ }
67
+
68
+ export interface MetricsSummary {
69
+ completed?: number;
70
+ failed?: number;
71
+ cpuCores?: number;
72
+ }
73
+
74
+ export interface CostInfo {
75
+ today_spent: number;
76
+ daily_budget: number;
77
+ pct_used: number;
78
+ }
79
+
80
+ export interface DoraMetric {
81
+ value: number;
82
+ unit: string;
83
+ grade: string;
84
+ }
85
+
86
+ export interface DoraGrades {
87
+ deploy_freq: DoraMetric;
88
+ lead_time: DoraMetric;
89
+ cfr: DoraMetric;
90
+ mttr: DoraMetric;
91
+ }
92
+
93
+ export interface AgentInfo {
94
+ id: string;
95
+ issue: number;
96
+ title: string;
97
+ machine: string;
98
+ stage: string;
99
+ iteration: number;
100
+ activity: string;
101
+ memory_mb: number;
102
+ cpu_pct: number;
103
+ status: "active" | "idle" | "stale" | "dead";
104
+ heartbeat_age_s: number;
105
+ started_at: string;
106
+ elapsed_s: number;
107
+ }
108
+
109
+ export interface FleetState {
110
+ timestamp: string;
111
+ daemon: DaemonInfo;
112
+ pipelines: PipelineInfo[];
113
+ queue: QueueItem[];
114
+ events: EventItem[];
115
+ scale: ScaleInfo;
116
+ metrics: MetricsSummary;
117
+ agents: AgentInfo[];
118
+ machines: MachineInfo[];
119
+ cost: CostInfo;
120
+ dora: DoraGrades;
121
+ team?: TeamData;
122
+ }
123
+
124
+ export interface CostBreakdown {
125
+ by_model?: Record<string, number>;
126
+ by_stage?: Record<string, number>;
127
+ by_issue?: Array<{ issue: number; cost: number }>;
128
+ budget?: number;
129
+ spent?: number;
130
+ }
131
+
132
+ export interface StageHistoryEntry {
133
+ stage: string;
134
+ duration_s: number;
135
+ ts: string;
136
+ }
137
+
138
+ export interface PipelineDetail {
139
+ issue: number;
140
+ title: string;
141
+ stage: string;
142
+ stageHistory: StageHistoryEntry[];
143
+ plan: string;
144
+ design: string;
145
+ dod: string;
146
+ intake: Record<string, unknown> | null;
147
+ elapsed_s: number;
148
+ branch: string;
149
+ prLink: string;
150
+ }
151
+
152
+ export interface TimelineEntry {
153
+ issue: number;
154
+ title: string;
155
+ segments: TimelineSegment[];
156
+ }
157
+
158
+ export interface TimelineSegment {
159
+ stage: string;
160
+ start: string;
161
+ end: string | null;
162
+ status: "complete" | "running" | "failed";
163
+ }
164
+
165
+ export interface MetricsData {
166
+ success_rate: number;
167
+ avg_duration_s: number;
168
+ throughput_per_hour: number;
169
+ total_completed: number;
170
+ total_failed: number;
171
+ stage_durations: Record<string, number>;
172
+ daily_counts: DailyCount[];
173
+ dora_grades: DoraGrades;
174
+ }
175
+
176
+ export interface DailyCount {
177
+ date: string;
178
+ completed: number;
179
+ failed: number;
180
+ }
181
+
182
+ export interface DoraMetrics {
183
+ deploy_freq?: DoraMetric;
184
+ lead_time?: DoraMetric;
185
+ cfr?: DoraMetric;
186
+ mttr?: DoraMetric;
187
+ }
188
+
189
+ export interface MachineInfo {
190
+ name: string;
191
+ host: string;
192
+ role: string;
193
+ max_workers: number;
194
+ active_workers: number;
195
+ registered_at: string;
196
+ ssh_user?: string;
197
+ shipwright_path?: string;
198
+ status: "online" | "degraded" | "offline";
199
+ health: MachineHealth;
200
+ join_token?: string;
201
+ }
202
+
203
+ export interface MachineHealth {
204
+ daemon_running: boolean;
205
+ heartbeat_count: number;
206
+ last_heartbeat_s_ago: number;
207
+ }
208
+
209
+ export interface JoinToken {
210
+ label: string;
211
+ created_at?: string;
212
+ used?: boolean;
213
+ token?: string;
214
+ }
215
+
216
+ export interface InsightsData {
217
+ patterns: FailurePattern[] | null;
218
+ decisions: Decision[] | null;
219
+ patrol: PatrolFinding[] | null;
220
+ heatmap: HeatmapData | null;
221
+ globalLearnings: Array<Record<string, unknown>> | null;
222
+ }
223
+
224
+ export interface FailurePattern {
225
+ description?: string;
226
+ pattern?: string;
227
+ frequency?: number;
228
+ count?: number;
229
+ root_cause?: string;
230
+ fix?: string;
231
+ suggested_fix?: string;
232
+ }
233
+
234
+ export interface Decision {
235
+ timestamp?: string;
236
+ ts?: string;
237
+ action?: string;
238
+ decision?: string;
239
+ outcome?: string;
240
+ result?: string;
241
+ issue?: number;
242
+ }
243
+
244
+ export interface PatrolFinding {
245
+ severity?: string;
246
+ type?: string;
247
+ category?: string;
248
+ description?: string;
249
+ message?: string;
250
+ file?: string;
251
+ }
252
+
253
+ // Heatmap from server: { heatmap: Record<stage, Record<date, count>> }
254
+ export interface HeatmapData {
255
+ heatmap: Record<string, Record<string, number>>;
256
+ }
257
+
258
+ export interface DaemonConfig {
259
+ paused?: boolean;
260
+ config?: Record<string, unknown>;
261
+ budget?: Record<string, unknown>;
262
+ }
263
+
264
+ export interface AlertInfo {
265
+ severity: string;
266
+ message: string;
267
+ type?: string;
268
+ issue?: number;
269
+ actions?: string[];
270
+ }
271
+
272
+ export interface TeamData {
273
+ total_online?: number;
274
+ total_active_pipelines?: number;
275
+ total_queued?: number;
276
+ developers?: TeamDeveloper[];
277
+ }
278
+
279
+ export interface TeamDeveloper {
280
+ developer_id: string;
281
+ machine_name: string;
282
+ hostname?: string;
283
+ platform?: string;
284
+ last_heartbeat?: number;
285
+ daemon_running: boolean;
286
+ daemon_pid?: number | null;
287
+ active_jobs: Array<{ issue: number; title?: string; stage?: string }>;
288
+ queued: number[];
289
+ events_since?: number;
290
+ _presence?: string;
291
+ }
292
+
293
+ export interface TeamActivityEvent {
294
+ ts?: string;
295
+ type: string;
296
+ issue?: number;
297
+ from_developer?: string;
298
+ stage?: string;
299
+ result?: string;
300
+ }
301
+
302
+ export interface StagePerformance {
303
+ name?: string;
304
+ stage?: string;
305
+ avg_s: number;
306
+ min_s?: number;
307
+ max_s?: number;
308
+ count: number;
309
+ trend_pct?: number;
310
+ }
311
+
312
+ export interface UserInfo {
313
+ username?: string;
314
+ avatarUrl?: string;
315
+ isAdmin?: boolean;
316
+ role?: "viewer" | "operator" | "admin";
317
+ }
318
+
319
+ export type TabId =
320
+ | "overview"
321
+ | "agents"
322
+ | "pipelines"
323
+ | "timeline"
324
+ | "activity"
325
+ | "metrics"
326
+ | "machines"
327
+ | "insights"
328
+ | "team"
329
+ | "fleet-map"
330
+ | "pipeline-theater"
331
+ | "agent-cockpit";
332
+
333
+ export interface View {
334
+ init(): void;
335
+ render(state: FleetState): void;
336
+ destroy(): void;
337
+ }