@s_s/harmonia 1.2.0 → 1.3.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 (54) hide show
  1. package/build/core/dispatch.d.ts +14 -11
  2. package/build/core/dispatch.js +37 -32
  3. package/build/core/dispatch.js.map +1 -1
  4. package/build/core/docs.d.ts +15 -11
  5. package/build/core/docs.js +23 -18
  6. package/build/core/docs.js.map +1 -1
  7. package/build/core/issues.d.ts +37 -0
  8. package/build/core/issues.js +100 -0
  9. package/build/core/issues.js.map +1 -0
  10. package/build/core/registry.d.ts +34 -0
  11. package/build/core/registry.js +59 -0
  12. package/build/core/registry.js.map +1 -1
  13. package/build/core/reviews.d.ts +9 -8
  14. package/build/core/reviews.js +21 -19
  15. package/build/core/reviews.js.map +1 -1
  16. package/build/core/state.d.ts +22 -14
  17. package/build/core/state.js +52 -30
  18. package/build/core/state.js.map +1 -1
  19. package/build/core/steps.d.ts +8 -7
  20. package/build/core/steps.js +20 -18
  21. package/build/core/steps.js.map +1 -1
  22. package/build/core/types.d.ts +31 -2
  23. package/build/index.js +4 -0
  24. package/build/index.js.map +1 -1
  25. package/build/setup/templates.js +70 -1
  26. package/build/setup/templates.js.map +1 -1
  27. package/build/tools/approve-doc.js +9 -31
  28. package/build/tools/approve-doc.js.map +1 -1
  29. package/build/tools/dispatch-role.js +8 -19
  30. package/build/tools/dispatch-role.js.map +1 -1
  31. package/build/tools/doc-tools.js +98 -62
  32. package/build/tools/doc-tools.js.map +1 -1
  33. package/build/tools/get-project-status.js +69 -24
  34. package/build/tools/get-project-status.js.map +1 -1
  35. package/build/tools/issue-tools.d.ts +10 -0
  36. package/build/tools/issue-tools.js +169 -0
  37. package/build/tools/issue-tools.js.map +1 -0
  38. package/build/tools/iteration-start.js +9 -4
  39. package/build/tools/iteration-start.js.map +1 -1
  40. package/build/tools/patch-start.d.ts +14 -0
  41. package/build/tools/patch-start.js +97 -0
  42. package/build/tools/patch-start.js.map +1 -0
  43. package/build/tools/project-init.js +6 -8
  44. package/build/tools/project-init.js.map +1 -1
  45. package/build/tools/report-dispatch.js +21 -32
  46. package/build/tools/report-dispatch.js.map +1 -1
  47. package/build/tools/set-scale.js +7 -19
  48. package/build/tools/set-scale.js.map +1 -1
  49. package/build/tools/update-phase.js +11 -22
  50. package/build/tools/update-phase.js.map +1 -1
  51. package/build/tools/utils.d.ts +34 -0
  52. package/build/tools/utils.js +61 -0
  53. package/build/tools/utils.js.map +1 -0
  54. package/package.json +1 -1
@@ -13,6 +13,7 @@
13
13
  * ├── overrides.json # global overrides (optional)
14
14
  * ├── my-app/
15
15
  * │ ├── overrides.json # project-level overrides (optional)
16
+ * │ ├── issues.json # project-level issue tracking (optional)
16
17
  * │ ├── iter-1/
17
18
  * │ │ ├── state.json
18
19
  * │ │ ├── docs/
@@ -20,6 +21,10 @@
20
21
  * │ │ └── ...
21
22
  * │ ├── iter-2/
22
23
  * │ │ └── ...
24
+ * │ ├── patch-1/
25
+ * │ │ ├── state.json # type: "patch", clarify/design skipped
26
+ * │ │ ├── docs/
27
+ * │ │ └── ...
23
28
  * └── another-project/
24
29
  * └── ...
25
30
  */
@@ -84,6 +89,9 @@ export async function registerProject(projectName, projectDir, workflow) {
84
89
  createdAt: new Date().toISOString(),
85
90
  currentIteration: 0,
86
91
  totalIterations: 0,
92
+ currentPatch: 0,
93
+ totalPatches: 0,
94
+ activeContext: '',
87
95
  };
88
96
  // Create project data directory under global dir
89
97
  const dataDir = getProjectDataDir(projectName);
@@ -143,10 +151,61 @@ export async function startIteration(projectName) {
143
151
  const newIteration = entry.totalIterations + 1;
144
152
  entry.currentIteration = newIteration;
145
153
  entry.totalIterations = newIteration;
154
+ entry.activeContext = `iter-${newIteration}`;
146
155
  // Create iteration directory with docs subdirectory
147
156
  const iterDir = getIterationDir(projectName, newIteration);
148
157
  await mkdir(join(iterDir, 'docs'), { recursive: true });
149
158
  await writeRegistry(registry);
150
159
  return newIteration;
151
160
  }
161
+ /**
162
+ * Get the patch directory for a specific project patch.
163
+ * Pure path concatenation — does NOT check if the directory exists.
164
+ */
165
+ export function getPatchDir(projectName, patch) {
166
+ return join(getProjectDataDir(projectName), `patch-${patch}`);
167
+ }
168
+ /**
169
+ * Start a new patch for a project.
170
+ * Creates the patch directory (with docs/ subdirectory) and updates the registry.
171
+ *
172
+ * @returns The new patch number
173
+ */
174
+ export async function startPatch(projectName) {
175
+ const registry = await readRegistry();
176
+ const entry = registry.projects[projectName];
177
+ if (!entry) {
178
+ throw new Error(`Project "${projectName}" not found in registry.`);
179
+ }
180
+ const newPatch = entry.totalPatches + 1;
181
+ entry.currentPatch = newPatch;
182
+ entry.totalPatches = newPatch;
183
+ entry.activeContext = `patch-${newPatch}`;
184
+ // Create patch directory with docs subdirectory
185
+ const patchDir = getPatchDir(projectName, newPatch);
186
+ await mkdir(join(patchDir, 'docs'), { recursive: true });
187
+ await writeRegistry(registry);
188
+ return newPatch;
189
+ }
190
+ /**
191
+ * Resolve the active context directory for a project.
192
+ * Parses activeContext string (e.g. "iter-1", "patch-2") into an absolute path.
193
+ *
194
+ * @returns { dir: string, type: 'iteration' | 'patch', number: number } or null if no active context
195
+ */
196
+ export function resolveContextDir(projectName, activeContext) {
197
+ if (!activeContext)
198
+ return null;
199
+ const iterMatch = activeContext.match(/^iter-(\d+)$/);
200
+ if (iterMatch) {
201
+ const num = parseInt(iterMatch[1], 10);
202
+ return { dir: getIterationDir(projectName, num), type: 'iteration', number: num };
203
+ }
204
+ const patchMatch = activeContext.match(/^patch-(\d+)$/);
205
+ if (patchMatch) {
206
+ const num = parseInt(patchMatch[1], 10);
207
+ return { dir: getPatchDir(projectName, num), type: 'patch', number: num };
208
+ }
209
+ return null;
210
+ }
152
211
  //# sourceMappingURL=registry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"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"}
@@ -1,26 +1,27 @@
1
1
  /**
2
- * Document review state management — <data_dir>/<project_name>/iter-<n>/reviews.json
2
+ * Document review state management — <context_dir>/reviews.json
3
3
  *
4
4
  * Tracks which documents are pending review, approved, or rejected.
5
+ * All public functions accept an optional contextDir parameter.
5
6
  */
6
7
  import type { DocReviewState } from './types.js';
7
8
  /**
8
- * Read the reviews state for a project iteration.
9
+ * Read the reviews state for a project context.
9
10
  */
10
- export declare function readReviews(projectName: string, iteration: number): Promise<Record<string, DocReviewState>>;
11
+ export declare function readReviews(projectName: string, iteration: number, contextDir?: string): Promise<Record<string, DocReviewState>>;
11
12
  /**
12
13
  * Submit a document for review. Sets status to "pending".
13
14
  */
14
- export declare function submitForReview(projectName: string, iteration: number, docId: string): Promise<DocReviewState>;
15
+ export declare function submitForReview(projectName: string, iteration: number, docId: string, contextDir?: string): Promise<DocReviewState>;
15
16
  /**
16
17
  * Approve or reject a document review.
17
18
  */
18
- export declare function resolveReview(projectName: string, iteration: number, docId: string, status: 'approved' | 'rejected', comment?: string): Promise<DocReviewState>;
19
+ export declare function resolveReview(projectName: string, iteration: number, docId: string, status: 'approved' | 'rejected', comment?: string, contextDir?: string): Promise<DocReviewState>;
19
20
  /**
20
21
  * Get the review state for a specific document.
21
22
  */
22
- export declare function getDocReview(projectName: string, iteration: number, docId: string): Promise<DocReviewState | null>;
23
+ export declare function getDocReview(projectName: string, iteration: number, docId: string, contextDir?: string): Promise<DocReviewState | null>;
23
24
  /**
24
- * Get all pending reviews for a project iteration.
25
+ * Get all pending reviews for a project context.
25
26
  */
26
- export declare function getPendingReviews(projectName: string, iteration: number): Promise<DocReviewState[]>;
27
+ export declare function getPendingReviews(projectName: string, iteration: number, contextDir?: string): Promise<DocReviewState[]>;
@@ -1,21 +1,23 @@
1
1
  /**
2
- * Document review state management — <data_dir>/<project_name>/iter-<n>/reviews.json
2
+ * Document review state management — <context_dir>/reviews.json
3
3
  *
4
4
  * Tracks which documents are pending review, approved, or rejected.
5
+ * All public functions accept an optional contextDir parameter.
5
6
  */
6
7
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
7
8
  import { join, dirname } from 'node:path';
8
9
  import { getIterationDir } from './registry.js';
9
10
  const REVIEWS_FILE = 'reviews.json';
10
- function reviewsPath(projectName, iteration) {
11
- return join(getIterationDir(projectName, iteration), REVIEWS_FILE);
11
+ function reviewsPath(projectName, iteration, contextDir) {
12
+ const base = contextDir ?? getIterationDir(projectName, iteration);
13
+ return join(base, REVIEWS_FILE);
12
14
  }
13
15
  /**
14
- * Read the reviews state for a project iteration.
16
+ * Read the reviews state for a project context.
15
17
  */
16
- export async function readReviews(projectName, iteration) {
18
+ export async function readReviews(projectName, iteration, contextDir) {
17
19
  try {
18
- const content = await readFile(reviewsPath(projectName, iteration), 'utf-8');
20
+ const content = await readFile(reviewsPath(projectName, iteration, contextDir), 'utf-8');
19
21
  const data = JSON.parse(content);
20
22
  return data.docs ?? {};
21
23
  }
@@ -26,8 +28,8 @@ export async function readReviews(projectName, iteration) {
26
28
  /**
27
29
  * Write reviews state to disk.
28
30
  */
29
- async function writeReviews(projectName, iteration, docs) {
30
- const filePath = reviewsPath(projectName, iteration);
31
+ async function writeReviews(projectName, iteration, docs, contextDir) {
32
+ const filePath = reviewsPath(projectName, iteration, contextDir);
31
33
  await mkdir(dirname(filePath), { recursive: true });
32
34
  const data = { docs };
33
35
  await writeFile(filePath, JSON.stringify(data, null, 2) + '\n', 'utf-8');
@@ -35,22 +37,22 @@ async function writeReviews(projectName, iteration, docs) {
35
37
  /**
36
38
  * Submit a document for review. Sets status to "pending".
37
39
  */
38
- export async function submitForReview(projectName, iteration, docId) {
39
- const reviews = await readReviews(projectName, iteration);
40
+ export async function submitForReview(projectName, iteration, docId, contextDir) {
41
+ const reviews = await readReviews(projectName, iteration, contextDir);
40
42
  const state = {
41
43
  docId,
42
44
  status: 'pending',
43
45
  submittedAt: new Date().toISOString(),
44
46
  };
45
47
  reviews[docId] = state;
46
- await writeReviews(projectName, iteration, reviews);
48
+ await writeReviews(projectName, iteration, reviews, contextDir);
47
49
  return state;
48
50
  }
49
51
  /**
50
52
  * Approve or reject a document review.
51
53
  */
52
- export async function resolveReview(projectName, iteration, docId, status, comment) {
53
- const reviews = await readReviews(projectName, iteration);
54
+ export async function resolveReview(projectName, iteration, docId, status, comment, contextDir) {
55
+ const reviews = await readReviews(projectName, iteration, contextDir);
54
56
  const existing = reviews[docId];
55
57
  if (!existing) {
56
58
  throw new Error(`No review pending for document "${docId}". Submit it for review first.`);
@@ -63,21 +65,21 @@ export async function resolveReview(projectName, iteration, docId, status, comme
63
65
  if (comment) {
64
66
  existing.comment = comment;
65
67
  }
66
- await writeReviews(projectName, iteration, reviews);
68
+ await writeReviews(projectName, iteration, reviews, contextDir);
67
69
  return existing;
68
70
  }
69
71
  /**
70
72
  * Get the review state for a specific document.
71
73
  */
72
- export async function getDocReview(projectName, iteration, docId) {
73
- const reviews = await readReviews(projectName, iteration);
74
+ export async function getDocReview(projectName, iteration, docId, contextDir) {
75
+ const reviews = await readReviews(projectName, iteration, contextDir);
74
76
  return reviews[docId] ?? null;
75
77
  }
76
78
  /**
77
- * Get all pending reviews for a project iteration.
79
+ * Get all pending reviews for a project context.
78
80
  */
79
- export async function getPendingReviews(projectName, iteration) {
80
- const reviews = await readReviews(projectName, iteration);
81
+ export async function getPendingReviews(projectName, iteration, contextDir) {
82
+ const reviews = await readReviews(projectName, iteration, contextDir);
81
83
  return Object.values(reviews).filter((r) => r.status === 'pending');
82
84
  }
83
85
  //# sourceMappingURL=reviews.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reviews.js","sourceRoot":"","sources":["../../src/core/reviews.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reviews.js","sourceRoot":"","sources":["../../src/core/reviews.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,YAAY,GAAG,cAAc,CAAC;AAMpC,SAAS,WAAW,CAAC,WAAmB,EAAE,SAAiB,EAAE,UAAmB;IAC5E,MAAM,IAAI,GAAG,UAAU,IAAI,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnE,OAAO,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC7B,WAAmB,EACnB,SAAiB,EACjB,UAAmB;IAEnB,IAAI,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QACzF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;QAChD,OAAO,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CACvB,WAAmB,EACnB,SAAiB,EACjB,IAAoC,EACpC,UAAmB;IAEnB,MAAM,QAAQ,GAAG,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAgB,EAAE,IAAI,EAAE,CAAC;IACnC,MAAM,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACjC,WAAmB,EACnB,SAAiB,EACjB,KAAa,EACb,UAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACtE,MAAM,KAAK,GAAmB;QAC1B,KAAK;QACL,MAAM,EAAE,SAAS;QACjB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACxC,CAAC;IACF,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;IACvB,MAAM,YAAY,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChE,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAC/B,WAAmB,EACnB,SAAiB,EACjB,KAAa,EACb,MAA+B,EAC/B,OAAgB,EAChB,UAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAEhC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,mCAAmC,KAAK,gCAAgC,CAAC,CAAC;IAC9F,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,uBAAuB,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACjF,CAAC;IAED,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,OAAO,EAAE,CAAC;QACV,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED,MAAM,YAAY,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;IAChE,OAAO,QAAQ,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAC9B,WAAmB,EACnB,SAAiB,EACjB,KAAa,EACb,UAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACtE,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACnC,WAAmB,EACnB,SAAiB,EACjB,UAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AACxE,CAAC"}
@@ -1,7 +1,11 @@
1
1
  /**
2
- * Project state management — manages <data_dir>/<project_name>/iter-<n>/state.json
2
+ * Project state management — manages state.json within iteration/patch directories.
3
+ *
4
+ * All functions accept an optional `contextDir` parameter. When provided, it is used
5
+ * directly as the directory containing state.json. When omitted, the directory is
6
+ * resolved from `getIterationDir(projectName, iteration)` for backward compatibility.
3
7
  */
4
- import type { PhaseStatus, ProjectScale, ProjectState, LoadedWorkflow } from './types.js';
8
+ import type { ContextType, PhaseStatus, ProjectScale, ProjectState, LoadedWorkflow } from './types.js';
5
9
  /**
6
10
  * Error thrown when a tool requires scale but it hasn't been set yet.
7
11
  */
@@ -9,28 +13,32 @@ export declare class ScaleNotSetError extends Error {
9
13
  constructor(projectName: string);
10
14
  }
11
15
  /**
12
- * Initialize a new project state file for a specific iteration.
13
- * Note: directory creation is handled by registry.startIteration().
14
- * This only writes the state.json.
16
+ * Initialize a new project state file.
17
+ *
18
+ * For iteration mode (default): all phases start normally (first = in_progress, rest = pending).
19
+ * For patch mode: clarify/design are marked as "skipped", first non-skipped phase is in_progress,
20
+ * scale is set to "small" automatically.
21
+ *
22
+ * @param contextDir - Optional explicit directory. If omitted, uses getIterationDir().
15
23
  */
16
- export declare function initProjectState(projectName: string, projectDir: string, workflow: LoadedWorkflow, iteration: number): Promise<ProjectState>;
24
+ export declare function initProjectState(projectName: string, projectDir: string, workflow: LoadedWorkflow, iteration: number, type?: ContextType, contextDir?: string): Promise<ProjectState>;
17
25
  /**
18
- * Read the current project state for a specific iteration.
26
+ * Read the current project state.
19
27
  */
20
- export declare function readState(projectName: string, iteration: number): Promise<ProjectState>;
28
+ export declare function readState(projectName: string, iteration: number, contextDir?: string): Promise<ProjectState>;
21
29
  /**
22
- * Write project state to disk for a specific iteration.
30
+ * Write project state to disk.
23
31
  */
24
- export declare function writeState(projectName: string, iteration: number, state: ProjectState): Promise<void>;
32
+ export declare function writeState(projectName: string, iteration: number, state: ProjectState, contextDir?: string): Promise<void>;
25
33
  /**
26
34
  * Update a specific phase's status.
27
35
  */
28
- export declare function updatePhaseStatus(projectName: string, iteration: number, phaseId: string, status: PhaseStatus, blockedReason?: string): Promise<ProjectState>;
36
+ export declare function updatePhaseStatus(projectName: string, iteration: number, phaseId: string, status: PhaseStatus, blockedReason?: string, contextDir?: string): Promise<ProjectState>;
29
37
  /**
30
- * Check if a project state file exists for a specific iteration.
38
+ * Check if a project state file exists.
31
39
  */
32
- export declare function projectStateExists(projectName: string, iteration: number): Promise<boolean>;
40
+ export declare function projectStateExists(projectName: string, iteration: number, contextDir?: string): Promise<boolean>;
33
41
  /**
34
42
  * Set the project scale. Scale is immutable once set.
35
43
  */
36
- export declare function setScale(projectName: string, iteration: number, scale: ProjectScale): Promise<ProjectState>;
44
+ export declare function setScale(projectName: string, iteration: number, scale: ProjectScale, contextDir?: string): Promise<ProjectState>;
@@ -1,5 +1,9 @@
1
1
  /**
2
- * Project state management — manages <data_dir>/<project_name>/iter-<n>/state.json
2
+ * Project state management — manages state.json within iteration/patch directories.
3
+ *
4
+ * All functions accept an optional `contextDir` parameter. When provided, it is used
5
+ * directly as the directory containing state.json. When omitted, the directory is
6
+ * resolved from `getIterationDir(projectName, iteration)` for backward compatibility.
3
7
  */
4
8
  import { mkdir, readFile, writeFile } from 'node:fs/promises';
5
9
  import { join, dirname } from 'node:path';
@@ -14,48 +18,65 @@ export class ScaleNotSetError extends Error {
14
18
  }
15
19
  }
16
20
  const STATE_FILE = 'state.json';
17
- function statePath(projectName, iteration) {
18
- return join(getIterationDir(projectName, iteration), STATE_FILE);
21
+ function resolveDir(projectName, iteration, contextDir) {
22
+ return contextDir ?? getIterationDir(projectName, iteration);
19
23
  }
24
+ function statePath(projectName, iteration, contextDir) {
25
+ return join(resolveDir(projectName, iteration, contextDir), STATE_FILE);
26
+ }
27
+ /** Phases to skip in patch mode (clarify and design) */
28
+ const PATCH_SKIP_PHASES = new Set(['clarify', 'design']);
20
29
  /**
21
- * Initialize a new project state file for a specific iteration.
22
- * Note: directory creation is handled by registry.startIteration().
23
- * This only writes the state.json.
30
+ * Initialize a new project state file.
31
+ *
32
+ * For iteration mode (default): all phases start normally (first = in_progress, rest = pending).
33
+ * For patch mode: clarify/design are marked as "skipped", first non-skipped phase is in_progress,
34
+ * scale is set to "small" automatically.
35
+ *
36
+ * @param contextDir - Optional explicit directory. If omitted, uses getIterationDir().
24
37
  */
25
- export async function initProjectState(projectName, projectDir, workflow, iteration) {
38
+ export async function initProjectState(projectName, projectDir, workflow, iteration, type = 'iteration', contextDir) {
26
39
  const now = new Date().toISOString();
27
40
  const phases = workflow.definition.phases;
28
- const firstPhaseId = phases[0]?.id ?? '';
41
+ const isPatch = type === 'patch';
42
+ // Find the first non-skipped phase
43
+ const firstActiveIndex = isPatch ? phases.findIndex((p) => !PATCH_SKIP_PHASES.has(p.id)) : 0;
44
+ const firstPhaseId = phases[firstActiveIndex]?.id ?? phases[0]?.id ?? '';
29
45
  const state = {
30
46
  projectName,
31
47
  projectDir,
32
48
  workflow: workflow.definition.name,
49
+ type,
33
50
  iteration,
34
- scale: null,
51
+ scale: isPatch ? 'small' : null,
35
52
  currentPhase: firstPhaseId,
36
- phases: phases.map((p, i) => ({
37
- id: p.id,
38
- status: i === 0 ? 'in_progress' : 'pending',
39
- ...(i === 0 ? { startedAt: now } : {}),
40
- })),
53
+ phases: phases.map((p, i) => {
54
+ if (isPatch && PATCH_SKIP_PHASES.has(p.id)) {
55
+ return { id: p.id, status: 'skipped' };
56
+ }
57
+ if (i === firstActiveIndex) {
58
+ return { id: p.id, status: 'in_progress', startedAt: now };
59
+ }
60
+ return { id: p.id, status: 'pending' };
61
+ }),
41
62
  createdAt: now,
42
63
  updatedAt: now,
43
64
  };
44
- await writeState(projectName, iteration, state);
65
+ await writeState(projectName, iteration, state, contextDir);
45
66
  return state;
46
67
  }
47
68
  /**
48
- * Read the current project state for a specific iteration.
69
+ * Read the current project state.
49
70
  */
50
- export async function readState(projectName, iteration) {
51
- const content = await readFile(statePath(projectName, iteration), 'utf-8');
71
+ export async function readState(projectName, iteration, contextDir) {
72
+ const content = await readFile(statePath(projectName, iteration, contextDir), 'utf-8');
52
73
  return JSON.parse(content);
53
74
  }
54
75
  /**
55
- * Write project state to disk for a specific iteration.
76
+ * Write project state to disk.
56
77
  */
57
- export async function writeState(projectName, iteration, state) {
58
- const filePath = statePath(projectName, iteration);
78
+ export async function writeState(projectName, iteration, state, contextDir) {
79
+ const filePath = statePath(projectName, iteration, contextDir);
59
80
  await mkdir(dirname(filePath), { recursive: true });
60
81
  state.updatedAt = new Date().toISOString();
61
82
  await writeFile(filePath, JSON.stringify(state, null, 2) + '\n', 'utf-8');
@@ -63,8 +84,8 @@ export async function writeState(projectName, iteration, state) {
63
84
  /**
64
85
  * Update a specific phase's status.
65
86
  */
66
- export async function updatePhaseStatus(projectName, iteration, phaseId, status, blockedReason) {
67
- const state = await readState(projectName, iteration);
87
+ export async function updatePhaseStatus(projectName, iteration, phaseId, status, blockedReason, contextDir) {
88
+ const state = await readState(projectName, iteration, contextDir);
68
89
  const phase = state.phases.find((p) => p.id === phaseId);
69
90
  if (!phase) {
70
91
  throw new Error(`Phase "${phaseId}" not found in project state`);
@@ -86,6 +107,7 @@ export async function updatePhaseStatus(projectName, iteration, phaseId, status,
86
107
  state.currentPhase = phaseId;
87
108
  }
88
109
  // If completing a phase, auto-advance currentPhase to the next pending one
110
+ // (skip over phases that are already "skipped")
89
111
  if (status === 'completed') {
90
112
  const idx = state.phases.findIndex((p) => p.id === phaseId);
91
113
  const next = state.phases.find((p, i) => i > idx && p.status === 'pending');
@@ -95,15 +117,15 @@ export async function updatePhaseStatus(projectName, iteration, phaseId, status,
95
117
  state.currentPhase = next.id;
96
118
  }
97
119
  }
98
- await writeState(projectName, iteration, state);
120
+ await writeState(projectName, iteration, state, contextDir);
99
121
  return state;
100
122
  }
101
123
  /**
102
- * Check if a project state file exists for a specific iteration.
124
+ * Check if a project state file exists.
103
125
  */
104
- export async function projectStateExists(projectName, iteration) {
126
+ export async function projectStateExists(projectName, iteration, contextDir) {
105
127
  try {
106
- await readFile(statePath(projectName, iteration), 'utf-8');
128
+ await readFile(statePath(projectName, iteration, contextDir), 'utf-8');
107
129
  return true;
108
130
  }
109
131
  catch {
@@ -113,13 +135,13 @@ export async function projectStateExists(projectName, iteration) {
113
135
  /**
114
136
  * Set the project scale. Scale is immutable once set.
115
137
  */
116
- export async function setScale(projectName, iteration, scale) {
117
- const state = await readState(projectName, iteration);
138
+ export async function setScale(projectName, iteration, scale, contextDir) {
139
+ const state = await readState(projectName, iteration, contextDir);
118
140
  if (state.scale !== null) {
119
141
  throw new Error(`Scale 已设定为 "${state.scale}",不可更改。如需调整规模,请重新评估 PRD。`);
120
142
  }
121
143
  state.scale = scale;
122
- await writeState(projectName, iteration, state);
144
+ await writeState(projectName, iteration, state, contextDir);
123
145
  return state;
124
146
  }
125
147
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,19 @@
1
1
  /**
2
- * Step state management — manages <data_dir>/<project_name>/iter-<n>/steps.json
2
+ * Step state management — manages <context_dir>/steps.json
3
3
  *
4
4
  * Tracks which sequential steps have been completed for each document,
5
5
  * supporting the P3 Sequential mode feature.
6
+ * All public functions accept an optional contextDir parameter.
6
7
  */
7
8
  import type { DocStepState } from './types.js';
8
9
  /**
9
- * Read the steps state for a project iteration.
10
+ * Read the steps state for a project context.
10
11
  */
11
- export declare function readSteps(projectName: string, iteration: number): Promise<Record<string, DocStepState>>;
12
+ export declare function readSteps(projectName: string, iteration: number, contextDir?: string): Promise<Record<string, DocStepState>>;
12
13
  /**
13
14
  * Get the step state for a specific document.
14
15
  */
15
- export declare function getDocStepState(projectName: string, iteration: number, docId: string): Promise<DocStepState | null>;
16
+ export declare function getDocStepState(projectName: string, iteration: number, docId: string, contextDir?: string): Promise<DocStepState | null>;
16
17
  /**
17
18
  * Get the set of completed step IDs for a document.
18
19
  */
@@ -23,12 +24,12 @@ export declare function getCompletedStepIds(state: DocStepState | null): Set<str
23
24
  *
24
25
  * @returns The updated DocStepState
25
26
  */
26
- export declare function recordStepCompletion(projectName: string, iteration: number, docId: string, stepId: string, artifactPath: string, allStepIds: string[]): Promise<DocStepState>;
27
+ export declare function recordStepCompletion(projectName: string, iteration: number, docId: string, stepId: string, artifactPath: string, allStepIds: string[], contextDir?: string): Promise<DocStepState>;
27
28
  /**
28
29
  * Mark a document as finalized (all steps completed + final doc written).
29
30
  */
30
- export declare function markFinalized(projectName: string, iteration: number, docId: string): Promise<DocStepState>;
31
+ export declare function markFinalized(projectName: string, iteration: number, docId: string, contextDir?: string): Promise<DocStepState>;
31
32
  /**
32
33
  * Check if a document's sequential process is finalized.
33
34
  */
34
- export declare function isDocFinalized(projectName: string, iteration: number, docId: string): Promise<boolean>;
35
+ export declare function isDocFinalized(projectName: string, iteration: number, docId: string, contextDir?: string): Promise<boolean>;
@@ -1,22 +1,24 @@
1
1
  /**
2
- * Step state management — manages <data_dir>/<project_name>/iter-<n>/steps.json
2
+ * Step state management — manages <context_dir>/steps.json
3
3
  *
4
4
  * Tracks which sequential steps have been completed for each document,
5
5
  * supporting the P3 Sequential mode feature.
6
+ * All public functions accept an optional contextDir parameter.
6
7
  */
7
8
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
8
9
  import { join, dirname } from 'node:path';
9
10
  import { getIterationDir } from './registry.js';
10
11
  const STEPS_FILE = 'steps.json';
11
- function stepsPath(projectName, iteration) {
12
- return join(getIterationDir(projectName, iteration), STEPS_FILE);
12
+ function stepsPath(projectName, iteration, contextDir) {
13
+ const base = contextDir ?? getIterationDir(projectName, iteration);
14
+ return join(base, STEPS_FILE);
13
15
  }
14
16
  /**
15
- * Read the steps state for a project iteration.
17
+ * Read the steps state for a project context.
16
18
  */
17
- export async function readSteps(projectName, iteration) {
19
+ export async function readSteps(projectName, iteration, contextDir) {
18
20
  try {
19
- const content = await readFile(stepsPath(projectName, iteration), 'utf-8');
21
+ const content = await readFile(stepsPath(projectName, iteration, contextDir), 'utf-8');
20
22
  const data = JSON.parse(content);
21
23
  return data.docs ?? {};
22
24
  }
@@ -27,8 +29,8 @@ export async function readSteps(projectName, iteration) {
27
29
  /**
28
30
  * Write steps state to disk.
29
31
  */
30
- async function writeSteps(projectName, iteration, docs) {
31
- const filePath = stepsPath(projectName, iteration);
32
+ async function writeSteps(projectName, iteration, docs, contextDir) {
33
+ const filePath = stepsPath(projectName, iteration, contextDir);
32
34
  await mkdir(dirname(filePath), { recursive: true });
33
35
  const data = { docs };
34
36
  await writeFile(filePath, JSON.stringify(data, null, 2) + '\n', 'utf-8');
@@ -36,8 +38,8 @@ async function writeSteps(projectName, iteration, docs) {
36
38
  /**
37
39
  * Get the step state for a specific document.
38
40
  */
39
- export async function getDocStepState(projectName, iteration, docId) {
40
- const docs = await readSteps(projectName, iteration);
41
+ export async function getDocStepState(projectName, iteration, docId, contextDir) {
42
+ const docs = await readSteps(projectName, iteration, contextDir);
41
43
  return docs[docId] ?? null;
42
44
  }
43
45
  /**
@@ -54,8 +56,8 @@ export function getCompletedStepIds(state) {
54
56
  *
55
57
  * @returns The updated DocStepState
56
58
  */
57
- export async function recordStepCompletion(projectName, iteration, docId, stepId, artifactPath, allStepIds) {
58
- const docs = await readSteps(projectName, iteration);
59
+ export async function recordStepCompletion(projectName, iteration, docId, stepId, artifactPath, allStepIds, contextDir) {
60
+ const docs = await readSteps(projectName, iteration, contextDir);
59
61
  let state = docs[docId];
60
62
  if (!state) {
61
63
  state = {
@@ -86,28 +88,28 @@ export async function recordStepCompletion(projectName, iteration, docId, stepId
86
88
  };
87
89
  state.completedSteps.push(record);
88
90
  docs[docId] = state;
89
- await writeSteps(projectName, iteration, docs);
91
+ await writeSteps(projectName, iteration, docs, contextDir);
90
92
  return state;
91
93
  }
92
94
  /**
93
95
  * Mark a document as finalized (all steps completed + final doc written).
94
96
  */
95
- export async function markFinalized(projectName, iteration, docId) {
96
- const docs = await readSteps(projectName, iteration);
97
+ export async function markFinalized(projectName, iteration, docId, contextDir) {
98
+ const docs = await readSteps(projectName, iteration, contextDir);
97
99
  const state = docs[docId];
98
100
  if (!state) {
99
101
  throw new Error(`No step state found for document "${docId}"`);
100
102
  }
101
103
  state.finalized = true;
102
104
  state.finalizedAt = new Date().toISOString();
103
- await writeSteps(projectName, iteration, docs);
105
+ await writeSteps(projectName, iteration, docs, contextDir);
104
106
  return state;
105
107
  }
106
108
  /**
107
109
  * Check if a document's sequential process is finalized.
108
110
  */
109
- export async function isDocFinalized(projectName, iteration, docId) {
110
- const state = await getDocStepState(projectName, iteration, docId);
111
+ export async function isDocFinalized(projectName, iteration, docId, contextDir) {
112
+ const state = await getDocStepState(projectName, iteration, docId, contextDir);
111
113
  return state?.finalized ?? false;
112
114
  }
113
115
  //# sourceMappingURL=steps.js.map