@agent-plan/server 0.2.19-next.1 → 0.2.19-next.10
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 +86 -17
- package/package.json +2 -2
- package/web-ui-dist/assets/index--nGmEtA7.js +216 -0
- package/web-ui-dist/assets/index-Bfahk4d3.css +1 -0
- package/web-ui-dist/index.html +2 -2
- package/web-ui-dist/assets/index-CZ27vQH6.js +0 -211
- package/web-ui-dist/assets/index-Jy8Yy6I4.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;AAiHpC,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;
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAiHpC,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;AAqyBD,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
|
@@ -344,6 +344,8 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
344
344
|
updatedAt: now,
|
|
345
345
|
handoff: "",
|
|
346
346
|
handoffUpdatedAt: "",
|
|
347
|
+
handoffReadAt: "",
|
|
348
|
+
handoffHistory: [],
|
|
347
349
|
};
|
|
348
350
|
await store.savePhase(phase);
|
|
349
351
|
// Link to feature if featureId provided
|
|
@@ -642,20 +644,52 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
642
644
|
});
|
|
643
645
|
// ── Reorder (priority) ───────────────────────────────────────────
|
|
644
646
|
app.post(route("/reorder"), async (c) => {
|
|
647
|
+
// Midpoint-insert reorder: only the moved item's priority changes (when
|
|
648
|
+
// the gap between its new neighbours allows it). When the gap is exhausted
|
|
649
|
+
// (≤1, e.g. all-zero defaults or tight spacing), the segment is reindexed
|
|
650
|
+
// with GAP. Keeps priority as int (no schema migration) and minimises the
|
|
651
|
+
// set of changed items per drag.
|
|
645
652
|
const body = await c.req.json();
|
|
646
|
-
const { kind,
|
|
647
|
-
if (!
|
|
648
|
-
return c.json({ error: "
|
|
649
|
-
const
|
|
653
|
+
const { kind, movedId, beforeId, afterId } = body;
|
|
654
|
+
if (!movedId)
|
|
655
|
+
return c.json({ error: "movedId required" }, 400);
|
|
656
|
+
const GAP = 10;
|
|
657
|
+
// Reindex a list in-place: reconstruct the desired order (moved removed +
|
|
658
|
+
// reinserted between beforeId and afterId) then assign (i+1)*GAP.
|
|
659
|
+
const reindexList = (all) => {
|
|
660
|
+
const sorted = [...all].sort((a, b) => a.priority - b.priority || a.number - b.number);
|
|
661
|
+
const moved = sorted.find((x) => x.id === movedId);
|
|
662
|
+
const withoutMoved = sorted.filter((x) => x.id !== movedId);
|
|
663
|
+
let insertIdx;
|
|
664
|
+
if (beforeId) {
|
|
665
|
+
const bi = withoutMoved.findIndex((x) => x.id === beforeId);
|
|
666
|
+
insertIdx = bi === -1 ? withoutMoved.length : bi + 1;
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
insertIdx = 0;
|
|
670
|
+
}
|
|
671
|
+
if (moved)
|
|
672
|
+
withoutMoved.splice(insertIdx, 0, moved);
|
|
673
|
+
withoutMoved.forEach((item, i) => { item.priority = (i + 1) * GAP; });
|
|
674
|
+
};
|
|
650
675
|
if (kind === "feature") {
|
|
651
676
|
// Priority-only: suspend status rollup so reordering never flips a
|
|
652
677
|
// partially-done feature to in-progress (priority ≠ status).
|
|
653
678
|
await store.runBatch(async () => {
|
|
654
679
|
await store.updateFeatures((doc) => {
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
680
|
+
const moved = doc.features.find((x) => x.id === movedId);
|
|
681
|
+
if (!moved)
|
|
682
|
+
return doc;
|
|
683
|
+
const before = beforeId ? doc.features.find((x) => x.id === beforeId) : null;
|
|
684
|
+
const after = afterId ? doc.features.find((x) => x.id === afterId) : null;
|
|
685
|
+
const beforeP = before ? before.priority : 0;
|
|
686
|
+
const maxP = doc.features.reduce((m, f) => Math.max(m, f.priority), 0);
|
|
687
|
+
const afterP = after ? after.priority : (maxP + GAP);
|
|
688
|
+
if (afterP - beforeP > 1) {
|
|
689
|
+
moved.priority = Math.floor((beforeP + afterP) / 2);
|
|
690
|
+
}
|
|
691
|
+
else {
|
|
692
|
+
reindexList(doc.features);
|
|
659
693
|
}
|
|
660
694
|
doc.features.sort((a, b) => a.priority - b.priority || a.number - b.number);
|
|
661
695
|
return doc;
|
|
@@ -665,10 +699,36 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
665
699
|
}
|
|
666
700
|
else if (kind === "phase") {
|
|
667
701
|
const phases = await store.loadAllPhases();
|
|
702
|
+
const moved = phases.find((p) => p.id === movedId);
|
|
703
|
+
if (!moved)
|
|
704
|
+
return c.json({ error: "moved phase not found" }, 404);
|
|
705
|
+
const siblings = phases.filter((p) => p.featureId === moved.featureId);
|
|
706
|
+
const before = beforeId ? siblings.find((p) => p.id === beforeId) : null;
|
|
707
|
+
const after = afterId ? siblings.find((p) => p.id === afterId) : null;
|
|
708
|
+
const beforeP = before ? before.priority : 0;
|
|
709
|
+
const maxP = siblings.reduce((m, p) => Math.max(m, p.priority), 0);
|
|
710
|
+
const afterP = after ? after.priority : (maxP + GAP);
|
|
668
711
|
await store.runBatch(async () => {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
712
|
+
if (afterP - beforeP > 1) {
|
|
713
|
+
await store.updatePhase(movedId, (entry) => { entry.priority = Math.floor((beforeP + afterP) / 2); return entry; });
|
|
714
|
+
}
|
|
715
|
+
else {
|
|
716
|
+
// Reindex all siblings (each phase is a separate file)
|
|
717
|
+
const sorted = [...siblings].sort((a, b) => a.priority - b.priority || a.number - b.number);
|
|
718
|
+
const withoutMoved = sorted.filter((x) => x.id !== movedId);
|
|
719
|
+
let insertIdx;
|
|
720
|
+
if (beforeId) {
|
|
721
|
+
const bi = withoutMoved.findIndex((x) => x.id === beforeId);
|
|
722
|
+
insertIdx = bi === -1 ? withoutMoved.length : bi + 1;
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
insertIdx = 0;
|
|
726
|
+
}
|
|
727
|
+
const movedEntry = sorted.find((x) => x.id === movedId);
|
|
728
|
+
if (movedEntry)
|
|
729
|
+
withoutMoved.splice(insertIdx, 0, movedEntry);
|
|
730
|
+
for (const [i, p] of withoutMoved.entries()) {
|
|
731
|
+
await store.updatePhase(p.id, (entry) => { entry.priority = (i + 1) * GAP; return entry; });
|
|
672
732
|
}
|
|
673
733
|
}
|
|
674
734
|
});
|
|
@@ -676,14 +736,23 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
676
736
|
}
|
|
677
737
|
else if (kind === "task") {
|
|
678
738
|
const allPhases = await store.loadAllPhases();
|
|
679
|
-
const host = allPhases.find((p) => p.tasks.some((t) =>
|
|
739
|
+
const host = allPhases.find((p) => p.tasks.some((t) => t.id === movedId));
|
|
680
740
|
if (host) {
|
|
681
741
|
await store.runBatch(async () => {
|
|
682
742
|
await store.updatePhase(host.id, (phase) => {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
743
|
+
const moved = phase.tasks.find((x) => x.id === movedId);
|
|
744
|
+
if (!moved)
|
|
745
|
+
return phase;
|
|
746
|
+
const before = beforeId ? phase.tasks.find((x) => x.id === beforeId) : null;
|
|
747
|
+
const after = afterId ? phase.tasks.find((x) => x.id === afterId) : null;
|
|
748
|
+
const beforeP = before ? before.priority : 0;
|
|
749
|
+
const maxP = phase.tasks.reduce((m, t) => Math.max(m, t.priority), 0);
|
|
750
|
+
const afterP = after ? after.priority : (maxP + GAP);
|
|
751
|
+
if (afterP - beforeP > 1) {
|
|
752
|
+
moved.priority = Math.floor((beforeP + afterP) / 2);
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
reindexList(phase.tasks);
|
|
687
756
|
}
|
|
688
757
|
phase.tasks.sort((a, b) => a.priority - b.priority || a.number - b.number);
|
|
689
758
|
phase.taskIds = phase.tasks.map((t) => t.id);
|
|
@@ -698,7 +767,7 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
|
|
|
698
767
|
}
|
|
699
768
|
await store.writeGenerated();
|
|
700
769
|
hub()?.broadcast({ type: "plan-rendered", data: {} });
|
|
701
|
-
return c.json({ ok: true, kind,
|
|
770
|
+
return c.json({ ok: true, kind, movedId });
|
|
702
771
|
});
|
|
703
772
|
// ── Render ───────────────────────────────────────────────────────
|
|
704
773
|
app.post(route("/render"), async (c) => {
|
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.10",
|
|
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.10"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/ws": "^8.18.0"
|