@agent-plan/core 0.2.24 → 0.2.26
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/display-status.d.ts +3 -3
- package/dist/display-status.d.ts.map +1 -1
- package/dist/display-status.js +5 -4
- package/dist/handoff-context.d.ts +91 -1
- package/dist/handoff-context.d.ts.map +1 -1
- package/dist/handoff-context.js +134 -2
- package/dist/index.d.ts +5 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/naming.d.ts +3 -0
- package/dist/naming.d.ts.map +1 -1
- package/dist/naming.js +7 -0
- package/dist/payload-fallback.d.ts +38 -0
- package/dist/payload-fallback.d.ts.map +1 -0
- package/dist/payload-fallback.js +73 -0
- package/dist/plan-store.d.ts +65 -8
- package/dist/plan-store.d.ts.map +1 -1
- package/dist/plan-store.js +391 -39
- package/dist/planner-rules.d.ts +3 -11
- package/dist/planner-rules.d.ts.map +1 -1
- package/dist/planner-rules.js +23 -6
- package/dist/planner-skill.d.ts +24 -0
- package/dist/planner-skill.d.ts.map +1 -0
- package/dist/planner-skill.js +113 -0
- package/dist/project-context-migration.d.ts +47 -0
- package/dist/project-context-migration.d.ts.map +1 -0
- package/dist/project-context-migration.js +168 -0
- package/dist/read-tracking.d.ts +27 -8
- package/dist/read-tracking.d.ts.map +1 -1
- package/dist/read-tracking.js +79 -34
- package/dist/recap.d.ts.map +1 -1
- package/dist/recap.js +2 -6
- package/dist/refs.d.ts +6 -1
- package/dist/refs.d.ts.map +1 -1
- package/dist/refs.js +25 -0
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +24 -1
- package/dist/requirement-macro-tasks.d.ts +18 -0
- package/dist/requirement-macro-tasks.d.ts.map +1 -0
- package/dist/requirement-macro-tasks.js +55 -0
- package/dist/schema.d.ts +1088 -273
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +65 -0
- package/dist/task-selection.js +2 -2
- package/dist/task-start-outcome.d.ts +1 -1
- package/dist/task-start-outcome.d.ts.map +1 -1
- package/dist/task-start-outcome.js +1 -0
- package/package.json +3 -1
- package/planner-skill.md +210 -0
- package/skills/grill-me/SKILL.md +10 -0
package/dist/display-status.d.ts
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* - `started`: the entity has clearly begun (historical progress exists) but
|
|
10
10
|
* no child is active now, and the unfinished remainder is mixed or cannot
|
|
11
11
|
* honestly collapse to one specific workflow label.
|
|
12
|
-
* - `closed`: every child is terminal, but outcomes are mixed
|
|
13
|
-
*
|
|
12
|
+
* - `closed`: every child is terminal, but outcomes are mixed without a
|
|
13
|
+
* positive completion rollup (for example, `canceled + rejected`).
|
|
14
14
|
*
|
|
15
15
|
* These are NEVER persisted: they are computed on demand from children's
|
|
16
16
|
* canonical workflow statuses. The canonical workflow model
|
|
@@ -62,7 +62,7 @@ export declare function countBreakdown(statuses: readonly WorkflowStatus[]): Sta
|
|
|
62
62
|
* Algorithm (locked by P039 accepted decisions):
|
|
63
63
|
* 1. If any meaningful child is active now → `in-progress`.
|
|
64
64
|
* 2. If every child is terminal:
|
|
65
|
-
* -
|
|
65
|
+
* - only `done` + `canceled`, with at least one `done` → `done`
|
|
66
66
|
* - all `canceled` → `canceled`
|
|
67
67
|
* - all `rejected` → `rejected`
|
|
68
68
|
* - otherwise → `closed` (mixed terminal outcomes)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display-status.d.ts","sourceRoot":"","sources":["../src/display-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,aAAa,GACb,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,GACN,UAAU,GACV,UAAU,CAAC;AAEf;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElE,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,aAAa,EAAE,aAAa,CAAC;IAC7B,wDAAwD;IACxD,SAAS,EAAE,eAAe,CAAC;IAC3B;+CAC2C;IAC3C,UAAU,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAMD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,eAAe,CAkBnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,SAAS,cAAc,EAAE,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"display-status.d.ts","sourceRoot":"","sources":["../src/display-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,aAAa,GACb,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,GACN,UAAU,GACV,UAAU,CAAC;AAEf;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElE,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,aAAa,EAAE,aAAa,CAAC;IAC7B,wDAAwD;IACxD,SAAS,EAAE,eAAe,CAAC;IAC3B;+CAC2C;IAC3C,UAAU,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAMD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,SAAS,cAAc,EAAE,GAAG,eAAe,CAkBnF;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,SAAS,cAAc,EAAE,GAAG,aAAa,CAoE3F;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAcrE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,UAAU,GAAG,WAAW,GAAG,cAAc,CAIpF"}
|
package/dist/display-status.js
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
* - `started`: the entity has clearly begun (historical progress exists) but
|
|
10
10
|
* no child is active now, and the unfinished remainder is mixed or cannot
|
|
11
11
|
* honestly collapse to one specific workflow label.
|
|
12
|
-
* - `closed`: every child is terminal, but outcomes are mixed
|
|
13
|
-
*
|
|
12
|
+
* - `closed`: every child is terminal, but outcomes are mixed without a
|
|
13
|
+
* positive completion rollup (for example, `canceled + rejected`).
|
|
14
14
|
*
|
|
15
15
|
* These are NEVER persisted: they are computed on demand from children's
|
|
16
16
|
* canonical workflow statuses. The canonical workflow model
|
|
@@ -65,7 +65,7 @@ function emptyBreakdown() {
|
|
|
65
65
|
* Algorithm (locked by P039 accepted decisions):
|
|
66
66
|
* 1. If any meaningful child is active now → `in-progress`.
|
|
67
67
|
* 2. If every child is terminal:
|
|
68
|
-
* -
|
|
68
|
+
* - only `done` + `canceled`, with at least one `done` → `done`
|
|
69
69
|
* - all `canceled` → `canceled`
|
|
70
70
|
* - all `rejected` → `rejected`
|
|
71
71
|
* - otherwise → `closed` (mixed terminal outcomes)
|
|
@@ -108,7 +108,8 @@ export function deriveParentDisplay(childStatuses) {
|
|
|
108
108
|
}
|
|
109
109
|
// 2. All children are terminal.
|
|
110
110
|
if (statuses.every((s) => TERMINAL.has(s))) {
|
|
111
|
-
if (statuses.
|
|
111
|
+
if (statuses.some((s) => s === "done")
|
|
112
|
+
&& statuses.every((s) => s === "done" || s === "canceled")) {
|
|
112
113
|
return { displayStatus: "done", breakdown, hasStarted, totalChildren, meaningfulChildren };
|
|
113
114
|
}
|
|
114
115
|
if (statuses.every((s) => s === "canceled")) {
|
|
@@ -1,5 +1,79 @@
|
|
|
1
|
-
import type { Feature, Phase, Task } from "./schema.js";
|
|
1
|
+
import type { Feature, HandoffCompletenessAudit, HandoffCompletenessEntry, HandoffSupportingDocument, Phase, Task } from "./schema.js";
|
|
2
2
|
export declare const COMPLETION_SUMMARY_HEADING = "**Completion summary:**";
|
|
3
|
+
export declare const HANDOFF_COMPLETENESS_AUDIT_VERSION = 1;
|
|
4
|
+
export declare const MAX_HANDOFF_CONTENT_CHARS = 24000;
|
|
5
|
+
export declare const HANDOFF_AUDIT_START_MARKER = "<!-- agent-plan:handoff-audit:start -->";
|
|
6
|
+
export declare const HANDOFF_AUDIT_END_MARKER = "<!-- agent-plan:handoff-audit:end -->";
|
|
7
|
+
export declare const HANDOFF_COMPLETENESS_CATEGORIES: readonly [{
|
|
8
|
+
readonly id: "exact-focus-resume-point";
|
|
9
|
+
readonly label: "Exact focus and resume point";
|
|
10
|
+
}, {
|
|
11
|
+
readonly id: "first-resume-action";
|
|
12
|
+
readonly label: "First resume action";
|
|
13
|
+
}, {
|
|
14
|
+
readonly id: "completed-work";
|
|
15
|
+
readonly label: "Completed work";
|
|
16
|
+
}, {
|
|
17
|
+
readonly id: "partial-work";
|
|
18
|
+
readonly label: "Partial work";
|
|
19
|
+
}, {
|
|
20
|
+
readonly id: "remaining-work";
|
|
21
|
+
readonly label: "Remaining work";
|
|
22
|
+
}, {
|
|
23
|
+
readonly id: "decisions-rationale";
|
|
24
|
+
readonly label: "Decisions and rationale";
|
|
25
|
+
}, {
|
|
26
|
+
readonly id: "rejected-alternatives";
|
|
27
|
+
readonly label: "Rejected alternatives";
|
|
28
|
+
}, {
|
|
29
|
+
readonly id: "files-symbols";
|
|
30
|
+
readonly label: "Files and symbols";
|
|
31
|
+
}, {
|
|
32
|
+
readonly id: "branch-worktree";
|
|
33
|
+
readonly label: "Branch and worktree";
|
|
34
|
+
}, {
|
|
35
|
+
readonly id: "commands-tools";
|
|
36
|
+
readonly label: "Commands and tools";
|
|
37
|
+
}, {
|
|
38
|
+
readonly id: "completed-verification";
|
|
39
|
+
readonly label: "Completed verification";
|
|
40
|
+
}, {
|
|
41
|
+
readonly id: "pending-verification";
|
|
42
|
+
readonly label: "Pending verification";
|
|
43
|
+
}, {
|
|
44
|
+
readonly id: "runtime-limitations-workarounds";
|
|
45
|
+
readonly label: "Runtime limitations and workarounds";
|
|
46
|
+
}, {
|
|
47
|
+
readonly id: "blockers-risks";
|
|
48
|
+
readonly label: "Blockers and risks";
|
|
49
|
+
}, {
|
|
50
|
+
readonly id: "user-visible-behavior";
|
|
51
|
+
readonly label: "User-visible behavior";
|
|
52
|
+
}, {
|
|
53
|
+
readonly id: "operator-actions";
|
|
54
|
+
readonly label: "Operator actions";
|
|
55
|
+
}, {
|
|
56
|
+
readonly id: "project-operating-notes";
|
|
57
|
+
readonly label: "Project-specific operating notes";
|
|
58
|
+
}, {
|
|
59
|
+
readonly id: "conversation-only-facts";
|
|
60
|
+
readonly label: "Conversation-only facts";
|
|
61
|
+
}];
|
|
62
|
+
export type HandoffCompletenessCategory = typeof HANDOFF_COMPLETENESS_CATEGORIES[number]["id"];
|
|
63
|
+
export type HandoffContractErrorCode = "HANDOFF_COMPLETENESS_AUDIT_REQUIRED" | "HANDOFF_CONTENT_LIMIT_EXCEEDED" | "HANDOFF_SUPPORTING_DOCUMENT_INVALID" | "HANDOFF_PERSISTENCE_VERIFICATION_FAILED";
|
|
64
|
+
export declare class HandoffContractError extends Error {
|
|
65
|
+
readonly code: HandoffContractErrorCode;
|
|
66
|
+
readonly details: Record<string, unknown>;
|
|
67
|
+
constructor(code: HandoffContractErrorCode, message: string, details?: Record<string, unknown>);
|
|
68
|
+
}
|
|
69
|
+
export interface HandoffCompletenessAuditInput {
|
|
70
|
+
version: number;
|
|
71
|
+
entries: HandoffCompletenessEntry[];
|
|
72
|
+
}
|
|
73
|
+
export interface HandoffSupportingDocumentInput {
|
|
74
|
+
path: string;
|
|
75
|
+
description: string;
|
|
76
|
+
}
|
|
3
77
|
export interface HandoffTaskContextUpdate {
|
|
4
78
|
taskId: string;
|
|
5
79
|
completionSummary: string;
|
|
@@ -35,11 +109,22 @@ export interface PhaseHandoffAudit {
|
|
|
35
109
|
number: number;
|
|
36
110
|
title: string;
|
|
37
111
|
}>;
|
|
112
|
+
completenessVersion: number;
|
|
113
|
+
maxContentChars: number;
|
|
114
|
+
completenessCategories: ReadonlyArray<{
|
|
115
|
+
id: HandoffCompletenessCategory;
|
|
116
|
+
label: string;
|
|
117
|
+
}>;
|
|
118
|
+
existingCompletenessAudit: HandoffCompletenessAudit | null;
|
|
38
119
|
}
|
|
39
120
|
export interface RefreshPhaseHandoffInput {
|
|
40
121
|
content: string;
|
|
41
122
|
expectedHandoffUpdatedAt: string;
|
|
42
123
|
reconciledExistingHandoff: boolean;
|
|
124
|
+
completenessAudit?: HandoffCompletenessAuditInput;
|
|
125
|
+
supportingDocuments?: HandoffSupportingDocumentInput[];
|
|
126
|
+
/** Populated and verified by PlanStore before pure domain application. */
|
|
127
|
+
verifiedSupportingDocuments?: HandoffSupportingDocument[];
|
|
43
128
|
contextSync: PhaseHandoffContextSync;
|
|
44
129
|
}
|
|
45
130
|
export interface RefreshPhaseHandoffResult {
|
|
@@ -47,9 +132,14 @@ export interface RefreshPhaseHandoffResult {
|
|
|
47
132
|
feature: Feature;
|
|
48
133
|
updatedTaskIds: string[];
|
|
49
134
|
handoffUpdatedAt: string;
|
|
135
|
+
handoffAudit: HandoffCompletenessAudit;
|
|
50
136
|
}
|
|
51
137
|
export declare function hasTaskCompletionEvidence(task: Task): boolean;
|
|
52
138
|
export declare function auditPhaseHandoff(phase: Phase, feature: Feature): PhaseHandoffAudit;
|
|
139
|
+
export declare function handoffContentHash(content: string): string;
|
|
140
|
+
export declare function validateHandoffCompletenessAudit(audit: HandoffCompletenessAuditInput | undefined): HandoffCompletenessEntry[];
|
|
141
|
+
export declare function renderHandoffCompletenessAudit(audit: HandoffCompletenessAuditInput): string;
|
|
142
|
+
export declare function renderVerifiedHandoffContent(content: string, audit?: HandoffCompletenessAuditInput): string;
|
|
53
143
|
export declare function validateCanonicalHandoffContent(content: string): void;
|
|
54
144
|
export declare function validateHandoffContextSync(phase: Phase, feature: Feature, input: RefreshPhaseHandoffInput): void;
|
|
55
145
|
export declare function applyHandoffContextSync(phase: Phase, feature: Feature, input: RefreshPhaseHandoffInput, timestamp: string): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handoff-context.d.ts","sourceRoot":"","sources":["../src/handoff-context.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handoff-context.d.ts","sourceRoot":"","sources":["../src/handoff-context.ts"],"names":[],"mappings":"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"}
|
package/dist/handoff-context.js
CHANGED
|
@@ -1,4 +1,39 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
1
2
|
export const COMPLETION_SUMMARY_HEADING = "**Completion summary:**";
|
|
3
|
+
export const HANDOFF_COMPLETENESS_AUDIT_VERSION = 1;
|
|
4
|
+
export const MAX_HANDOFF_CONTENT_CHARS = 24_000;
|
|
5
|
+
export const HANDOFF_AUDIT_START_MARKER = "<!-- agent-plan:handoff-audit:start -->";
|
|
6
|
+
export const HANDOFF_AUDIT_END_MARKER = "<!-- agent-plan:handoff-audit:end -->";
|
|
7
|
+
export const HANDOFF_COMPLETENESS_CATEGORIES = [
|
|
8
|
+
{ id: "exact-focus-resume-point", label: "Exact focus and resume point" },
|
|
9
|
+
{ id: "first-resume-action", label: "First resume action" },
|
|
10
|
+
{ id: "completed-work", label: "Completed work" },
|
|
11
|
+
{ id: "partial-work", label: "Partial work" },
|
|
12
|
+
{ id: "remaining-work", label: "Remaining work" },
|
|
13
|
+
{ id: "decisions-rationale", label: "Decisions and rationale" },
|
|
14
|
+
{ id: "rejected-alternatives", label: "Rejected alternatives" },
|
|
15
|
+
{ id: "files-symbols", label: "Files and symbols" },
|
|
16
|
+
{ id: "branch-worktree", label: "Branch and worktree" },
|
|
17
|
+
{ id: "commands-tools", label: "Commands and tools" },
|
|
18
|
+
{ id: "completed-verification", label: "Completed verification" },
|
|
19
|
+
{ id: "pending-verification", label: "Pending verification" },
|
|
20
|
+
{ id: "runtime-limitations-workarounds", label: "Runtime limitations and workarounds" },
|
|
21
|
+
{ id: "blockers-risks", label: "Blockers and risks" },
|
|
22
|
+
{ id: "user-visible-behavior", label: "User-visible behavior" },
|
|
23
|
+
{ id: "operator-actions", label: "Operator actions" },
|
|
24
|
+
{ id: "project-operating-notes", label: "Project-specific operating notes" },
|
|
25
|
+
{ id: "conversation-only-facts", label: "Conversation-only facts" },
|
|
26
|
+
];
|
|
27
|
+
export class HandoffContractError extends Error {
|
|
28
|
+
code;
|
|
29
|
+
details;
|
|
30
|
+
constructor(code, message, details = {}) {
|
|
31
|
+
super(message);
|
|
32
|
+
this.name = "HandoffContractError";
|
|
33
|
+
this.code = code;
|
|
34
|
+
this.details = details;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
2
37
|
export function hasTaskCompletionEvidence(task) {
|
|
3
38
|
if (task.status !== "done")
|
|
4
39
|
return true;
|
|
@@ -17,6 +52,10 @@ export function auditPhaseHandoff(phase, feature) {
|
|
|
17
52
|
handoffUpdatedAt: phase.handoffUpdatedAt,
|
|
18
53
|
missingCompletionTaskIds: missingCompletionTasks.map((task) => task.id),
|
|
19
54
|
missingCompletionTasks,
|
|
55
|
+
completenessVersion: HANDOFF_COMPLETENESS_AUDIT_VERSION,
|
|
56
|
+
maxContentChars: MAX_HANDOFF_CONTENT_CHARS,
|
|
57
|
+
completenessCategories: HANDOFF_COMPLETENESS_CATEGORIES,
|
|
58
|
+
existingCompletenessAudit: phase.handoffAudit,
|
|
20
59
|
};
|
|
21
60
|
}
|
|
22
61
|
function nonEmpty(value, field) {
|
|
@@ -34,6 +73,74 @@ function appendSection(existing, section) {
|
|
|
34
73
|
return existing;
|
|
35
74
|
return existing.trim() ? `${existing.trim()}\n\n---\n${normalized}` : normalized;
|
|
36
75
|
}
|
|
76
|
+
function isSubstantive(value) {
|
|
77
|
+
const normalized = value.trim();
|
|
78
|
+
if (normalized.length < 12)
|
|
79
|
+
return false;
|
|
80
|
+
return !/^(?:n\/?a|none|nothing|unknown|same as above|see (?:above|handoff|document)|not applicable|tbd)[.!]?$/i.test(normalized);
|
|
81
|
+
}
|
|
82
|
+
function stripRenderedCompletenessAudit(content) {
|
|
83
|
+
const start = content.indexOf(HANDOFF_AUDIT_START_MARKER);
|
|
84
|
+
if (start < 0)
|
|
85
|
+
return content.trim();
|
|
86
|
+
const end = content.indexOf(HANDOFF_AUDIT_END_MARKER, start);
|
|
87
|
+
if (end < 0)
|
|
88
|
+
return content.slice(0, start).trim();
|
|
89
|
+
return `${content.slice(0, start)}${content.slice(end + HANDOFF_AUDIT_END_MARKER.length)}`.trim();
|
|
90
|
+
}
|
|
91
|
+
export function handoffContentHash(content) {
|
|
92
|
+
return createHash("sha256").update(content).digest("hex");
|
|
93
|
+
}
|
|
94
|
+
export function validateHandoffCompletenessAudit(audit) {
|
|
95
|
+
const expectedIds = HANDOFF_COMPLETENESS_CATEGORIES.map((entry) => entry.id);
|
|
96
|
+
if (!audit || audit.version !== HANDOFF_COMPLETENESS_AUDIT_VERSION) {
|
|
97
|
+
throw new HandoffContractError("HANDOFF_COMPLETENESS_AUDIT_REQUIRED", `Handoff completeness audit version ${HANDOFF_COMPLETENESS_AUDIT_VERSION} is required.`, { requiredVersion: HANDOFF_COMPLETENESS_AUDIT_VERSION, missingCategories: expectedIds });
|
|
98
|
+
}
|
|
99
|
+
const byCategory = new Map();
|
|
100
|
+
const duplicates = [];
|
|
101
|
+
for (const entry of audit.entries) {
|
|
102
|
+
if (byCategory.has(entry.category))
|
|
103
|
+
duplicates.push(entry.category);
|
|
104
|
+
else
|
|
105
|
+
byCategory.set(entry.category, entry);
|
|
106
|
+
}
|
|
107
|
+
const missingCategories = expectedIds.filter((id) => !byCategory.has(id));
|
|
108
|
+
const unknownCategories = [...byCategory.keys()].filter((id) => !expectedIds.includes(id));
|
|
109
|
+
const invalidCategories = expectedIds.filter((id) => {
|
|
110
|
+
const entry = byCategory.get(id);
|
|
111
|
+
return entry ? !isSubstantive(entry.detail) : false;
|
|
112
|
+
});
|
|
113
|
+
if (missingCategories.length > 0 || unknownCategories.length > 0 || duplicates.length > 0 || invalidCategories.length > 0) {
|
|
114
|
+
throw new HandoffContractError("HANDOFF_COMPLETENESS_AUDIT_REQUIRED", "The handoff completeness audit is missing required categories or contains non-substantive entries.", { missingCategories, invalidCategories, unknownCategories, duplicateCategories: [...new Set(duplicates)] });
|
|
115
|
+
}
|
|
116
|
+
return expectedIds.map((id) => byCategory.get(id));
|
|
117
|
+
}
|
|
118
|
+
export function renderHandoffCompletenessAudit(audit) {
|
|
119
|
+
const entries = validateHandoffCompletenessAudit(audit);
|
|
120
|
+
const labels = new Map(HANDOFF_COMPLETENESS_CATEGORIES.map((entry) => [entry.id, entry.label]));
|
|
121
|
+
return [
|
|
122
|
+
HANDOFF_AUDIT_START_MARKER,
|
|
123
|
+
`## Operational completeness audit (v${HANDOFF_COMPLETENESS_AUDIT_VERSION})`,
|
|
124
|
+
"",
|
|
125
|
+
...entries.flatMap((entry) => [
|
|
126
|
+
`### ${labels.get(entry.category) ?? entry.category}`,
|
|
127
|
+
`**Status:** ${entry.status}`,
|
|
128
|
+
entry.detail.trim(),
|
|
129
|
+
"",
|
|
130
|
+
]),
|
|
131
|
+
HANDOFF_AUDIT_END_MARKER,
|
|
132
|
+
].join("\n").trim();
|
|
133
|
+
}
|
|
134
|
+
export function renderVerifiedHandoffContent(content, audit) {
|
|
135
|
+
const base = stripRenderedCompletenessAudit(content);
|
|
136
|
+
validateCanonicalHandoffContent(base);
|
|
137
|
+
validateHandoffCompletenessAudit(audit);
|
|
138
|
+
const rendered = `${base}\n\n${renderHandoffCompletenessAudit(audit)}`.trim();
|
|
139
|
+
if (rendered.length > MAX_HANDOFF_CONTENT_CHARS) {
|
|
140
|
+
throw new HandoffContractError("HANDOFF_CONTENT_LIMIT_EXCEEDED", `Canonical handoff content is ${rendered.length} characters; the maximum is ${MAX_HANDOFF_CONTENT_CHARS}. Move extended detail to committed Markdown under .planner/docs/ and link it with a substantive explanation.`, { contentLength: rendered.length, maxContentChars: MAX_HANDOFF_CONTENT_CHARS });
|
|
141
|
+
}
|
|
142
|
+
return rendered;
|
|
143
|
+
}
|
|
37
144
|
export function validateCanonicalHandoffContent(content) {
|
|
38
145
|
const body = nonEmpty(content, "Handoff content");
|
|
39
146
|
const required = [
|
|
@@ -53,7 +160,22 @@ export function validateCanonicalHandoffContent(content) {
|
|
|
53
160
|
throw new Error(`Canonical handoff is missing required sections: ${missing.join(", ")}.`);
|
|
54
161
|
}
|
|
55
162
|
export function validateHandoffContextSync(phase, feature, input) {
|
|
56
|
-
|
|
163
|
+
renderVerifiedHandoffContent(input.content, input.completenessAudit);
|
|
164
|
+
const requestedDocuments = input.supportingDocuments ?? [];
|
|
165
|
+
const verifiedDocuments = input.verifiedSupportingDocuments ?? [];
|
|
166
|
+
if (requestedDocuments.length !== verifiedDocuments.length) {
|
|
167
|
+
throw new HandoffContractError("HANDOFF_SUPPORTING_DOCUMENT_INVALID", "Every supporting document must be validated by PlanStore before the handoff is written.", { requestedCount: requestedDocuments.length, verifiedCount: verifiedDocuments.length });
|
|
168
|
+
}
|
|
169
|
+
for (let index = 0; index < requestedDocuments.length; index += 1) {
|
|
170
|
+
const requested = requestedDocuments[index];
|
|
171
|
+
const verified = verifiedDocuments[index];
|
|
172
|
+
if (requested.path !== verified.path || !isSubstantive(requested.description) || requested.description.trim() !== verified.description) {
|
|
173
|
+
throw new HandoffContractError("HANDOFF_SUPPORTING_DOCUMENT_INVALID", `Supporting document ${requested.path || `(index ${index})`} is not valid or lacks a substantive description.`, { index, path: requested.path });
|
|
174
|
+
}
|
|
175
|
+
if (!input.content.includes(requested.path)) {
|
|
176
|
+
throw new HandoffContractError("HANDOFF_SUPPORTING_DOCUMENT_INVALID", `Canonical handoff content must link supporting document ${requested.path}.`, { index, path: requested.path });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
57
179
|
if (phase.status === "done" || phase.status === "canceled") {
|
|
58
180
|
throw new Error(`Cannot write a handoff on ${phase.status} phase ${phase.id}; completed phases have no pending handoff.`);
|
|
59
181
|
}
|
|
@@ -100,6 +222,8 @@ export function validateHandoffContextSync(phase, feature, input) {
|
|
|
100
222
|
}
|
|
101
223
|
export function applyHandoffContextSync(phase, feature, input, timestamp) {
|
|
102
224
|
validateHandoffContextSync(phase, feature, input);
|
|
225
|
+
const handoffContent = renderVerifiedHandoffContent(input.content, input.completenessAudit);
|
|
226
|
+
const auditEntries = validateHandoffCompletenessAudit(input.completenessAudit);
|
|
103
227
|
const nextPhase = structuredClone(phase);
|
|
104
228
|
const nextFeature = structuredClone(feature);
|
|
105
229
|
const updatedTaskIds = [];
|
|
@@ -141,8 +265,16 @@ export function applyHandoffContextSync(phase, feature, input, timestamp) {
|
|
|
141
265
|
nextFeature.workDone = appendSection(nextFeature.workDone, featureUpdate.workDone);
|
|
142
266
|
nextFeature.workRemaining = appendSection(nextFeature.workRemaining, featureUpdate.workRemaining);
|
|
143
267
|
}
|
|
144
|
-
nextPhase.handoff =
|
|
268
|
+
nextPhase.handoff = handoffContent;
|
|
145
269
|
nextPhase.handoffUpdatedAt = timestamp;
|
|
270
|
+
nextPhase.handoffAudit = {
|
|
271
|
+
version: HANDOFF_COMPLETENESS_AUDIT_VERSION,
|
|
272
|
+
entries: auditEntries,
|
|
273
|
+
supportingDocuments: input.verifiedSupportingDocuments ?? [],
|
|
274
|
+
contentHash: handoffContentHash(handoffContent),
|
|
275
|
+
contentLength: handoffContent.length,
|
|
276
|
+
verifiedAt: timestamp,
|
|
277
|
+
};
|
|
146
278
|
nextPhase.handoffReadAt = "";
|
|
147
279
|
nextPhase.updatedAt = timestamp;
|
|
148
280
|
nextFeature.updatedAt = timestamp;
|
package/dist/index.d.ts
CHANGED
|
@@ -4,14 +4,18 @@ export * from "./schema.js";
|
|
|
4
4
|
export * from "./checklist.js";
|
|
5
5
|
export * from "./recap.js";
|
|
6
6
|
export * from "./planner-rules.js";
|
|
7
|
+
export * from "./planner-skill.js";
|
|
7
8
|
export * from "./display-status.js";
|
|
8
9
|
export * from "./task-context.js";
|
|
9
10
|
export * from "./task-selection.js";
|
|
10
11
|
export * from "./task-start-outcome.js";
|
|
11
12
|
export * from "./read-tracking.js";
|
|
13
|
+
export * from "./payload-fallback.js";
|
|
12
14
|
export * from "./handoff-context.js";
|
|
15
|
+
export * from "./project-context-migration.js";
|
|
16
|
+
export * from "./requirement-macro-tasks.js";
|
|
13
17
|
export * from "./package-version.js";
|
|
14
|
-
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock, type PhaseHandoffSummary, type OrphanPhaseSummary } from "./plan-store.js";
|
|
18
|
+
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock, type IdeaCreateInput, type IdeaUpdateInput, type IdeaPromotionTargetInput, type PhaseHandoffSummary, type OrphanPhaseSummary } from "./plan-store.js";
|
|
15
19
|
export { PlanRenderer } from "./renderer.js";
|
|
16
20
|
export { ExportService } from "./export-service.js";
|
|
17
21
|
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,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,uBAAuB,EAAE,eAAe,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,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,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,sBAAsB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,uBAAuB,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,eAAe,EAAE,KAAK,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAC1R,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
|
@@ -4,12 +4,16 @@ export * from "./schema.js";
|
|
|
4
4
|
export * from "./checklist.js";
|
|
5
5
|
export * from "./recap.js";
|
|
6
6
|
export * from "./planner-rules.js";
|
|
7
|
+
export * from "./planner-skill.js";
|
|
7
8
|
export * from "./display-status.js";
|
|
8
9
|
export * from "./task-context.js";
|
|
9
10
|
export * from "./task-selection.js";
|
|
10
11
|
export * from "./task-start-outcome.js";
|
|
11
12
|
export * from "./read-tracking.js";
|
|
13
|
+
export * from "./payload-fallback.js";
|
|
12
14
|
export * from "./handoff-context.js";
|
|
15
|
+
export * from "./project-context-migration.js";
|
|
16
|
+
export * from "./requirement-macro-tasks.js";
|
|
13
17
|
export * from "./package-version.js";
|
|
14
18
|
export { PlanStore, PlanStoreError, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock } from "./plan-store.js";
|
|
15
19
|
export { PlanRenderer } from "./renderer.js";
|
package/dist/naming.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export declare function formatThreeDigitNumber(value: number): string;
|
|
|
39
39
|
export declare function formatPhaseRef(phaseNumber: number, featureNumber?: number): string;
|
|
40
40
|
/** Human-readable feature ref: `F00x`. Harness-agnostic. */
|
|
41
41
|
export declare function formatFeatureRef(featureNumber: number): string;
|
|
42
|
+
/** Human-readable idea ref: `I00x`. Ideas use an independent global sequence. */
|
|
43
|
+
export declare function formatIdeaRef(ideaNumber: number): string;
|
|
42
44
|
/** Find the parent feature's number for a phase (for P00x(F00x) composite refs). */
|
|
43
45
|
export declare function featureNumberOfPhase(phase: {
|
|
44
46
|
featureId?: string | null | undefined;
|
|
@@ -53,6 +55,7 @@ export declare function isLegacyPhaseId(phaseId: string): boolean;
|
|
|
53
55
|
export declare function migratePhaseId(featureId: string, number: number, slug: string): string;
|
|
54
56
|
export declare function createTaskId(): string;
|
|
55
57
|
export declare function createRequirementId(): string;
|
|
58
|
+
export declare function createIdeaId(): string;
|
|
56
59
|
export declare function createMacroTaskId(): string;
|
|
57
60
|
export declare function createFeatureId(): string;
|
|
58
61
|
export declare function createChecklistItemId(taskId: string, number: number, title: string): string;
|
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,4EAA4E;AAC5E,eAAO,MAAM,YAAY,QAAoE,CAAC;AAE9F,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtD;AAED;;gEAEgE;AAChE,wBAAsB,sBAAsB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACnE,IAAI,EAAE,SAAS,GAAG,OAAO,EACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,GACnC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAStD;AAGD;;;;;qCAKqC;AACrC,wBAAgB,aAAa,CAAC,QAAQ,GAAE,GAAG,CAAC,MAAM,CAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CA2BtF;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;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
|
|
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,4EAA4E;AAC5E,eAAO,MAAM,YAAY,QAAoE,CAAC;AAE9F,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEtD;AAED;;gEAEgE;AAChE,wBAAsB,sBAAsB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACnE,IAAI,EAAE,SAAS,GAAG,OAAO,EACzB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,GACnC,OAAO,CAAC;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAStD;AAGD;;;;;qCAKqC;AACrC,wBAAgB,aAAa,CAAC,QAAQ,GAAE,GAAG,CAAC,MAAM,CAAa,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CA2BtF;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,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAExD;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,YAAY,IAAI,MAAM,CAErC;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;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C"}
|
package/dist/naming.js
CHANGED
|
@@ -94,6 +94,10 @@ export function formatPhaseRef(phaseNumber, featureNumber) {
|
|
|
94
94
|
export function formatFeatureRef(featureNumber) {
|
|
95
95
|
return `F${formatThreeDigitNumber(featureNumber)}`;
|
|
96
96
|
}
|
|
97
|
+
/** Human-readable idea ref: `I00x`. Ideas use an independent global sequence. */
|
|
98
|
+
export function formatIdeaRef(ideaNumber) {
|
|
99
|
+
return `I${formatThreeDigitNumber(ideaNumber)}`;
|
|
100
|
+
}
|
|
97
101
|
/** Find the parent feature's number for a phase (for P00x(F00x) composite refs). */
|
|
98
102
|
export function featureNumberOfPhase(phase, features) {
|
|
99
103
|
return phase.featureId ? features.find((f) => f.id === phase.featureId)?.number : undefined;
|
|
@@ -116,6 +120,9 @@ export function createTaskId() {
|
|
|
116
120
|
export function createRequirementId() {
|
|
117
121
|
return randomUUID();
|
|
118
122
|
}
|
|
123
|
+
export function createIdeaId() {
|
|
124
|
+
return randomUUID();
|
|
125
|
+
}
|
|
119
126
|
export function createMacroTaskId() {
|
|
120
127
|
return randomUUID();
|
|
121
128
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type PlannerPayloadEntity = "project" | "feature" | "phase" | "task";
|
|
2
|
+
export type PlannerPayloadOperation = "update" | "discuss";
|
|
3
|
+
export type PlannerPayloadFailureCode = "NO_MUTABLE_FIELDS_RECEIVED" | "DESCRIPTION_MARKDOWN_FALLBACK_REQUIRED";
|
|
4
|
+
export interface DescriptionFallbackInput {
|
|
5
|
+
entityId?: string;
|
|
6
|
+
inputField: string;
|
|
7
|
+
storedField: string;
|
|
8
|
+
descriptionRefField: string;
|
|
9
|
+
}
|
|
10
|
+
export interface NoMutableFieldsReceivedInput {
|
|
11
|
+
entity: PlannerPayloadEntity;
|
|
12
|
+
ref: string;
|
|
13
|
+
operation: PlannerPayloadOperation;
|
|
14
|
+
mutableFields: readonly string[];
|
|
15
|
+
retryCommand: string;
|
|
16
|
+
readBackCommand?: string;
|
|
17
|
+
descriptionFallback?: DescriptionFallbackInput;
|
|
18
|
+
}
|
|
19
|
+
export interface NoMutableFieldsReceivedResult {
|
|
20
|
+
updated: false;
|
|
21
|
+
discussed?: false;
|
|
22
|
+
reason: "no-mutable-fields";
|
|
23
|
+
errorCode: PlannerPayloadFailureCode;
|
|
24
|
+
suspectedLongTextPayloadLoss: boolean;
|
|
25
|
+
entity: PlannerPayloadEntity;
|
|
26
|
+
ref: string;
|
|
27
|
+
operation: PlannerPayloadOperation;
|
|
28
|
+
mutableFields: string[];
|
|
29
|
+
fallbackDocPath?: string;
|
|
30
|
+
fallbackDescriptionTemplate?: string;
|
|
31
|
+
nextActions: string[];
|
|
32
|
+
message: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function normalizeDescriptionRef(value: string | undefined): string | undefined;
|
|
35
|
+
export declare function isPlannerDescriptionRef(value: string): boolean;
|
|
36
|
+
export declare function suggestedDescriptionRefPath(entity: PlannerPayloadEntity, entityId?: string): string;
|
|
37
|
+
export declare function noMutableFieldsReceived(input: NoMutableFieldsReceivedInput): NoMutableFieldsReceivedResult;
|
|
38
|
+
//# sourceMappingURL=payload-fallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-fallback.d.ts","sourceRoot":"","sources":["../src/payload-fallback.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC;AAC5E,MAAM,MAAM,uBAAuB,GAAG,QAAQ,GAAG,SAAS,CAAC;AAC3D,MAAM,MAAM,yBAAyB,GAAG,4BAA4B,GAAG,wCAAwC,CAAC;AAEhH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAC3C,MAAM,EAAE,oBAAoB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,wBAAwB,CAAC;CAChD;AAED,MAAM,WAAW,6BAA6B;IAC5C,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,CAAC,EAAE,KAAK,CAAC;IAClB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,SAAS,EAAE,yBAAyB,CAAC;IACrC,4BAA4B,EAAE,OAAO,CAAC;IACtC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,uBAAuB,CAAC;IACnC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGrF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAO9D;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAWnG;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,4BAA4B,GAClC,6BAA6B,CAgD/B"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export function normalizeDescriptionRef(value) {
|
|
2
|
+
const trimmed = value?.trim();
|
|
3
|
+
return trimmed ? trimmed : undefined;
|
|
4
|
+
}
|
|
5
|
+
export function isPlannerDescriptionRef(value) {
|
|
6
|
+
if (!value.startsWith(".planner/docs/"))
|
|
7
|
+
return false;
|
|
8
|
+
if (value.includes("\\") || value.includes("\0"))
|
|
9
|
+
return false;
|
|
10
|
+
const parts = value.split("/");
|
|
11
|
+
if (parts.length < 4)
|
|
12
|
+
return false;
|
|
13
|
+
if (parts[0] !== ".planner" || parts[1] !== "docs")
|
|
14
|
+
return false;
|
|
15
|
+
return parts.slice(2).every((part) => part.length > 0 && part !== "." && part !== "..");
|
|
16
|
+
}
|
|
17
|
+
export function suggestedDescriptionRefPath(entity, entityId) {
|
|
18
|
+
switch (entity) {
|
|
19
|
+
case "project":
|
|
20
|
+
return ".planner/docs/project/description.md";
|
|
21
|
+
case "feature":
|
|
22
|
+
return `.planner/docs/features/${entityId ?? "feature"}.md`;
|
|
23
|
+
case "phase":
|
|
24
|
+
return `.planner/docs/phases/${entityId ?? "phase"}.md`;
|
|
25
|
+
case "task":
|
|
26
|
+
return `.planner/docs/tasks/${entityId ?? "task"}.md`;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
export function noMutableFieldsReceived(input) {
|
|
30
|
+
const mutableFields = [...input.mutableFields];
|
|
31
|
+
const fallbackDocPath = input.descriptionFallback
|
|
32
|
+
? suggestedDescriptionRefPath(input.entity, input.descriptionFallback.entityId)
|
|
33
|
+
: undefined;
|
|
34
|
+
const nextActions = input.descriptionFallback && fallbackDocPath
|
|
35
|
+
? [
|
|
36
|
+
`Create a committed markdown file at ${fallbackDocPath} containing the full intended ${input.descriptionFallback.storedField}.`,
|
|
37
|
+
`Retry ${input.retryCommand} with a concise ${input.descriptionFallback.inputField} summary and ${input.descriptionFallback.descriptionRefField} set to ${fallbackDocPath}.`,
|
|
38
|
+
...(input.readBackCommand
|
|
39
|
+
? [`Read back ${input.readBackCommand} and confirm the summary plus ${input.descriptionFallback.descriptionRefField} survived.`]
|
|
40
|
+
: []),
|
|
41
|
+
"Continue only after the read-back confirms the markdown reference persisted.",
|
|
42
|
+
]
|
|
43
|
+
: [
|
|
44
|
+
`Retry ${input.retryCommand} with at least one mutable field: ${mutableFields.join(", ")}.`,
|
|
45
|
+
];
|
|
46
|
+
const fallbackDescriptionTemplate = fallbackDocPath
|
|
47
|
+
? `Concise summary here. Full description is stored in ${fallbackDocPath}.`
|
|
48
|
+
: undefined;
|
|
49
|
+
const message = [
|
|
50
|
+
"Not updated — no mutable fields were received.",
|
|
51
|
+
"No planner data was changed.",
|
|
52
|
+
input.descriptionFallback
|
|
53
|
+
? `If you attempted to send a long ${input.descriptionFallback.inputField}, it may have exceeded the tool payload limit before reaching the planner.`
|
|
54
|
+
: `Provide at least one mutable field for this ${input.operation} operation.`,
|
|
55
|
+
"Next required actions:",
|
|
56
|
+
...nextActions.map((action, index) => `${index + 1}. ${action}`),
|
|
57
|
+
].join("\n");
|
|
58
|
+
return {
|
|
59
|
+
updated: false,
|
|
60
|
+
...(input.operation === "discuss" ? { discussed: false } : {}),
|
|
61
|
+
reason: "no-mutable-fields",
|
|
62
|
+
errorCode: input.descriptionFallback ? "DESCRIPTION_MARKDOWN_FALLBACK_REQUIRED" : "NO_MUTABLE_FIELDS_RECEIVED",
|
|
63
|
+
suspectedLongTextPayloadLoss: Boolean(input.descriptionFallback),
|
|
64
|
+
entity: input.entity,
|
|
65
|
+
ref: input.ref,
|
|
66
|
+
operation: input.operation,
|
|
67
|
+
mutableFields,
|
|
68
|
+
...(fallbackDocPath ? { fallbackDocPath } : {}),
|
|
69
|
+
...(fallbackDescriptionTemplate ? { fallbackDescriptionTemplate } : {}),
|
|
70
|
+
nextActions,
|
|
71
|
+
message,
|
|
72
|
+
};
|
|
73
|
+
}
|