@agent-plan/core 0.2.19-next.2 → 0.2.19-next.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.
- package/dist/checklist.d.ts +16 -0
- package/dist/checklist.d.ts.map +1 -0
- package/dist/checklist.js +52 -0
- package/dist/display-status.d.ts +99 -0
- package/dist/display-status.d.ts.map +1 -0
- package/dist/display-status.js +176 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/naming.d.ts +21 -3
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +45 -3
- package/dist/plan-store.d.ts +205 -22
- package/dist/plan-store.d.ts.map +1 -1
- package/dist/plan-store.js +940 -187
- package/dist/recap.d.ts.map +1 -1
- package/dist/recap.js +35 -9
- package/dist/refs.d.ts +23 -0
- package/dist/refs.d.ts.map +1 -1
- package/dist/refs.js +81 -0
- package/dist/schema.d.ts +806 -128
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +73 -4
- package/dist/task-context.d.ts +16 -0
- package/dist/task-context.d.ts.map +1 -0
- package/dist/task-context.js +65 -0
- package/dist/task-selection.d.ts +23 -0
- package/dist/task-selection.d.ts.map +1 -0
- package/dist/task-selection.js +66 -0
- package/package.json +4 -1
package/dist/recap.d.ts.map
CHANGED
|
@@ -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,
|
|
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,CAgJhH"}
|
package/dist/recap.js
CHANGED
|
@@ -49,7 +49,6 @@ export async function buildRecap(st, web = {}, opts = {}) {
|
|
|
49
49
|
const featureAddCmd = cmd("/planner feature add", "planner-feature-add");
|
|
50
50
|
const phaseAddCmd = cmd("/planner phase add", "planner-phase-add");
|
|
51
51
|
const handoffShowCmd = cmd("/planner handoff show", "planner-handoff-show");
|
|
52
|
-
const handoffClearCmd = cmd("/planner handoff clear", "planner-handoff-clear");
|
|
53
52
|
const lines = [];
|
|
54
53
|
lines.push(italian ? "## Ripresa planner" : "## Planner recap");
|
|
55
54
|
const name = plan.project.name || "(unnamed project)";
|
|
@@ -63,6 +62,10 @@ export async function buildRecap(st, web = {}, opts = {}) {
|
|
|
63
62
|
const tr = tref(focusTask.task.number);
|
|
64
63
|
lines.push(`${italian ? "Focus corrente" : "Current focus"}: ${fr} — ${focusFeature?.name ?? "?"} / ${pr} — ${focusPhase.title} / ${tr} — ${focusTask.task.title} (in-progress)`);
|
|
65
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
|
+
}
|
|
66
69
|
else if (planComplete) {
|
|
67
70
|
lines.push(italian
|
|
68
71
|
? "Focus corrente: piano completo — tutte le feature/fasi/task sono concluse."
|
|
@@ -71,18 +74,41 @@ export async function buildRecap(st, web = {}, opts = {}) {
|
|
|
71
74
|
else {
|
|
72
75
|
lines.push(`${italian ? "Focus corrente" : "Current focus"}: ${italian ? "nessun task attivo — rivedi il piano e scegli il prossimo task concreto" : "no active task — review the plan and pick the next concrete task"}`);
|
|
73
76
|
}
|
|
74
|
-
// Next step:
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
77
|
+
// Next step: the phase handoff (phase.handoff) is the authoritative,
|
|
78
|
+
// actively-managed resume context. When a handoff is pending, point to it
|
|
79
|
+
// instead of surfacing potentially-stale resume.json nextSteps. When no
|
|
80
|
+
// handoff exists, fall back to resume.nextSteps but mark them as possibly
|
|
81
|
+
// stale (free-text that refreshResume never touches, so they can drift).
|
|
82
|
+
if (handoffs.length > 0) {
|
|
83
|
+
lines.push(italian
|
|
84
|
+
? `Prossimo step: leggi l'handoff di fase pendente sotto (fonte autorevole, gestita attivamente). I nextSteps legacy di resume.json sono soppressi perché possono essere stale.`
|
|
85
|
+
: `Next step: read the pending phase handoff below (authoritative, actively maintained). Legacy resume.json nextSteps are suppressed because they may be stale.`);
|
|
86
|
+
}
|
|
87
|
+
else if (!planComplete && resume?.nextSteps?.length) {
|
|
78
88
|
lines.push(`${italian ? "Prossimo step" : "Next step"}: ${resume.nextSteps[0]}`);
|
|
89
|
+
const staleNote = resume.nextStepsUpdatedAt
|
|
90
|
+
? (italian
|
|
91
|
+
? `⚠️ nextSteps free-text da resume.json, ultimo aggiornamento ${resume.nextStepsUpdatedAt} — può essere stale; verifica contro lo stato attuale prima di agire.`
|
|
92
|
+
: `⚠️ nextSteps are free-text from resume.json, last updated ${resume.nextStepsUpdatedAt} — may be stale; verify against current state before acting.`)
|
|
93
|
+
: (italian
|
|
94
|
+
? `⚠️ nextSteps free-text da resume.json — può essere stale; verifica contro lo stato attuale prima di agire.`
|
|
95
|
+
: `⚠️ nextSteps are free-text from resume.json — may be stale; verify against current state before acting.`);
|
|
96
|
+
lines.push(staleNote);
|
|
79
97
|
}
|
|
80
98
|
if (handoffs.length > 0) {
|
|
99
|
+
const top = handoffs[0];
|
|
81
100
|
lines.push("", italian ? `## Handoff di fase pendenti (${handoffs.length})` : `## Pending phase handoffs (${handoffs.length})`);
|
|
82
101
|
handoffs.forEach((h, i) => lines.push(`[${i + 1}] ${h.compositeRef} — ${h.updatedAt} — "${h.firstLine}"`));
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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 è MANTENUTO finché un task della fase non parte (auto-archiviato) o la fase non si conclude — non serve cancellarlo a mano.`
|
|
105
|
+
: `→ Do you want to resume from ${top.compositeRef}? Read the handoff with ${handoffShowCmd} ${top.compositeRef} and start the first relevant task. It is KEPT until a task in that phase starts (then auto-archived) or the phase completes — no need to clear it manually.`);
|
|
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 è MANTENUTO finché un task della fase non parte (auto-archiviato) o la fase non si conclude — non serve cancellarlo a mano.`
|
|
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 is KEPT until a task in that phase starts (then auto-archived) or the phase completes — no need to clear it manually.`);
|
|
111
|
+
}
|
|
86
112
|
}
|
|
87
113
|
else if (planComplete) {
|
|
88
114
|
lines.push("", italian
|
|
@@ -100,6 +126,6 @@ export async function buildRecap(st, web = {}, opts = {}) {
|
|
|
100
126
|
else {
|
|
101
127
|
lines.push("", italian ? "## Web UI" : "## Web UI", `🌐 Web UI: ${italian ? "non attiva — avvia con /planner load" : "not running — start with /planner load"}`);
|
|
102
128
|
}
|
|
103
|
-
lines.push("", italian ? "
|
|
129
|
+
lines.push("", italian ? "Pronto a riprendere?" : "Ready to resume?");
|
|
104
130
|
return lines.join("\n");
|
|
105
131
|
}
|
package/dist/refs.d.ts
CHANGED
|
@@ -21,4 +21,27 @@ import type { Phase, Feature } from "./schema.js";
|
|
|
21
21
|
* @param ref the human-facing ref (P00x / P00x(F00x) / UUID / title)
|
|
22
22
|
*/
|
|
23
23
|
export declare function findPhaseByRef(phases: Phase[], features: Feature[], ref: string): Phase | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve a task reference to { phase, task }. Harness-agnostic, shared by all
|
|
26
|
+
* adapters so resolution semantics are identical everywhere.
|
|
27
|
+
*
|
|
28
|
+
* Supported task refs (case-insensitive):
|
|
29
|
+
* - UUID: "bd6ed366-..." -> task.id
|
|
30
|
+
* - Short: "T003" | "t3" -> task.number (GLOBALLY unique under the
|
|
31
|
+
* new global-sequence numbering; bare T00x
|
|
32
|
+
* is unambiguous across all phases)
|
|
33
|
+
* - Compos: "F001/P002/T003" -> feature/phase/task numbers with parent
|
|
34
|
+
* "P002(F001)/T003" validation (feature + phase must match)
|
|
35
|
+
* "P002/T003"
|
|
36
|
+
* - ShortId: "UUXD1" -> task.shortId (5-char, globally unique)
|
|
37
|
+
* - Title: exact match, then includes (backward-compat fallback)
|
|
38
|
+
*
|
|
39
|
+
* Returns `undefined` when not found, or when a composite parent (phase/feature)
|
|
40
|
+
* does not match the resolved task's parent.
|
|
41
|
+
*/
|
|
42
|
+
import type { Task } from "./schema.js";
|
|
43
|
+
export declare function findTaskByRef(phases: Phase[], features: Feature[], ref: string): {
|
|
44
|
+
phase: Phase;
|
|
45
|
+
task: Task;
|
|
46
|
+
} | undefined;
|
|
24
47
|
//# sourceMappingURL=refs.d.ts.map
|
package/dist/refs.d.ts.map
CHANGED
|
@@ -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"}
|
|
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
|
@@ -40,3 +40,84 @@ export function findPhaseByRef(phases, features, ref) {
|
|
|
40
40
|
return (phases.find((p) => p.title.toLowerCase() === normalized) ??
|
|
41
41
|
phases.find((p) => p.title.toLowerCase().includes(normalized)));
|
|
42
42
|
}
|
|
43
|
+
// Extract optional feature/phase/task numbers from a composite ref.
|
|
44
|
+
// Accepts 1+ digits so "t3" == "t003". Numbers are GLOBAL (post-migration).
|
|
45
|
+
function parseTaskComposite(ref) {
|
|
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 {};
|
|
59
|
+
}
|
|
60
|
+
export function findTaskByRef(phases, features, ref) {
|
|
61
|
+
const normalized = ref.trim().toLowerCase();
|
|
62
|
+
if (!normalized)
|
|
63
|
+
return undefined;
|
|
64
|
+
// 1. UUID (exact)
|
|
65
|
+
for (const phase of phases) {
|
|
66
|
+
const task = phase.tasks.find((t) => t.id.toLowerCase() === normalized);
|
|
67
|
+
if (task)
|
|
68
|
+
return { phase, task };
|
|
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
|
+
}
|
|
80
|
+
// 2. Composite / short ref with a T segment
|
|
81
|
+
const { featureNum, phaseNum, taskNum } = parseTaskComposite(normalized);
|
|
82
|
+
if (taskNum !== undefined) {
|
|
83
|
+
if (phaseNum !== undefined) {
|
|
84
|
+
// Composite: validate phase (and feature if present), then resolve task by number.
|
|
85
|
+
const phase = phases.find((p) => p.number === phaseNum);
|
|
86
|
+
if (!phase)
|
|
87
|
+
return undefined;
|
|
88
|
+
if (featureNum !== undefined) {
|
|
89
|
+
const feat = features.find((f) => f.number === featureNum);
|
|
90
|
+
if (!feat || phase.featureId !== feat.id)
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const task = phase.tasks.find((t) => t.number === taskNum);
|
|
94
|
+
if (task)
|
|
95
|
+
return { phase, task };
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
// Bare T00x — globally unique under the new numbering. Find the one task.
|
|
99
|
+
for (const phase of phases) {
|
|
100
|
+
const task = phase.tasks.find((t) => t.number === taskNum);
|
|
101
|
+
if (task)
|
|
102
|
+
return { phase, task };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// 3. ShortId (5-char)
|
|
106
|
+
for (const phase of phases) {
|
|
107
|
+
const task = phase.tasks.find((t) => t.shortId && t.shortId.toLowerCase() === normalized);
|
|
108
|
+
if (task)
|
|
109
|
+
return { phase, task };
|
|
110
|
+
}
|
|
111
|
+
// 4. Title fallback (backward compatibility)
|
|
112
|
+
for (const phase of phases) {
|
|
113
|
+
const exact = phase.tasks.find((t) => t.title.toLowerCase() === normalized);
|
|
114
|
+
if (exact)
|
|
115
|
+
return { phase, task: exact };
|
|
116
|
+
}
|
|
117
|
+
for (const phase of phases) {
|
|
118
|
+
const incl = phase.tasks.find((t) => t.title.toLowerCase().includes(normalized));
|
|
119
|
+
if (incl)
|
|
120
|
+
return { phase, task: incl };
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|