@agent-plan/server 0.2.19-next.20 → 0.2.19-next.22
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/dist/serve.d.ts.map +1 -1
- package/dist/serve.js +33 -5
- package/package.json +2 -2
- package/web-ui-dist/assets/{index-DVspmkeP.js → index-B4qv5MwQ.js} +68 -68
- package/web-ui-dist/assets/index-CTAfas5X.css +1 -0
- package/web-ui-dist/index.html +2 -2
- package/web-ui-dist/assets/index-Cxg9j9PL.css +0 -1
package/dist/serve.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAuIpC,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC;IACzF,MAAM,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CACrC;AAo0BD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,GAAG,SAAS,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,KAAK,CAAC;IACX,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAkFvE"}
|
package/dist/serve.js
CHANGED
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
|
|
|
6
6
|
import { createAdaptorServer } from "@hono/node-server";
|
|
7
7
|
import { Hono } from "hono";
|
|
8
8
|
import { cors } from "hono/cors";
|
|
9
|
-
import { ExportService, PlanStore, PlanStoreError, createFeatureId, createPhaseId, createChecklistItemId, createShortId, createTaskId, normalizeSlug, withFeatureLock, needsMotivation } from "@agent-plan/core";
|
|
9
|
+
import { ExportService, PlanStore, PlanStoreError, createFeatureId, createPhaseId, createChecklistItemId, createShortId, createTaskId, findPhaseByRef, normalizeSlug, withFeatureLock, needsMotivation } from "@agent-plan/core";
|
|
10
10
|
import { WsHub } from "./ws-hub.js";
|
|
11
11
|
// ─── Watcher ────────────────────────────────────────────────────────────
|
|
12
12
|
let watcherAbort = null;
|
|
@@ -14,6 +14,22 @@ let watcherHubRef = { current: null };
|
|
|
14
14
|
function nowISO() {
|
|
15
15
|
return new Date().toISOString();
|
|
16
16
|
}
|
|
17
|
+
/** Resolve requirement phase refs before persistence so requirements never dangle. */
|
|
18
|
+
async function resolveRequirementPhaseIds(store, linkedPhaseIds) {
|
|
19
|
+
if (!Array.isArray(linkedPhaseIds) || linkedPhaseIds.length === 0) {
|
|
20
|
+
return { error: "linkedPhaseIds must contain at least one phase" };
|
|
21
|
+
}
|
|
22
|
+
const refs = linkedPhaseIds.map((entry) => typeof entry === "string" ? entry.trim() : "");
|
|
23
|
+
if (refs.some((ref) => !ref)) {
|
|
24
|
+
return { error: "linkedPhaseIds must contain non-empty phase references" };
|
|
25
|
+
}
|
|
26
|
+
const [phases, featuresDocument] = await Promise.all([store.loadAllPhases(), store.loadFeatures()]);
|
|
27
|
+
const resolved = refs.map((ref) => findPhaseByRef(phases, featuresDocument.features, ref));
|
|
28
|
+
const missing = resolved.findIndex((phase) => !phase);
|
|
29
|
+
if (missing !== -1)
|
|
30
|
+
return { error: `linked phase not found: ${refs[missing]}` };
|
|
31
|
+
return { linkedPhaseIds: [...new Set(resolved.map((phase) => phase.id))] };
|
|
32
|
+
}
|
|
17
33
|
function nextTaskNumber(phase) {
|
|
18
34
|
const numbers = phase.tasks.map((task) => task.number || 0).filter((n) => Number.isFinite(n));
|
|
19
35
|
return (numbers.length > 0 ? Math.max(...numbers) : 0) + 1;
|
|
@@ -168,21 +184,29 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
168
184
|
app.get(route("/requirements"), async (c) => c.json(await store.loadRequirements()));
|
|
169
185
|
app.post(route("/requirements"), async (c) => {
|
|
170
186
|
const body = await c.req.json();
|
|
171
|
-
const
|
|
187
|
+
const links = await resolveRequirementPhaseIds(store, body.linkedPhaseIds);
|
|
188
|
+
if ("error" in links)
|
|
189
|
+
return c.json({ error: links.error }, 400);
|
|
190
|
+
const requirement = { ...body, linkedPhaseIds: links.linkedPhaseIds };
|
|
191
|
+
const reqs = await store.updateRequirements((doc) => { doc.requirements.push(requirement); return doc; });
|
|
172
192
|
await store.writeGenerated();
|
|
173
193
|
hub()?.broadcast({ type: "requirements-updated", data: reqs });
|
|
174
194
|
hub()?.broadcast({ type: "plan-rendered", data: {} });
|
|
175
|
-
return c.json(
|
|
195
|
+
return c.json(requirement, 201);
|
|
176
196
|
});
|
|
177
197
|
app.put(route("/requirements/:id"), async (c) => {
|
|
178
198
|
const id = c.req.param("id");
|
|
179
199
|
const body = await c.req.json();
|
|
200
|
+
const links = await resolveRequirementPhaseIds(store, body.linkedPhaseIds);
|
|
201
|
+
if ("error" in links)
|
|
202
|
+
return c.json({ error: links.error }, 400);
|
|
203
|
+
const requirement = { ...body, linkedPhaseIds: links.linkedPhaseIds };
|
|
180
204
|
let found = false;
|
|
181
205
|
const reqs = await store.updateRequirements((doc) => {
|
|
182
206
|
const idx = doc.requirements.findIndex((r) => r.id === id);
|
|
183
207
|
if (idx === -1)
|
|
184
208
|
return doc;
|
|
185
|
-
doc.requirements[idx] =
|
|
209
|
+
doc.requirements[idx] = requirement;
|
|
186
210
|
found = true;
|
|
187
211
|
return doc;
|
|
188
212
|
});
|
|
@@ -191,7 +215,7 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
191
215
|
await store.writeGenerated();
|
|
192
216
|
hub()?.broadcast({ type: "requirements-updated", data: reqs });
|
|
193
217
|
hub()?.broadcast({ type: "plan-rendered", data: {} });
|
|
194
|
-
return c.json(
|
|
218
|
+
return c.json(requirement);
|
|
195
219
|
});
|
|
196
220
|
app.delete(route("/requirements/:id"), async (c) => {
|
|
197
221
|
const id = c.req.param("id");
|
|
@@ -800,6 +824,10 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
800
824
|
const list = await store.listHandoffs();
|
|
801
825
|
return c.json({ handoffs: list });
|
|
802
826
|
});
|
|
827
|
+
app.get(route("/handoffs/archive"), async (c) => {
|
|
828
|
+
const archived = await store.listArchivedHandoffs();
|
|
829
|
+
return c.json({ archived });
|
|
830
|
+
});
|
|
803
831
|
app.get(route("/phases/:id/handoff"), async (c) => {
|
|
804
832
|
const id = c.req.param("id");
|
|
805
833
|
if (!id)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/server",
|
|
3
|
-
"version": "0.2.19-next.
|
|
3
|
+
"version": "0.2.19-next.22",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Local HTTP/WebSocket server for Agent Plan dashboards and planner APIs.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@hono/node-server": "^1.14.0",
|
|
42
42
|
"hono": "^4.7.0",
|
|
43
43
|
"ws": "^8.18.0",
|
|
44
|
-
"@agent-plan/core": "0.2.19-next.
|
|
44
|
+
"@agent-plan/core": "0.2.19-next.22"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/ws": "^8.18.0"
|