@s_s/harmonia 1.0.0 → 1.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 (114) hide show
  1. package/README.md +396 -2
  2. package/build/cli/setup.d.ts +21 -0
  3. package/build/cli/setup.js +72 -0
  4. package/build/cli/setup.js.map +1 -0
  5. package/build/core/dispatch.d.ts +10 -0
  6. package/build/core/dispatch.js +21 -0
  7. package/build/core/dispatch.js.map +1 -1
  8. package/build/core/docs.d.ts +13 -0
  9. package/build/core/docs.js +32 -0
  10. package/build/core/docs.js.map +1 -1
  11. package/build/core/registry.d.ts +1 -1
  12. package/build/core/registry.js +5 -16
  13. package/build/core/registry.js.map +1 -1
  14. package/build/core/schema.d.ts +38 -0
  15. package/build/core/schema.js +187 -0
  16. package/build/core/schema.js.map +1 -0
  17. package/build/core/state.d.ts +11 -1
  18. package/build/core/state.js +23 -2
  19. package/build/core/state.js.map +1 -1
  20. package/build/core/steps.d.ts +34 -0
  21. package/build/core/steps.js +113 -0
  22. package/build/core/steps.js.map +1 -0
  23. package/build/core/types.d.ts +81 -4
  24. package/build/core/workflow.d.ts +26 -6
  25. package/build/core/workflow.js +88 -11
  26. package/build/core/workflow.js.map +1 -1
  27. package/build/hooks/claude-code.d.ts +20 -0
  28. package/build/hooks/claude-code.js +218 -0
  29. package/build/hooks/claude-code.js.map +1 -0
  30. package/build/hooks/content.d.ts +43 -0
  31. package/build/hooks/content.js +109 -0
  32. package/build/hooks/content.js.map +1 -0
  33. package/build/hooks/install.d.ts +40 -0
  34. package/build/hooks/install.js +63 -0
  35. package/build/hooks/install.js.map +1 -0
  36. package/build/hooks/openclaw.d.ts +24 -0
  37. package/build/hooks/openclaw.js +219 -0
  38. package/build/hooks/openclaw.js.map +1 -0
  39. package/build/hooks/opencode.d.ts +29 -0
  40. package/build/hooks/opencode.js +226 -0
  41. package/build/hooks/opencode.js.map +1 -0
  42. package/build/index.d.ts +4 -7
  43. package/build/index.js +80 -42
  44. package/build/index.js.map +1 -1
  45. package/build/setup/inject.d.ts +13 -17
  46. package/build/setup/inject.js +34 -92
  47. package/build/setup/inject.js.map +1 -1
  48. package/build/setup/templates.d.ts +12 -16
  49. package/build/setup/templates.js +52 -69
  50. package/build/setup/templates.js.map +1 -1
  51. package/build/tools/approve-doc.d.ts +1 -1
  52. package/build/tools/approve-doc.js +4 -4
  53. package/build/tools/approve-doc.js.map +1 -1
  54. package/build/tools/dispatch-role.d.ts +2 -2
  55. package/build/tools/dispatch-role.js +41 -11
  56. package/build/tools/dispatch-role.js.map +1 -1
  57. package/build/tools/doc-tools.d.ts +11 -3
  58. package/build/tools/doc-tools.js +257 -13
  59. package/build/tools/doc-tools.js.map +1 -1
  60. package/build/tools/get-project-status.d.ts +4 -2
  61. package/build/tools/get-project-status.js +165 -50
  62. package/build/tools/get-project-status.js.map +1 -1
  63. package/build/tools/get-role-prompt.d.ts +2 -2
  64. package/build/tools/get-role-prompt.js +4 -4
  65. package/build/tools/get-role-prompt.js.map +1 -1
  66. package/build/tools/override-tools.d.ts +1 -1
  67. package/build/tools/override-tools.js +4 -4
  68. package/build/tools/override-tools.js.map +1 -1
  69. package/build/tools/project-init.d.ts +5 -1
  70. package/build/tools/project-init.js +92 -32
  71. package/build/tools/project-init.js.map +1 -1
  72. package/build/tools/report-dispatch.d.ts +6 -3
  73. package/build/tools/report-dispatch.js +45 -8
  74. package/build/tools/report-dispatch.js.map +1 -1
  75. package/build/tools/set-scale.d.ts +6 -0
  76. package/build/tools/set-scale.js +92 -0
  77. package/build/tools/set-scale.js.map +1 -0
  78. package/build/tools/setup-project.d.ts +1 -1
  79. package/build/tools/setup-project.js +33 -5
  80. package/build/tools/setup-project.js.map +1 -1
  81. package/build/tools/update-phase.d.ts +8 -3
  82. package/build/tools/update-phase.js +85 -20
  83. package/build/tools/update-phase.js.map +1 -1
  84. package/package.json +2 -1
  85. package/workflows/dev/roles/architect.md +1 -1
  86. package/workflows/dev/roles/pm.md +5 -5
  87. package/workflows/dev/roles/tester.md +1 -1
  88. package/workflows/dev/schemas/api-design.json +25 -0
  89. package/workflows/dev/schemas/data-model.json +20 -0
  90. package/workflows/dev/schemas/deploy.json +20 -0
  91. package/workflows/dev/schemas/fsd.json +25 -0
  92. package/workflows/dev/schemas/prd.completeness-check.json +24 -0
  93. package/workflows/dev/schemas/prd.draft.json +15 -0
  94. package/workflows/dev/schemas/prd.final.json +30 -0
  95. package/workflows/dev/schemas/prd.json +30 -0
  96. package/workflows/dev/schemas/prd.requirements.json +25 -0
  97. package/workflows/dev/schemas/project-plan.json +20 -0
  98. package/workflows/dev/schemas/prototype.json +4 -0
  99. package/workflows/dev/schemas/retrospective.json +20 -0
  100. package/workflows/dev/schemas/risk-assessment.json +15 -0
  101. package/workflows/dev/schemas/task-breakdown.coarse.json +15 -0
  102. package/workflows/dev/schemas/task-breakdown.dependencies.json +20 -0
  103. package/workflows/dev/schemas/task-breakdown.detailed.json +10 -0
  104. package/workflows/dev/schemas/task-breakdown.final.json +10 -0
  105. package/workflows/dev/schemas/task-breakdown.json +10 -0
  106. package/workflows/dev/schemas/tech-design.analysis.json +25 -0
  107. package/workflows/dev/schemas/tech-design.api-contract.json +20 -0
  108. package/workflows/dev/schemas/tech-design.draft.json +15 -0
  109. package/workflows/dev/schemas/tech-design.final.json +30 -0
  110. package/workflows/dev/schemas/tech-design.json +30 -0
  111. package/workflows/dev/schemas/test-plan.json +20 -0
  112. package/workflows/dev/schemas/test-report.json +25 -0
  113. package/workflows/dev/schemas/user-stories.json +10 -0
  114. package/workflows/dev/workflow.json +85 -5
@@ -22,13 +22,14 @@
22
22
  */
23
23
  import { mkdir, readFile, writeFile } from 'node:fs/promises';
24
24
  import { join } from 'node:path';
25
- import { homedir } from 'node:os';
26
- import { platform } from 'node:os';
25
+ import { createKit } from '@s_s/agent-kit';
27
26
  const REGISTRY_FILE = 'registry.json';
27
+ /** Shared kit instance for data directory resolution */
28
+ const kit = createKit('harmonia');
28
29
  /**
29
30
  * Get the global Harmonia data directory, following system conventions.
30
31
  *
31
- * Resolution order:
32
+ * Delegates to @s_s/agent-kit which handles:
32
33
  * 1. HARMONIA_DATA_DIR env var (explicit override)
33
34
  * 2. Platform default:
34
35
  * - macOS: ~/Library/Application Support/harmonia
@@ -36,19 +37,7 @@ const REGISTRY_FILE = 'registry.json';
36
37
  * - Linux: $XDG_DATA_HOME/harmonia (defaults to ~/.local/share/harmonia)
37
38
  */
38
39
  export function getGlobalDir() {
39
- const envDir = process.env.HARMONIA_DATA_DIR;
40
- if (envDir)
41
- return envDir;
42
- const home = homedir();
43
- switch (platform()) {
44
- case 'darwin':
45
- return join(home, 'Library', 'Application Support', 'harmonia');
46
- case 'win32':
47
- return join(process.env.APPDATA || join(home, 'AppData', 'Roaming'), 'harmonia');
48
- default:
49
- // Linux and others: follow XDG Base Directory spec
50
- return join(process.env.XDG_DATA_HOME || join(home, '.local', 'share'), 'harmonia');
51
- }
40
+ return kit.getDataDir();
52
41
  }
53
42
  /**
54
43
  * Get the data directory for a specific project within the global dir.
@@ -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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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Document schema loader and validator.
3
+ *
4
+ * Loads schema definitions from the resolved workflow directory's schemas/ subdirectory
5
+ * and validates document content against them before writing.
6
+ */
7
+ import type { DocSchema, ProjectScale } from './types.js';
8
+ /**
9
+ * Load a document schema from the workflow's schemas directory.
10
+ * Returns undefined if no schema file exists for this doc_id.
11
+ *
12
+ * For step schemas, pass a composite id like "prd.requirements".
13
+ */
14
+ export declare function loadDocSchema(builtinDir: string, customDir: string, workflowName: string, docId: string): Promise<DocSchema | undefined>;
15
+ export interface ValidationError {
16
+ /** Error type */
17
+ type: 'missing_section' | 'missing_html_tag' | 'content_too_short' | 'empty_content' | 'missing_json_field' | 'invalid_json' | 'wrong_json_type' | 'json_array_too_short';
18
+ /** Human-readable message */
19
+ message: string;
20
+ }
21
+ export interface ValidationResult {
22
+ valid: boolean;
23
+ errors: ValidationError[];
24
+ }
25
+ /**
26
+ * Validate document content against a schema.
27
+ *
28
+ * @param content - Document content (markdown, HTML, or JSON)
29
+ * @param schema - Schema definition
30
+ * @param scale - Project scale (affects which sections are required). When null, scale-dependent checks are skipped.
31
+ * @param isHtml - Whether the document is HTML format
32
+ * @param isJson - Whether the document is JSON format (for step artifacts)
33
+ */
34
+ export declare function validateDoc(content: string, schema: DocSchema, scale: ProjectScale | null, isHtml?: boolean, isJson?: boolean): ValidationResult;
35
+ /**
36
+ * Format validation errors into a human-readable string for tool response.
37
+ */
38
+ export declare function formatValidationErrors(errors: ValidationError[]): string;
@@ -0,0 +1,187 @@
1
+ /**
2
+ * Document schema loader and validator.
3
+ *
4
+ * Loads schema definitions from the resolved workflow directory's schemas/ subdirectory
5
+ * and validates document content against them before writing.
6
+ */
7
+ import { readFile } from 'node:fs/promises';
8
+ import { join } from 'node:path';
9
+ import { resolveWorkflowDir } from './workflow.js';
10
+ // ─── Schema Loading ───
11
+ /**
12
+ * Load a document schema from the workflow's schemas directory.
13
+ * Returns undefined if no schema file exists for this doc_id.
14
+ *
15
+ * For step schemas, pass a composite id like "prd.requirements".
16
+ */
17
+ export async function loadDocSchema(builtinDir, customDir, workflowName, docId) {
18
+ const workflowDir = await resolveWorkflowDir(builtinDir, customDir, workflowName);
19
+ const schemaPath = join(workflowDir, 'schemas', `${docId}.json`);
20
+ try {
21
+ const raw = await readFile(schemaPath, 'utf-8');
22
+ return JSON.parse(raw);
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ /**
29
+ * Normalize a heading string for comparison.
30
+ * Strips leading #'s and whitespace, lowercases.
31
+ */
32
+ function normalizeHeading(heading) {
33
+ return heading
34
+ .replace(/^#+\s*/, '')
35
+ .trim()
36
+ .toLowerCase();
37
+ }
38
+ /**
39
+ * Extract the heading level (number of #) from a heading string.
40
+ */
41
+ function headingLevel(heading) {
42
+ const match = heading.match(/^(#+)/);
43
+ return match ? match[1].length : 0;
44
+ }
45
+ /**
46
+ * Extract all headings from markdown content.
47
+ * Returns array of raw heading lines (e.g. "## 项目概述").
48
+ */
49
+ function extractHeadings(content) {
50
+ const lines = content.split('\n');
51
+ return lines.filter((line) => /^#{1,6}\s+/.test(line.trim()));
52
+ }
53
+ /**
54
+ * Check if a required section is present in the document headings.
55
+ * Matches primary heading or any alias, with level-aware + normalized comparison.
56
+ */
57
+ function sectionPresent(section, headings) {
58
+ const candidates = [section.heading, ...(section.aliases ?? [])];
59
+ const level = headingLevel(section.heading);
60
+ for (const candidate of candidates) {
61
+ const candidateNorm = normalizeHeading(candidate);
62
+ const candidateLevel = headingLevel(candidate) || level;
63
+ for (const h of headings) {
64
+ if (headingLevel(h) === candidateLevel && normalizeHeading(h) === candidateNorm) {
65
+ return true;
66
+ }
67
+ }
68
+ }
69
+ return false;
70
+ }
71
+ /**
72
+ * Validate document content against a schema.
73
+ *
74
+ * @param content - Document content (markdown, HTML, or JSON)
75
+ * @param schema - Schema definition
76
+ * @param scale - Project scale (affects which sections are required). When null, scale-dependent checks are skipped.
77
+ * @param isHtml - Whether the document is HTML format
78
+ * @param isJson - Whether the document is JSON format (for step artifacts)
79
+ */
80
+ export function validateDoc(content, schema, scale, isHtml = false, isJson = false) {
81
+ const errors = [];
82
+ // Empty content check
83
+ const trimmed = content.trim();
84
+ if (!trimmed) {
85
+ return {
86
+ valid: false,
87
+ errors: [{ type: 'empty_content', message: '文档内容为空' }],
88
+ };
89
+ }
90
+ // Minimum length check
91
+ if (schema.minLength && trimmed.length < schema.minLength) {
92
+ errors.push({
93
+ type: 'content_too_short',
94
+ message: `文档内容过短(${trimmed.length} 字符),最少需要 ${schema.minLength} 字符`,
95
+ });
96
+ }
97
+ // Markdown section checks
98
+ if (schema.sections && !isHtml && !isJson) {
99
+ const headings = extractHeadings(content);
100
+ for (const section of schema.sections) {
101
+ // When scale is null, skip scale-dependent section requirements
102
+ const isRequired = scale !== null ? section.required[scale] : false;
103
+ if (isRequired && !sectionPresent(section, headings)) {
104
+ const aliasList = section.aliases?.length ? `(或: ${section.aliases.join(', ')})` : '';
105
+ errors.push({
106
+ type: 'missing_section',
107
+ message: `缺少必需章节: ${section.heading}${aliasList}`,
108
+ });
109
+ }
110
+ }
111
+ }
112
+ // HTML tag checks
113
+ if (schema.htmlTags && isHtml) {
114
+ for (const tag of schema.htmlTags) {
115
+ // Check for opening tag (case-insensitive)
116
+ const regex = new RegExp(`<${tag}[\\s>]`, 'i');
117
+ if (!regex.test(content)) {
118
+ errors.push({
119
+ type: 'missing_html_tag',
120
+ message: `缺少必需的 HTML 标签: <${tag}>`,
121
+ });
122
+ }
123
+ }
124
+ }
125
+ // JSON field checks
126
+ if (schema.jsonFields && isJson) {
127
+ let parsed = null;
128
+ try {
129
+ parsed = JSON.parse(content);
130
+ }
131
+ catch {
132
+ errors.push({
133
+ type: 'invalid_json',
134
+ message: '内容不是合法的 JSON 格式',
135
+ });
136
+ }
137
+ if (parsed) {
138
+ for (const fieldDef of schema.jsonFields) {
139
+ // When scale is null, skip scale-dependent field requirements
140
+ const isRequired = scale !== null ? fieldDef.required[scale] : false;
141
+ if (!isRequired)
142
+ continue;
143
+ const value = parsed[fieldDef.field];
144
+ if (value === undefined || value === null) {
145
+ errors.push({
146
+ type: 'missing_json_field',
147
+ message: `缺少必需的 JSON 字段: "${fieldDef.field}"`,
148
+ });
149
+ continue;
150
+ }
151
+ // Type check
152
+ if (fieldDef.type) {
153
+ const actualType = Array.isArray(value) ? 'array' : typeof value;
154
+ if (actualType !== fieldDef.type) {
155
+ errors.push({
156
+ type: 'wrong_json_type',
157
+ message: `字段 "${fieldDef.field}" 类型错误: 期望 ${fieldDef.type},实际 ${actualType}`,
158
+ });
159
+ continue;
160
+ }
161
+ }
162
+ // Array minItems check
163
+ if (fieldDef.minItems && Array.isArray(value) && value.length < fieldDef.minItems) {
164
+ errors.push({
165
+ type: 'json_array_too_short',
166
+ message: `字段 "${fieldDef.field}" 数组元素过少: 最少 ${fieldDef.minItems} 个,实际 ${value.length} 个`,
167
+ });
168
+ }
169
+ }
170
+ }
171
+ }
172
+ return {
173
+ valid: errors.length === 0,
174
+ errors,
175
+ };
176
+ }
177
+ /**
178
+ * Format validation errors into a human-readable string for tool response.
179
+ */
180
+ export function formatValidationErrors(errors) {
181
+ const lines = ['文档校验失败,请修正后重新提交:', ''];
182
+ for (const err of errors) {
183
+ lines.push(`- ${err.message}`);
184
+ }
185
+ return lines.join('\n');
186
+ }
187
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"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"}
@@ -2,12 +2,18 @@
2
2
  * Project state management — manages <data_dir>/<project_name>/state.json
3
3
  */
4
4
  import type { PhaseStatus, ProjectScale, ProjectState, LoadedWorkflow } from './types.js';
5
+ /**
6
+ * Error thrown when a tool requires scale but it hasn't been set yet.
7
+ */
8
+ export declare class ScaleNotSetError extends Error {
9
+ constructor(projectName: string);
10
+ }
5
11
  /**
6
12
  * Initialize a new project state file.
7
13
  * Note: directory creation and registry are handled by registry.registerProject().
8
14
  * This only writes the state.json.
9
15
  */
10
- export declare function initProjectState(projectName: string, projectDir: string, workflow: LoadedWorkflow, scale?: ProjectScale): Promise<ProjectState>;
16
+ export declare function initProjectState(projectName: string, projectDir: string, workflow: LoadedWorkflow): Promise<ProjectState>;
11
17
  /**
12
18
  * Read the current project state.
13
19
  */
@@ -24,3 +30,7 @@ export declare function updatePhaseStatus(projectName: string, phaseId: string,
24
30
  * Check if a project state file exists.
25
31
  */
26
32
  export declare function projectStateExists(projectName: string): Promise<boolean>;
33
+ /**
34
+ * Set the project scale. Scale is immutable once set.
35
+ */
36
+ export declare function setScale(projectName: string, scale: ProjectScale): Promise<ProjectState>;
@@ -4,6 +4,15 @@
4
4
  import { mkdir, readFile, writeFile } from 'node:fs/promises';
5
5
  import { join, dirname } from 'node:path';
6
6
  import { getProjectDataDir } from './registry.js';
7
+ /**
8
+ * Error thrown when a tool requires scale but it hasn't been set yet.
9
+ */
10
+ export class ScaleNotSetError extends Error {
11
+ constructor(projectName) {
12
+ super(`项目 "${projectName}" 尚未设定 scale。请先完成 PRD 审批,然后调用 project_set_scale 设定项目规模。`);
13
+ this.name = 'ScaleNotSetError';
14
+ }
15
+ }
7
16
  const STATE_FILE = 'state.json';
8
17
  function statePath(projectName) {
9
18
  return join(getProjectDataDir(projectName), STATE_FILE);
@@ -13,7 +22,7 @@ function statePath(projectName) {
13
22
  * Note: directory creation and registry are handled by registry.registerProject().
14
23
  * This only writes the state.json.
15
24
  */
16
- export async function initProjectState(projectName, projectDir, workflow, scale = 'small') {
25
+ export async function initProjectState(projectName, projectDir, workflow) {
17
26
  const now = new Date().toISOString();
18
27
  const phases = workflow.definition.phases;
19
28
  const firstPhaseId = phases[0]?.id ?? '';
@@ -21,7 +30,7 @@ export async function initProjectState(projectName, projectDir, workflow, scale
21
30
  projectName,
22
31
  projectDir,
23
32
  workflow: workflow.definition.name,
24
- scale,
33
+ scale: null,
25
34
  currentPhase: firstPhaseId,
26
35
  phases: phases.map((p, i) => ({
27
36
  id: p.id,
@@ -100,4 +109,16 @@ export async function projectStateExists(projectName) {
100
109
  return false;
101
110
  }
102
111
  }
112
+ /**
113
+ * Set the project scale. Scale is immutable once set.
114
+ */
115
+ export async function setScale(projectName, scale) {
116
+ const state = await readState(projectName);
117
+ if (state.scale !== null) {
118
+ throw new Error(`Scale 已设定为 "${state.scale}",不可更改。如需调整规模,请重新评估 PRD。`);
119
+ }
120
+ state.scale = scale;
121
+ await writeState(projectName, state);
122
+ return state;
123
+ }
103
124
  //# 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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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Step state management — manages <data_dir>/<project_name>/steps.json
3
+ *
4
+ * Tracks which sequential steps have been completed for each document,
5
+ * supporting the P3 Sequential mode feature.
6
+ */
7
+ import type { DocStepState } from './types.js';
8
+ /**
9
+ * Read the steps state for a project.
10
+ */
11
+ export declare function readSteps(projectName: string): Promise<Record<string, DocStepState>>;
12
+ /**
13
+ * Get the step state for a specific document.
14
+ */
15
+ export declare function getDocStepState(projectName: string, docId: string): Promise<DocStepState | null>;
16
+ /**
17
+ * Get the set of completed step IDs for a document.
18
+ */
19
+ export declare function getCompletedStepIds(state: DocStepState | null): Set<string>;
20
+ /**
21
+ * Record a step as completed. If the step was already completed,
22
+ * it is overwritten and all subsequent steps are cleared (rollback).
23
+ *
24
+ * @returns The updated DocStepState
25
+ */
26
+ export declare function recordStepCompletion(projectName: string, docId: string, stepId: string, artifactPath: string, allStepIds: string[]): Promise<DocStepState>;
27
+ /**
28
+ * Mark a document as finalized (all steps completed + final doc written).
29
+ */
30
+ export declare function markFinalized(projectName: string, docId: string): Promise<DocStepState>;
31
+ /**
32
+ * Check if a document's sequential process is finalized.
33
+ */
34
+ export declare function isDocFinalized(projectName: string, docId: string): Promise<boolean>;
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Step state management — manages <data_dir>/<project_name>/steps.json
3
+ *
4
+ * Tracks which sequential steps have been completed for each document,
5
+ * supporting the P3 Sequential mode feature.
6
+ */
7
+ import { readFile, writeFile, mkdir } from 'node:fs/promises';
8
+ import { join, dirname } from 'node:path';
9
+ import { getProjectDataDir } from './registry.js';
10
+ const STEPS_FILE = 'steps.json';
11
+ function stepsPath(projectName) {
12
+ return join(getProjectDataDir(projectName), STEPS_FILE);
13
+ }
14
+ /**
15
+ * Read the steps state for a project.
16
+ */
17
+ export async function readSteps(projectName) {
18
+ try {
19
+ const content = await readFile(stepsPath(projectName), 'utf-8');
20
+ const data = JSON.parse(content);
21
+ return data.docs ?? {};
22
+ }
23
+ catch {
24
+ return {};
25
+ }
26
+ }
27
+ /**
28
+ * Write steps state to disk.
29
+ */
30
+ async function writeSteps(projectName, docs) {
31
+ const filePath = stepsPath(projectName);
32
+ await mkdir(dirname(filePath), { recursive: true });
33
+ const data = { docs };
34
+ await writeFile(filePath, JSON.stringify(data, null, 2) + '\n', 'utf-8');
35
+ }
36
+ /**
37
+ * Get the step state for a specific document.
38
+ */
39
+ export async function getDocStepState(projectName, docId) {
40
+ const docs = await readSteps(projectName);
41
+ return docs[docId] ?? null;
42
+ }
43
+ /**
44
+ * Get the set of completed step IDs for a document.
45
+ */
46
+ export function getCompletedStepIds(state) {
47
+ if (!state)
48
+ return new Set();
49
+ return new Set(state.completedSteps.map((s) => s.stepId));
50
+ }
51
+ /**
52
+ * Record a step as completed. If the step was already completed,
53
+ * it is overwritten and all subsequent steps are cleared (rollback).
54
+ *
55
+ * @returns The updated DocStepState
56
+ */
57
+ export async function recordStepCompletion(projectName, docId, stepId, artifactPath, allStepIds) {
58
+ const docs = await readSteps(projectName);
59
+ let state = docs[docId];
60
+ if (!state) {
61
+ state = {
62
+ docId,
63
+ completedSteps: [],
64
+ finalized: false,
65
+ };
66
+ }
67
+ // Find the index of this step in the workflow's step order
68
+ const stepIndex = allStepIds.indexOf(stepId);
69
+ // Check if this step was already completed — if so, rollback subsequent steps
70
+ const existingIndex = state.completedSteps.findIndex((s) => s.stepId === stepId);
71
+ if (existingIndex >= 0) {
72
+ // Clear this step and all subsequent steps
73
+ state.completedSteps = state.completedSteps.filter((s) => {
74
+ const sIdx = allStepIds.indexOf(s.stepId);
75
+ return sIdx < stepIndex;
76
+ });
77
+ // Reset finalized flag
78
+ state.finalized = false;
79
+ delete state.finalizedAt;
80
+ }
81
+ // Record the new step
82
+ const record = {
83
+ stepId,
84
+ completedAt: new Date().toISOString(),
85
+ artifactPath,
86
+ };
87
+ state.completedSteps.push(record);
88
+ docs[docId] = state;
89
+ await writeSteps(projectName, docs);
90
+ return state;
91
+ }
92
+ /**
93
+ * Mark a document as finalized (all steps completed + final doc written).
94
+ */
95
+ export async function markFinalized(projectName, docId) {
96
+ const docs = await readSteps(projectName);
97
+ const state = docs[docId];
98
+ if (!state) {
99
+ throw new Error(`No step state found for document "${docId}"`);
100
+ }
101
+ state.finalized = true;
102
+ state.finalizedAt = new Date().toISOString();
103
+ await writeSteps(projectName, docs);
104
+ return state;
105
+ }
106
+ /**
107
+ * Check if a document's sequential process is finalized.
108
+ */
109
+ export async function isDocFinalized(projectName, docId) {
110
+ const state = await getDocStepState(projectName, docId);
111
+ return state?.finalized ?? false;
112
+ }
113
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/core/steps.ts"],"names":[],"mappings":"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"}