@agent-plan/server 0.2.19 → 0.2.21

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.
@@ -1 +1 @@
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,CA6EvE"}
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;AAg4BD,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,CA6EvE"}
package/dist/serve.js CHANGED
@@ -251,6 +251,7 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
251
251
  priority,
252
252
  name,
253
253
  description: body.description ?? "",
254
+ descriptionUpdatedAt: now,
254
255
  status: "planned",
255
256
  discussedAt: "",
256
257
  contextReady: false,
@@ -368,6 +369,7 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
368
369
  contextReadyReason: "",
369
370
  summary: body.summary ?? "",
370
371
  description: body.description ?? "",
372
+ descriptionUpdatedAt: now,
371
373
  notes: "",
372
374
  goals: [],
373
375
  nonGoals: [],
@@ -471,6 +473,8 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
471
473
  const title = body.title?.trim();
472
474
  if (!title)
473
475
  return c.json({ error: "title required" }, 400);
476
+ if (body.status === "paused")
477
+ return c.json({ error: "A task cannot be created paused without an in-progress checkpoint. Create it planned, then use task_pause/task_switch." }, 400);
474
478
  const phase = await store.loadPhase(phaseId).catch(() => null);
475
479
  if (!phase)
476
480
  return c.json({ error: "phase not found" }, 404);
@@ -499,6 +503,7 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
499
503
  title,
500
504
  status: initialStatus,
501
505
  description: body.description ?? "",
506
+ descriptionUpdatedAt: now,
502
507
  notes: "",
503
508
  statusLog: [],
504
509
  decisions: [],
@@ -506,6 +511,8 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
506
511
  checklist: checklistItems,
507
512
  subtasks: [],
508
513
  dependsOn: [],
514
+ pauseSnapshot: null,
515
+ pauseHistory: [],
509
516
  startedAt: initialStatus === "in-progress" || initialStatus === "done" ? now : "",
510
517
  completedAt: initialStatus === "done" ? now : "",
511
518
  createdAt: now,
@@ -566,6 +573,56 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
566
573
  }
567
574
  return c.json(Array.from(activeTasksMap.values()));
568
575
  });
576
+ app.get(route("/tasks/focus"), async (c) => {
577
+ const [phases, featuresDoc, project] = await Promise.all([
578
+ store.loadAllPhases(), store.loadFeatures(), store.loadProject(),
579
+ ]);
580
+ const featureIdToNum = new Map(featuresDoc.features.map((feature) => [feature.id, feature.number]));
581
+ const openReturn = [...project.workDeviations]
582
+ .filter((deviation) => deviation.state === "resume-required" || deviation.state === "resolved")
583
+ .sort((left, right) => right.createdAt.localeCompare(left.createdAt));
584
+ const pendingByTask = new Map();
585
+ for (const deviation of openReturn) {
586
+ if (!pendingByTask.has(deviation.resumeTaskId))
587
+ pendingByTask.set(deviation.resumeTaskId, deviation);
588
+ }
589
+ const pendingOrder = new Map(openReturn.map((deviation, index) => [deviation.id, index]));
590
+ const active = [];
591
+ const paused = [];
592
+ const pendingResume = [];
593
+ for (const phase of phases) {
594
+ if (!phase.featureId)
595
+ continue;
596
+ for (const task of phase.tasks) {
597
+ const deviation = pendingByTask.get(task.id);
598
+ if (task.status !== "in-progress" && task.status !== "paused" && !deviation)
599
+ continue;
600
+ const summary = {
601
+ id: task.id,
602
+ number: task.number,
603
+ shortId: task.shortId,
604
+ title: task.title,
605
+ phaseId: phase.id,
606
+ phaseNumber: phase.number,
607
+ featureId: phase.featureId,
608
+ featureNumber: featureIdToNum.get(phase.featureId) ?? 0,
609
+ status: task.status,
610
+ pauseSnapshot: task.pauseSnapshot ?? deviation?.snapshot ?? null,
611
+ pendingResume: Boolean(deviation),
612
+ deviationId: deviation?.id ?? "",
613
+ };
614
+ if (deviation)
615
+ pendingResume.push(summary);
616
+ else if (task.status === "in-progress")
617
+ active.push(summary);
618
+ else if (task.status === "paused")
619
+ paused.push(summary);
620
+ }
621
+ }
622
+ pendingResume.sort((left, right) => (pendingOrder.get(left.deviationId) ?? Number.MAX_SAFE_INTEGER) - (pendingOrder.get(right.deviationId) ?? Number.MAX_SAFE_INTEGER));
623
+ paused.sort((left, right) => (right.pauseSnapshot?.pausedAt ?? "").localeCompare(left.pauseSnapshot?.pausedAt ?? ""));
624
+ return c.json({ active, paused, pendingResume });
625
+ });
569
626
  app.get(route("/tasks/:id"), async (c) => {
570
627
  const taskId = c.req.param("id");
571
628
  const phases = await store.loadAllPhases();
@@ -587,6 +644,9 @@ function createApiApp(store, hubRef, apiPrefix = "", uiConfig, isBusy) {
587
644
  const existing = phase.tasks.find((t) => t.id === taskId);
588
645
  if (!existing)
589
646
  return c.json({ error: "task not found" }, 404);
647
+ if (body.status && body.status !== existing.status && (body.status === "paused" || existing.status === "paused")) {
648
+ return c.json({ error: "Paused lifecycle transitions require task_pause/task_switch/task_start so the resume checkpoint and return stack remain consistent." }, 400);
649
+ }
590
650
  // Validate motivation requirement for status transitions.
591
651
  if (body.status && body.status !== existing.status && needsMotivation(existing.status, body.status)) {
592
652
  if (!body.motivation || !body.motivation.trim()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-plan/server",
3
- "version": "0.2.19",
3
+ "version": "0.2.21",
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"
44
+ "@agent-plan/core": "0.2.21"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/ws": "^8.18.0"