@agent-plan/core 0.2.19-next.3 → 0.2.19-next.5
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 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/plan-store.d.ts +32 -0
- package/dist/plan-store.d.ts.map +1 -1
- package/dist/plan-store.js +129 -34
- package/dist/recap.d.ts.map +1 -1
- package/dist/recap.js +21 -7
- package/dist/refs.d.ts +23 -0
- package/dist/refs.d.ts.map +1 -1
- package/dist/refs.js +66 -0
- package/dist/schema.d.ts +40 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +11 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from "./naming.js";
|
|
|
2
2
|
export * from "./refs.js";
|
|
3
3
|
export * from "./schema.js";
|
|
4
4
|
export * from "./recap.js";
|
|
5
|
-
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, withFeatureLock, type PhaseHandoffSummary } from "./plan-store.js";
|
|
5
|
+
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock, type PhaseHandoffSummary } from "./plan-store.js";
|
|
6
6
|
export { PlanRenderer } from "./renderer.js";
|
|
7
7
|
export { ExportService } from "./export-service.js";
|
|
8
8
|
export type { CodebaseProfile, ResumeFocus, ActivityEntry, ActivityLog, AmbientFacts } from "./schema.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,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,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,uBAAuB,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtL,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
|
@@ -2,6 +2,6 @@ export * from "./naming.js";
|
|
|
2
2
|
export * from "./refs.js";
|
|
3
3
|
export * from "./schema.js";
|
|
4
4
|
export * from "./recap.js";
|
|
5
|
-
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, withFeatureLock } from "./plan-store.js";
|
|
5
|
+
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock } from "./plan-store.js";
|
|
6
6
|
export { PlanRenderer } from "./renderer.js";
|
|
7
7
|
export { ExportService } from "./export-service.js";
|
package/dist/plan-store.d.ts
CHANGED
|
@@ -17,6 +17,26 @@ export interface PhaseHandoffSummary {
|
|
|
17
17
|
firstLine: string;
|
|
18
18
|
}
|
|
19
19
|
export declare function migrateToUuids(store: PlanStore): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* One-time idempotent migration to GLOBAL F/P/T numbering.
|
|
22
|
+
*
|
|
23
|
+
* Legacy plans assign Phase.number per-feature and Task.number per-phase, so
|
|
24
|
+
* every feature has a P001 and every phase has a T001 (ambiguous in chat/handoffs).
|
|
25
|
+
* This renumbers ALL features/phases/tasks by `createdAt` asc (stable tiebreak by
|
|
26
|
+
* id) into a single project-wide 1..N sequence and sets the monotonic project
|
|
27
|
+
* counters (nextFeatureNumber/nextPhaseNumber/nextTaskNumber).
|
|
28
|
+
*
|
|
29
|
+
* Idempotent: if no duplicate phase/task/feature numbers exist across the
|
|
30
|
+
* project, the plan is already global → no renumber writes happen (only the
|
|
31
|
+
* counters are ensured, in case project.json predates them). MUST run before
|
|
32
|
+
* ensureStructureOrdering (which no longer renumbers — numbers are stable).
|
|
33
|
+
*/
|
|
34
|
+
export declare function migrateToGlobalSequence(store: PlanStore): Promise<{
|
|
35
|
+
migrated: boolean;
|
|
36
|
+
phases: number;
|
|
37
|
+
tasks: number;
|
|
38
|
+
features: number;
|
|
39
|
+
}>;
|
|
20
40
|
export declare class PlanStore {
|
|
21
41
|
readonly root: string;
|
|
22
42
|
private autoSync;
|
|
@@ -67,6 +87,18 @@ export declare class PlanStore {
|
|
|
67
87
|
exists(): Promise<boolean>;
|
|
68
88
|
loadManifest(): Promise<Manifest>;
|
|
69
89
|
loadProject(): Promise<Project>;
|
|
90
|
+
/**
|
|
91
|
+
* Allocate the next global sequence number for a feature/phase/task.
|
|
92
|
+
* Reads the monotonic counter from project.json, increments it, persists,
|
|
93
|
+
* and returns the allocated number. MUST be called within withFeatureLock
|
|
94
|
+
* (adapters create entities inside a lock) so the counter is race-free.
|
|
95
|
+
* The counter never reuses a number — deletions leave gaps (by design:
|
|
96
|
+
* stable references survive deletion).
|
|
97
|
+
*/
|
|
98
|
+
allocFeatureNumber(): Promise<number>;
|
|
99
|
+
allocPhaseNumber(): Promise<number>;
|
|
100
|
+
allocTaskNumber(): Promise<number>;
|
|
101
|
+
private allocSeqNumber;
|
|
70
102
|
loadPhase(phaseId: string): Promise<Phase>;
|
|
71
103
|
/** Read raw feature files WITHOUT the derived `status` field. Used
|
|
72
104
|
* internally so loadFeatures/loadAll can derive status from phases without
|
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;AA4BD,qBAAa,SAAS;IACpB,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAO1B,OAAO,CAAC,eAAe,CAAS;gBAEpB,IAAI,EAAE,MAAM;IAIxB;;4EAEwE;IACxE,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAEpC;;;2BAGuB;YACT,UAAU;IAUxB,2EAA2E;IACrE,oBAAoB,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI/D;;oFAEgF;IAC1E,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;YAIrC,aAAa;IAK3B,OAAO,CAAC,cAAc;
|
|
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
|
@@ -176,6 +176,91 @@ export async function migrateToUuids(store) {
|
|
|
176
176
|
await store.writeGenerated();
|
|
177
177
|
});
|
|
178
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* One-time idempotent migration to GLOBAL F/P/T numbering.
|
|
181
|
+
*
|
|
182
|
+
* Legacy plans assign Phase.number per-feature and Task.number per-phase, so
|
|
183
|
+
* every feature has a P001 and every phase has a T001 (ambiguous in chat/handoffs).
|
|
184
|
+
* This renumbers ALL features/phases/tasks by `createdAt` asc (stable tiebreak by
|
|
185
|
+
* id) into a single project-wide 1..N sequence and sets the monotonic project
|
|
186
|
+
* counters (nextFeatureNumber/nextPhaseNumber/nextTaskNumber).
|
|
187
|
+
*
|
|
188
|
+
* Idempotent: if no duplicate phase/task/feature numbers exist across the
|
|
189
|
+
* project, the plan is already global → no renumber writes happen (only the
|
|
190
|
+
* counters are ensured, in case project.json predates them). MUST run before
|
|
191
|
+
* ensureStructureOrdering (which no longer renumbers — numbers are stable).
|
|
192
|
+
*/
|
|
193
|
+
export async function migrateToGlobalSequence(store) {
|
|
194
|
+
return store.runBatchForMigration(async () => {
|
|
195
|
+
const ws = await store.loadAll();
|
|
196
|
+
const phases = ws.phases;
|
|
197
|
+
const features = ws.features.features;
|
|
198
|
+
const project = ws.project;
|
|
199
|
+
const allTasks = [];
|
|
200
|
+
for (const phase of phases)
|
|
201
|
+
for (const task of phase.tasks)
|
|
202
|
+
allTasks.push({ phase, task });
|
|
203
|
+
const hasDupes = (nums) => new Set(nums).size !== nums.length;
|
|
204
|
+
const phaseDupes = hasDupes(phases.map((p) => p.number));
|
|
205
|
+
const taskDupes = hasDupes(allTasks.map((x) => x.task.number));
|
|
206
|
+
const featureDupes = hasDupes(features.map((f) => f.number));
|
|
207
|
+
const maxP = phases.reduce((m, p) => Math.max(m, p.number), 0);
|
|
208
|
+
const maxT = allTasks.reduce((m, x) => Math.max(m, x.task.number), 0);
|
|
209
|
+
const maxF = features.reduce((m, f) => Math.max(m, f.number), 0);
|
|
210
|
+
if (!phaseDupes && !taskDupes && !featureDupes) {
|
|
211
|
+
// Already global. Ensure counters are set (project.json may predate them).
|
|
212
|
+
let changed = false;
|
|
213
|
+
if (project.nextPhaseNumber <= maxP) {
|
|
214
|
+
project.nextPhaseNumber = maxP + 1;
|
|
215
|
+
changed = true;
|
|
216
|
+
}
|
|
217
|
+
if (project.nextTaskNumber <= maxT) {
|
|
218
|
+
project.nextTaskNumber = maxT + 1;
|
|
219
|
+
changed = true;
|
|
220
|
+
}
|
|
221
|
+
if (project.nextFeatureNumber <= maxF) {
|
|
222
|
+
project.nextFeatureNumber = maxF + 1;
|
|
223
|
+
changed = true;
|
|
224
|
+
}
|
|
225
|
+
if (changed)
|
|
226
|
+
await store.saveProject(project);
|
|
227
|
+
return { migrated: false, phases: phases.length, tasks: allTasks.length, features: features.length };
|
|
228
|
+
}
|
|
229
|
+
const renumber = (arr) => arr
|
|
230
|
+
.slice()
|
|
231
|
+
.sort((a, b) => a.createdAt.localeCompare(b.createdAt) || a.id.localeCompare(b.id))
|
|
232
|
+
.map((x, i) => ({ ...x, number: i + 1 }));
|
|
233
|
+
const newFeatures = renumber(features);
|
|
234
|
+
const newPhases = renumber(phases);
|
|
235
|
+
const numberedTasks = renumber(allTasks.map((x) => x.task));
|
|
236
|
+
// Reassemble renumbered tasks into their phases, preserving each phase's task order.
|
|
237
|
+
const tasksByPhase = new Map();
|
|
238
|
+
for (let i = 0; i < allTasks.length; i++) {
|
|
239
|
+
const pid = allTasks[i].phase.id;
|
|
240
|
+
const bucket = tasksByPhase.get(pid) ?? [];
|
|
241
|
+
bucket.push(numberedTasks[i]);
|
|
242
|
+
tasksByPhase.set(pid, bucket);
|
|
243
|
+
}
|
|
244
|
+
const finalPhases = newPhases.map((p) => {
|
|
245
|
+
const tasks = tasksByPhase.get(p.id) ?? [];
|
|
246
|
+
const order = new Map(tasks.map((t) => [t.id, t]));
|
|
247
|
+
const ordered = p.taskIds.map((id) => order.get(id)).filter((t) => Boolean(t));
|
|
248
|
+
for (const t of tasks.sort((a, b) => a.number - b.number))
|
|
249
|
+
if (!ordered.includes(t))
|
|
250
|
+
ordered.push(t);
|
|
251
|
+
return { ...p, tasks: ordered, taskIds: ordered.map((t) => t.id) };
|
|
252
|
+
});
|
|
253
|
+
await store.saveFeatures({ features: newFeatures });
|
|
254
|
+
for (const p of finalPhases)
|
|
255
|
+
await store.savePhase(p);
|
|
256
|
+
project.nextFeatureNumber = newFeatures.length + 1;
|
|
257
|
+
project.nextPhaseNumber = newPhases.length + 1;
|
|
258
|
+
project.nextTaskNumber = numberedTasks.length + 1;
|
|
259
|
+
await store.saveProject(project);
|
|
260
|
+
await store.writeGenerated();
|
|
261
|
+
return { migrated: true, phases: newPhases.length, tasks: numberedTasks.length, features: newFeatures.length };
|
|
262
|
+
});
|
|
263
|
+
}
|
|
179
264
|
async function readJson(path, schema) {
|
|
180
265
|
try {
|
|
181
266
|
const raw = await readFile(path, "utf-8");
|
|
@@ -240,24 +325,13 @@ export class PlanStore {
|
|
|
240
325
|
// save. Kept so existing save* call sites compile unchanged.
|
|
241
326
|
}
|
|
242
327
|
normalizeTasks(tasks) {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (task.number !== nextNumber)
|
|
247
|
-
changed = true;
|
|
248
|
-
return { ...task, number: nextNumber };
|
|
249
|
-
});
|
|
250
|
-
return { tasks: normalized, changed };
|
|
328
|
+
// Numbers are a STABLE global sequence (assigned once at create from project.nextTaskNumber).
|
|
329
|
+
// Do NOT renumber here — renumbering would break references after deletions.
|
|
330
|
+
return { tasks, changed: false };
|
|
251
331
|
}
|
|
252
332
|
normalizeFeaturesDocument(doc) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const nextNumber = index + 1;
|
|
256
|
-
if (feature.number !== nextNumber)
|
|
257
|
-
changed = true;
|
|
258
|
-
return { ...feature, number: nextNumber };
|
|
259
|
-
});
|
|
260
|
-
return { doc: { features: normalized }, changed };
|
|
333
|
+
// Numbers are a STABLE global sequence (assigned once at create from project.nextFeatureNumber).
|
|
334
|
+
return { doc, changed: false };
|
|
261
335
|
}
|
|
262
336
|
normalizePhaseDocument(phase) {
|
|
263
337
|
const { tasks, changed } = this.normalizeTasks(phase.tasks);
|
|
@@ -287,10 +361,7 @@ export class PlanStore {
|
|
|
287
361
|
orphanPhases.push(phase);
|
|
288
362
|
}
|
|
289
363
|
}
|
|
290
|
-
const normalizedFeatures = featuresDoc.features.map((feature
|
|
291
|
-
const nextFeatureNumber = featureIndex + 1;
|
|
292
|
-
if (feature.number !== nextFeatureNumber)
|
|
293
|
-
changed = true;
|
|
364
|
+
const normalizedFeatures = featuresDoc.features.map((feature) => {
|
|
294
365
|
const linked = feature.phaseIds.map((id) => phaseById.get(id)).filter((phase) => Boolean(phase));
|
|
295
366
|
const linkedIds = new Set(linked.map((phase) => phase.id));
|
|
296
367
|
const inferred = (phasesByFeature.get(feature.id) ?? []).filter((phase) => !linkedIds.has(phase.id));
|
|
@@ -299,12 +370,7 @@ export class PlanStore {
|
|
|
299
370
|
if (normalizedPhaseIds.length !== feature.phaseIds.length || normalizedPhaseIds.some((id, index) => id !== feature.phaseIds[index])) {
|
|
300
371
|
changed = true;
|
|
301
372
|
}
|
|
302
|
-
orderedPhases.forEach((phase
|
|
303
|
-
const nextPhaseNumber = index + 1;
|
|
304
|
-
if (phase.number !== nextPhaseNumber) {
|
|
305
|
-
phase.number = nextPhaseNumber;
|
|
306
|
-
changed = true;
|
|
307
|
-
}
|
|
373
|
+
orderedPhases.forEach((phase) => {
|
|
308
374
|
const normalizedPhase = this.normalizePhaseDocument(phase);
|
|
309
375
|
if (normalizedPhase.changed) {
|
|
310
376
|
phase.tasks = normalizedPhase.phase.tasks;
|
|
@@ -314,16 +380,10 @@ export class PlanStore {
|
|
|
314
380
|
});
|
|
315
381
|
return {
|
|
316
382
|
...feature,
|
|
317
|
-
number: nextFeatureNumber,
|
|
318
383
|
phaseIds: normalizedPhaseIds,
|
|
319
384
|
};
|
|
320
385
|
});
|
|
321
|
-
orphanPhases.forEach((phase
|
|
322
|
-
const nextPhaseNumber = index + 1;
|
|
323
|
-
if (phase.number !== nextPhaseNumber) {
|
|
324
|
-
phase.number = nextPhaseNumber;
|
|
325
|
-
changed = true;
|
|
326
|
-
}
|
|
386
|
+
orphanPhases.forEach((phase) => {
|
|
327
387
|
const normalizedPhase = this.normalizePhaseDocument(phase);
|
|
328
388
|
if (normalizedPhase.changed) {
|
|
329
389
|
phase.tasks = normalizedPhase.phase.tasks;
|
|
@@ -453,6 +513,9 @@ export class PlanStore {
|
|
|
453
513
|
beforeTaskStart: [],
|
|
454
514
|
afterPhaseComplete: [],
|
|
455
515
|
},
|
|
516
|
+
nextFeatureNumber: 1,
|
|
517
|
+
nextPhaseNumber: 1,
|
|
518
|
+
nextTaskNumber: 1,
|
|
456
519
|
});
|
|
457
520
|
await this.saveRequirements({ requirements: [] });
|
|
458
521
|
await this.saveFeatures({ features: [] });
|
|
@@ -461,6 +524,7 @@ export class PlanStore {
|
|
|
461
524
|
currentPhaseId: "",
|
|
462
525
|
inProgressTaskIds: [],
|
|
463
526
|
nextSteps: ["Run /planner project discuss to bootstrap discovery"],
|
|
527
|
+
nextStepsUpdatedAt: nowISO(),
|
|
464
528
|
blockers: [],
|
|
465
529
|
notes: "Project initialized. Awaiting discovery.",
|
|
466
530
|
lastSessionSummary: "",
|
|
@@ -516,6 +580,24 @@ export class PlanStore {
|
|
|
516
580
|
async loadProject() {
|
|
517
581
|
return readJson(this.projectPath(), ProjectSchema);
|
|
518
582
|
}
|
|
583
|
+
/**
|
|
584
|
+
* Allocate the next global sequence number for a feature/phase/task.
|
|
585
|
+
* Reads the monotonic counter from project.json, increments it, persists,
|
|
586
|
+
* and returns the allocated number. MUST be called within withFeatureLock
|
|
587
|
+
* (adapters create entities inside a lock) so the counter is race-free.
|
|
588
|
+
* The counter never reuses a number — deletions leave gaps (by design:
|
|
589
|
+
* stable references survive deletion).
|
|
590
|
+
*/
|
|
591
|
+
async allocFeatureNumber() { return this.allocSeqNumber("nextFeatureNumber"); }
|
|
592
|
+
async allocPhaseNumber() { return this.allocSeqNumber("nextPhaseNumber"); }
|
|
593
|
+
async allocTaskNumber() { return this.allocSeqNumber("nextTaskNumber"); }
|
|
594
|
+
async allocSeqNumber(key) {
|
|
595
|
+
const project = await this.loadProject();
|
|
596
|
+
const n = project[key];
|
|
597
|
+
project[key] = n + 1;
|
|
598
|
+
await this.saveProject(project);
|
|
599
|
+
return n;
|
|
600
|
+
}
|
|
519
601
|
async loadPhase(phaseId) {
|
|
520
602
|
const raw = await readJson(this.phasePath(phaseId), PhaseSchema);
|
|
521
603
|
const normalized = this.normalizePhaseDocument(raw).phase;
|
|
@@ -591,7 +673,18 @@ export class PlanStore {
|
|
|
591
673
|
}
|
|
592
674
|
}
|
|
593
675
|
async saveResume(resume) {
|
|
594
|
-
|
|
676
|
+
// Track when `nextSteps` actually change (free-text can go stale; the recap
|
|
677
|
+
// surfaces nextStepsUpdatedAt so staleness is visible). Preserved when
|
|
678
|
+
// refreshResume keeps existing nextSteps; bumped only on a real change.
|
|
679
|
+
const existing = await this.loadResume().catch(() => null);
|
|
680
|
+
const nextStepsChanged = JSON.stringify(existing?.nextSteps ?? []) !== JSON.stringify(resume.nextSteps ?? []);
|
|
681
|
+
const withTs = {
|
|
682
|
+
...resume,
|
|
683
|
+
nextStepsUpdatedAt: nextStepsChanged
|
|
684
|
+
? nowISO()
|
|
685
|
+
: (resume.nextStepsUpdatedAt || existing?.nextStepsUpdatedAt || nowISO()),
|
|
686
|
+
};
|
|
687
|
+
const parsed = ResumeFocusSchema.parse(withTs);
|
|
595
688
|
await atomicWriteJson(this.resumePath(), parsed);
|
|
596
689
|
await this.touchManifest();
|
|
597
690
|
}
|
|
@@ -607,6 +700,7 @@ export class PlanStore {
|
|
|
607
700
|
currentPhaseId: "",
|
|
608
701
|
inProgressTaskIds: [],
|
|
609
702
|
nextSteps: [],
|
|
703
|
+
nextStepsUpdatedAt: "",
|
|
610
704
|
blockers: [],
|
|
611
705
|
notes: "",
|
|
612
706
|
lastSessionSummary: "",
|
|
@@ -669,6 +763,7 @@ export class PlanStore {
|
|
|
669
763
|
currentPhaseId: inProgressPhases[0]?.id ?? existing?.currentPhaseId ?? "",
|
|
670
764
|
inProgressTaskIds: inProgressTasks.map((t) => t.id),
|
|
671
765
|
nextSteps: existing?.nextSteps ?? [],
|
|
766
|
+
nextStepsUpdatedAt: existing?.nextStepsUpdatedAt ?? "",
|
|
672
767
|
blockers: blockedTasks.map((t) => `${t.id}: ${t.title}`),
|
|
673
768
|
notes: notes ?? existing?.notes ?? "",
|
|
674
769
|
lastSessionSummary: lastSessionSummary ?? existing?.lastSessionSummary ?? "",
|
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,CA8HhH"}
|
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)";
|
|
@@ -71,18 +70,33 @@ export async function buildRecap(st, web = {}, opts = {}) {
|
|
|
71
70
|
else {
|
|
72
71
|
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
72
|
}
|
|
74
|
-
// Next step:
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
73
|
+
// Next step: the phase handoff (phase.handoff) is the authoritative,
|
|
74
|
+
// actively-managed resume context. When a handoff is pending, point to it
|
|
75
|
+
// instead of surfacing potentially-stale resume.json nextSteps. When no
|
|
76
|
+
// handoff exists, fall back to resume.nextSteps but mark them as possibly
|
|
77
|
+
// stale (free-text that refreshResume never touches, so they can drift).
|
|
78
|
+
if (handoffs.length > 0) {
|
|
79
|
+
lines.push(italian
|
|
80
|
+
? `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.`
|
|
81
|
+
: `Next step: read the pending phase handoff below (authoritative, actively maintained). Legacy resume.json nextSteps are suppressed because they may be stale.`);
|
|
82
|
+
}
|
|
83
|
+
else if (!planComplete && resume?.nextSteps?.length) {
|
|
78
84
|
lines.push(`${italian ? "Prossimo step" : "Next step"}: ${resume.nextSteps[0]}`);
|
|
85
|
+
const staleNote = resume.nextStepsUpdatedAt
|
|
86
|
+
? (italian
|
|
87
|
+
? `⚠️ nextSteps free-text da resume.json, ultimo aggiornamento ${resume.nextStepsUpdatedAt} — può essere stale; verifica contro lo stato attuale prima di agire.`
|
|
88
|
+
: `⚠️ nextSteps are free-text from resume.json, last updated ${resume.nextStepsUpdatedAt} — may be stale; verify against current state before acting.`)
|
|
89
|
+
: (italian
|
|
90
|
+
? `⚠️ nextSteps free-text da resume.json — può essere stale; verifica contro lo stato attuale prima di agire.`
|
|
91
|
+
: `⚠️ nextSteps are free-text from resume.json — may be stale; verify against current state before acting.`);
|
|
92
|
+
lines.push(staleNote);
|
|
79
93
|
}
|
|
80
94
|
if (handoffs.length > 0) {
|
|
81
95
|
lines.push("", italian ? `## Handoff di fase pendenti (${handoffs.length})` : `## Pending phase handoffs (${handoffs.length})`);
|
|
82
96
|
handoffs.forEach((h, i) => lines.push(`[${i + 1}] ${h.compositeRef} — ${h.updatedAt} — "${h.firstLine}"`));
|
|
83
97
|
lines.push("", italian
|
|
84
|
-
? `→ Leggi quello pertinente con ${handoffShowCmd} <ref> (valida contro lo stato attuale)
|
|
85
|
-
: `→ Read the relevant one with ${handoffShowCmd} <ref> (validate against current state)
|
|
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.`);
|
|
86
100
|
}
|
|
87
101
|
else if (planComplete) {
|
|
88
102
|
lines.push("", italian
|
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;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"}
|
package/dist/refs.js
CHANGED
|
@@ -40,3 +40,69 @@ 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
|
+
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
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export function findTaskByRef(phases, features, ref) {
|
|
56
|
+
const normalized = ref.trim().toLowerCase();
|
|
57
|
+
if (!normalized)
|
|
58
|
+
return undefined;
|
|
59
|
+
// 1. UUID (exact)
|
|
60
|
+
for (const phase of phases) {
|
|
61
|
+
const task = phase.tasks.find((t) => t.id.toLowerCase() === normalized);
|
|
62
|
+
if (task)
|
|
63
|
+
return { phase, task };
|
|
64
|
+
}
|
|
65
|
+
// 2. Composite / short ref with a T segment
|
|
66
|
+
const { featureNum, phaseNum, taskNum } = parseTaskComposite(normalized);
|
|
67
|
+
if (taskNum !== undefined) {
|
|
68
|
+
if (phaseNum !== undefined) {
|
|
69
|
+
// Composite: validate phase (and feature if present), then resolve task by number.
|
|
70
|
+
const phase = phases.find((p) => p.number === phaseNum);
|
|
71
|
+
if (!phase)
|
|
72
|
+
return undefined;
|
|
73
|
+
if (featureNum !== undefined) {
|
|
74
|
+
const feat = features.find((f) => f.number === featureNum);
|
|
75
|
+
if (!feat || phase.featureId !== feat.id)
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
const task = phase.tasks.find((t) => t.number === taskNum);
|
|
79
|
+
if (task)
|
|
80
|
+
return { phase, task };
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
// Bare T00x — globally unique under the new numbering. Find the one task.
|
|
84
|
+
for (const phase of phases) {
|
|
85
|
+
const task = phase.tasks.find((t) => t.number === taskNum);
|
|
86
|
+
if (task)
|
|
87
|
+
return { phase, task };
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 3. ShortId (5-char)
|
|
91
|
+
for (const phase of phases) {
|
|
92
|
+
const task = phase.tasks.find((t) => t.shortId && t.shortId.toLowerCase() === normalized);
|
|
93
|
+
if (task)
|
|
94
|
+
return { phase, task };
|
|
95
|
+
}
|
|
96
|
+
// 4. Title fallback (backward compatibility)
|
|
97
|
+
for (const phase of phases) {
|
|
98
|
+
const exact = phase.tasks.find((t) => t.title.toLowerCase() === normalized);
|
|
99
|
+
if (exact)
|
|
100
|
+
return { phase, task: exact };
|
|
101
|
+
}
|
|
102
|
+
for (const phase of phases) {
|
|
103
|
+
const incl = phase.tasks.find((t) => t.title.toLowerCase().includes(normalized));
|
|
104
|
+
if (incl)
|
|
105
|
+
return { phase, task: incl };
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
package/dist/schema.d.ts
CHANGED
|
@@ -133,6 +133,10 @@ export declare const ResumeFocusSchema: z.ZodObject<{
|
|
|
133
133
|
currentPhaseId: z.ZodDefault<z.ZodString>;
|
|
134
134
|
inProgressTaskIds: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
135
135
|
nextSteps: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
136
|
+
/** When `nextSteps` last changed (free-text can go stale; the recap surfaces
|
|
137
|
+
* this so staleness is visible). Preserved across refreshResume (which keeps
|
|
138
|
+
* existing nextSteps); bumped only when saveResume receives new nextSteps. */
|
|
139
|
+
nextStepsUpdatedAt: z.ZodDefault<z.ZodString>;
|
|
136
140
|
blockers: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
137
141
|
notes: z.ZodDefault<z.ZodString>;
|
|
138
142
|
lastSessionSummary: z.ZodDefault<z.ZodString>;
|
|
@@ -142,6 +146,7 @@ export declare const ResumeFocusSchema: z.ZodObject<{
|
|
|
142
146
|
currentPhaseId: string;
|
|
143
147
|
inProgressTaskIds: string[];
|
|
144
148
|
nextSteps: string[];
|
|
149
|
+
nextStepsUpdatedAt: string;
|
|
145
150
|
blockers: string[];
|
|
146
151
|
notes: string;
|
|
147
152
|
lastSessionSummary: string;
|
|
@@ -151,6 +156,7 @@ export declare const ResumeFocusSchema: z.ZodObject<{
|
|
|
151
156
|
currentPhaseId?: string | undefined;
|
|
152
157
|
inProgressTaskIds?: string[] | undefined;
|
|
153
158
|
nextSteps?: string[] | undefined;
|
|
159
|
+
nextStepsUpdatedAt?: string | undefined;
|
|
154
160
|
blockers?: string[] | undefined;
|
|
155
161
|
notes?: string | undefined;
|
|
156
162
|
lastSessionSummary?: string | undefined;
|
|
@@ -314,6 +320,10 @@ export declare const ProjectSchema: z.ZodObject<{
|
|
|
314
320
|
rationale?: string | undefined;
|
|
315
321
|
implementationNotes?: string | undefined;
|
|
316
322
|
}>, "many">>;
|
|
323
|
+
/** Monotonic global sequence counters — assigned at creation, never reused (gaps on delete). */
|
|
324
|
+
nextFeatureNumber: z.ZodDefault<z.ZodNumber>;
|
|
325
|
+
nextPhaseNumber: z.ZodDefault<z.ZodNumber>;
|
|
326
|
+
nextTaskNumber: z.ZodDefault<z.ZodNumber>;
|
|
317
327
|
}, "strip", z.ZodTypeAny, {
|
|
318
328
|
name: string;
|
|
319
329
|
goal: string;
|
|
@@ -340,6 +350,9 @@ export declare const ProjectSchema: z.ZodObject<{
|
|
|
340
350
|
implementationNotes: string;
|
|
341
351
|
acceptedAt: string;
|
|
342
352
|
}[];
|
|
353
|
+
nextFeatureNumber: number;
|
|
354
|
+
nextPhaseNumber: number;
|
|
355
|
+
nextTaskNumber: number;
|
|
343
356
|
}, {
|
|
344
357
|
name: string;
|
|
345
358
|
workflowRules: {
|
|
@@ -366,6 +379,9 @@ export declare const ProjectSchema: z.ZodObject<{
|
|
|
366
379
|
rationale?: string | undefined;
|
|
367
380
|
implementationNotes?: string | undefined;
|
|
368
381
|
}[] | undefined;
|
|
382
|
+
nextFeatureNumber?: number | undefined;
|
|
383
|
+
nextPhaseNumber?: number | undefined;
|
|
384
|
+
nextTaskNumber?: number | undefined;
|
|
369
385
|
}>;
|
|
370
386
|
export declare const SubtaskStatusSchema: z.ZodEnum<["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
371
387
|
export declare const TaskStatusSchema: z.ZodEnum<["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]>;
|
|
@@ -441,6 +457,7 @@ export declare const StatusLogEntrySchema: z.ZodObject<{
|
|
|
441
457
|
export declare const TaskSchema: z.ZodEffects<z.ZodObject<{
|
|
442
458
|
id: z.ZodString;
|
|
443
459
|
phaseId: z.ZodString;
|
|
460
|
+
/** Global project-wide task sequence (assigned once at creation from project.nextTaskNumber; stable, gaps on delete). Bare T00x is unambiguous. */
|
|
444
461
|
number: z.ZodDefault<z.ZodNumber>;
|
|
445
462
|
shortId: z.ZodDefault<z.ZodString>;
|
|
446
463
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -737,6 +754,7 @@ export declare const HandoffHistoryEntrySchema: z.ZodObject<{
|
|
|
737
754
|
export declare const PhaseSchema: z.ZodObject<{
|
|
738
755
|
id: z.ZodString;
|
|
739
756
|
featureId: z.ZodOptional<z.ZodString>;
|
|
757
|
+
/** Global project-wide phase sequence (assigned once at creation from project.nextPhaseNumber; stable, gaps on delete). Bare P00x is unambiguous. */
|
|
740
758
|
number: z.ZodNumber;
|
|
741
759
|
shortId: z.ZodDefault<z.ZodString>;
|
|
742
760
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -782,6 +800,7 @@ export declare const PhaseSchema: z.ZodObject<{
|
|
|
782
800
|
tasks: z.ZodDefault<z.ZodArray<z.ZodEffects<z.ZodObject<{
|
|
783
801
|
id: z.ZodString;
|
|
784
802
|
phaseId: z.ZodString;
|
|
803
|
+
/** Global project-wide task sequence (assigned once at creation from project.nextTaskNumber; stable, gaps on delete). Bare T00x is unambiguous. */
|
|
785
804
|
number: z.ZodDefault<z.ZodNumber>;
|
|
786
805
|
shortId: z.ZodDefault<z.ZodString>;
|
|
787
806
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -1267,6 +1286,7 @@ export declare const PhaseSchema: z.ZodObject<{
|
|
|
1267
1286
|
}>;
|
|
1268
1287
|
export declare const FeatureSchema: z.ZodObject<{
|
|
1269
1288
|
id: z.ZodString;
|
|
1289
|
+
/** Global project-wide feature sequence (assigned once at creation from project.nextFeatureNumber; stable, gaps on delete). */
|
|
1270
1290
|
number: z.ZodDefault<z.ZodNumber>;
|
|
1271
1291
|
shortId: z.ZodDefault<z.ZodString>;
|
|
1272
1292
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -1361,6 +1381,7 @@ export declare const FeatureSchema: z.ZodObject<{
|
|
|
1361
1381
|
export declare const FeaturesDocumentSchema: z.ZodObject<{
|
|
1362
1382
|
features: z.ZodArray<z.ZodObject<{
|
|
1363
1383
|
id: z.ZodString;
|
|
1384
|
+
/** Global project-wide feature sequence (assigned once at creation from project.nextFeatureNumber; stable, gaps on delete). */
|
|
1364
1385
|
number: z.ZodDefault<z.ZodNumber>;
|
|
1365
1386
|
shortId: z.ZodDefault<z.ZodString>;
|
|
1366
1387
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -1763,6 +1784,10 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1763
1784
|
rationale?: string | undefined;
|
|
1764
1785
|
implementationNotes?: string | undefined;
|
|
1765
1786
|
}>, "many">>;
|
|
1787
|
+
/** Monotonic global sequence counters — assigned at creation, never reused (gaps on delete). */
|
|
1788
|
+
nextFeatureNumber: z.ZodDefault<z.ZodNumber>;
|
|
1789
|
+
nextPhaseNumber: z.ZodDefault<z.ZodNumber>;
|
|
1790
|
+
nextTaskNumber: z.ZodDefault<z.ZodNumber>;
|
|
1766
1791
|
}, "strip", z.ZodTypeAny, {
|
|
1767
1792
|
name: string;
|
|
1768
1793
|
goal: string;
|
|
@@ -1789,6 +1814,9 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1789
1814
|
implementationNotes: string;
|
|
1790
1815
|
acceptedAt: string;
|
|
1791
1816
|
}[];
|
|
1817
|
+
nextFeatureNumber: number;
|
|
1818
|
+
nextPhaseNumber: number;
|
|
1819
|
+
nextTaskNumber: number;
|
|
1792
1820
|
}, {
|
|
1793
1821
|
name: string;
|
|
1794
1822
|
workflowRules: {
|
|
@@ -1815,10 +1843,14 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
1815
1843
|
rationale?: string | undefined;
|
|
1816
1844
|
implementationNotes?: string | undefined;
|
|
1817
1845
|
}[] | undefined;
|
|
1846
|
+
nextFeatureNumber?: number | undefined;
|
|
1847
|
+
nextPhaseNumber?: number | undefined;
|
|
1848
|
+
nextTaskNumber?: number | undefined;
|
|
1818
1849
|
}>;
|
|
1819
1850
|
features: z.ZodObject<{
|
|
1820
1851
|
features: z.ZodArray<z.ZodObject<{
|
|
1821
1852
|
id: z.ZodString;
|
|
1853
|
+
/** Global project-wide feature sequence (assigned once at creation from project.nextFeatureNumber; stable, gaps on delete). */
|
|
1822
1854
|
number: z.ZodDefault<z.ZodNumber>;
|
|
1823
1855
|
shortId: z.ZodDefault<z.ZodString>;
|
|
1824
1856
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -2071,6 +2103,7 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2071
2103
|
phases: z.ZodArray<z.ZodObject<{
|
|
2072
2104
|
id: z.ZodString;
|
|
2073
2105
|
featureId: z.ZodOptional<z.ZodString>;
|
|
2106
|
+
/** Global project-wide phase sequence (assigned once at creation from project.nextPhaseNumber; stable, gaps on delete). Bare P00x is unambiguous. */
|
|
2074
2107
|
number: z.ZodNumber;
|
|
2075
2108
|
shortId: z.ZodDefault<z.ZodString>;
|
|
2076
2109
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -2116,6 +2149,7 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2116
2149
|
tasks: z.ZodDefault<z.ZodArray<z.ZodEffects<z.ZodObject<{
|
|
2117
2150
|
id: z.ZodString;
|
|
2118
2151
|
phaseId: z.ZodString;
|
|
2152
|
+
/** Global project-wide task sequence (assigned once at creation from project.nextTaskNumber; stable, gaps on delete). Bare T00x is unambiguous. */
|
|
2119
2153
|
number: z.ZodDefault<z.ZodNumber>;
|
|
2120
2154
|
shortId: z.ZodDefault<z.ZodString>;
|
|
2121
2155
|
priority: z.ZodDefault<z.ZodNumber>;
|
|
@@ -2681,6 +2715,9 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2681
2715
|
implementationNotes: string;
|
|
2682
2716
|
acceptedAt: string;
|
|
2683
2717
|
}[];
|
|
2718
|
+
nextFeatureNumber: number;
|
|
2719
|
+
nextPhaseNumber: number;
|
|
2720
|
+
nextTaskNumber: number;
|
|
2684
2721
|
};
|
|
2685
2722
|
phases: {
|
|
2686
2723
|
number: number;
|
|
@@ -2853,6 +2890,9 @@ export declare const PlanWorkspaceSchema: z.ZodObject<{
|
|
|
2853
2890
|
rationale?: string | undefined;
|
|
2854
2891
|
implementationNotes?: string | undefined;
|
|
2855
2892
|
}[] | undefined;
|
|
2893
|
+
nextFeatureNumber?: number | undefined;
|
|
2894
|
+
nextPhaseNumber?: number | undefined;
|
|
2895
|
+
nextTaskNumber?: number | undefined;
|
|
2856
2896
|
};
|
|
2857
2897
|
phases: {
|
|
2858
2898
|
number: number;
|
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
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.js
CHANGED
|
@@ -37,6 +37,10 @@ export const ResumeFocusSchema = z.object({
|
|
|
37
37
|
currentPhaseId: z.string().default(""),
|
|
38
38
|
inProgressTaskIds: z.array(z.string().min(1)).default([]),
|
|
39
39
|
nextSteps: z.array(z.string().min(1)).default([]),
|
|
40
|
+
/** When `nextSteps` last changed (free-text can go stale; the recap surfaces
|
|
41
|
+
* this so staleness is visible). Preserved across refreshResume (which keeps
|
|
42
|
+
* existing nextSteps); bumped only when saveResume receives new nextSteps. */
|
|
43
|
+
nextStepsUpdatedAt: z.string().default(""),
|
|
40
44
|
blockers: z.array(z.string().min(1)).default([]),
|
|
41
45
|
notes: z.string().default(""),
|
|
42
46
|
lastSessionSummary: z.string().default(""),
|
|
@@ -87,6 +91,10 @@ export const ProjectSchema = z.object({
|
|
|
87
91
|
chatLanguage: z.string().default(""),
|
|
88
92
|
workflowRules: WorkflowRulesSchema,
|
|
89
93
|
acceptedDecisions: z.array(AcceptedDecisionSchema).default([]),
|
|
94
|
+
/** Monotonic global sequence counters — assigned at creation, never reused (gaps on delete). */
|
|
95
|
+
nextFeatureNumber: z.number().int().positive().default(1),
|
|
96
|
+
nextPhaseNumber: z.number().int().positive().default(1),
|
|
97
|
+
nextTaskNumber: z.number().int().positive().default(1),
|
|
90
98
|
});
|
|
91
99
|
export const SubtaskStatusSchema = z.enum(["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]);
|
|
92
100
|
export const TaskStatusSchema = z.enum(["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"]);
|
|
@@ -137,6 +145,7 @@ export const StatusLogEntrySchema = z.object({
|
|
|
137
145
|
export const TaskSchema = z.object({
|
|
138
146
|
id: z.string(),
|
|
139
147
|
phaseId: z.string(),
|
|
148
|
+
/** Global project-wide task sequence (assigned once at creation from project.nextTaskNumber; stable, gaps on delete). Bare T00x is unambiguous. */
|
|
140
149
|
number: z.number().int().nonnegative().default(0),
|
|
141
150
|
shortId: z.string().regex(/^(|[A-Z2-9]{5})$/).default(""),
|
|
142
151
|
priority: z.number().int().nonnegative().default(0),
|
|
@@ -173,6 +182,7 @@ export const HandoffHistoryEntrySchema = z.object({
|
|
|
173
182
|
export const PhaseSchema = z.object({
|
|
174
183
|
id: z.string(),
|
|
175
184
|
featureId: z.string().optional(),
|
|
185
|
+
/** Global project-wide phase sequence (assigned once at creation from project.nextPhaseNumber; stable, gaps on delete). Bare P00x is unambiguous. */
|
|
176
186
|
number: z.number().int().positive(),
|
|
177
187
|
shortId: z.string().regex(/^(|[A-Z2-9]{5})$/).default(""),
|
|
178
188
|
priority: z.number().int().nonnegative().default(0),
|
|
@@ -215,6 +225,7 @@ export const PhaseSchema = z.object({
|
|
|
215
225
|
});
|
|
216
226
|
export const FeatureSchema = z.object({
|
|
217
227
|
id: z.string(),
|
|
228
|
+
/** Global project-wide feature sequence (assigned once at creation from project.nextFeatureNumber; stable, gaps on delete). */
|
|
218
229
|
number: z.number().int().nonnegative().default(0),
|
|
219
230
|
shortId: z.string().regex(/^(|[A-Z2-9]{5})$/).default(""),
|
|
220
231
|
priority: z.number().int().nonnegative().default(0),
|
package/package.json
CHANGED