opencode-dashboard 0.1.0 → 0.2.0
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/README.md +20 -1
- package/bin/cli.ts +16 -2
- package/dist/assets/{index-W-qyIr7d.js → index-DJanV0JQ.js} +2 -2
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/plugin/index.ts +245 -5
- package/server/index.ts +23 -3
- package/server/pid.ts +115 -5
- package/server/routes.ts +131 -0
- package/server/sse.ts +16 -0
- package/server/state.ts +518 -1
- package/shared/types.ts +17 -7
- package/shared/version.ts +46 -0
package/shared/types.ts
CHANGED
|
@@ -135,6 +135,7 @@ export interface ProjectState {
|
|
|
135
135
|
pipelines: Map<string, Pipeline>;
|
|
136
136
|
lastBeadSnapshot: BeadRecord[];
|
|
137
137
|
columns: ColumnConfig[]; // dynamic column layout from agent discovery
|
|
138
|
+
activeAgents?: string[]; // currently active agent names (serialized form of Set<string>)
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
// ============================================================
|
|
@@ -230,19 +231,19 @@ export interface BeadRemovedPayload extends BaseEventPayload {
|
|
|
230
231
|
beadId: string;
|
|
231
232
|
}
|
|
232
233
|
|
|
233
|
-
/** agent:active —
|
|
234
|
+
/** agent:active — agent session started (subagent child session or primary built-in agent) */
|
|
234
235
|
export interface AgentActivePayload extends BaseEventPayload {
|
|
235
236
|
agent: string; // agent name
|
|
236
237
|
sessionId: string;
|
|
237
|
-
parentSessionId
|
|
238
|
-
beadId: string;
|
|
238
|
+
parentSessionId?: string; // present for subagent sessions, absent for primary agents
|
|
239
|
+
beadId: string | null;
|
|
239
240
|
}
|
|
240
241
|
|
|
241
|
-
/** agent:idle —
|
|
242
|
+
/** agent:idle — agent session finished work (subagent or primary built-in agent) */
|
|
242
243
|
export interface AgentIdlePayload extends BaseEventPayload {
|
|
243
244
|
agent: string; // agent name
|
|
244
245
|
sessionId: string;
|
|
245
|
-
beadId: string;
|
|
246
|
+
beadId: string | null;
|
|
246
247
|
}
|
|
247
248
|
|
|
248
249
|
/** beads:refreshed — summary after bead state refresh */
|
|
@@ -262,9 +263,16 @@ export interface PipelineDonePayload extends BaseEventPayload {
|
|
|
262
263
|
pipelineId: string;
|
|
263
264
|
}
|
|
264
265
|
|
|
265
|
-
/** columns:update —
|
|
266
|
+
/** columns:update — server broadcasts visible column set for the project.
|
|
267
|
+
*
|
|
268
|
+
* The SSE bridge in routes.ts sends `visibleColumns` (the subset currently
|
|
269
|
+
* visible based on active pipelines / agents). The original plugin payload
|
|
270
|
+
* uses `columns` (full set). The reducer accepts either field so it works
|
|
271
|
+
* with both the SSE bridge and the raw plugin event.
|
|
272
|
+
*/
|
|
266
273
|
export interface ColumnsUpdatePayload extends BaseEventPayload {
|
|
267
|
-
columns
|
|
274
|
+
columns?: ColumnConfig[];
|
|
275
|
+
visibleColumns?: ColumnConfig[];
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
/** Map of event type to its payload type */
|
|
@@ -399,4 +407,6 @@ export interface ColumnConfig {
|
|
|
399
407
|
type: "status" | "agent"; // bookend vs agent column
|
|
400
408
|
color: string; // hex color for accent border (e.g., "#8b5cf6")
|
|
401
409
|
order: number; // position in board (0-based)
|
|
410
|
+
group?: "pipeline" | "standalone"; // visibility logic grouping for pipeline columns
|
|
411
|
+
source?: "discovered" | "dynamic"; // how the column was created (debugging/logging)
|
|
402
412
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build hash computation for code staleness detection.
|
|
3
|
+
*
|
|
4
|
+
* Both the server (at startup) and the plugin (at connect time) compute
|
|
5
|
+
* a hash of the key source files. If the hashes differ, the server is
|
|
6
|
+
* running stale code and should be restarted.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "crypto";
|
|
9
|
+
import { readFileSync } from "fs";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
|
|
12
|
+
/** Files whose content determines the server's behavior */
|
|
13
|
+
const HASH_FILES = [
|
|
14
|
+
"server/index.ts",
|
|
15
|
+
"server/routes.ts",
|
|
16
|
+
"server/state.ts",
|
|
17
|
+
"server/pid.ts",
|
|
18
|
+
"server/sse.ts",
|
|
19
|
+
"shared/types.ts",
|
|
20
|
+
"shared/version.ts",
|
|
21
|
+
"plugin/index.ts",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
/** Package root directory (one level up from shared/) */
|
|
25
|
+
const PACKAGE_ROOT = join(import.meta.dir, "..");
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Compute a deterministic hash of the key source files.
|
|
29
|
+
* Returns a 12-character hex string.
|
|
30
|
+
*
|
|
31
|
+
* Both the server and plugin call this — if the result differs,
|
|
32
|
+
* the server is running stale code.
|
|
33
|
+
*/
|
|
34
|
+
export function computeBuildHash(): string {
|
|
35
|
+
const hasher = createHash("sha256");
|
|
36
|
+
for (const relPath of HASH_FILES) {
|
|
37
|
+
try {
|
|
38
|
+
const content = readFileSync(join(PACKAGE_ROOT, relPath), "utf-8");
|
|
39
|
+
hasher.update(content);
|
|
40
|
+
} catch {
|
|
41
|
+
// File missing — hash the path as placeholder to maintain consistency
|
|
42
|
+
hasher.update(`__missing__:${relPath}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return hasher.digest("hex").slice(0, 12);
|
|
46
|
+
}
|