forge-cc 0.1.0

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.
Files changed (105) hide show
  1. package/.forge.json +5 -0
  2. package/AGENTS.md +42 -0
  3. package/README.md +283 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +148 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/loader.d.ts +2 -0
  8. package/dist/config/loader.js +44 -0
  9. package/dist/config/loader.js.map +1 -0
  10. package/dist/config/schema.d.ts +57 -0
  11. package/dist/config/schema.js +15 -0
  12. package/dist/config/schema.js.map +1 -0
  13. package/dist/gates/index.d.ts +11 -0
  14. package/dist/gates/index.js +106 -0
  15. package/dist/gates/index.js.map +1 -0
  16. package/dist/gates/lint-gate.d.ts +2 -0
  17. package/dist/gates/lint-gate.js +66 -0
  18. package/dist/gates/lint-gate.js.map +1 -0
  19. package/dist/gates/prd-gate.d.ts +7 -0
  20. package/dist/gates/prd-gate.js +193 -0
  21. package/dist/gates/prd-gate.js.map +1 -0
  22. package/dist/gates/runtime-gate.d.ts +5 -0
  23. package/dist/gates/runtime-gate.js +99 -0
  24. package/dist/gates/runtime-gate.js.map +1 -0
  25. package/dist/gates/tests-gate.d.ts +2 -0
  26. package/dist/gates/tests-gate.js +116 -0
  27. package/dist/gates/tests-gate.js.map +1 -0
  28. package/dist/gates/types-gate.d.ts +2 -0
  29. package/dist/gates/types-gate.js +59 -0
  30. package/dist/gates/types-gate.js.map +1 -0
  31. package/dist/gates/visual-gate.d.ts +6 -0
  32. package/dist/gates/visual-gate.js +118 -0
  33. package/dist/gates/visual-gate.js.map +1 -0
  34. package/dist/go/auto-chain.d.ts +107 -0
  35. package/dist/go/auto-chain.js +303 -0
  36. package/dist/go/auto-chain.js.map +1 -0
  37. package/dist/go/executor.d.ts +130 -0
  38. package/dist/go/executor.js +409 -0
  39. package/dist/go/executor.js.map +1 -0
  40. package/dist/go/finalize.d.ts +58 -0
  41. package/dist/go/finalize.js +200 -0
  42. package/dist/go/finalize.js.map +1 -0
  43. package/dist/go/linear-sync.d.ts +75 -0
  44. package/dist/go/linear-sync.js +239 -0
  45. package/dist/go/linear-sync.js.map +1 -0
  46. package/dist/go/verify-loop.d.ts +47 -0
  47. package/dist/go/verify-loop.js +172 -0
  48. package/dist/go/verify-loop.js.map +1 -0
  49. package/dist/hooks/pre-commit.d.ts +5 -0
  50. package/dist/hooks/pre-commit.js +69 -0
  51. package/dist/hooks/pre-commit.js.map +1 -0
  52. package/dist/linear/client.d.ts +108 -0
  53. package/dist/linear/client.js +388 -0
  54. package/dist/linear/client.js.map +1 -0
  55. package/dist/linear/issues.d.ts +20 -0
  56. package/dist/linear/issues.js +39 -0
  57. package/dist/linear/issues.js.map +1 -0
  58. package/dist/linear/milestones.d.ts +11 -0
  59. package/dist/linear/milestones.js +32 -0
  60. package/dist/linear/milestones.js.map +1 -0
  61. package/dist/linear/projects.d.ts +16 -0
  62. package/dist/linear/projects.js +50 -0
  63. package/dist/linear/projects.js.map +1 -0
  64. package/dist/reporter/human.d.ts +2 -0
  65. package/dist/reporter/human.js +63 -0
  66. package/dist/reporter/human.js.map +1 -0
  67. package/dist/reporter/json.d.ts +2 -0
  68. package/dist/reporter/json.js +4 -0
  69. package/dist/reporter/json.js.map +1 -0
  70. package/dist/server.d.ts +2 -0
  71. package/dist/server.js +109 -0
  72. package/dist/server.js.map +1 -0
  73. package/dist/spec/generator.d.ts +14 -0
  74. package/dist/spec/generator.js +206 -0
  75. package/dist/spec/generator.js.map +1 -0
  76. package/dist/spec/interview.d.ts +104 -0
  77. package/dist/spec/interview.js +342 -0
  78. package/dist/spec/interview.js.map +1 -0
  79. package/dist/spec/linear-sync.d.ts +48 -0
  80. package/dist/spec/linear-sync.js +125 -0
  81. package/dist/spec/linear-sync.js.map +1 -0
  82. package/dist/spec/scanner.d.ts +45 -0
  83. package/dist/spec/scanner.js +473 -0
  84. package/dist/spec/scanner.js.map +1 -0
  85. package/dist/spec/templates.d.ts +345 -0
  86. package/dist/spec/templates.js +86 -0
  87. package/dist/spec/templates.js.map +1 -0
  88. package/dist/state/reader.d.ts +29 -0
  89. package/dist/state/reader.js +116 -0
  90. package/dist/state/reader.js.map +1 -0
  91. package/dist/state/writer.d.ts +60 -0
  92. package/dist/state/writer.js +222 -0
  93. package/dist/state/writer.js.map +1 -0
  94. package/dist/types.d.ts +64 -0
  95. package/dist/types.js +2 -0
  96. package/dist/types.js.map +1 -0
  97. package/dist/utils/browser.d.ts +10 -0
  98. package/dist/utils/browser.js +89 -0
  99. package/dist/utils/browser.js.map +1 -0
  100. package/hooks/pre-commit-verify.js +103 -0
  101. package/package.json +68 -0
  102. package/skills/README.md +33 -0
  103. package/skills/forge-go.md +332 -0
  104. package/skills/forge-spec.md +251 -0
  105. package/skills/forge-triage.md +133 -0
@@ -0,0 +1,345 @@
1
+ import { z } from "zod";
2
+ export declare const UserStorySchema: z.ZodObject<{
3
+ id: z.ZodString;
4
+ title: z.ZodString;
5
+ description: z.ZodString;
6
+ acceptanceCriteria: z.ZodArray<z.ZodString, "many">;
7
+ }, "strip", z.ZodTypeAny, {
8
+ description: string;
9
+ title: string;
10
+ id: string;
11
+ acceptanceCriteria: string[];
12
+ }, {
13
+ description: string;
14
+ title: string;
15
+ id: string;
16
+ acceptanceCriteria: string[];
17
+ }>;
18
+ export declare const MilestoneWaveSchema: z.ZodObject<{
19
+ waveNumber: z.ZodNumber;
20
+ agents: z.ZodArray<z.ZodObject<{
21
+ name: z.ZodString;
22
+ task: z.ZodString;
23
+ files: z.ZodArray<z.ZodString, "many">;
24
+ }, "strip", z.ZodTypeAny, {
25
+ name: string;
26
+ task: string;
27
+ files: string[];
28
+ }, {
29
+ name: string;
30
+ task: string;
31
+ files: string[];
32
+ }>, "many">;
33
+ }, "strip", z.ZodTypeAny, {
34
+ waveNumber: number;
35
+ agents: {
36
+ name: string;
37
+ task: string;
38
+ files: string[];
39
+ }[];
40
+ }, {
41
+ waveNumber: number;
42
+ agents: {
43
+ name: string;
44
+ task: string;
45
+ files: string[];
46
+ }[];
47
+ }>;
48
+ export declare const MilestoneSchema: z.ZodObject<{
49
+ number: z.ZodNumber;
50
+ name: z.ZodString;
51
+ goal: z.ZodString;
52
+ assignedTo: z.ZodString;
53
+ waves: z.ZodArray<z.ZodObject<{
54
+ waveNumber: z.ZodNumber;
55
+ agents: z.ZodArray<z.ZodObject<{
56
+ name: z.ZodString;
57
+ task: z.ZodString;
58
+ files: z.ZodArray<z.ZodString, "many">;
59
+ }, "strip", z.ZodTypeAny, {
60
+ name: string;
61
+ task: string;
62
+ files: string[];
63
+ }, {
64
+ name: string;
65
+ task: string;
66
+ files: string[];
67
+ }>, "many">;
68
+ }, "strip", z.ZodTypeAny, {
69
+ waveNumber: number;
70
+ agents: {
71
+ name: string;
72
+ task: string;
73
+ files: string[];
74
+ }[];
75
+ }, {
76
+ waveNumber: number;
77
+ agents: {
78
+ name: string;
79
+ task: string;
80
+ files: string[];
81
+ }[];
82
+ }>, "many">;
83
+ verificationCommands: z.ZodArray<z.ZodString, "many">;
84
+ }, "strip", z.ZodTypeAny, {
85
+ number: number;
86
+ name: string;
87
+ goal: string;
88
+ assignedTo: string;
89
+ waves: {
90
+ waveNumber: number;
91
+ agents: {
92
+ name: string;
93
+ task: string;
94
+ files: string[];
95
+ }[];
96
+ }[];
97
+ verificationCommands: string[];
98
+ }, {
99
+ number: number;
100
+ name: string;
101
+ goal: string;
102
+ assignedTo: string;
103
+ waves: {
104
+ waveNumber: number;
105
+ agents: {
106
+ name: string;
107
+ task: string;
108
+ files: string[];
109
+ }[];
110
+ }[];
111
+ verificationCommands: string[];
112
+ }>;
113
+ export declare const PRDSchema: z.ZodObject<{
114
+ project: z.ZodString;
115
+ status: z.ZodString;
116
+ branch: z.ZodString;
117
+ created: z.ZodString;
118
+ assignedTo: z.ZodString;
119
+ linearProject: z.ZodOptional<z.ZodString>;
120
+ overview: z.ZodString;
121
+ problemStatement: z.ZodString;
122
+ scope: z.ZodObject<{
123
+ inScope: z.ZodArray<z.ZodString, "many">;
124
+ outOfScope: z.ZodArray<z.ZodString, "many">;
125
+ sacred: z.ZodArray<z.ZodString, "many">;
126
+ }, "strip", z.ZodTypeAny, {
127
+ inScope: string[];
128
+ outOfScope: string[];
129
+ sacred: string[];
130
+ }, {
131
+ inScope: string[];
132
+ outOfScope: string[];
133
+ sacred: string[];
134
+ }>;
135
+ userStories: z.ZodArray<z.ZodObject<{
136
+ id: z.ZodString;
137
+ title: z.ZodString;
138
+ description: z.ZodString;
139
+ acceptanceCriteria: z.ZodArray<z.ZodString, "many">;
140
+ }, "strip", z.ZodTypeAny, {
141
+ description: string;
142
+ title: string;
143
+ id: string;
144
+ acceptanceCriteria: string[];
145
+ }, {
146
+ description: string;
147
+ title: string;
148
+ id: string;
149
+ acceptanceCriteria: string[];
150
+ }>, "many">;
151
+ technicalDesign: z.ZodObject<{
152
+ projectStructure: z.ZodOptional<z.ZodString>;
153
+ keyTypes: z.ZodOptional<z.ZodString>;
154
+ dependencies: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
155
+ existingCode: z.ZodOptional<z.ZodString>;
156
+ }, "strip", z.ZodTypeAny, {
157
+ projectStructure?: string | undefined;
158
+ keyTypes?: string | undefined;
159
+ dependencies?: string[] | undefined;
160
+ existingCode?: string | undefined;
161
+ }, {
162
+ projectStructure?: string | undefined;
163
+ keyTypes?: string | undefined;
164
+ dependencies?: string[] | undefined;
165
+ existingCode?: string | undefined;
166
+ }>;
167
+ milestones: z.ZodArray<z.ZodObject<{
168
+ number: z.ZodNumber;
169
+ name: z.ZodString;
170
+ goal: z.ZodString;
171
+ assignedTo: z.ZodString;
172
+ waves: z.ZodArray<z.ZodObject<{
173
+ waveNumber: z.ZodNumber;
174
+ agents: z.ZodArray<z.ZodObject<{
175
+ name: z.ZodString;
176
+ task: z.ZodString;
177
+ files: z.ZodArray<z.ZodString, "many">;
178
+ }, "strip", z.ZodTypeAny, {
179
+ name: string;
180
+ task: string;
181
+ files: string[];
182
+ }, {
183
+ name: string;
184
+ task: string;
185
+ files: string[];
186
+ }>, "many">;
187
+ }, "strip", z.ZodTypeAny, {
188
+ waveNumber: number;
189
+ agents: {
190
+ name: string;
191
+ task: string;
192
+ files: string[];
193
+ }[];
194
+ }, {
195
+ waveNumber: number;
196
+ agents: {
197
+ name: string;
198
+ task: string;
199
+ files: string[];
200
+ }[];
201
+ }>, "many">;
202
+ verificationCommands: z.ZodArray<z.ZodString, "many">;
203
+ }, "strip", z.ZodTypeAny, {
204
+ number: number;
205
+ name: string;
206
+ goal: string;
207
+ assignedTo: string;
208
+ waves: {
209
+ waveNumber: number;
210
+ agents: {
211
+ name: string;
212
+ task: string;
213
+ files: string[];
214
+ }[];
215
+ }[];
216
+ verificationCommands: string[];
217
+ }, {
218
+ number: number;
219
+ name: string;
220
+ goal: string;
221
+ assignedTo: string;
222
+ waves: {
223
+ waveNumber: number;
224
+ agents: {
225
+ name: string;
226
+ task: string;
227
+ files: string[];
228
+ }[];
229
+ }[];
230
+ verificationCommands: string[];
231
+ }>, "many">;
232
+ verification: z.ZodObject<{
233
+ perMilestone: z.ZodArray<z.ZodString, "many">;
234
+ overall: z.ZodArray<z.ZodString, "many">;
235
+ }, "strip", z.ZodTypeAny, {
236
+ perMilestone: string[];
237
+ overall: string[];
238
+ }, {
239
+ perMilestone: string[];
240
+ overall: string[];
241
+ }>;
242
+ }, "strip", z.ZodTypeAny, {
243
+ status: string;
244
+ branch: string;
245
+ milestones: {
246
+ number: number;
247
+ name: string;
248
+ goal: string;
249
+ assignedTo: string;
250
+ waves: {
251
+ waveNumber: number;
252
+ agents: {
253
+ name: string;
254
+ task: string;
255
+ files: string[];
256
+ }[];
257
+ }[];
258
+ verificationCommands: string[];
259
+ }[];
260
+ project: string;
261
+ assignedTo: string;
262
+ created: string;
263
+ overview: string;
264
+ problemStatement: string;
265
+ scope: {
266
+ inScope: string[];
267
+ outOfScope: string[];
268
+ sacred: string[];
269
+ };
270
+ userStories: {
271
+ description: string;
272
+ title: string;
273
+ id: string;
274
+ acceptanceCriteria: string[];
275
+ }[];
276
+ technicalDesign: {
277
+ projectStructure?: string | undefined;
278
+ keyTypes?: string | undefined;
279
+ dependencies?: string[] | undefined;
280
+ existingCode?: string | undefined;
281
+ };
282
+ verification: {
283
+ perMilestone: string[];
284
+ overall: string[];
285
+ };
286
+ linearProject?: string | undefined;
287
+ }, {
288
+ status: string;
289
+ branch: string;
290
+ milestones: {
291
+ number: number;
292
+ name: string;
293
+ goal: string;
294
+ assignedTo: string;
295
+ waves: {
296
+ waveNumber: number;
297
+ agents: {
298
+ name: string;
299
+ task: string;
300
+ files: string[];
301
+ }[];
302
+ }[];
303
+ verificationCommands: string[];
304
+ }[];
305
+ project: string;
306
+ assignedTo: string;
307
+ created: string;
308
+ overview: string;
309
+ problemStatement: string;
310
+ scope: {
311
+ inScope: string[];
312
+ outOfScope: string[];
313
+ sacred: string[];
314
+ };
315
+ userStories: {
316
+ description: string;
317
+ title: string;
318
+ id: string;
319
+ acceptanceCriteria: string[];
320
+ }[];
321
+ technicalDesign: {
322
+ projectStructure?: string | undefined;
323
+ keyTypes?: string | undefined;
324
+ dependencies?: string[] | undefined;
325
+ existingCode?: string | undefined;
326
+ };
327
+ verification: {
328
+ perMilestone: string[];
329
+ overall: string[];
330
+ };
331
+ linearProject?: string | undefined;
332
+ }>;
333
+ export type UserStory = z.infer<typeof UserStorySchema>;
334
+ export type MilestoneWave = z.infer<typeof MilestoneWaveSchema>;
335
+ export type Milestone = z.infer<typeof MilestoneSchema>;
336
+ export type PRDData = z.infer<typeof PRDSchema>;
337
+ /**
338
+ * Validates raw data against the PRD schema.
339
+ * Throws a ZodError if validation fails.
340
+ */
341
+ export declare function validatePRD(data: unknown): PRDData;
342
+ /**
343
+ * Creates an empty PRD scaffold with sensible defaults.
344
+ */
345
+ export declare function createEmptyPRD(projectName: string): PRDData;
@@ -0,0 +1,86 @@
1
+ import { z } from "zod";
2
+ // ── Zod Schemas ──────────────────────────────────────────────────────
3
+ export const UserStorySchema = z.object({
4
+ id: z.string(),
5
+ title: z.string(),
6
+ description: z.string(),
7
+ acceptanceCriteria: z.array(z.string()),
8
+ });
9
+ export const MilestoneWaveSchema = z.object({
10
+ waveNumber: z.number(),
11
+ agents: z.array(z.object({
12
+ name: z.string(),
13
+ task: z.string(),
14
+ files: z.array(z.string()),
15
+ })),
16
+ });
17
+ export const MilestoneSchema = z.object({
18
+ number: z.number(),
19
+ name: z.string(),
20
+ goal: z.string(),
21
+ assignedTo: z.string(),
22
+ waves: z.array(MilestoneWaveSchema),
23
+ verificationCommands: z.array(z.string()),
24
+ });
25
+ export const PRDSchema = z.object({
26
+ project: z.string(),
27
+ status: z.string(),
28
+ branch: z.string(),
29
+ created: z.string(),
30
+ assignedTo: z.string(),
31
+ linearProject: z.string().optional(),
32
+ overview: z.string(),
33
+ problemStatement: z.string(),
34
+ scope: z.object({
35
+ inScope: z.array(z.string()),
36
+ outOfScope: z.array(z.string()),
37
+ sacred: z.array(z.string()),
38
+ }),
39
+ userStories: z.array(UserStorySchema),
40
+ technicalDesign: z.object({
41
+ projectStructure: z.string().optional(),
42
+ keyTypes: z.string().optional(),
43
+ dependencies: z.array(z.string()).optional(),
44
+ existingCode: z.string().optional(),
45
+ }),
46
+ milestones: z.array(MilestoneSchema),
47
+ verification: z.object({
48
+ perMilestone: z.array(z.string()),
49
+ overall: z.array(z.string()),
50
+ }),
51
+ });
52
+ // ── Helper Functions ─────────────────────────────────────────────────
53
+ /**
54
+ * Validates raw data against the PRD schema.
55
+ * Throws a ZodError if validation fails.
56
+ */
57
+ export function validatePRD(data) {
58
+ return PRDSchema.parse(data);
59
+ }
60
+ /**
61
+ * Creates an empty PRD scaffold with sensible defaults.
62
+ */
63
+ export function createEmptyPRD(projectName) {
64
+ return {
65
+ project: projectName,
66
+ status: "Draft",
67
+ branch: "",
68
+ created: new Date().toISOString().split("T")[0],
69
+ assignedTo: "",
70
+ overview: "",
71
+ problemStatement: "",
72
+ scope: {
73
+ inScope: [],
74
+ outOfScope: [],
75
+ sacred: [],
76
+ },
77
+ userStories: [],
78
+ technicalDesign: {},
79
+ milestones: [],
80
+ verification: {
81
+ perMilestone: [],
82
+ overall: [],
83
+ },
84
+ };
85
+ }
86
+ //# sourceMappingURL=templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/spec/templates.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface StateInfo {
2
+ currentMilestone: {
3
+ number: number;
4
+ name: string;
5
+ } | null;
6
+ branch: string | null;
7
+ lastSession: string | null;
8
+ nextActions: string[];
9
+ raw: string;
10
+ }
11
+ export interface MilestoneProgress {
12
+ number: number;
13
+ name: string;
14
+ status: string;
15
+ }
16
+ export interface RoadmapInfo {
17
+ milestones: MilestoneProgress[];
18
+ raw: string;
19
+ }
20
+ export interface SessionContext {
21
+ state: StateInfo | null;
22
+ roadmap: RoadmapInfo | null;
23
+ currentMilestoneSection: string | null;
24
+ estimatedTokens: number;
25
+ }
26
+ export declare function readStateFile(projectDir: string): Promise<StateInfo | null>;
27
+ export declare function readRoadmapProgress(projectDir: string): Promise<RoadmapInfo | null>;
28
+ export declare function readCurrentMilestone(prdPath: string, milestoneNumber: number): Promise<string | null>;
29
+ export declare function readSessionContext(projectDir: string, prdPath: string, milestoneNumber: number): Promise<SessionContext>;
@@ -0,0 +1,116 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ // ---------------------------------------------------------------------------
4
+ // Helpers
5
+ // ---------------------------------------------------------------------------
6
+ async function safeRead(filePath) {
7
+ try {
8
+ return await readFile(filePath, "utf-8");
9
+ }
10
+ catch {
11
+ return null;
12
+ }
13
+ }
14
+ function estimateTokens(...texts) {
15
+ let chars = 0;
16
+ for (const t of texts) {
17
+ if (t)
18
+ chars += t.length;
19
+ }
20
+ return Math.ceil(chars / 4);
21
+ }
22
+ // ---------------------------------------------------------------------------
23
+ // readStateFile
24
+ // ---------------------------------------------------------------------------
25
+ export async function readStateFile(projectDir) {
26
+ const raw = await safeRead(join(projectDir, ".planning", "STATE.md"));
27
+ if (raw === null)
28
+ return null;
29
+ // Extract milestone: "Milestone 2 — Linear Integration + Triage Skill"
30
+ let currentMilestone = null;
31
+ const milestoneMatch = raw.match(/\*\*Milestone:\*\*\s*Milestone\s+(\d+)\s*[—–-]\s*(.+)/);
32
+ if (milestoneMatch) {
33
+ currentMilestone = {
34
+ number: parseInt(milestoneMatch[1], 10),
35
+ name: milestoneMatch[2].trim(),
36
+ };
37
+ }
38
+ // Extract branch
39
+ let branch = null;
40
+ const branchMatch = raw.match(/\*\*Branch:\*\*\s*`?([^\s`]+)`?/);
41
+ if (branchMatch) {
42
+ branch = branchMatch[1];
43
+ }
44
+ // Extract last session date
45
+ let lastSession = null;
46
+ const sessionMatch = raw.match(/\*\*Last Session:\*\*\s*(\S+)/);
47
+ if (sessionMatch) {
48
+ lastSession = sessionMatch[1];
49
+ }
50
+ // Extract next actions — numbered list items after "## Next Actions"
51
+ const nextActions = [];
52
+ const actionsSection = raw.match(/##\s*Next Actions\s*\n([\s\S]*?)(?=\n##\s|\n---|\s*$)/);
53
+ if (actionsSection) {
54
+ const lines = actionsSection[1].split("\n");
55
+ for (const line of lines) {
56
+ const item = line.match(/^\s*\d+\.\s+(.+)/);
57
+ if (item) {
58
+ nextActions.push(item[1].trim());
59
+ }
60
+ }
61
+ }
62
+ return { currentMilestone, branch, lastSession, nextActions, raw };
63
+ }
64
+ // ---------------------------------------------------------------------------
65
+ // readRoadmapProgress
66
+ // ---------------------------------------------------------------------------
67
+ export async function readRoadmapProgress(projectDir) {
68
+ const raw = await safeRead(join(projectDir, ".planning", "ROADMAP.md"));
69
+ if (raw === null)
70
+ return null;
71
+ const milestones = [];
72
+ // Match table rows: | 1 | Core CLI + Verification Engine | Complete (2026-02-15) |
73
+ const tableRowRe = /^\|\s*(\d+)\s*\|\s*(.+?)\s*\|\s*(.+?)\s*\|/gm;
74
+ let match;
75
+ while ((match = tableRowRe.exec(raw)) !== null) {
76
+ // Skip the header separator row (contains dashes)
77
+ if (match[2].includes("---"))
78
+ continue;
79
+ // Skip the header row itself
80
+ if (match[1] === "Milestone" || match[2] === "Name")
81
+ continue;
82
+ milestones.push({
83
+ number: parseInt(match[1], 10),
84
+ name: match[2].trim(),
85
+ status: match[3].trim(),
86
+ });
87
+ }
88
+ return { milestones, raw };
89
+ }
90
+ // ---------------------------------------------------------------------------
91
+ // readCurrentMilestone
92
+ // ---------------------------------------------------------------------------
93
+ export async function readCurrentMilestone(prdPath, milestoneNumber) {
94
+ const raw = await safeRead(prdPath);
95
+ if (raw === null)
96
+ return null;
97
+ // Look for "### Milestone {n}:" header and extract until next milestone or separator
98
+ const pattern = new RegExp(`(###\\s*Milestone\\s+${milestoneNumber}\\s*[:\\—–-][\\s\\S]*?)(?=\\n###\\s*Milestone\\s+\\d|\\n---|$)`);
99
+ const match = raw.match(pattern);
100
+ if (!match)
101
+ return null;
102
+ return match[1].trim();
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // readSessionContext
106
+ // ---------------------------------------------------------------------------
107
+ export async function readSessionContext(projectDir, prdPath, milestoneNumber) {
108
+ const [state, roadmap, currentMilestoneSection] = await Promise.all([
109
+ readStateFile(projectDir),
110
+ readRoadmapProgress(projectDir),
111
+ readCurrentMilestone(prdPath, milestoneNumber),
112
+ ]);
113
+ const estimatedTokens = estimateTokens(state?.raw, roadmap?.raw, currentMilestoneSection);
114
+ return { state, roadmap, currentMilestoneSection, estimatedTokens };
115
+ }
116
+ //# sourceMappingURL=reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/state/reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ export interface StateWriteInput {
2
+ project: string;
3
+ milestone: {
4
+ number: number;
5
+ name: string;
6
+ };
7
+ branch: string;
8
+ activePrd: string;
9
+ lastSession: string;
10
+ milestoneTable: Array<{
11
+ number: number;
12
+ name: string;
13
+ status: string;
14
+ }>;
15
+ nextActions: string[];
16
+ }
17
+ export interface SessionMemoryInput {
18
+ date: string;
19
+ developer: string;
20
+ workingOn: string;
21
+ status: string;
22
+ next: string;
23
+ blockers: string;
24
+ }
25
+ export declare function writeStateFile(projectDir: string, info: StateWriteInput): Promise<void>;
26
+ export declare function updateRoadmapMilestone(projectDir: string, milestoneNumber: number, status: string): Promise<void>;
27
+ export declare function writeSessionMemory(projectDir: string, branch: string, data: SessionMemoryInput): Promise<void>;
28
+ export interface CommitOptions {
29
+ projectDir: string;
30
+ milestoneNumber: number;
31
+ milestoneName: string;
32
+ filesToStage: string[];
33
+ push?: boolean;
34
+ branch?: string;
35
+ }
36
+ export interface CommitResult {
37
+ commitSha: string;
38
+ pushed: boolean;
39
+ }
40
+ export interface MilestoneUpdateOptions {
41
+ projectDir: string;
42
+ project: string;
43
+ milestoneNumber: number;
44
+ milestoneName: string;
45
+ branch: string;
46
+ activePrd: string;
47
+ developer: string;
48
+ nextMilestone?: {
49
+ number: number;
50
+ name: string;
51
+ };
52
+ milestoneTable: Array<{
53
+ number: number;
54
+ name: string;
55
+ status: string;
56
+ }>;
57
+ }
58
+ export declare function commitMilestoneWork(options: CommitOptions): CommitResult;
59
+ export declare function isLastMilestone(projectDir: string, milestoneNumber: number): Promise<boolean>;
60
+ export declare function updateMilestoneProgress(options: MilestoneUpdateOptions): Promise<void>;