sensorium-mcp 3.1.2 → 3.1.3-board.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.
- package/Install-Sensorium.ps1 +61 -0
- package/dist/board/api/api.js +61 -0
- package/dist/board/api/client.js +96 -0
- package/dist/board/components/BottomNav.js +32 -0
- package/dist/board/components/Card.js +44 -0
- package/dist/board/components/CommentComposer.js +26 -0
- package/dist/board/components/CommentList.js +39 -0
- package/dist/board/components/Dropdown.js +66 -0
- package/dist/board/components/Lane.js +40 -0
- package/dist/board/components/PriorityChip.js +17 -0
- package/dist/board/components/ProfileSummary.js +39 -0
- package/dist/board/components/StateBanner.js +22 -0
- package/dist/board/components/StatusChip.js +21 -0
- package/dist/board/components/TokenEntry.js +42 -0
- package/dist/board/config.js +56 -0
- package/dist/board/index.html +18 -0
- package/dist/board/main.js +37 -0
- package/dist/board/mock/api.mock.js +193 -0
- package/dist/board/mock/fixtures.js +164 -0
- package/dist/board/schema/policy.js +192 -0
- package/dist/board/state/auth.js +55 -0
- package/dist/board/state/useBoard.js +149 -0
- package/dist/board/state/useBuilder.js +98 -0
- package/dist/board/state/useCard.js +67 -0
- package/dist/board/styles/board.css +1760 -0
- package/dist/board/styles/tokens.css +71 -0
- package/dist/board/vendor/vue.esm-browser.js +9 -0
- package/dist/board/views/App.js +65 -0
- package/dist/board/views/BoardView.js +84 -0
- package/dist/board/views/BuilderView.js +303 -0
- package/dist/board/views/CardView.js +245 -0
- package/dist/board/views/SettingsView.js +145 -0
- package/dist/config/agent-settings.d.ts +2 -0
- package/dist/config/agent-settings.d.ts.map +1 -1
- package/dist/config/agent-settings.js +23 -0
- package/dist/config/agent-settings.js.map +1 -1
- package/dist/config/index.d.ts +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +12 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/misc-settings.d.ts +14 -0
- package/dist/config/misc-settings.d.ts.map +1 -1
- package/dist/config/misc-settings.js +53 -0
- package/dist/config/misc-settings.js.map +1 -1
- package/dist/dashboard/board-static.d.ts +23 -0
- package/dist/dashboard/board-static.d.ts.map +1 -0
- package/dist/dashboard/board-static.js +131 -0
- package/dist/dashboard/board-static.js.map +1 -0
- package/dist/dashboard/routes/board.d.ts +73 -0
- package/dist/dashboard/routes/board.d.ts.map +1 -0
- package/dist/dashboard/routes/board.js +623 -0
- package/dist/dashboard/routes/board.js.map +1 -0
- package/dist/dashboard/routes/claude.d.ts.map +1 -1
- package/dist/dashboard/routes/claude.js +10 -1
- package/dist/dashboard/routes/claude.js.map +1 -1
- package/dist/dashboard/routes/settings.d.ts +2 -0
- package/dist/dashboard/routes/settings.d.ts.map +1 -1
- package/dist/dashboard/routes/settings.js +24 -1
- package/dist/dashboard/routes/settings.js.map +1 -1
- package/dist/dashboard/routes/threads-read.d.ts +7 -3
- package/dist/dashboard/routes/threads-read.d.ts.map +1 -1
- package/dist/dashboard/routes/threads-read.js +19 -4
- package/dist/dashboard/routes/threads-read.js.map +1 -1
- package/dist/dashboard/routes/types.d.ts +6 -0
- package/dist/dashboard/routes/types.d.ts.map +1 -1
- package/dist/dashboard/routes/types.js.map +1 -1
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +42 -1
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/spa.html +12 -12
- package/dist/data/board/board-schema.d.ts +22 -0
- package/dist/data/board/board-schema.d.ts.map +1 -0
- package/dist/data/board/board-schema.js +103 -0
- package/dist/data/board/board-schema.js.map +1 -0
- package/dist/data/board/board-types.d.ts +117 -0
- package/dist/data/board/board-types.d.ts.map +1 -0
- package/dist/data/board/board-types.js +9 -0
- package/dist/data/board/board-types.js.map +1 -0
- package/dist/data/board/card.repository.d.ts +64 -0
- package/dist/data/board/card.repository.d.ts.map +1 -0
- package/dist/data/board/card.repository.js +272 -0
- package/dist/data/board/card.repository.js.map +1 -0
- package/dist/data/board/comment.repository.d.ts +12 -0
- package/dist/data/board/comment.repository.d.ts.map +1 -0
- package/dist/data/board/comment.repository.js +31 -0
- package/dist/data/board/comment.repository.js.map +1 -0
- package/dist/data/board/lane.repository.d.ts +18 -0
- package/dist/data/board/lane.repository.d.ts.map +1 -0
- package/dist/data/board/lane.repository.js +44 -0
- package/dist/data/board/lane.repository.js.map +1 -0
- package/dist/data/board/profile-defaults.d.ts +19 -0
- package/dist/data/board/profile-defaults.d.ts.map +1 -0
- package/dist/data/board/profile-defaults.js +118 -0
- package/dist/data/board/profile-defaults.js.map +1 -0
- package/dist/data/memory/migration-runner.d.ts.map +1 -1
- package/dist/data/memory/migration-runner.js +4 -0
- package/dist/data/memory/migration-runner.js.map +1 -1
- package/dist/data/memory/narrative-store.d.ts +14 -0
- package/dist/data/memory/narrative-store.d.ts.map +1 -1
- package/dist/data/memory/narrative-store.js +36 -0
- package/dist/data/memory/narrative-store.js.map +1 -1
- package/dist/data/memory/narrative.d.ts.map +1 -1
- package/dist/data/memory/narrative.js +13 -1
- package/dist/data/memory/narrative.js.map +1 -1
- package/dist/data/memory/schema.d.ts.map +1 -1
- package/dist/data/memory/schema.js +4 -0
- package/dist/data/memory/schema.js.map +1 -1
- package/dist/index.js +84 -2
- package/dist/index.js.map +1 -1
- package/dist/integrations/openai/speech.d.ts.map +1 -1
- package/dist/integrations/openai/speech.js +52 -19
- package/dist/integrations/openai/speech.js.map +1 -1
- package/dist/lib/http-retry.d.ts +91 -0
- package/dist/lib/http-retry.d.ts.map +1 -0
- package/dist/lib/http-retry.js +177 -0
- package/dist/lib/http-retry.js.map +1 -0
- package/dist/lib/usage-metering/pricing.js +1 -1
- package/dist/lib/usage-metering/pricing.js.map +1 -1
- package/dist/lib/utils.d.ts +10 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +22 -0
- package/dist/lib/utils.js.map +1 -1
- package/dist/server/http-server.d.ts +3 -1
- package/dist/server/http-server.d.ts.map +1 -1
- package/dist/server/http-server.js +6 -2
- package/dist/server/http-server.js.map +1 -1
- package/dist/services/board/board-signals.d.ts +25 -0
- package/dist/services/board/board-signals.d.ts.map +1 -0
- package/dist/services/board/board-signals.js +83 -0
- package/dist/services/board/board-signals.js.map +1 -0
- package/dist/services/board/card-briefing.d.ts +17 -0
- package/dist/services/board/card-briefing.d.ts.map +1 -0
- package/dist/services/board/card-briefing.js +86 -0
- package/dist/services/board/card-briefing.js.map +1 -0
- package/dist/services/board/orchestrator.service.d.ts +55 -0
- package/dist/services/board/orchestrator.service.d.ts.map +1 -0
- package/dist/services/board/orchestrator.service.js +198 -0
- package/dist/services/board/orchestrator.service.js.map +1 -0
- package/dist/services/board/release-worker.d.ts +32 -0
- package/dist/services/board/release-worker.d.ts.map +1 -0
- package/dist/services/board/release-worker.js +49 -0
- package/dist/services/board/release-worker.js.map +1 -0
- package/dist/services/board/report-capture.d.ts +48 -0
- package/dist/services/board/report-capture.d.ts.map +1 -0
- package/dist/services/board/report-capture.js +172 -0
- package/dist/services/board/report-capture.js.map +1 -0
- package/dist/services/board/worker-spawn.d.ts +30 -0
- package/dist/services/board/worker-spawn.d.ts.map +1 -0
- package/dist/services/board/worker-spawn.js +90 -0
- package/dist/services/board/worker-spawn.js.map +1 -0
- package/dist/services/broker-client.d.ts +30 -0
- package/dist/services/broker-client.d.ts.map +1 -1
- package/dist/services/broker-client.js +23 -0
- package/dist/services/broker-client.js.map +1 -1
- package/dist/services/codex-spawn.service.d.ts +2 -2
- package/dist/services/codex-spawn.service.d.ts.map +1 -1
- package/dist/services/codex-spawn.service.js +54 -54
- package/dist/services/codex-spawn.service.js.map +1 -1
- package/dist/services/http-retry.d.ts +1 -90
- package/dist/services/http-retry.d.ts.map +1 -1
- package/dist/services/http-retry.js +1 -176
- package/dist/services/http-retry.js.map +1 -1
- package/dist/services/mcp-config.service.d.ts.map +1 -1
- package/dist/services/mcp-config.service.js +5 -1
- package/dist/services/mcp-config.service.js.map +1 -1
- package/dist/services/passive-notice.service.d.ts +39 -0
- package/dist/services/passive-notice.service.d.ts.map +1 -0
- package/dist/services/passive-notice.service.js +274 -0
- package/dist/services/passive-notice.service.js.map +1 -0
- package/dist/services/spawn-common.d.ts.map +1 -1
- package/dist/services/spawn-common.js +14 -1
- package/dist/services/spawn-common.js.map +1 -1
- package/dist/services/telegram.d.ts +7 -5
- package/dist/services/telegram.d.ts.map +1 -1
- package/dist/services/telegram.js +18 -13
- package/dist/services/telegram.js.map +1 -1
- package/dist/services/usage/usage-inbox-notifier.d.ts +50 -0
- package/dist/services/usage/usage-inbox-notifier.d.ts.map +1 -0
- package/dist/services/usage/usage-inbox-notifier.js +118 -0
- package/dist/services/usage/usage-inbox-notifier.js.map +1 -0
- package/dist/services/usage/usage-poller.service.d.ts +41 -0
- package/dist/services/usage/usage-poller.service.d.ts.map +1 -0
- package/dist/services/usage/usage-poller.service.js +66 -0
- package/dist/services/usage/usage-poller.service.js.map +1 -0
- package/dist/services/usage/usage-snapshot-provider.d.ts +29 -0
- package/dist/services/usage/usage-snapshot-provider.d.ts.map +1 -0
- package/dist/services/usage/usage-snapshot-provider.js +59 -0
- package/dist/services/usage/usage-snapshot-provider.js.map +1 -0
- package/dist/services/usage/usage-types.d.ts +23 -0
- package/dist/services/usage/usage-types.d.ts.map +1 -0
- package/dist/services/usage/usage-types.js +14 -0
- package/dist/services/usage/usage-types.js.map +1 -0
- package/dist/services/worker-cleanup.service.d.ts +6 -1
- package/dist/services/worker-cleanup.service.d.ts.map +1 -1
- package/dist/services/worker-cleanup.service.js +123 -10
- package/dist/services/worker-cleanup.service.js.map +1 -1
- package/dist/tools/delegate-tool.d.ts.map +1 -1
- package/dist/tools/delegate-tool.js +34 -2
- package/dist/tools/delegate-tool.js.map +1 -1
- package/dist/tools/utility-tools.d.ts.map +1 -1
- package/dist/tools/utility-tools.js +7 -3
- package/dist/tools/utility-tools.js.map +1 -1
- package/dist/tools/wait/consolidation-strategy.d.ts +42 -0
- package/dist/tools/wait/consolidation-strategy.d.ts.map +1 -0
- package/dist/tools/wait/consolidation-strategy.js +50 -0
- package/dist/tools/wait/consolidation-strategy.js.map +1 -0
- package/dist/tools/wait/drive-handler.d.ts +5 -7
- package/dist/tools/wait/drive-handler.d.ts.map +1 -1
- package/dist/tools/wait/drive-handler.js +30 -48
- package/dist/tools/wait/drive-handler.js.map +1 -1
- package/dist/tools/wait/message-delivery.d.ts.map +1 -1
- package/dist/tools/wait/message-delivery.js +13 -0
- package/dist/tools/wait/message-delivery.js.map +1 -1
- package/package.json +2 -2
- package/templates/atomic-build-spec.default.md +57 -0
- package/templates/buildless-vue-preview.default.md +47 -0
- package/templates/phased-build.default.md +59 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard API — Agent Task Board routes.
|
|
3
|
+
*
|
|
4
|
+
* The ONLY write surface for the board (single-writer invariant): the operator
|
|
5
|
+
* acts here; agents never see these endpoints. The orchestrator service is the
|
|
6
|
+
* other writer (worker reports → comments, status moves) but that is server
|
|
7
|
+
* code, not an exposed surface.
|
|
8
|
+
*
|
|
9
|
+
* Routes (all Bearer-auth like every /api/*):
|
|
10
|
+
* GET /api/board/cards?includeArchived=1&lane=<threadId>
|
|
11
|
+
* POST /api/board/cards
|
|
12
|
+
* GET /api/board/cards/:id (card + comments)
|
|
13
|
+
* PATCH /api/board/cards/:id
|
|
14
|
+
* DELETE /api/board/cards/:id
|
|
15
|
+
* POST /api/board/cards/:id/comments
|
|
16
|
+
* GET /api/board/lanes
|
|
17
|
+
* POST /api/board/lanes
|
|
18
|
+
* DELETE /api/board/lanes/:threadId
|
|
19
|
+
* GET /api/board/profiles
|
|
20
|
+
* PUT /api/board/profiles
|
|
21
|
+
*/
|
|
22
|
+
import { readBody } from "./types.js";
|
|
23
|
+
import { errorMessage } from "../../lib/utils.js";
|
|
24
|
+
import { getMaxConcurrentThreads } from "../../config/index.js";
|
|
25
|
+
import { getUsageSnapshotProvider } from "../../services/usage/usage-snapshot-provider.js";
|
|
26
|
+
import { buildDonePatch, createCard, deleteCard, getCard, listCards, updateCard, } from "../../data/board/card.repository.js";
|
|
27
|
+
import { addComment, listComments } from "../../data/board/comment.repository.js";
|
|
28
|
+
import { listLanes, removeLane, upsertLane } from "../../data/board/lane.repository.js";
|
|
29
|
+
import { getProfileForType, getProfileTemplates, saveProfileOverrides, } from "../../data/board/profile-defaults.js";
|
|
30
|
+
import { getThread } from "../../data/memory/thread-registry.js";
|
|
31
|
+
import { releaseWorkerForCard, } from "../../services/board/release-worker.js";
|
|
32
|
+
/** Assemble the decommission deps the release-worker path needs from the
|
|
33
|
+
* dashboard context (single place carrying telegram/chatId into the routes). */
|
|
34
|
+
function releaseDeps(args) {
|
|
35
|
+
return {
|
|
36
|
+
db: args.db,
|
|
37
|
+
telegram: args.ctx.telegram,
|
|
38
|
+
chatId: args.ctx.chatId,
|
|
39
|
+
threadLifecycle: args.ctx.threadLifecycle,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** Operator-legal status targets. in_progress is entered ONLY by the
|
|
43
|
+
* orchestrator's atomic claim (a hand-set in_progress card would have no
|
|
44
|
+
* worker and sit stuck); blocked ONLY by worker reports / exit safety nets
|
|
45
|
+
* (a hand-set blocked card would carry no reason). */
|
|
46
|
+
const OPERATOR_STATUS_TARGETS = ["backlog", "done"];
|
|
47
|
+
async function parseJsonBody(args) {
|
|
48
|
+
try {
|
|
49
|
+
const parsed = JSON.parse(await readBody(args.req));
|
|
50
|
+
return typeof parsed === "object" && parsed !== null
|
|
51
|
+
? parsed
|
|
52
|
+
: null;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const asInt = (v) => {
|
|
59
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? Number(v) : NaN;
|
|
60
|
+
return Number.isInteger(n) ? n : undefined;
|
|
61
|
+
};
|
|
62
|
+
/** A lane must be a REAL registered thread — a typo'd id must not silently
|
|
63
|
+
* become a live connected lane that dispatch then spawns workers against. */
|
|
64
|
+
function validateLaneThread(db, threadId) {
|
|
65
|
+
const thread = getThread(db, threadId);
|
|
66
|
+
if (!thread)
|
|
67
|
+
return `Thread ${threadId} does not exist in the thread registry`;
|
|
68
|
+
if (thread.type === "worker")
|
|
69
|
+
return `Thread ${threadId} is a worker — lanes must be root/branch threads`;
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
/** Valid card types = builtin + operator-defined profile templates. An unknown
|
|
73
|
+
* type would silently seed an EMPTY profile, stripping tests/PR/review rigor. */
|
|
74
|
+
function validateCardType(type) {
|
|
75
|
+
const known = Object.keys(getProfileTemplates());
|
|
76
|
+
return known.includes(type)
|
|
77
|
+
? null
|
|
78
|
+
: `Unknown card type '${type}' — known types: ${known.join(", ")}`;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Empty/zeroed input means "no recurrence" — NULL, not a 1-minute respawn loop.
|
|
82
|
+
* An emptied number input arrives as '' (asInt('')=0) or 0; treating either as
|
|
83
|
+
* Math.max(1,0)=1 turned "no recurrence" into "every minute" (H3 regression).
|
|
84
|
+
* Only an intentional integer ≥1 sets a real cadence; everything falsy → null.
|
|
85
|
+
*/
|
|
86
|
+
function parseRecurDelay(v) {
|
|
87
|
+
if (v === null || v === undefined || v === "")
|
|
88
|
+
return null;
|
|
89
|
+
const n = asInt(v);
|
|
90
|
+
if (n === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
return n >= 1 ? n : null;
|
|
93
|
+
}
|
|
94
|
+
/** Order-independent equality for two execution profiles (flat primitives +
|
|
95
|
+
* a skills string[]). Used to tell an actual profile edit apart from an
|
|
96
|
+
* unchanged profile bundled into a PATCH that only touches allowed fields. */
|
|
97
|
+
function profileChanged(a, b) {
|
|
98
|
+
const keys = [...new Set([...Object.keys(a), ...Object.keys(b)])].sort();
|
|
99
|
+
return JSON.stringify(a, keys) !== JSON.stringify(b, keys);
|
|
100
|
+
}
|
|
101
|
+
/** Providers a card/profile may name (ExecutionProfile.agentType contract). An
|
|
102
|
+
* unknown value must 400 — otherwise it slips past card creation and silently
|
|
103
|
+
* falls through to the default Claude spawn branch instead of erroring. */
|
|
104
|
+
const AGENT_TYPES = ["claude", "copilot", "codex", "fable"];
|
|
105
|
+
/** Every legal ExecutionProfile field. PUT /profiles validates each persisted
|
|
106
|
+
* per-type profile against this whitelist so junk keys can't be stored. */
|
|
107
|
+
const PROFILE_FIELDS = [
|
|
108
|
+
"repository",
|
|
109
|
+
"createBranch",
|
|
110
|
+
"skills",
|
|
111
|
+
"operatorReview",
|
|
112
|
+
"openPr",
|
|
113
|
+
"expertReview",
|
|
114
|
+
"reviewAgentType",
|
|
115
|
+
"workerSplit",
|
|
116
|
+
"agentType",
|
|
117
|
+
"size",
|
|
118
|
+
"runTests",
|
|
119
|
+
"build",
|
|
120
|
+
"push",
|
|
121
|
+
"ciCheck",
|
|
122
|
+
"inline",
|
|
123
|
+
"ttlMinutes",
|
|
124
|
+
];
|
|
125
|
+
/** Reject a profile naming an unknown agentType/reviewAgentType. Empty (absent/
|
|
126
|
+
* null) means "default" and is fine; a garbage provider is a 400, not a silent
|
|
127
|
+
* fall-through to the Claude spawn branch. */
|
|
128
|
+
function validateProfileAgents(profile) {
|
|
129
|
+
for (const field of ["agentType", "reviewAgentType"]) {
|
|
130
|
+
const v = profile[field];
|
|
131
|
+
if (v !== undefined && v !== null && !AGENT_TYPES.includes(v))
|
|
132
|
+
return `Unknown ${field} '${String(v)}' — allowed: ${AGENT_TYPES.join(", ")}`;
|
|
133
|
+
}
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
/** Well-formedness of a single per-type profile persisted via PUT /profiles: a
|
|
137
|
+
* plain object whose keys are all real ExecutionProfile fields with valid agent
|
|
138
|
+
* enums. A non-object or a junk key is rejected outright. */
|
|
139
|
+
function validateProfileShape(value) {
|
|
140
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
141
|
+
return "each profile must be a JSON object";
|
|
142
|
+
const profile = value;
|
|
143
|
+
for (const key of Object.keys(profile))
|
|
144
|
+
if (!PROFILE_FIELDS.includes(key))
|
|
145
|
+
return `unknown profile field '${key}'`;
|
|
146
|
+
return validateProfileAgents(profile);
|
|
147
|
+
}
|
|
148
|
+
// ── Cards ────────────────────────────────────────────────────────────────────
|
|
149
|
+
/** GET /api/board/cards → { cards } (comments not included; fetch per card). */
|
|
150
|
+
export const handleGetBoardCards = ({ url, json, db }) => {
|
|
151
|
+
try {
|
|
152
|
+
// A malformed ?lane= must 400, not silently drop the filter and return ALL
|
|
153
|
+
// cards (a caller scoping to one lane would leak every lane's cards).
|
|
154
|
+
const laneParam = url.searchParams.get("lane");
|
|
155
|
+
let laneThreadId;
|
|
156
|
+
if (laneParam !== null) {
|
|
157
|
+
laneThreadId = asInt(laneParam);
|
|
158
|
+
if (laneThreadId === undefined) {
|
|
159
|
+
json({ error: "'lane' must be an integer thread id" }, 400);
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
json({
|
|
164
|
+
cards: listCards(db, {
|
|
165
|
+
includeArchived: url.searchParams.get("includeArchived") === "1",
|
|
166
|
+
...(laneThreadId !== undefined ? { laneThreadId } : {}),
|
|
167
|
+
}),
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
json({ error: errorMessage(err) }, 500);
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
};
|
|
175
|
+
/** POST /api/board/cards — create; type seeds the profile, explicit fields win. */
|
|
176
|
+
export const handlePostBoardCard = async (args) => {
|
|
177
|
+
const { json, db } = args;
|
|
178
|
+
try {
|
|
179
|
+
const body = await parseJsonBody(args);
|
|
180
|
+
const title = typeof body?.title === "string" ? body.title.trim() : "";
|
|
181
|
+
const laneThreadId = asInt(body?.laneThreadId);
|
|
182
|
+
if (!body || !title || laneThreadId === undefined) {
|
|
183
|
+
json({ error: "'title' and integer 'laneThreadId' are required" }, 400);
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
const laneError = validateLaneThread(db, laneThreadId);
|
|
187
|
+
if (laneError) {
|
|
188
|
+
json({ error: laneError }, 400);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
const type = typeof body.type === "string" ? body.type : "chore";
|
|
192
|
+
const typeError = validateCardType(type);
|
|
193
|
+
if (typeError) {
|
|
194
|
+
json({ error: typeError }, 400);
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
// A garbage non-empty recurDelayMin ("abc") must 400, not silently clear
|
|
198
|
+
// recurrence. parseRecurDelay returns undefined ONLY for such garbage;
|
|
199
|
+
// ''/null/absent → null (no recurrence, fine).
|
|
200
|
+
const recurDelay = parseRecurDelay(body.recurDelayMin);
|
|
201
|
+
if (recurDelay === undefined) {
|
|
202
|
+
json({ error: "'recurDelayMin' must be an integer ≥ 1 (or empty to disable)" }, 400);
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
if (typeof body.profile === "object" && body.profile !== null) {
|
|
206
|
+
const agentError = validateProfileAgents(body.profile);
|
|
207
|
+
if (agentError) {
|
|
208
|
+
json({ error: agentError }, 400);
|
|
209
|
+
return true;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
const profile = {
|
|
213
|
+
...getProfileForType(type),
|
|
214
|
+
...(typeof body.profile === "object" && body.profile !== null
|
|
215
|
+
? body.profile
|
|
216
|
+
: {}),
|
|
217
|
+
};
|
|
218
|
+
// Connecting the lane on first use is idempotent and saves a separate call.
|
|
219
|
+
upsertLane(db, laneThreadId);
|
|
220
|
+
const card = createCard(db, {
|
|
221
|
+
title,
|
|
222
|
+
description: typeof body.description === "string" ? body.description : "",
|
|
223
|
+
acceptance: typeof body.acceptance === "string" ? body.acceptance : "",
|
|
224
|
+
type,
|
|
225
|
+
laneThreadId,
|
|
226
|
+
priority: asInt(body.priority) ?? 0,
|
|
227
|
+
profile,
|
|
228
|
+
escalate: body.escalate === true,
|
|
229
|
+
...(recurDelay != null ? { recurDelayMin: recurDelay } : {}),
|
|
230
|
+
});
|
|
231
|
+
json({ card }, 201);
|
|
232
|
+
}
|
|
233
|
+
catch (err) {
|
|
234
|
+
json({ error: errorMessage(err) }, 500);
|
|
235
|
+
}
|
|
236
|
+
return true;
|
|
237
|
+
};
|
|
238
|
+
/** GET /api/board/cards/:id → { card, comments } */
|
|
239
|
+
export function handleGetBoardCard(args, cardId) {
|
|
240
|
+
const { json, db } = args;
|
|
241
|
+
try {
|
|
242
|
+
const card = getCard(db, cardId);
|
|
243
|
+
if (!card) {
|
|
244
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
245
|
+
return true;
|
|
246
|
+
}
|
|
247
|
+
json({ card, comments: listComments(db, cardId) });
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
json({ error: errorMessage(err) }, 500);
|
|
251
|
+
}
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* PATCH /api/board/cards/:id — operator edits, drag-drop status moves, resume.
|
|
256
|
+
*
|
|
257
|
+
* Live-card policy (design D2/D4): a card that is in_progress is TASK-IMMUTABLE.
|
|
258
|
+
* The bound worker owns what it is DOING; the only way to change that is an
|
|
259
|
+
* explicit Stop (POST .../stop) that decommissions it. So while in_progress:
|
|
260
|
+
* • re-laning, archiving, and profile/type edits are REFUSED (409) — "Stop
|
|
261
|
+
* first" — because they would silently diverge from what the worker runs.
|
|
262
|
+
* • moving to backlog (re-run) or done ALLOWS the move but first releases
|
|
263
|
+
* (kills + tears down) the bound worker, so no orphaned/duplicate worker
|
|
264
|
+
* survives to double-push or leak its report (R1 closes B1/B2).
|
|
265
|
+
* Leaving in_progress/blocked clears the worker binding + blocked reason so a
|
|
266
|
+
* later dispatch spawns a FRESH stateless worker (design §3.5).
|
|
267
|
+
*/
|
|
268
|
+
export async function handlePatchBoardCard(args, cardId) {
|
|
269
|
+
const { json, db } = args;
|
|
270
|
+
try {
|
|
271
|
+
const body = await parseJsonBody(args);
|
|
272
|
+
if (!body) {
|
|
273
|
+
json({ error: "JSON body required" }, 400);
|
|
274
|
+
return true;
|
|
275
|
+
}
|
|
276
|
+
const existing = getCard(db, cardId);
|
|
277
|
+
if (!existing) {
|
|
278
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
// Does this PATCH move the card OUT of in_progress by an operator status
|
|
282
|
+
// target? Only then do the live-card edit guards relax (the move itself is
|
|
283
|
+
// the sanctioned "Stop-then-change" — it releases the worker below).
|
|
284
|
+
const targetStatus = typeof body.status === "string" && body.status !== existing.status
|
|
285
|
+
? body.status
|
|
286
|
+
: undefined;
|
|
287
|
+
const leavingInProgress = existing.status === "in_progress" &&
|
|
288
|
+
targetStatus !== undefined &&
|
|
289
|
+
OPERATOR_STATUS_TARGETS.includes(targetStatus);
|
|
290
|
+
const liveLocked = existing.status === "in_progress" && !leavingInProgress;
|
|
291
|
+
const patch = {};
|
|
292
|
+
if (typeof body.title === "string" && body.title.trim())
|
|
293
|
+
patch.title = body.title.trim();
|
|
294
|
+
if (typeof body.description === "string")
|
|
295
|
+
patch.description = body.description;
|
|
296
|
+
if (typeof body.acceptance === "string")
|
|
297
|
+
patch.acceptance = body.acceptance;
|
|
298
|
+
if (typeof body.type === "string") {
|
|
299
|
+
const typeError = validateCardType(body.type);
|
|
300
|
+
if (typeError) {
|
|
301
|
+
json({ error: typeError }, 400);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
// M3: type reseeds the standing orders — a task mutation. Refuse on a live
|
|
305
|
+
// card (the running worker was already briefed from the old type).
|
|
306
|
+
if (liveLocked && body.type !== existing.type) {
|
|
307
|
+
json({ error: "Card is locked while running — Stop the card to change its type" }, 409);
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
patch.type = body.type;
|
|
311
|
+
}
|
|
312
|
+
const patchLane = asInt(body.laneThreadId);
|
|
313
|
+
if (patchLane !== undefined) {
|
|
314
|
+
const laneError = validateLaneThread(db, patchLane);
|
|
315
|
+
if (laneError) {
|
|
316
|
+
json({ error: laneError }, 400);
|
|
317
|
+
return true;
|
|
318
|
+
}
|
|
319
|
+
// M1: re-laning a live card would leave the worker reporting to the old
|
|
320
|
+
// lane → lost report / false BLOCKED. Refuse until stopped.
|
|
321
|
+
if (liveLocked && patchLane !== existing.laneThreadId) {
|
|
322
|
+
json({ error: "Stop the card before re-laning" }, 409);
|
|
323
|
+
return true;
|
|
324
|
+
}
|
|
325
|
+
upsertLane(db, patchLane);
|
|
326
|
+
patch.laneThreadId = patchLane;
|
|
327
|
+
}
|
|
328
|
+
if (asInt(body.priority) !== undefined)
|
|
329
|
+
patch.priority = asInt(body.priority);
|
|
330
|
+
if (typeof body.escalate === "boolean")
|
|
331
|
+
patch.escalate = body.escalate;
|
|
332
|
+
if ("recurDelayMin" in body) {
|
|
333
|
+
// A garbage non-empty recurDelayMin must 400, not silently clear
|
|
334
|
+
// recurrence (undefined ⇒ garbage; ''/null ⇒ intentional disable).
|
|
335
|
+
const parsedDelay = parseRecurDelay(body.recurDelayMin);
|
|
336
|
+
if (parsedDelay === undefined) {
|
|
337
|
+
json({ error: "'recurDelayMin' must be an integer ≥ 1 (or empty to disable)" }, 400);
|
|
338
|
+
return true;
|
|
339
|
+
}
|
|
340
|
+
const nextDelay = parsedDelay;
|
|
341
|
+
patch.recurDelayMin = nextDelay;
|
|
342
|
+
// M7.1: enabling recurrence on a card that was never a recurring original
|
|
343
|
+
// must anchor the group here. Otherwise the card completes but
|
|
344
|
+
// listDueRecurrences (which requires recur_group_id NOT NULL) never
|
|
345
|
+
// respawns it AND archiveDoneOlderThan skips it (next_spawn_at is set) —
|
|
346
|
+
// a permanent zombie stuck in Done. Anchor to its own id, matching how
|
|
347
|
+
// createCard seeds a brand-new recurring original.
|
|
348
|
+
if (nextDelay != null && existing.recurDelayMin == null && existing.recurGroupId == null)
|
|
349
|
+
patch.recurGroupId = cardId;
|
|
350
|
+
}
|
|
351
|
+
if (typeof body.profile === "object" && body.profile !== null) {
|
|
352
|
+
// A typo'd agentType/reviewAgentType must 400 (would otherwise fall
|
|
353
|
+
// through to the default spawn branch on the next dispatch).
|
|
354
|
+
const agentError = validateProfileAgents(body.profile);
|
|
355
|
+
if (agentError) {
|
|
356
|
+
json({ error: agentError }, 400);
|
|
357
|
+
return true;
|
|
358
|
+
}
|
|
359
|
+
// M3: profile/agentType is baked at spawn — CHANGING it mid-run is a
|
|
360
|
+
// misleading no-op against the live worker. Refuse a real change until
|
|
361
|
+
// stopped; an unchanged profile bundled with an allowed edit passes.
|
|
362
|
+
if (liveLocked && profileChanged(existing.profile, body.profile)) {
|
|
363
|
+
json({ error: "Card is locked while running — Stop the card to change its profile" }, 409);
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
patch.profile = body.profile;
|
|
367
|
+
}
|
|
368
|
+
if ("archivedAt" in body) {
|
|
369
|
+
const archiving = body.archivedAt !== null;
|
|
370
|
+
// M2: archiving a live card orphans its worker and (pre-fix) leaked a
|
|
371
|
+
// concurrency slot forever. Refuse until stopped; un-archiving is fine.
|
|
372
|
+
if (archiving && liveLocked) {
|
|
373
|
+
json({ error: "Stop the card before archiving" }, 409);
|
|
374
|
+
return true;
|
|
375
|
+
}
|
|
376
|
+
patch.archivedAt = archiving ? new Date().toISOString() : null;
|
|
377
|
+
// M7.2: archiving a DONE recurring card must also stop recurrence — else
|
|
378
|
+
// next_spawn_at survives and the card still respawns (possibly into a
|
|
379
|
+
// since-deleted lane). Mirror the resume path's clear.
|
|
380
|
+
if (archiving)
|
|
381
|
+
patch.nextSpawnAt = null;
|
|
382
|
+
}
|
|
383
|
+
if (targetStatus !== undefined) {
|
|
384
|
+
if (!OPERATOR_STATUS_TARGETS.includes(targetStatus)) {
|
|
385
|
+
json({
|
|
386
|
+
error: `Operator moves may only target ${OPERATOR_STATUS_TARGETS.join("/")} — in_progress and blocked are set by the board itself`,
|
|
387
|
+
}, 400);
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
// R1: releasing a live card's worker BEFORE the DB move is what prevents
|
|
391
|
+
// the next tick from spawning a second worker on the same card.
|
|
392
|
+
if (leavingInProgress)
|
|
393
|
+
await releaseWorkerForCard(releaseDeps(args), existing.workerThreadId);
|
|
394
|
+
patch.status = targetStatus;
|
|
395
|
+
if (targetStatus === "backlog") {
|
|
396
|
+
// Resume/re-run: next dispatch spawns a fresh worker briefed from the
|
|
397
|
+
// card. The resumed card IS the group's live instance again — clear any
|
|
398
|
+
// pending respawn time or the group could double-spawn (H3).
|
|
399
|
+
patch.workerThreadId = null;
|
|
400
|
+
patch.blockedReason = null;
|
|
401
|
+
patch.nextSpawnAt = null;
|
|
402
|
+
}
|
|
403
|
+
else if (targetStatus === "done") {
|
|
404
|
+
// Single DONE-transition source — same patch the worker-report path uses.
|
|
405
|
+
Object.assign(patch, buildDonePatch(existing));
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
json({ card: updateCard(db, cardId, patch) });
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
json({ error: errorMessage(err) }, 500);
|
|
412
|
+
}
|
|
413
|
+
return true;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* POST /api/board/cards/:id/stop — explicit operator Stop (design D3).
|
|
417
|
+
* Decommission the bound worker (kill + teardown) and park the card in blocked
|
|
418
|
+
* with a clear reason. Blocked is never auto-dispatched, so the card sits safely
|
|
419
|
+
* until the operator resumes it (→ backlog re-dispatches a fresh worker).
|
|
420
|
+
*/
|
|
421
|
+
export async function handleStopBoardCard(args, cardId) {
|
|
422
|
+
const { json, db } = args;
|
|
423
|
+
try {
|
|
424
|
+
const existing = getCard(db, cardId);
|
|
425
|
+
if (!existing) {
|
|
426
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
if (existing.status !== "in_progress") {
|
|
430
|
+
json({ error: `Card ${cardId} is not running (status: ${existing.status})` }, 409);
|
|
431
|
+
return true;
|
|
432
|
+
}
|
|
433
|
+
await releaseWorkerForCard(releaseDeps(args), existing.workerThreadId);
|
|
434
|
+
const card = updateCard(db, cardId, {
|
|
435
|
+
status: "blocked",
|
|
436
|
+
blockedReason: "Stopped by operator",
|
|
437
|
+
workerThreadId: null,
|
|
438
|
+
nextSpawnAt: null,
|
|
439
|
+
});
|
|
440
|
+
json({ card });
|
|
441
|
+
}
|
|
442
|
+
catch (err) {
|
|
443
|
+
json({ error: errorMessage(err) }, 500);
|
|
444
|
+
}
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
/** DELETE /api/board/cards/:id — remove the card. A live card's bound worker
|
|
448
|
+
* is decommissioned first (R1/B8) so deleting it never orphans a running
|
|
449
|
+
* worker that would push/report against a card that no longer exists. */
|
|
450
|
+
export async function handleDeleteBoardCard(args, cardId) {
|
|
451
|
+
const { json, db } = args;
|
|
452
|
+
try {
|
|
453
|
+
const existing = getCard(db, cardId);
|
|
454
|
+
if (!existing) {
|
|
455
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
456
|
+
return true;
|
|
457
|
+
}
|
|
458
|
+
if (existing.status === "in_progress") {
|
|
459
|
+
await releaseWorkerForCard(releaseDeps(args), existing.workerThreadId);
|
|
460
|
+
}
|
|
461
|
+
if (!deleteCard(db, cardId)) {
|
|
462
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
463
|
+
return true;
|
|
464
|
+
}
|
|
465
|
+
json({ ok: true });
|
|
466
|
+
}
|
|
467
|
+
catch (err) {
|
|
468
|
+
json({ error: errorMessage(err) }, 500);
|
|
469
|
+
}
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
/** POST /api/board/cards/:id/comments — operator comment. */
|
|
473
|
+
export async function handlePostBoardComment(args, cardId) {
|
|
474
|
+
const { json, db } = args;
|
|
475
|
+
try {
|
|
476
|
+
const body = await parseJsonBody(args);
|
|
477
|
+
const content = typeof body?.content === "string" ? body.content.trim() : "";
|
|
478
|
+
if (!content) {
|
|
479
|
+
json({ error: "'content' is required" }, 400);
|
|
480
|
+
return true;
|
|
481
|
+
}
|
|
482
|
+
if (!getCard(db, cardId)) {
|
|
483
|
+
json({ error: `Card ${cardId} not found` }, 404);
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
json({ comment: addComment(db, cardId, "operator", content) }, 201);
|
|
487
|
+
}
|
|
488
|
+
catch (err) {
|
|
489
|
+
json({ error: errorMessage(err) }, 500);
|
|
490
|
+
}
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
// ── Lanes ────────────────────────────────────────────────────────────────────
|
|
494
|
+
/** GET /api/board/lanes → lanes decorated with thread names for the UI. */
|
|
495
|
+
export const handleGetBoardLanes = ({ json, db }) => {
|
|
496
|
+
try {
|
|
497
|
+
const lanes = listLanes(db).map((lane) => ({
|
|
498
|
+
...lane,
|
|
499
|
+
name: getThread(db, lane.threadId)?.name ?? `Thread ${lane.threadId}`,
|
|
500
|
+
}));
|
|
501
|
+
json({ lanes });
|
|
502
|
+
}
|
|
503
|
+
catch (err) {
|
|
504
|
+
json({ error: errorMessage(err) }, 500);
|
|
505
|
+
}
|
|
506
|
+
return true;
|
|
507
|
+
};
|
|
508
|
+
/** POST /api/board/lanes — connect/disconnect a thread, set max_concurrent. */
|
|
509
|
+
export const handlePostBoardLane = async (args) => {
|
|
510
|
+
const { json, db } = args;
|
|
511
|
+
try {
|
|
512
|
+
const body = await parseJsonBody(args);
|
|
513
|
+
const threadId = asInt(body?.threadId);
|
|
514
|
+
if (threadId === undefined) {
|
|
515
|
+
json({ error: "integer 'threadId' is required" }, 400);
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
const laneError = validateLaneThread(db, threadId);
|
|
519
|
+
if (laneError) {
|
|
520
|
+
json({ error: laneError }, 400);
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
// maxConcurrent must be a sane slot count: 0/negative makes a lane silently
|
|
524
|
+
// never dispatch; an absurd value would let one lane monopolise the global
|
|
525
|
+
// cap. Bound it to 1..global-cap.
|
|
526
|
+
const maxConcurrent = asInt(body?.maxConcurrent);
|
|
527
|
+
if (maxConcurrent !== undefined) {
|
|
528
|
+
const maxAllowed = getMaxConcurrentThreads();
|
|
529
|
+
if (maxConcurrent < 1 || maxConcurrent > maxAllowed) {
|
|
530
|
+
json({ error: `'maxConcurrent' must be an integer between 1 and ${maxAllowed}` }, 400);
|
|
531
|
+
return true;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
const lane = upsertLane(db, threadId, {
|
|
535
|
+
...(typeof body?.connected === "boolean" ? { connected: body.connected } : {}),
|
|
536
|
+
...(maxConcurrent !== undefined ? { maxConcurrent } : {}),
|
|
537
|
+
});
|
|
538
|
+
json({ lane });
|
|
539
|
+
}
|
|
540
|
+
catch (err) {
|
|
541
|
+
json({ error: errorMessage(err) }, 500);
|
|
542
|
+
}
|
|
543
|
+
return true;
|
|
544
|
+
};
|
|
545
|
+
/** DELETE /api/board/lanes/:threadId */
|
|
546
|
+
export function handleDeleteBoardLane(args, threadId) {
|
|
547
|
+
const { json, db } = args;
|
|
548
|
+
try {
|
|
549
|
+
// No FK on board_cards.lane_thread_id (SQLite would need a table rebuild),
|
|
550
|
+
// so guard here instead: removing a lane that still owns live cards would
|
|
551
|
+
// orphan them invisibly. Archived cards don't block removal; use
|
|
552
|
+
// "disconnect" to merely stop dispatch without removing the lane.
|
|
553
|
+
const liveCards = listCards(db, { laneThreadId: threadId }).length;
|
|
554
|
+
if (liveCards > 0) {
|
|
555
|
+
json({
|
|
556
|
+
error: `Lane ${threadId} still has ${liveCards} non-archived card(s) — move or archive them first, or disconnect the lane instead`,
|
|
557
|
+
}, 409);
|
|
558
|
+
return true;
|
|
559
|
+
}
|
|
560
|
+
if (removeLane(db, threadId))
|
|
561
|
+
json({ ok: true });
|
|
562
|
+
else
|
|
563
|
+
json({ error: "Lane not found" }, 404);
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
json({ error: errorMessage(err) }, 500);
|
|
567
|
+
}
|
|
568
|
+
return true;
|
|
569
|
+
}
|
|
570
|
+
// ── Profile templates ────────────────────────────────────────────────────────
|
|
571
|
+
/** GET /api/board/profiles → effective per-type templates (builtin ⊕ overrides). */
|
|
572
|
+
export const handleGetBoardProfiles = ({ json }) => {
|
|
573
|
+
try {
|
|
574
|
+
json({ profiles: getProfileTemplates() });
|
|
575
|
+
}
|
|
576
|
+
catch (err) {
|
|
577
|
+
json({ error: errorMessage(err) }, 500);
|
|
578
|
+
}
|
|
579
|
+
return true;
|
|
580
|
+
};
|
|
581
|
+
/** PUT /api/board/profiles — persist operator overrides wholesale. */
|
|
582
|
+
export const handlePutBoardProfiles = async (args) => {
|
|
583
|
+
const { json } = args;
|
|
584
|
+
try {
|
|
585
|
+
const body = await parseJsonBody(args);
|
|
586
|
+
if (!body || Array.isArray(body)) {
|
|
587
|
+
json({ error: "JSON body required ({ '<type>': {profile} })" }, 400);
|
|
588
|
+
return true;
|
|
589
|
+
}
|
|
590
|
+
// Reject an empty {} that would erase every override (a fat-finger wipe).
|
|
591
|
+
const types = Object.keys(body);
|
|
592
|
+
if (types.length === 0) {
|
|
593
|
+
json({ error: "Refusing to erase all profile overrides — send at least one per-type profile" }, 400);
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
// Persist only well-formed per-type profiles: each value must be a plain
|
|
597
|
+
// object whose keys are real ExecutionProfile fields with valid agent enums.
|
|
598
|
+
for (const type of types) {
|
|
599
|
+
const shapeError = validateProfileShape(body[type]);
|
|
600
|
+
if (shapeError) {
|
|
601
|
+
json({ error: `profile '${type}': ${shapeError}` }, 400);
|
|
602
|
+
return true;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
saveProfileOverrides(body);
|
|
606
|
+
json({ profiles: getProfileTemplates() });
|
|
607
|
+
}
|
|
608
|
+
catch (err) {
|
|
609
|
+
json({ error: errorMessage(err) }, 500);
|
|
610
|
+
}
|
|
611
|
+
return true;
|
|
612
|
+
};
|
|
613
|
+
// ── Usage read-model ─────────────────────────────────────────────────────────
|
|
614
|
+
/**
|
|
615
|
+
* GET /api/board/usage → current usage snapshot(s) from the shared provider.
|
|
616
|
+
* Agent-type-blind consumer of the port (OCP): returns whatever the poller has
|
|
617
|
+
* stored, `{ sources: [] }` when the monitor is inert.
|
|
618
|
+
*/
|
|
619
|
+
export function handleGetBoardUsage({ json }) {
|
|
620
|
+
json({ sources: getUsageSnapshotProvider().getAll() });
|
|
621
|
+
return true;
|
|
622
|
+
}
|
|
623
|
+
//# sourceMappingURL=board.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"board.js","sourceRoot":"","sources":["../../../src/dashboard/routes/board.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/dashboard/routes/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../src/dashboard/routes/claude.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAyCxE,eAAO,MAAM,eAAe,EAAE,YAG7B,CAAC;AAIF,eAAO,MAAM,gBAAgB,EAAE,YA4E9B,CAAC"}
|