@agent-plan/core 0.2.19-next.9 → 0.2.19

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":"recap.d.ts","sourceRoot":"","sources":["../src/recap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,KAAK,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,GAAE,YAAiB,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8HhH"}
1
+ {"version":3,"file":"recap.d.ts","sourceRoot":"","sources":["../src/recap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAED,yEAAyE;AACzE,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,KAAK,CAAC;AAExC,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,YAAY,CAAC;CACxB;AAKD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,GAAE,YAAiB,EAAE,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkJhH"}
package/dist/recap.js CHANGED
@@ -62,6 +62,10 @@ export async function buildRecap(st, web = {}, opts = {}) {
62
62
  const tr = tref(focusTask.task.number);
63
63
  lines.push(`${italian ? "Focus corrente" : "Current focus"}: ${fr} — ${focusFeature?.name ?? "?"} / ${pr} — ${focusPhase.title} / ${tr} — ${focusTask.task.title} (in-progress)`);
64
64
  }
65
+ else if (handoffs.length > 0) {
66
+ const top = handoffs[0];
67
+ lines.push(`${italian ? "Focus corrente" : "Current focus"}: ${italian ? "nessun task attivo" : "no active task"} · ${italian ? "handoff pendente più recente" : "most recent pending handoff"}: ${top.compositeRef} — "${top.firstLine}"`);
68
+ }
65
69
  else if (planComplete) {
66
70
  lines.push(italian
67
71
  ? "Focus corrente: piano completo — tutte le feature/fasi/task sono concluse."
@@ -92,11 +96,19 @@ export async function buildRecap(st, web = {}, opts = {}) {
92
96
  lines.push(staleNote);
93
97
  }
94
98
  if (handoffs.length > 0) {
99
+ const top = handoffs[0];
95
100
  lines.push("", italian ? `## Handoff di fase pendenti (${handoffs.length})` : `## Pending phase handoffs (${handoffs.length})`);
96
101
  handoffs.forEach((h, i) => lines.push(`[${i + 1}] ${h.compositeRef} — ${h.updatedAt} — "${h.firstLine}"`));
97
- lines.push("", italian
98
- ? `→ Leggi quello pertinente con ${handoffShowCmd} <ref> (valida contro lo stato attuale). L'handoff è MANTENUTO finché un task della fase non parte (auto-archiviato) o la fase non si conclude — non serve cancellarlo a mano.`
99
- : `→ Read the relevant one with ${handoffShowCmd} <ref> (validate against current state). It is KEPT until a task in that phase starts (then auto-archived) or the phase completes no need to clear it manually.`);
102
+ if (handoffs.length === 1) {
103
+ lines.push("", italian
104
+ ? `→ Vuoi riprendere da ${top.compositeRef}? Leggi l'handoff con ${handoffShowCmd} ${top.compositeRef} e avvia il primo task pertinente. L'handoff resta attivo finché tutti i task della fase non sono done/canceled, viene sostituito da un nuovo handoff, oppure viene cancellato esplicitamente.`
105
+ : `→ Do you want to resume from ${top.compositeRef}? Read the handoff with ${handoffShowCmd} ${top.compositeRef} and start the first relevant task. It stays active until every phase task is done/canceled, a new handoff replaces it, or it is explicitly cleared.`);
106
+ }
107
+ else {
108
+ lines.push("", italian
109
+ ? `→ Scegli da quale fase ripartire. Il più recente è [1] ${top.compositeRef} — leggilo con ${handoffShowCmd} ${top.compositeRef} e avvia il primo task pertinente. Ogni handoff resta attivo finché tutti i task della fase non sono done/canceled, viene sostituito da un nuovo handoff, oppure viene cancellato esplicitamente.`
110
+ : `→ Choose which phase to resume from. The most recent is [1] ${top.compositeRef} — read it with ${handoffShowCmd} ${top.compositeRef} and start the first relevant task. Each handoff stays active until every phase task is done/canceled, a new handoff replaces it, or it is explicitly cleared.`);
111
+ }
100
112
  }
101
113
  else if (planComplete) {
102
114
  lines.push("", italian
@@ -108,12 +120,14 @@ export async function buildRecap(st, web = {}, opts = {}) {
108
120
  ? `Nessun handoff pendente e nessun task in-progress. Usa ${taskAddCmd} / ${taskStartCmd} per iniziare.`
109
121
  : `No phase handoff pending and no task in-progress. Use ${taskAddCmd} / ${taskStartCmd} to begin work.`);
110
122
  }
123
+ lines.push("", italian ? "Pronto a riprendere?" : "Ready to resume?");
124
+ // Keep this as the final line: harnesses such as Codex display MCP results
125
+ // compactly, so callers can preserve the dashboard address verbatim.
111
126
  if (web.localUrl) {
112
127
  lines.push("", italian ? "## Web UI" : "## Web UI", `🌐 Web UI: ${web.localUrl}${web.lanUrl ? " (LAN: " + web.lanUrl + ")" : ""}${web.port ? " (port " + web.port + ")" : ""}`);
113
128
  }
114
129
  else {
115
130
  lines.push("", italian ? "## Web UI" : "## Web UI", `🌐 Web UI: ${italian ? "non attiva — avvia con /planner load" : "not running — start with /planner load"}`);
116
131
  }
117
- lines.push("", italian ? "Vuoi che riprendiamo da qui?" : "Do you want to resume from here?");
118
132
  return lines.join("\n");
119
133
  }
@@ -1 +1 @@
1
- {"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAKlD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,GAAG,EAAE,MAAM,GACV,KAAK,GAAG,SAAS,CAgCnB;AACD;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAexC,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,GAAG,EAAE,MAAM,GACV;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CAiD1C"}
1
+ {"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../src/refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAKlD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,GAAG,EAAE,MAAM,GACV,KAAK,GAAG,SAAS,CAgCnB;AACD;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAiBxC,wBAAgB,aAAa,CAC3B,MAAM,EAAE,KAAK,EAAE,EACf,QAAQ,EAAE,OAAO,EAAE,EACnB,GAAG,EAAE,MAAM,GACV;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,SAAS,CA2D1C"}
package/dist/refs.js CHANGED
@@ -43,14 +43,19 @@ export function findPhaseByRef(phases, features, ref) {
43
43
  // Extract optional feature/phase/task numbers from a composite ref.
44
44
  // Accepts 1+ digits so "t3" == "t003". Numbers are GLOBAL (post-migration).
45
45
  function parseTaskComposite(ref) {
46
- const t = ref.match(/t0*(\d+)/);
47
- const p = ref.match(/p0*(\d+)/);
48
- const f = ref.match(/f0*(\d+)/);
49
- return {
50
- taskNum: t ? parseInt(t[1], 10) : undefined,
51
- phaseNum: p ? parseInt(p[1], 10) : undefined,
52
- featureNum: f ? parseInt(f[1], 10) : undefined,
53
- };
46
+ // Anchored patterns only: composite refs (F00x/P00x/T00x, P00x(F00x)/T00x,
47
+ // P00x/T00x) and bare T00x. A 5-char shortId (e.g. "HT23X") or a title never
48
+ // matches these because they are anchored to the WHOLE string.
49
+ const composite = ref.match(/^f0*(\d+)\/p0*(\d+)\/t0*(\d+)$/);
50
+ if (composite)
51
+ return { featureNum: parseInt(composite[1], 10), phaseNum: parseInt(composite[2], 10), taskNum: parseInt(composite[3], 10) };
52
+ const phaseTask = ref.match(/^p0*(\d+)(?:\(f0*(\d+)\))?\/t0*(\d+)$/);
53
+ if (phaseTask)
54
+ return { phaseNum: parseInt(phaseTask[1], 10), featureNum: phaseTask[2] ? parseInt(phaseTask[2], 10) : undefined, taskNum: parseInt(phaseTask[3], 10) };
55
+ const bare = ref.match(/^t0*(\d+)$/);
56
+ if (bare)
57
+ return { taskNum: parseInt(bare[1], 10) };
58
+ return {};
54
59
  }
55
60
  export function findTaskByRef(phases, features, ref) {
56
61
  const normalized = ref.trim().toLowerCase();
@@ -62,6 +67,16 @@ export function findTaskByRef(phases, features, ref) {
62
67
  if (task)
63
68
  return { phase, task };
64
69
  }
70
+ // 1b. ShortId (5-char) — check BEFORE composite so a shortId like "HT23X"
71
+ // or "T1234" is never misread as a numeric task ref (regexes are anchored now,
72
+ // but a 5-char ref can still look numeric). SHORT_ID_LENGTH is always 5.
73
+ if (normalized.length === 5) {
74
+ for (const phase of phases) {
75
+ const task = phase.tasks.find((t) => t.shortId && t.shortId.toLowerCase() === normalized);
76
+ if (task)
77
+ return { phase, task };
78
+ }
79
+ }
65
80
  // 2. Composite / short ref with a T segment
66
81
  const { featureNum, phaseNum, taskNum } = parseTaskComposite(normalized);
67
82
  if (taskNum !== undefined) {