@agent-plan/core 0.2.19-next.0 → 0.2.19-next.1
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/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/naming.d.ts +9 -0
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +8 -0
- package/dist/plan-store.d.ts +12 -4
- package/dist/plan-store.d.ts.map +1 -1
- package/dist/plan-store.js +100 -123
- package/dist/recap.d.ts +32 -0
- package/dist/recap.d.ts.map +1 -0
- package/dist/recap.js +105 -0
- package/dist/refs.d.ts.map +1 -1
- package/dist/refs.js +6 -1
- package/dist/schema.d.ts +13 -27
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./naming.js";
|
|
2
2
|
export * from "./refs.js";
|
|
3
3
|
export * from "./schema.js";
|
|
4
|
+
export * from "./recap.js";
|
|
4
5
|
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, withFeatureLock, type PhaseHandoffSummary } from "./plan-store.js";
|
|
5
6
|
export { PlanRenderer } from "./renderer.js";
|
|
6
7
|
export { ExportService } from "./export-service.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7J,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAC7J,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./naming.js";
|
|
2
2
|
export * from "./refs.js";
|
|
3
3
|
export * from "./schema.js";
|
|
4
|
+
export * from "./recap.js";
|
|
4
5
|
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, withFeatureLock } from "./plan-store.js";
|
|
5
6
|
export { PlanRenderer } from "./renderer.js";
|
|
6
7
|
export { ExportService } from "./export-service.js";
|
package/dist/naming.d.ts
CHANGED
|
@@ -20,6 +20,15 @@ export declare function formatThreeDigitNumber(value: number): string;
|
|
|
20
20
|
* feature number is known. Harness-agnostic (used by core handoff listing +
|
|
21
21
|
* adapters). */
|
|
22
22
|
export declare function formatPhaseRef(phaseNumber: number, featureNumber?: number): string;
|
|
23
|
+
/** Human-readable feature ref: `F00x`. Harness-agnostic. */
|
|
24
|
+
export declare function formatFeatureRef(featureNumber: number): string;
|
|
25
|
+
/** Find the parent feature's number for a phase (for P00x(F00x) composite refs). */
|
|
26
|
+
export declare function featureNumberOfPhase(phase: {
|
|
27
|
+
featureId?: string | null | undefined;
|
|
28
|
+
}, features: {
|
|
29
|
+
id: string;
|
|
30
|
+
number: number;
|
|
31
|
+
}[]): number | undefined;
|
|
23
32
|
export declare function createPhaseId(): string;
|
|
24
33
|
/** True for legacy phase ids that are NOT feature-scoped (e.g. `phase-01-...`). */
|
|
25
34
|
export declare function isLegacyPhaseId(phaseId: string): boolean;
|
package/dist/naming.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAKA;iFACiF;AACjF,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAErE,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAEhD;;qFAEqF;AACrF,wBAAgB,aAAa,CAAC,QAAQ,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,MAAM,CAUvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;8BAI8B;AAC9B,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAK,EAAE,QAAQ,SAAa,GAAG,MAAM,CAGnF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;iBAEiB;AACjB,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlF;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../src/naming.ts"],"names":[],"mappings":"AAKA;iFACiF;AACjF,eAAO,MAAM,kBAAkB,qCAAqC,CAAC;AAErE,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,gBAAgB,QAAkB,CAAC;AAEhD;;qFAEqF;AACrF,wBAAgB,aAAa,CAAC,QAAQ,GAAE,GAAG,CAAC,MAAM,CAAa,GAAG,MAAM,CAUvE;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOnD;AAED;;;;8BAI8B;AAC9B,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,SAAK,EAAE,QAAQ,SAAa,GAAG,MAAM,CAGnF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;iBAEiB;AACjB,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAGlF;AAED,4DAA4D;AAC5D,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,oFAAoF;AACpF,wBAAgB,oBAAoB,CAClC,KAAK,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,EAChD,QAAQ,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EAAE,GACzC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,mFAAmF;AACnF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAGtF;AAED,wBAAgB,YAAY,IAAI,MAAM,CAErC;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE3F"}
|
package/dist/naming.js
CHANGED
|
@@ -51,6 +51,14 @@ export function formatPhaseRef(phaseNumber, featureNumber) {
|
|
|
51
51
|
const p = `P${formatThreeDigitNumber(phaseNumber)}`;
|
|
52
52
|
return featureNumber != null ? `${p}(F${formatThreeDigitNumber(featureNumber)})` : p;
|
|
53
53
|
}
|
|
54
|
+
/** Human-readable feature ref: `F00x`. Harness-agnostic. */
|
|
55
|
+
export function formatFeatureRef(featureNumber) {
|
|
56
|
+
return `F${formatThreeDigitNumber(featureNumber)}`;
|
|
57
|
+
}
|
|
58
|
+
/** Find the parent feature's number for a phase (for P00x(F00x) composite refs). */
|
|
59
|
+
export function featureNumberOfPhase(phase, features) {
|
|
60
|
+
return phase.featureId ? features.find((f) => f.id === phase.featureId)?.number : undefined;
|
|
61
|
+
}
|
|
54
62
|
export function createPhaseId() {
|
|
55
63
|
return randomUUID();
|
|
56
64
|
}
|
package/dist/plan-store.d.ts
CHANGED
|
@@ -34,6 +34,10 @@ export declare class PlanStore {
|
|
|
34
34
|
private runAsBatch;
|
|
35
35
|
/** Public batch wrapper used by the module-level migrateToUuids helper. */
|
|
36
36
|
runBatchForMigration<T>(fn: () => Promise<T>): Promise<T>;
|
|
37
|
+
/** Public batch wrapper: suspend autoSync (status rollup) for a sequence of
|
|
38
|
+
* writes. Use for priority-only reorders so they don't recompute phase/feature
|
|
39
|
+
* status (a reorder must not flip a partially-done feature to in-progress). */
|
|
40
|
+
runBatch<T>(fn: () => Promise<T>): Promise<T>;
|
|
37
41
|
private maybeAutoSync;
|
|
38
42
|
private normalizeTasks;
|
|
39
43
|
private normalizeFeaturesDocument;
|
|
@@ -65,6 +69,10 @@ export declare class PlanStore {
|
|
|
65
69
|
loadManifest(): Promise<Manifest>;
|
|
66
70
|
loadProject(): Promise<Project>;
|
|
67
71
|
loadPhase(phaseId: string): Promise<Phase>;
|
|
72
|
+
/** Read raw feature files WITHOUT the derived `status` field. Used
|
|
73
|
+
* internally so loadFeatures/loadAll can derive status from phases without
|
|
74
|
+
* double-loading. */
|
|
75
|
+
private loadRawFeatures;
|
|
68
76
|
loadFeatures(): Promise<FeaturesDocument>;
|
|
69
77
|
loadCodebaseProfile(): Promise<CodebaseProfile | null>;
|
|
70
78
|
saveCodebaseProfile(profile: CodebaseProfile): Promise<void>;
|
|
@@ -155,10 +163,10 @@ export declare class PlanStore {
|
|
|
155
163
|
private derivePhaseStatus;
|
|
156
164
|
private deriveFeatureStatus;
|
|
157
165
|
syncStatuses(): Promise<string[]>;
|
|
158
|
-
/**
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
166
|
+
/** Auto-clear a phase's handoff when its DERIVED status is done. Status itself
|
|
167
|
+
* is no longer persisted (derived on read), so the only remaining side effect
|
|
168
|
+
* of a task→done transition is clearing a stale handoff on a completed phase.
|
|
169
|
+
* Returns the composite ref of the phase if its handoff was cleared, else null. */
|
|
162
170
|
syncTaskStatusRollup(phaseId: string): Promise<string | null>;
|
|
163
171
|
updateProject(updater: (p: Project) => Project): Promise<Project>;
|
|
164
172
|
updateFeatures(updater: (f: FeaturesDocument) => FeaturesDocument): Promise<FeaturesDocument>;
|
package/dist/plan-store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan-store.d.ts","sourceRoot":"","sources":["../src/plan-store.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,OAAO,EACZ,KAAK,gBAAgB,EAGrB,KAAK,QAAQ,EAEb,KAAK,KAAK,EAEV,KAAK,aAAa,EAElB,KAAK,OAAO,EAEZ,KAAK,oBAAoB,EAIzB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,WAAW,EACjB,MAAM,aAAa,CAAC;AAOrB,qBAAa,cAAe,SAAQ,KAAK;aAGrB,KAAK,CAAC,EAAE,OAAO;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAeD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAElF;AAKD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,GAAG,IAAI,CAEvE;AAaD,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAStF;AAmDD,mFAAmF;AACnF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,SAAS,EAAE,MAAM,CAAC;IAClB,yFAAyF;IACzF,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,wBAAsB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAsEpE;
|
|
1
|
+
{"version":3,"file":"plan-store.d.ts","sourceRoot":"","sources":["../src/plan-store.ts"],"names":[],"mappings":"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"}
|
package/dist/plan-store.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { access, copyFile, mkdir, readdir, readFile, rename, stat, unlink, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { CodebaseProfileSchema, FeatureSchema, FeaturesDocumentSchema, ManifestSchema, PhaseSchema,
|
|
3
|
+
import { CodebaseProfileSchema, FeatureSchema, FeaturesDocumentSchema, ManifestSchema, PhaseSchema, ProjectSchema, RequirementsDocumentSchema, ResumeFocusSchema, ActivityLogSchema, } from "./schema.js";
|
|
4
4
|
import { createFeatureId, createPhaseId, createRequirementId, createShortId, createTaskId, formatPhaseRef, isLegacyPhaseId } from "./naming.js";
|
|
5
5
|
function nowISO() {
|
|
6
6
|
return new Date().toISOString();
|
|
@@ -193,7 +193,6 @@ async function readJson(path, schema) {
|
|
|
193
193
|
throw new PlanStoreError(`read failed: ${path}`, cause);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
// ─── PlanStore ──────────────────────────────────────────────────────────
|
|
197
196
|
export class PlanStore {
|
|
198
197
|
root;
|
|
199
198
|
autoSync = false;
|
|
@@ -230,16 +229,15 @@ export class PlanStore {
|
|
|
230
229
|
async runBatchForMigration(fn) {
|
|
231
230
|
return this.runAsBatch(fn);
|
|
232
231
|
}
|
|
232
|
+
/** Public batch wrapper: suspend autoSync (status rollup) for a sequence of
|
|
233
|
+
* writes. Use for priority-only reorders so they don't recompute phase/feature
|
|
234
|
+
* status (a reorder must not flip a partially-done feature to in-progress). */
|
|
235
|
+
async runBatch(fn) {
|
|
236
|
+
return this.runAsBatch(fn);
|
|
237
|
+
}
|
|
233
238
|
async maybeAutoSync() {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
this.syncGuard = true;
|
|
238
|
-
await this.syncStatuses();
|
|
239
|
-
}
|
|
240
|
-
finally {
|
|
241
|
-
this.syncGuard = false;
|
|
242
|
-
}
|
|
239
|
+
// No-op: status is derived on read, so there is nothing to sync after a
|
|
240
|
+
// save. Kept so existing save* call sites compile unchanged.
|
|
243
241
|
}
|
|
244
242
|
normalizeTasks(tasks) {
|
|
245
243
|
let changed = false;
|
|
@@ -510,11 +508,14 @@ export class PlanStore {
|
|
|
510
508
|
return readJson(this.projectPath(), ProjectSchema);
|
|
511
509
|
}
|
|
512
510
|
async loadPhase(phaseId) {
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
511
|
+
const raw = await readJson(this.phasePath(phaseId), PhaseSchema);
|
|
512
|
+
const normalized = this.normalizePhaseDocument(raw).phase;
|
|
513
|
+
return { ...normalized, status: this.derivePhaseStatus(normalized.tasks) };
|
|
514
|
+
}
|
|
515
|
+
/** Read raw feature files WITHOUT the derived `status` field. Used
|
|
516
|
+
* internally so loadFeatures/loadAll can derive status from phases without
|
|
517
|
+
* double-loading. */
|
|
518
|
+
async loadRawFeatures() {
|
|
518
519
|
let jsonFiles = [];
|
|
519
520
|
try {
|
|
520
521
|
const all = await readdir(this.featuresDir());
|
|
@@ -524,28 +525,41 @@ export class PlanStore {
|
|
|
524
525
|
// features/ absent → fall through to legacy single-file layout
|
|
525
526
|
}
|
|
526
527
|
if (jsonFiles.length > 0) {
|
|
527
|
-
const
|
|
528
|
+
const out = [];
|
|
528
529
|
for (const f of jsonFiles) {
|
|
529
530
|
const id = f.replace(/\.json$/, "");
|
|
530
531
|
try {
|
|
531
|
-
|
|
532
|
+
out.push(await readJson(this.featurePath(id), FeatureSchema));
|
|
532
533
|
}
|
|
533
534
|
catch (err) {
|
|
534
535
|
// Skip an invalid feature file rather than failing the whole load.
|
|
535
536
|
console.warn(`[plan-store] skipping invalid feature file ${f}:`, err);
|
|
536
537
|
}
|
|
537
538
|
}
|
|
538
|
-
|
|
539
|
+
// Deterministic order: sort by the persisted `number` (creation order)
|
|
540
|
+
// so callers that renumber by index (normalizeFeaturesDocument) and
|
|
541
|
+
// callers that keep persisted numbers (loadAll) agree, regardless of the
|
|
542
|
+
// filesystem readdir order. Tiebreak by id for full determinism.
|
|
543
|
+
out.sort((a, b) => (a.number - b.number) || a.id.localeCompare(b.id));
|
|
544
|
+
return out;
|
|
539
545
|
}
|
|
540
546
|
// Legacy: single features.json (pre-migration read; migration writes on first write op).
|
|
541
547
|
try {
|
|
542
548
|
const legacy = await readJson(this.featuresPath(), FeaturesDocumentSchema);
|
|
543
|
-
|
|
549
|
+
const legacyFeatures = legacy.features;
|
|
550
|
+
legacyFeatures.sort((a, b) => (a.number - b.number) || a.id.localeCompare(b.id));
|
|
551
|
+
return legacyFeatures;
|
|
544
552
|
}
|
|
545
553
|
catch {
|
|
546
|
-
return
|
|
554
|
+
return [];
|
|
547
555
|
}
|
|
548
556
|
}
|
|
557
|
+
async loadFeatures() {
|
|
558
|
+
const raws = await this.loadRawFeatures();
|
|
559
|
+
const phases = await this.loadAllPhases();
|
|
560
|
+
const features = raws.map((f) => ({ ...f, status: this.deriveFeatureStatus(f.id, phases) }));
|
|
561
|
+
return this.normalizeFeaturesDocument({ features }).doc;
|
|
562
|
+
}
|
|
549
563
|
async loadCodebaseProfile() {
|
|
550
564
|
try {
|
|
551
565
|
return await readJson(this.codebasePath(), CodebaseProfileSchema);
|
|
@@ -731,14 +745,15 @@ export class PlanStore {
|
|
|
731
745
|
});
|
|
732
746
|
}
|
|
733
747
|
async loadAll() {
|
|
734
|
-
const [manifest, project,
|
|
748
|
+
const [manifest, project, requirements, phases] = await Promise.all([
|
|
735
749
|
this.loadManifest(),
|
|
736
750
|
this.loadProject(),
|
|
737
|
-
this.loadFeatures(),
|
|
738
751
|
this.loadRequirements(),
|
|
739
752
|
this.loadAllPhases(),
|
|
740
753
|
]);
|
|
741
|
-
|
|
754
|
+
const rawFeatures = await this.loadRawFeatures();
|
|
755
|
+
const features = rawFeatures.map((f) => ({ ...f, status: this.deriveFeatureStatus(f.id, phases) }));
|
|
756
|
+
return { manifest, project, requirements, phases, features: { features } };
|
|
742
757
|
}
|
|
743
758
|
/** Migrate legacy non-feature-scoped phase ids to feature-scoped ids and repair
|
|
744
759
|
* dangling feature.phaseIds references. Idempotent. */
|
|
@@ -1042,123 +1057,77 @@ export class PlanStore {
|
|
|
1042
1057
|
const duplicateShortIds = [...sidCounts.entries()].filter(([, c]) => c > 1).map(([id]) => id);
|
|
1043
1058
|
return { duplicatePhaseIds, danglingPhaseIds, duplicateShortIds };
|
|
1044
1059
|
}
|
|
1045
|
-
derivePhaseStatus(
|
|
1046
|
-
if (
|
|
1047
|
-
return
|
|
1048
|
-
const taskStatuses =
|
|
1049
|
-
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
const anyWaiting = taskStatuses.some((status) => status === "waiting");
|
|
1053
|
-
const anyDeferred = taskStatuses.some((status) => status === "deferred");
|
|
1054
|
-
const anyPlanned = taskStatuses.some((status) => status === "planned");
|
|
1055
|
-
const anyDone = taskStatuses.some((status) => status === "done");
|
|
1056
|
-
if (allRejectedOrCanceled)
|
|
1060
|
+
derivePhaseStatus(tasks) {
|
|
1061
|
+
if (tasks.length === 0)
|
|
1062
|
+
return "draft";
|
|
1063
|
+
const taskStatuses = tasks.map((task) => task.status);
|
|
1064
|
+
// Ignore rejected/canceled tasks (void) when deriving progress.
|
|
1065
|
+
const meaningful = taskStatuses.filter((s) => s !== "rejected" && s !== "canceled");
|
|
1066
|
+
if (meaningful.length === 0)
|
|
1057
1067
|
return "rejected";
|
|
1058
|
-
if (
|
|
1059
|
-
return "
|
|
1060
|
-
|
|
1068
|
+
if (meaningful.every((s) => s === "done"))
|
|
1069
|
+
return "done";
|
|
1070
|
+
// Lifecycle truth: any progress (active work OR partial completion) ⇒
|
|
1071
|
+
// in-progress, until fully done. This is what prevents a single
|
|
1072
|
+
// blocked/waiting/deferred task from poisoning the parent when there is
|
|
1073
|
+
// substantial done or in-progress work (the long-standing rollup bug).
|
|
1074
|
+
if (meaningful.some((s) => s === "in-progress") || meaningful.some((s) => s === "done"))
|
|
1061
1075
|
return "in-progress";
|
|
1062
|
-
|
|
1076
|
+
// No progress at all ⇒ surface the stall / not-started state (blocked > waiting > deferred > planned).
|
|
1077
|
+
if (meaningful.some((s) => s === "blocked"))
|
|
1078
|
+
return "blocked";
|
|
1079
|
+
if (meaningful.some((s) => s === "waiting"))
|
|
1063
1080
|
return "waiting";
|
|
1064
|
-
if (
|
|
1081
|
+
if (meaningful.some((s) => s === "deferred"))
|
|
1065
1082
|
return "deferred";
|
|
1066
|
-
if (anyPlanned)
|
|
1067
|
-
return "planned";
|
|
1068
|
-
if (anyDone)
|
|
1069
|
-
return "done";
|
|
1070
1083
|
return "planned";
|
|
1071
1084
|
}
|
|
1072
|
-
deriveFeatureStatus(featureId,
|
|
1085
|
+
deriveFeatureStatus(featureId, phases) {
|
|
1073
1086
|
const featurePhases = phases.filter((phase) => phase.featureId === featureId);
|
|
1074
1087
|
if (featurePhases.length === 0)
|
|
1075
|
-
return
|
|
1088
|
+
return "planned";
|
|
1076
1089
|
const phaseStatuses = featurePhases.map((phase) => phase.status);
|
|
1077
|
-
|
|
1078
|
-
const
|
|
1079
|
-
|
|
1080
|
-
const anyWaiting = phaseStatuses.some((status) => status === "waiting");
|
|
1081
|
-
const anyDeferred = phaseStatuses.some((status) => status === "deferred");
|
|
1082
|
-
const anyPlannedLike = phaseStatuses.some((status) => status === "draft" || status === "planned");
|
|
1083
|
-
const anyDone = phaseStatuses.every((status) => status === "done");
|
|
1084
|
-
if (allRejectedOrCanceled)
|
|
1090
|
+
// Ignore rejected/canceled phases when deriving progress.
|
|
1091
|
+
const meaningful = phaseStatuses.filter((s) => s !== "rejected" && s !== "canceled");
|
|
1092
|
+
if (meaningful.length === 0)
|
|
1085
1093
|
return "rejected";
|
|
1086
|
-
if (
|
|
1087
|
-
return "
|
|
1088
|
-
|
|
1094
|
+
if (meaningful.every((s) => s === "done"))
|
|
1095
|
+
return "done";
|
|
1096
|
+
// Any progress (an active phase, or a partially-complete done phase) ⇒
|
|
1097
|
+
// in-progress. Prevents a single stalled phase from poisoning the feature
|
|
1098
|
+
// when other phases have done/in-progress work.
|
|
1099
|
+
if (meaningful.some((s) => s === "discovery" || s === "in-progress") || meaningful.some((s) => s === "done"))
|
|
1089
1100
|
return "in-progress";
|
|
1090
|
-
|
|
1101
|
+
// No progress at all ⇒ surface the stall / not-started state.
|
|
1102
|
+
if (meaningful.some((s) => s === "blocked"))
|
|
1103
|
+
return "blocked";
|
|
1104
|
+
if (meaningful.some((s) => s === "waiting"))
|
|
1091
1105
|
return "waiting";
|
|
1092
|
-
if (
|
|
1106
|
+
if (meaningful.some((s) => s === "deferred"))
|
|
1093
1107
|
return "deferred";
|
|
1094
|
-
if (anyPlannedLike)
|
|
1095
|
-
return "planned";
|
|
1096
|
-
if (anyDone)
|
|
1097
|
-
return "done";
|
|
1098
1108
|
return "planned";
|
|
1099
1109
|
}
|
|
1100
1110
|
async syncStatuses() {
|
|
1101
|
-
//
|
|
1102
|
-
//
|
|
1103
|
-
//
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
const featNum = new Map(features.features.map((f) => [f.id, f.number]));
|
|
1111
|
-
// 1. Update Phase statuses based on tasks; auto-clear handoff when a
|
|
1112
|
-
// phase transitions to done (completed phases don't keep stale
|
|
1113
|
-
// handoffs). handoffUpdatedAt is kept as an audit trail.
|
|
1114
|
-
for (const phase of phases) {
|
|
1115
|
-
const was = phase.status;
|
|
1116
|
-
phase.status = this.derivePhaseStatus(phase);
|
|
1117
|
-
if (phase.status === "done" && was !== "done" && phase.handoff) {
|
|
1118
|
-
phase.handoff = "";
|
|
1119
|
-
cleared.push(formatPhaseRef(phase.number, featNum.get(phase.featureId ?? "")));
|
|
1120
|
-
}
|
|
1121
|
-
}
|
|
1122
|
-
// 2. Update Feature statuses based on phases
|
|
1123
|
-
for (const feature of features.features) {
|
|
1124
|
-
feature.status = this.deriveFeatureStatus(feature.id, feature.status, phases);
|
|
1125
|
-
}
|
|
1126
|
-
// 3. Save everything
|
|
1127
|
-
await this.saveFeatures(features);
|
|
1128
|
-
for (const phase of phases) {
|
|
1129
|
-
await this.savePhase(phase);
|
|
1130
|
-
}
|
|
1131
|
-
// 4. Refresh resume focus so a subentrating agent sees current state
|
|
1132
|
-
await this.refreshResume();
|
|
1133
|
-
});
|
|
1134
|
-
return cleared;
|
|
1135
|
-
}
|
|
1136
|
-
/** Optimized rollup: syncs only the affected phase and its parent feature.
|
|
1137
|
-
* Drastically reduces write operations and 'busy' window for task updates.
|
|
1138
|
-
* Returns the composite ref of the phase if its handoff was auto-cleared
|
|
1139
|
-
* (phase transitioned to done), else null. */
|
|
1111
|
+
// No-op: phase/feature status is now DERIVED at read time (never persisted),
|
|
1112
|
+
// so there is nothing to sync. Kept for backward compatibility with callers
|
|
1113
|
+
// (serve.ts, adapters) that invoke it after mutations.
|
|
1114
|
+
return [];
|
|
1115
|
+
}
|
|
1116
|
+
/** Auto-clear a phase's handoff when its DERIVED status is done. Status itself
|
|
1117
|
+
* is no longer persisted (derived on read), so the only remaining side effect
|
|
1118
|
+
* of a task→done transition is clearing a stale handoff on a completed phase.
|
|
1119
|
+
* Returns the composite ref of the phase if its handoff was cleared, else null. */
|
|
1140
1120
|
async syncTaskStatusRollup(phaseId) {
|
|
1141
1121
|
const phase = await this.loadPhase(phaseId);
|
|
1142
|
-
|
|
1143
|
-
phase.status
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
phase.
|
|
1148
|
-
await this.savePhase(phase);
|
|
1149
|
-
let feature;
|
|
1150
|
-
if (phase.featureId) {
|
|
1151
|
-
const featuresDoc = await this.loadFeatures();
|
|
1152
|
-
feature = featuresDoc.features.find((f) => f.id === phase.featureId);
|
|
1153
|
-
if (feature) {
|
|
1154
|
-
// To derive feature status, we still need the statuses of all its phases
|
|
1155
|
-
const allPhases = await this.loadAllPhases();
|
|
1156
|
-
feature.status = this.deriveFeatureStatus(feature.id, feature.status, allPhases);
|
|
1157
|
-
await this.saveFeatures(featuresDoc);
|
|
1158
|
-
}
|
|
1122
|
+
let cleared = null;
|
|
1123
|
+
if (phase.status === "done" && phase.handoff !== "") {
|
|
1124
|
+
await this.updatePhase(phaseId, (p) => ({ ...p, handoff: "", handoffUpdatedAt: nowISO() }));
|
|
1125
|
+
const features = await this.loadFeatures();
|
|
1126
|
+
const feature = features.features.find((f) => f.id === phase.featureId);
|
|
1127
|
+
cleared = formatPhaseRef(phase.number, feature?.number);
|
|
1159
1128
|
}
|
|
1160
1129
|
await this.refreshResume();
|
|
1161
|
-
return cleared
|
|
1130
|
+
return cleared;
|
|
1162
1131
|
}
|
|
1163
1132
|
// ── Savers ───────────────────────────────────────────────────────────
|
|
1164
1133
|
async updateProject(updater) {
|
|
@@ -1247,9 +1216,17 @@ export class PlanStore {
|
|
|
1247
1216
|
* task_create / phase_update calls on the SAME phaseId so batch operations
|
|
1248
1217
|
* don't lose tasks (last-write-wins race condition). */
|
|
1249
1218
|
async updatePhase(phaseId, updater) {
|
|
1250
|
-
|
|
1219
|
+
// Augment the raw (on-disk) phase with its DERIVED status before handing it
|
|
1220
|
+
// to the updater, so updaters that read 'phase.status' see the truth. The
|
|
1221
|
+
// returned object's 'status' is stripped by PhaseSchema.parse (status is
|
|
1222
|
+
// not persisted); the return value is re-derived for the caller.
|
|
1223
|
+
const raw = await atomicUpdateJson(this.phasePath(phaseId), PhaseSchema, (rawPhase) => {
|
|
1224
|
+
const current = { ...rawPhase, status: this.derivePhaseStatus(rawPhase.tasks) };
|
|
1225
|
+
const next = updater(current);
|
|
1226
|
+
return this.normalizePhaseDocument(next).phase;
|
|
1227
|
+
});
|
|
1251
1228
|
await this.maybeAutoSync();
|
|
1252
|
-
return
|
|
1229
|
+
return { ...raw, status: this.derivePhaseStatus(raw.tasks) };
|
|
1253
1230
|
}
|
|
1254
1231
|
// ── Phase-scoped handoff (entity field, harness-agnostic) ────────────
|
|
1255
1232
|
/** Get the handoff text for a phase ("" if none). Throws if phase missing. */
|
package/dist/recap.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { PlanStore } from "./plan-store.js";
|
|
2
|
+
/**
|
|
3
|
+
* Web UI info for the recap (harness-agnostic — no module globals).
|
|
4
|
+
* Pass { localUrl, lanUrl, port } from whichever harness runs the server.
|
|
5
|
+
* Omit/empty → the recap notes the dashboard is not running.
|
|
6
|
+
*/
|
|
7
|
+
export interface RecapWebInfo {
|
|
8
|
+
localUrl?: string | undefined;
|
|
9
|
+
lanUrl?: string | undefined;
|
|
10
|
+
port?: number | undefined;
|
|
11
|
+
}
|
|
12
|
+
/** Which harness is presenting the recap — drives command-name hints. */
|
|
13
|
+
export type RecapHarness = "pi" | "mcp";
|
|
14
|
+
export interface RecapOptions {
|
|
15
|
+
harness?: RecapHarness;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Build a consolidated planner recap (project state + active focus + pending
|
|
19
|
+
* handoffs + web URL). SHARED across all harnesses (Pi command, Pi tool,
|
|
20
|
+
* Claude Code/Codex MCP) so every adapter presents identical content.
|
|
21
|
+
*
|
|
22
|
+
* English by default; Italian if project.chatLanguage is set to Italian.
|
|
23
|
+
* Uses human-readable names/titles plus composite IDs (F00x / P00x(F00x) / T00x)
|
|
24
|
+
* so the user/agent can reference entities unambiguously.
|
|
25
|
+
*
|
|
26
|
+
* Pass opts.harness to get harness-correct command hints in the actionable
|
|
27
|
+
* lines (e.g. "/planner task start" in Pi vs "planner-task-start" in MCP).
|
|
28
|
+
* When the plan is fully complete, stale resume.nextSteps are suppressed and a
|
|
29
|
+
* "plan complete — add a feature/phase to continue" hint is shown instead.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildRecap(st: PlanStore, web?: RecapWebInfo, opts?: RecapOptions): Promise<string>;
|
|
32
|
+
//# sourceMappingURL=recap.d.ts.map
|
|
@@ -0,0 +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,CA+GhH"}
|
package/dist/recap.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { formatPhaseRef, formatTwoDigitNumber } from "./naming.js";
|
|
2
|
+
const fref = (n) => `F${formatTwoDigitNumber(n)}`;
|
|
3
|
+
const tref = (n) => `T${formatTwoDigitNumber(n)}`;
|
|
4
|
+
/**
|
|
5
|
+
* Build a consolidated planner recap (project state + active focus + pending
|
|
6
|
+
* handoffs + web URL). SHARED across all harnesses (Pi command, Pi tool,
|
|
7
|
+
* Claude Code/Codex MCP) so every adapter presents identical content.
|
|
8
|
+
*
|
|
9
|
+
* English by default; Italian if project.chatLanguage is set to Italian.
|
|
10
|
+
* Uses human-readable names/titles plus composite IDs (F00x / P00x(F00x) / T00x)
|
|
11
|
+
* so the user/agent can reference entities unambiguously.
|
|
12
|
+
*
|
|
13
|
+
* Pass opts.harness to get harness-correct command hints in the actionable
|
|
14
|
+
* lines (e.g. "/planner task start" in Pi vs "planner-task-start" in MCP).
|
|
15
|
+
* When the plan is fully complete, stale resume.nextSteps are suppressed and a
|
|
16
|
+
* "plan complete — add a feature/phase to continue" hint is shown instead.
|
|
17
|
+
*/
|
|
18
|
+
export async function buildRecap(st, web = {}, opts = {}) {
|
|
19
|
+
const [plan, resume, handoffs] = await Promise.all([
|
|
20
|
+
st.loadAll(),
|
|
21
|
+
st.loadResume().catch(() => null),
|
|
22
|
+
st.listHandoffs(),
|
|
23
|
+
]);
|
|
24
|
+
const feats = plan.features.features;
|
|
25
|
+
const phases = plan.phases;
|
|
26
|
+
const allTasks = phases.flatMap((p) => p.tasks.map((task) => ({ phase: p, task })));
|
|
27
|
+
const totalF = feats.length;
|
|
28
|
+
const doneF = feats.filter((x) => x.status === "done").length;
|
|
29
|
+
const activeF = feats.filter((x) => x.status === "in-progress").length;
|
|
30
|
+
const totalP = phases.length;
|
|
31
|
+
const doneP = phases.filter((x) => x.status === "done").length;
|
|
32
|
+
const activeP = phases.filter((x) => x.status === "in-progress" || x.status === "discovery").length;
|
|
33
|
+
const totalT = allTasks.length;
|
|
34
|
+
const doneT = allTasks.filter(({ task }) => task.status === "done").length;
|
|
35
|
+
const activeT = allTasks.filter(({ task }) => task.status === "in-progress").length;
|
|
36
|
+
// Plan is fully complete: there is work and all of it is done, nothing active.
|
|
37
|
+
// (totalT > 0 guards the empty/unstarted case from looking "complete".)
|
|
38
|
+
const planComplete = totalT > 0 && doneT === totalT && doneP === totalP && doneF === totalF;
|
|
39
|
+
// Current focus = first in-progress task (and its phase/feature).
|
|
40
|
+
const focusTask = allTasks.find(({ task }) => task.status === "in-progress");
|
|
41
|
+
const focusPhase = focusTask?.phase;
|
|
42
|
+
const focusFeature = focusPhase ? feats.find((x) => x.id === focusPhase.featureId) : undefined;
|
|
43
|
+
const italian = (plan.project.chatLanguage || "").toLowerCase().includes("ital");
|
|
44
|
+
// Harness-aware command names for actionable hints.
|
|
45
|
+
const isPi = opts.harness === "pi";
|
|
46
|
+
const cmd = (piCmd, mcpCmd) => (isPi ? piCmd : mcpCmd);
|
|
47
|
+
const taskAddCmd = cmd("/planner task add", "planner-task-add");
|
|
48
|
+
const taskStartCmd = cmd("/planner task start", "planner-task-start");
|
|
49
|
+
const featureAddCmd = cmd("/planner feature add", "planner-feature-add");
|
|
50
|
+
const phaseAddCmd = cmd("/planner phase add", "planner-phase-add");
|
|
51
|
+
const handoffShowCmd = cmd("/planner handoff show", "planner-handoff-show");
|
|
52
|
+
const handoffClearCmd = cmd("/planner handoff clear", "planner-handoff-clear");
|
|
53
|
+
const lines = [];
|
|
54
|
+
lines.push(italian ? "## Ripresa planner" : "## Planner recap");
|
|
55
|
+
const name = plan.project.name || "(unnamed project)";
|
|
56
|
+
lines.push(`${italian ? "Progetto" : "Project"}: ${name}${plan.project.goal ? " — " + plan.project.goal : ""}`);
|
|
57
|
+
lines.push(italian
|
|
58
|
+
? `Avanzamento: feature ${doneF}/${totalF} completate (${activeF} attive) · fasi ${doneP}/${totalP} completate (${activeP} attive) · task ${doneT}/${totalT} completati (${activeT} attivi)`
|
|
59
|
+
: `Progress: Features ${doneF}/${totalF} done (${activeF} active) · Phases ${doneP}/${totalP} done (${activeP} active) · Tasks ${doneT}/${totalT} done (${activeT} active)`);
|
|
60
|
+
if (focusTask && focusPhase) {
|
|
61
|
+
const fr = focusFeature ? fref(focusFeature.number) : "?";
|
|
62
|
+
const pr = formatPhaseRef(focusPhase.number, focusFeature?.number);
|
|
63
|
+
const tr = tref(focusTask.task.number);
|
|
64
|
+
lines.push(`${italian ? "Focus corrente" : "Current focus"}: ${fr} — ${focusFeature?.name ?? "?"} / ${pr} — ${focusPhase.title} / ${tr} — ${focusTask.task.title} (in-progress)`);
|
|
65
|
+
}
|
|
66
|
+
else if (planComplete) {
|
|
67
|
+
lines.push(italian
|
|
68
|
+
? "Focus corrente: piano completo — tutte le feature/fasi/task sono concluse."
|
|
69
|
+
: "Current focus: plan complete — all features/phases/tasks are done.");
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
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
|
+
}
|
|
74
|
+
// Next step: only surface resume.nextSteps when the plan is NOT complete —
|
|
75
|
+
// otherwise stale init-time steps (e.g. "bootstrap discovery") leak through
|
|
76
|
+
// and contradict an all-done plan.
|
|
77
|
+
if (!planComplete && resume?.nextSteps?.length) {
|
|
78
|
+
lines.push(`${italian ? "Prossimo step" : "Next step"}: ${resume.nextSteps[0]}`);
|
|
79
|
+
}
|
|
80
|
+
if (handoffs.length > 0) {
|
|
81
|
+
lines.push("", italian ? `## Handoff di fase pendenti (${handoffs.length})` : `## Pending phase handoffs (${handoffs.length})`);
|
|
82
|
+
handoffs.forEach((h, i) => lines.push(`[${i + 1}] ${h.compositeRef} — ${h.updatedAt} — "${h.firstLine}"`));
|
|
83
|
+
lines.push("", italian
|
|
84
|
+
? `→ Leggi quello pertinente con ${handoffShowCmd} <ref> (valida contro lo stato attuale), poi ${handoffClearCmd} <ref> una volta consumato.`
|
|
85
|
+
: `→ Read the relevant one with ${handoffShowCmd} <ref> (validate against current state), then call ${handoffClearCmd} <ref> once consumed (delete-on-resume).`);
|
|
86
|
+
}
|
|
87
|
+
else if (planComplete) {
|
|
88
|
+
lines.push("", italian
|
|
89
|
+
? `Piano completo — aggiungi una nuova feature (${featureAddCmd}) o fase (${phaseAddCmd}) per continuare.`
|
|
90
|
+
: `Plan complete — add a new feature (${featureAddCmd}) or phase (${phaseAddCmd}) to continue.`);
|
|
91
|
+
}
|
|
92
|
+
else if (activeT === 0) {
|
|
93
|
+
lines.push("", italian
|
|
94
|
+
? `Nessun handoff pendente e nessun task in-progress. Usa ${taskAddCmd} / ${taskStartCmd} per iniziare.`
|
|
95
|
+
: `No phase handoff pending and no task in-progress. Use ${taskAddCmd} / ${taskStartCmd} to begin work.`);
|
|
96
|
+
}
|
|
97
|
+
if (web.localUrl) {
|
|
98
|
+
lines.push("", italian ? "## Web UI" : "## Web UI", `🌐 Web UI: ${web.localUrl}${web.lanUrl ? " (LAN: " + web.lanUrl + ")" : ""}${web.port ? " (port " + web.port + ")" : ""}`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
lines.push("", italian ? "## Web UI" : "## Web UI", `🌐 Web UI: ${italian ? "non attiva — avvia con /planner load" : "not running — start with /planner load"}`);
|
|
102
|
+
}
|
|
103
|
+
lines.push("", italian ? "Vuoi che riprendiamo da qui?" : "Do you want to resume from here?");
|
|
104
|
+
return lines.join("\n");
|
|
105
|
+
}
|
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,
|
|
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"}
|
package/dist/refs.js
CHANGED
|
@@ -31,7 +31,12 @@ export function findPhaseByRef(phases, features, ref) {
|
|
|
31
31
|
if (found)
|
|
32
32
|
return found;
|
|
33
33
|
}
|
|
34
|
-
// 3.
|
|
34
|
+
// 3. ShortId
|
|
35
|
+
found = phases.find((p) => p.shortId && p.shortId.toLowerCase() === normalized);
|
|
36
|
+
if (found)
|
|
37
|
+
return found;
|
|
38
|
+
// 4. Title fallback (backward compatibility with agents using titles)
|
|
39
|
+
// 5. Title fallback (backward compatibility with agents using titles)
|
|
35
40
|
return (phases.find((p) => p.title.toLowerCase() === normalized) ??
|
|
36
41
|
phases.find((p) => p.title.toLowerCase().includes(normalized)));
|
|
37
42
|
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -727,7 +727,6 @@ export declare const PhaseSchema: z.ZodObject<{
|
|
|
727
727
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
728
728
|
slug: z.ZodString;
|
|
729
729
|
title: z.ZodString;
|
|
730
|
-
status: z.ZodEnum<["draft", "discovery", "planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
731
730
|
discussedAt: z.ZodDefault<z.ZodString>;
|
|
732
731
|
contextReady: z.ZodDefault<z.ZodBoolean>;
|
|
733
732
|
contextReadyReason: z.ZodDefault<z.ZodString>;
|
|
@@ -1052,7 +1051,6 @@ export declare const PhaseSchema: z.ZodObject<{
|
|
|
1052
1051
|
handoffUpdatedAt: z.ZodDefault<z.ZodString>;
|
|
1053
1052
|
}, "strip", z.ZodTypeAny, {
|
|
1054
1053
|
number: number;
|
|
1055
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
1056
1054
|
dependencies: string[];
|
|
1057
1055
|
updatedAt: string;
|
|
1058
1056
|
notes: string;
|
|
@@ -1135,7 +1133,6 @@ export declare const PhaseSchema: z.ZodObject<{
|
|
|
1135
1133
|
featureId?: string | undefined;
|
|
1136
1134
|
}, {
|
|
1137
1135
|
number: number;
|
|
1138
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
1139
1136
|
updatedAt: string;
|
|
1140
1137
|
id: string;
|
|
1141
1138
|
createdAt: string;
|
|
@@ -1224,7 +1221,6 @@ export declare const FeatureSchema: z.ZodObject<{
|
|
|
1224
1221
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
1225
1222
|
name: z.ZodString;
|
|
1226
1223
|
description: z.ZodDefault<z.ZodString>;
|
|
1227
|
-
status: z.ZodEnum<["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
1228
1224
|
discussedAt: z.ZodDefault<z.ZodString>;
|
|
1229
1225
|
contextReady: z.ZodDefault<z.ZodBoolean>;
|
|
1230
1226
|
contextReadyReason: z.ZodDefault<z.ZodString>;
|
|
@@ -1260,7 +1256,6 @@ export declare const FeatureSchema: z.ZodObject<{
|
|
|
1260
1256
|
updatedAt: z.ZodString;
|
|
1261
1257
|
}, "strip", z.ZodTypeAny, {
|
|
1262
1258
|
number: number;
|
|
1263
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1264
1259
|
name: string;
|
|
1265
1260
|
updatedAt: string;
|
|
1266
1261
|
id: string;
|
|
@@ -1286,7 +1281,6 @@ export declare const FeatureSchema: z.ZodObject<{
|
|
|
1286
1281
|
workRemaining: string;
|
|
1287
1282
|
phaseIds: string[];
|
|
1288
1283
|
}, {
|
|
1289
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1290
1284
|
name: string;
|
|
1291
1285
|
updatedAt: string;
|
|
1292
1286
|
id: string;
|
|
@@ -1321,7 +1315,6 @@ export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
|
1321
1315
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
1322
1316
|
name: z.ZodString;
|
|
1323
1317
|
description: z.ZodDefault<z.ZodString>;
|
|
1324
|
-
status: z.ZodEnum<["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
1325
1318
|
discussedAt: z.ZodDefault<z.ZodString>;
|
|
1326
1319
|
contextReady: z.ZodDefault<z.ZodBoolean>;
|
|
1327
1320
|
contextReadyReason: z.ZodDefault<z.ZodString>;
|
|
@@ -1357,7 +1350,6 @@ export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
|
1357
1350
|
updatedAt: z.ZodString;
|
|
1358
1351
|
}, "strip", z.ZodTypeAny, {
|
|
1359
1352
|
number: number;
|
|
1360
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1361
1353
|
name: string;
|
|
1362
1354
|
updatedAt: string;
|
|
1363
1355
|
id: string;
|
|
@@ -1383,7 +1375,6 @@ export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
|
1383
1375
|
workRemaining: string;
|
|
1384
1376
|
phaseIds: string[];
|
|
1385
1377
|
}, {
|
|
1386
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1387
1378
|
name: string;
|
|
1388
1379
|
updatedAt: string;
|
|
1389
1380
|
id: string;
|
|
@@ -1413,7 +1404,6 @@ export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
|
1413
1404
|
}, "strip", z.ZodTypeAny, {
|
|
1414
1405
|
features: {
|
|
1415
1406
|
number: number;
|
|
1416
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1417
1407
|
name: string;
|
|
1418
1408
|
updatedAt: string;
|
|
1419
1409
|
id: string;
|
|
@@ -1441,7 +1431,6 @@ export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
|
1441
1431
|
}[];
|
|
1442
1432
|
}, {
|
|
1443
1433
|
features: {
|
|
1444
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1445
1434
|
name: string;
|
|
1446
1435
|
updatedAt: string;
|
|
1447
1436
|
id: string;
|
|
@@ -1784,7 +1773,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1784
1773
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
1785
1774
|
name: z.ZodString;
|
|
1786
1775
|
description: z.ZodDefault<z.ZodString>;
|
|
1787
|
-
status: z.ZodEnum<["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
1788
1776
|
discussedAt: z.ZodDefault<z.ZodString>;
|
|
1789
1777
|
contextReady: z.ZodDefault<z.ZodBoolean>;
|
|
1790
1778
|
contextReadyReason: z.ZodDefault<z.ZodString>;
|
|
@@ -1820,7 +1808,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1820
1808
|
updatedAt: z.ZodString;
|
|
1821
1809
|
}, "strip", z.ZodTypeAny, {
|
|
1822
1810
|
number: number;
|
|
1823
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1824
1811
|
name: string;
|
|
1825
1812
|
updatedAt: string;
|
|
1826
1813
|
id: string;
|
|
@@ -1846,7 +1833,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1846
1833
|
workRemaining: string;
|
|
1847
1834
|
phaseIds: string[];
|
|
1848
1835
|
}, {
|
|
1849
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1850
1836
|
name: string;
|
|
1851
1837
|
updatedAt: string;
|
|
1852
1838
|
id: string;
|
|
@@ -1876,7 +1862,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1876
1862
|
}, "strip", z.ZodTypeAny, {
|
|
1877
1863
|
features: {
|
|
1878
1864
|
number: number;
|
|
1879
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1880
1865
|
name: string;
|
|
1881
1866
|
updatedAt: string;
|
|
1882
1867
|
id: string;
|
|
@@ -1904,7 +1889,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1904
1889
|
}[];
|
|
1905
1890
|
}, {
|
|
1906
1891
|
features: {
|
|
1907
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
1908
1892
|
name: string;
|
|
1909
1893
|
updatedAt: string;
|
|
1910
1894
|
id: string;
|
|
@@ -2041,7 +2025,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2041
2025
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
2042
2026
|
slug: z.ZodString;
|
|
2043
2027
|
title: z.ZodString;
|
|
2044
|
-
status: z.ZodEnum<["draft", "discovery", "planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
2045
2028
|
discussedAt: z.ZodDefault<z.ZodString>;
|
|
2046
2029
|
contextReady: z.ZodDefault<z.ZodBoolean>;
|
|
2047
2030
|
contextReadyReason: z.ZodDefault<z.ZodString>;
|
|
@@ -2366,7 +2349,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2366
2349
|
handoffUpdatedAt: z.ZodDefault<z.ZodString>;
|
|
2367
2350
|
}, "strip", z.ZodTypeAny, {
|
|
2368
2351
|
number: number;
|
|
2369
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
2370
2352
|
dependencies: string[];
|
|
2371
2353
|
updatedAt: string;
|
|
2372
2354
|
notes: string;
|
|
@@ -2449,7 +2431,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2449
2431
|
featureId?: string | undefined;
|
|
2450
2432
|
}, {
|
|
2451
2433
|
number: number;
|
|
2452
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
2453
2434
|
updatedAt: string;
|
|
2454
2435
|
id: string;
|
|
2455
2436
|
createdAt: string;
|
|
@@ -2535,7 +2516,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2535
2516
|
features: {
|
|
2536
2517
|
features: {
|
|
2537
2518
|
number: number;
|
|
2538
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
2539
2519
|
name: string;
|
|
2540
2520
|
updatedAt: string;
|
|
2541
2521
|
id: string;
|
|
@@ -2617,7 +2597,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2617
2597
|
};
|
|
2618
2598
|
phases: {
|
|
2619
2599
|
number: number;
|
|
2620
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
2621
2600
|
dependencies: string[];
|
|
2622
2601
|
updatedAt: string;
|
|
2623
2602
|
notes: string;
|
|
@@ -2702,7 +2681,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2702
2681
|
}, {
|
|
2703
2682
|
features: {
|
|
2704
2683
|
features: {
|
|
2705
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting";
|
|
2706
2684
|
name: string;
|
|
2707
2685
|
updatedAt: string;
|
|
2708
2686
|
id: string;
|
|
@@ -2785,7 +2763,6 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2785
2763
|
};
|
|
2786
2764
|
phases: {
|
|
2787
2765
|
number: number;
|
|
2788
|
-
status: "planned" | "in-progress" | "done" | "blocked" | "canceled" | "rejected" | "deferred" | "waiting" | "draft" | "discovery";
|
|
2789
2766
|
updatedAt: string;
|
|
2790
2767
|
id: string;
|
|
2791
2768
|
createdAt: string;
|
|
@@ -2876,8 +2853,12 @@ export type ActivityEntry = z.infer<typeof ActivityEntrySchema>;
|
|
|
2876
2853
|
export type ActivityLog = z.infer<typeof ActivityLogSchema>;
|
|
2877
2854
|
export type ResumeFocus = z.infer<typeof ResumeFocusSchema>;
|
|
2878
2855
|
export type FeatureStatus = z.infer<typeof FeatureStatusSchema>;
|
|
2879
|
-
export type Feature = z.infer<typeof FeatureSchema
|
|
2880
|
-
|
|
2856
|
+
export type Feature = z.infer<typeof FeatureSchema> & {
|
|
2857
|
+
status: FeatureStatus;
|
|
2858
|
+
};
|
|
2859
|
+
export type FeaturesDocument = {
|
|
2860
|
+
features: Feature[];
|
|
2861
|
+
};
|
|
2881
2862
|
export type PhaseStatus = z.infer<typeof PhaseStatusSchema>;
|
|
2882
2863
|
export type TaskStatus = z.infer<typeof TaskStatusSchema>;
|
|
2883
2864
|
export type RequirementStatus = z.infer<typeof RequirementStatusSchema>;
|
|
@@ -2890,9 +2871,14 @@ export type Subtask = z.infer<typeof SubtaskSchema>;
|
|
|
2890
2871
|
export type ChecklistItem = z.infer<typeof ChecklistItemSchema>;
|
|
2891
2872
|
export type StatusLogEntry = z.infer<typeof StatusLogEntrySchema>;
|
|
2892
2873
|
export type Task = z.infer<typeof TaskSchema>;
|
|
2893
|
-
export type Phase = z.infer<typeof PhaseSchema
|
|
2874
|
+
export type Phase = z.infer<typeof PhaseSchema> & {
|
|
2875
|
+
status: PhaseStatus;
|
|
2876
|
+
};
|
|
2894
2877
|
export type MacroTask = z.infer<typeof MacroTaskSchema>;
|
|
2895
2878
|
export type Requirement = z.infer<typeof RequirementSchema>;
|
|
2896
2879
|
export type RequirementsDocument = z.infer<typeof RequirementsDocumentSchema>;
|
|
2897
|
-
export type PlanWorkspace = z.infer<typeof PlanWorkspaceSchema
|
|
2880
|
+
export type PlanWorkspace = Omit<z.infer<typeof PlanWorkspaceSchema>, "phases" | "features"> & {
|
|
2881
|
+
phases: Phase[];
|
|
2882
|
+
features: FeaturesDocument;
|
|
2883
|
+
};
|
|
2898
2884
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,eAAe,aAAwB,CAAC;AACrD,eAAO,MAAM,UAAU,aAAiD,CAAC;AAEzE,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;EAK7B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBhC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS5B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;EAM9B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE5B,CAAC;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;EAMzB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;EAOjC,CAAC;AAEH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,CAAC;AAEH,eAAO,MAAM,mBAAmB,yGAAuG,CAAC;AACxI,eAAO,MAAM,gBAAgB,yGAAuG,CAAC;AACrI,eAAO,MAAM,iBAAiB,+HAA6H,CAAC;AAC5J,eAAO,MAAM,uBAAuB,yGAAuG,CAAC;AAC5I,eAAO,MAAM,mBAAmB,yGAAuG,CAAC;AAExI,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;EAOxB,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;EAI9B,CAAC;AAIH,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,aAEzC,CAAC;AAEH;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAK7E;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;EAO/B,CAAC;AAEH,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4BpB,CAAC;AAEJ,eAAO,MAAM,WAAW
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.js
CHANGED
|
@@ -171,7 +171,9 @@ export const PhaseSchema = z.object({
|
|
|
171
171
|
priority: z.number().int().nonnegative().default(0),
|
|
172
172
|
slug: SlugSchema,
|
|
173
173
|
title: z.string().min(1),
|
|
174
|
-
|
|
174
|
+
// NOTE: `status` is intentionally ABSENT from the schema — it is a DERIVED
|
|
175
|
+
// value (computed from child tasks at read time) and is never persisted.
|
|
176
|
+
// The runtime `Phase` type re-adds it as a non-optional field (see below).
|
|
175
177
|
discussedAt: z.string().default(""),
|
|
176
178
|
contextReady: z.boolean().default(false),
|
|
177
179
|
contextReadyReason: z.string().default(""),
|
|
@@ -201,7 +203,8 @@ export const FeatureSchema = z.object({
|
|
|
201
203
|
priority: z.number().int().nonnegative().default(0),
|
|
202
204
|
name: z.string().min(1),
|
|
203
205
|
description: z.string().default(""),
|
|
204
|
-
|
|
206
|
+
// NOTE: `status` is intentionally ABSENT — it is DERIVED from child phases
|
|
207
|
+
// at read time and never persisted. The runtime `Feature` type re-adds it.
|
|
205
208
|
discussedAt: z.string().default(""),
|
|
206
209
|
contextReady: z.boolean().default(false),
|
|
207
210
|
contextReadyReason: z.string().default(""),
|
package/package.json
CHANGED