@nova286/nova-workflow 0.2.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 (79) hide show
  1. package/README.md +246 -0
  2. package/dist/cli/commands/archive.d.ts +1 -0
  3. package/dist/cli/commands/archive.js +120 -0
  4. package/dist/cli/commands/archive.js.map +1 -0
  5. package/dist/cli/commands/context.d.ts +1 -0
  6. package/dist/cli/commands/context.js +23 -0
  7. package/dist/cli/commands/context.js.map +1 -0
  8. package/dist/cli/commands/guard.d.ts +1 -0
  9. package/dist/cli/commands/guard.js +21 -0
  10. package/dist/cli/commands/guard.js.map +1 -0
  11. package/dist/cli/commands/init.d.ts +1 -0
  12. package/dist/cli/commands/init.js +22 -0
  13. package/dist/cli/commands/init.js.map +1 -0
  14. package/dist/cli/commands/status.d.ts +1 -0
  15. package/dist/cli/commands/status.js +72 -0
  16. package/dist/cli/commands/status.js.map +1 -0
  17. package/dist/cli/error-handler.d.ts +1 -0
  18. package/dist/cli/error-handler.js +18 -0
  19. package/dist/cli/error-handler.js.map +1 -0
  20. package/dist/cli/index.d.ts +2 -0
  21. package/dist/cli/index.js +35 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/cli/ui.d.ts +10 -0
  24. package/dist/cli/ui.js +21 -0
  25. package/dist/cli/ui.js.map +1 -0
  26. package/dist/cli-core/__tests__/context-generator.test.d.ts +1 -0
  27. package/dist/cli-core/__tests__/context-generator.test.js +97 -0
  28. package/dist/cli-core/__tests__/context-generator.test.js.map +1 -0
  29. package/dist/cli-core/__tests__/dispatcher.test.d.ts +1 -0
  30. package/dist/cli-core/__tests__/dispatcher.test.js +99 -0
  31. package/dist/cli-core/__tests__/dispatcher.test.js.map +1 -0
  32. package/dist/cli-core/__tests__/guard.test.d.ts +1 -0
  33. package/dist/cli-core/__tests__/guard.test.js +136 -0
  34. package/dist/cli-core/__tests__/guard.test.js.map +1 -0
  35. package/dist/cli-core/__tests__/init-manager.test.d.ts +1 -0
  36. package/dist/cli-core/__tests__/init-manager.test.js +150 -0
  37. package/dist/cli-core/__tests__/init-manager.test.js.map +1 -0
  38. package/dist/cli-core/__tests__/pipeline.test.d.ts +1 -0
  39. package/dist/cli-core/__tests__/pipeline.test.js +119 -0
  40. package/dist/cli-core/__tests__/pipeline.test.js.map +1 -0
  41. package/dist/cli-core/__tests__/project-detect.test.d.ts +1 -0
  42. package/dist/cli-core/__tests__/project-detect.test.js +92 -0
  43. package/dist/cli-core/__tests__/project-detect.test.js.map +1 -0
  44. package/dist/cli-core/__tests__/state-manager.test.d.ts +1 -0
  45. package/dist/cli-core/__tests__/state-manager.test.js +120 -0
  46. package/dist/cli-core/__tests__/state-manager.test.js.map +1 -0
  47. package/dist/cli-core/adapters/claude-code.d.ts +6 -0
  48. package/dist/cli-core/adapters/claude-code.js +311 -0
  49. package/dist/cli-core/adapters/claude-code.js.map +1 -0
  50. package/dist/cli-core/context-generator.d.ts +4 -0
  51. package/dist/cli-core/context-generator.js +81 -0
  52. package/dist/cli-core/context-generator.js.map +1 -0
  53. package/dist/cli-core/dispatcher.d.ts +11 -0
  54. package/dist/cli-core/dispatcher.js +169 -0
  55. package/dist/cli-core/dispatcher.js.map +1 -0
  56. package/dist/cli-core/guard.d.ts +1 -0
  57. package/dist/cli-core/guard.js +57 -0
  58. package/dist/cli-core/guard.js.map +1 -0
  59. package/dist/cli-core/init-manager.d.ts +25 -0
  60. package/dist/cli-core/init-manager.js +182 -0
  61. package/dist/cli-core/init-manager.js.map +1 -0
  62. package/dist/cli-core/pipeline.d.ts +7 -0
  63. package/dist/cli-core/pipeline.js +79 -0
  64. package/dist/cli-core/pipeline.js.map +1 -0
  65. package/dist/cli-core/platform-client.d.ts +19 -0
  66. package/dist/cli-core/platform-client.js +119 -0
  67. package/dist/cli-core/platform-client.js.map +1 -0
  68. package/dist/cli-core/project-detect.d.ts +1 -0
  69. package/dist/cli-core/project-detect.js +64 -0
  70. package/dist/cli-core/project-detect.js.map +1 -0
  71. package/dist/cli-core/state.d.ts +11 -0
  72. package/dist/cli-core/state.js +106 -0
  73. package/dist/cli-core/state.js.map +1 -0
  74. package/dist/cli-core/types.d.ts +141 -0
  75. package/dist/cli-core/types.js +13 -0
  76. package/dist/cli-core/types.js.map +1 -0
  77. package/package.json +33 -0
  78. package/templates/docs/design.md +41 -0
  79. package/templates/docs/proposal.md +25 -0
@@ -0,0 +1,311 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ClaudeCodeAdapter = void 0;
37
+ const fs = __importStar(require("fs/promises"));
38
+ const path = __importStar(require("path"));
39
+ const SKILL_TEMPLATES = {
40
+ 'nova.md': `---
41
+ description: Nova — unified entry point. Shows progress and suggests next action.
42
+ ---
43
+
44
+ # Nova
45
+
46
+ Read \`.nova.yaml\` and present a compact overview with a clear next action.
47
+
48
+ ## Step 1: Read State
49
+ Parse \`.nova.yaml\`. For each phase, determine status (pending / in-progress / done).
50
+ If \`.nova.yaml\` does not exist, say: "Nova not initialized. Run \`nova init\` first."
51
+
52
+ ## Step 2: Show Overview
53
+ \`\`\`
54
+ Nova · <project-name>
55
+ ────────────────────────────────────────
56
+ propose [done] docs/proposals/proposal.md
57
+ design [done] docs/designs/design.md · 6 tasks
58
+ implement [in-progress] 3/6 tasks done
59
+ verify [pending]
60
+ archive [pending]
61
+ ────────────────────────────────────────
62
+ \`\`\`
63
+
64
+ ## Step 3: Suggest Next Action
65
+ Based on the first phase that is NOT done:
66
+ - propose: pending → "/nova-propose — Start with a proposal"
67
+ - design: pending → "/nova-design — Create technical design"
68
+ - implement: pending → "/nova-implement — Start implementing"
69
+ - verify: pending → "/nova-verify — Run review pipeline"
70
+ - all done → "nova archive — Finalize project"
71
+
72
+ Show: "Next: <suggestion>"
73
+ Also list: /nova-propose /nova-design /nova-implement /nova-verify /nova-iterate /nova-status
74
+
75
+ ## Step 4: Act
76
+ Ask: "Run the suggested action, pick another, or do something else?"
77
+
78
+ ## Constraints
79
+ Read-only unless the user explicitly confirms an action.
80
+ `,
81
+ 'nova-propose.md': `---
82
+ description: Nova propose phase — generate a feature proposal from interactive Q&A
83
+ ---
84
+
85
+ # Nova Propose Phase
86
+
87
+ You are executing the **propose phase** of a Nova workflow. Your role is to
88
+ orchestrate requirements exploration and produce a structured proposal document.
89
+
90
+ ## Step 1: Verify State
91
+ Read \`.nova.yaml\`. Check \`phases.open.status\`. If pending, update to
92
+ \`in-progress\` and set \`startedAt\`.
93
+
94
+ ## Step 2: Gather Context
95
+ Read \`AGENTS.md\`, \`CLAUDE.md\`, \`README.md\`, \`package.json\`, \`src/\` to
96
+ understand the project.
97
+
98
+ ## Step 3: Explore Requirements
99
+ Use the **brainstorming skill** to explore the problem space: clarify the problem,
100
+ explore alternatives, identify risks, define success criteria. Summarize for the
101
+ user and ask them to confirm before proceeding.
102
+
103
+ ## Step 4: Generate Proposal
104
+ Write \`docs/proposals/proposal.md\` with: Problem Statement, Proposed Solution,
105
+ User Stories (prioritized), Scope & Deliverables (in/out), Success Criteria
106
+ (measurable), Risks & Constraints.
107
+
108
+ ## Step 5: Update State
109
+ Set \`phases.open.status = 'in-progress'\`,
110
+ \`phases.open.proposal = 'docs/proposals/proposal.md'\`.
111
+
112
+ ## Constraints
113
+ - Read any file for context. Write only to \`docs/proposals/\` and \`.nova.yaml\`.
114
+ - Do not modify source code — the implement phase handles that.
115
+ `,
116
+ 'nova-design.md': `---
117
+ description: Nova design phase — generate technical design from approved proposal
118
+ ---
119
+
120
+ # Nova Design Phase
121
+
122
+ You are executing the **design phase** of a Nova workflow. Your role is to
123
+ orchestrate architecture exploration and produce a design document with an
124
+ actionable task list.
125
+
126
+ ## Step 1: Verify State
127
+ Read \`.nova.yaml\`. Require \`phases.open.status: done\` with a non-empty proposal.
128
+ Update \`phases.design.status\` to \`in-progress\` and set \`startedAt\`.
129
+
130
+ ## Step 2: Load Context
131
+ Read the proposal (\`phases.open.proposal\`), \`AGENTS.md\`, \`package.json\`, \`src/\`.
132
+
133
+ ## Step 3: Explore Architecture Options
134
+ Use the **brainstorming skill** to explore at least 2 architectural approaches.
135
+ For each: architecture pattern, tech stack rationale, component structure, data
136
+ flow, key trade-offs. Present alternatives to the user for selection.
137
+
138
+ ## Step 4: Generate Design Document
139
+ Based on the user-selected approach, use the **writing-plans skill** to produce
140
+ \`docs/designs/design.md\` with: Architecture Overview, Tech Stack, Component
141
+ Breakdown, Data Flow, Implementation Plan (YAML task list), Risks & Mitigations.
142
+
143
+ ## Step 5: Validate Tasks
144
+ Verify each task has all required fields (id, title, type, description, files,
145
+ acceptance, priority, estimatedComplexity).
146
+
147
+ ## Step 6: Update State
148
+ Set \`phases.design.status = 'done'\`, \`designDoc\`, \`tasks\` from parsed YAML.
149
+
150
+ ## Constraints
151
+ - Design and plan only — no implementation code.
152
+ - Tasks must be concrete: specific file paths, verifiable acceptance criteria.
153
+ `,
154
+ 'nova-implement.md': `---
155
+ description: Nova implement phase — execute design tasks with retry and tracing
156
+ ---
157
+
158
+ # Nova Implement Phase
159
+
160
+ You are executing the **implement phase** of a Nova workflow. Your role is to
161
+ execute each task from the design phase, routing by task type.
162
+
163
+ ## Step 1: Verify State
164
+ Read \`.nova.yaml\`. Require \`phases.design.status: done\` with non-empty tasks.
165
+ Update \`phases.build.status\` to \`in-progress\` and set \`startedAt\`.
166
+
167
+ ## Step 2: Load Task List
168
+ Show task summary (id, title, type, priority). Ask user to confirm before
169
+ proceeding.
170
+
171
+ ## Step 3: Execute Each Task
172
+ For each task in priority order:
173
+
174
+ ### Route by Task Type
175
+ - **implementation** — write production code following project conventions
176
+ - **testing** — use the **test-driven-development skill**
177
+ - **design** — update design documents (noted for user review)
178
+
179
+ ### Verify After Each Task
180
+ 1. Run type check (\`npx tsc --noEmit\`)
181
+ 2. Run tests (\`npx jest --no-coverage\`)
182
+ 3. Fix before marking complete
183
+
184
+ ### Record Result
185
+ Update \`.nova.yaml\` with task status (done/failed) and timestamp.
186
+ On failure, ask user: abort, skip, or retry.
187
+
188
+ ## Step 4: Final Verification
189
+ Run full test suite and type check. Report summary.
190
+
191
+ ## Step 5: Update State
192
+ Set \`phases.build.status = 'done'\`.
193
+
194
+ ## Constraints
195
+ - Follow existing project conventions. Never leave TODOs or stubs.
196
+ - Run checks after EACH task, not just at the end.
197
+ `,
198
+ 'nova-verify.md': `---
199
+ description: Nova verify phase — run code review and security review pipeline
200
+ ---
201
+
202
+ # Nova Verify Phase
203
+
204
+ You are executing the **verify phase** of a Nova workflow. Your role is to
205
+ orchestrate a verification pipeline using ECC review skills.
206
+
207
+ ## Step 1: Verify State
208
+ Read \`.nova.yaml\`. Require \`phases.build.status: done\`.
209
+ Update \`phases.verify.status\` to \`in-progress\` and set \`startedAt\`.
210
+
211
+ ## Step 2: Gather Context
212
+ Load completed tasks from \`phases.design.tasks\`. Read changed files and the
213
+ design document.
214
+
215
+ ## Step 3: Run Code Review
216
+ Use the **ecc:code-reviewer** skill to review each task's changed files:
217
+ correctness, conventions, error handling, test coverage, type safety.
218
+ Verdict: PASS / CHANGES_REQUESTED / COMMENT.
219
+
220
+ ## Step 4: Run Security Review
221
+ Use the **ecc:security-reviewer** skill to audit each task's changed files:
222
+ injection risks, secret exposure, insecure dependencies, input validation.
223
+ Verdict: PASS / VULNERABILITY_FOUND. Include severity and remediation.
224
+
225
+ ## Step 5: Generate Report
226
+ Write \`docs/designs/verification-report.md\` with summary, per-task results,
227
+ overall assessment (PASS / NEEDS_FIXES / BLOCKED), and recommendations.
228
+
229
+ ## Step 6: Update State
230
+ Set \`phases.verify.status = 'done'\`, \`pipelineResult\` with stage results.
231
+
232
+ ## Constraints
233
+ - Be specific — reference file paths and line numbers.
234
+ - Security findings must include severity and remediation.
235
+ `,
236
+ 'nova-iterate.md': `---
237
+ description: Nova iterate — roll back to a previous phase for iteration
238
+ ---
239
+
240
+ # Nova Iterate Phase
241
+
242
+ You are handling a **phase iteration** in a Nova workflow. Software development
243
+ is iterative — implementation reveals design gaps, verification reveals spec issues.
244
+
245
+ ## Step 1: Detect Current Phase
246
+ Read \`.nova.yaml\`. Determine which phase is active and which earlier phases are
247
+ valid rollback targets.
248
+
249
+ ## Step 2: Present Options
250
+ Show valid rollback targets. For each, explain what will be reset.
251
+ Ask user: which phase, why (recorded in history), keep or discard work?
252
+
253
+ ## Step 3: Execute Rollback
254
+ - **Keep work**: Reset state only — preserve all files. Set target phase and all
255
+ subsequent phases to \`pending\`, clear task results and timestamps.
256
+ - **Discard work**: Additionally revert changed files via \`git checkout\`.
257
+
258
+ ## Step 4: Record Iteration
259
+ Add to \`.nova.yaml\` metadata.history:
260
+ \`"Iterated <from> to <target>: <user's reason>"\`
261
+
262
+ ## Step 5: Report Next Steps
263
+ Summarize what changed and which command to run next.
264
+
265
+ ## Constraints
266
+ - Never delete code files without explicit user confirmation.
267
+ - Always record the iteration reason.
268
+ `,
269
+ 'nova-status.md': `---
270
+ description: Nova status — display phase progress, task completion, and stuck detection
271
+ ---
272
+
273
+ # Nova Status
274
+
275
+ Display current project status from \`.nova.yaml\`.
276
+
277
+ ## Step 1: Load State
278
+ Read \`.nova.yaml\`. Parse all phase statuses and task results.
279
+
280
+ ## Step 2: Display Summary
281
+ Show each phase with status icon (pending/in-progress/done), timestamps, and
282
+ key artifacts. For the build phase, show per-task completion.
283
+
284
+ ## Step 3: Detect Issues
285
+ Flag: phases stuck in-progress, failed tasks, skipped guard conditions,
286
+ missing artifacts.
287
+ `,
288
+ };
289
+ class ClaudeCodeAdapter {
290
+ constructor() {
291
+ this.name = 'claude-code';
292
+ }
293
+ async setup(cwd) {
294
+ const dir = path.join(cwd, '.claude', 'commands');
295
+ await fs.mkdir(dir, { recursive: true });
296
+ for (const [filename, content] of Object.entries(SKILL_TEMPLATES)) {
297
+ await this.writeCommand(dir, filename, content);
298
+ }
299
+ }
300
+ async writeCommand(dir, file, content) {
301
+ const filePath = path.join(dir, file);
302
+ try {
303
+ await fs.access(filePath);
304
+ return;
305
+ }
306
+ catch { }
307
+ await fs.writeFile(filePath, content);
308
+ }
309
+ }
310
+ exports.ClaudeCodeAdapter = ClaudeCodeAdapter;
311
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/cli-core/adapters/claude-code.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,2CAA6B;AAG7B,MAAM,eAAe,GAA2B;IAC9C,SAAS,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCZ;IAEC,iBAAiB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCpB;IAEC,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnB;IAEC,mBAAmB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2CtB;IAEC,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnB;IAEC,iBAAiB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCpB;IAEC,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;CAkBnB;CACA,CAAC;AAEF,MAAa,iBAAiB;IAA9B;QACE,SAAI,GAAG,aAAa,CAAC;IAavB,CAAC;IAZC,KAAK,CAAC,KAAK,CAAC,GAAW;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QAClD,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;YAClE,MAAM,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACO,KAAK,CAAC,YAAY,CAAC,GAAW,EAAE,IAAY,EAAE,OAAe;QACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACnD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;CACF;AAdD,8CAcC"}
@@ -0,0 +1,4 @@
1
+ import { TaskContext } from './types';
2
+ export declare class ContextGenerator {
3
+ static generateFromTask(task: any): Promise<TaskContext>;
4
+ }
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextGenerator = void 0;
4
+ const state_1 = require("./state");
5
+ const PROJECT_TYPE_ENV = {
6
+ node: { language: 'TypeScript', framework: 'Express.js', buildTool: 'npm', testFramework: 'jest' },
7
+ python: { language: 'Python', framework: '', buildTool: 'pip', testFramework: 'pytest' },
8
+ go: { language: 'Go', framework: '', buildTool: 'go', testFramework: 'testing' },
9
+ java: { language: 'Java', framework: 'Spring Boot', buildTool: 'maven', testFramework: 'junit' },
10
+ rust: { language: 'Rust', framework: '', buildTool: 'cargo', testFramework: 'cargo test' },
11
+ ruby: { language: 'Ruby', framework: 'Rails', buildTool: 'bundler', testFramework: 'rspec' },
12
+ php: { language: 'PHP', framework: 'Laravel', buildTool: 'composer', testFramework: 'phpunit' },
13
+ cpp: { language: 'C++', framework: '', buildTool: 'cmake', testFramework: 'gtest' },
14
+ csharp: { language: 'C#', framework: '.NET', buildTool: 'dotnet', testFramework: 'xunit' },
15
+ swift: { language: 'Swift', framework: 'SwiftUI', buildTool: 'swift', testFramework: 'XCTest' },
16
+ kotlin: { language: 'Kotlin', framework: 'Spring Boot', buildTool: 'gradle', testFramework: 'junit' },
17
+ };
18
+ const TYPE_MAP = {
19
+ implementation: 'implementation',
20
+ design: 'design',
21
+ review: 'review',
22
+ test: 'testing',
23
+ testing: 'testing',
24
+ security: 'security',
25
+ };
26
+ class ContextGenerator {
27
+ static async generateFromTask(task) {
28
+ const state = await state_1.StateManager.load();
29
+ const projectType = state.projectType || '';
30
+ const env = PROJECT_TYPE_ENV[projectType] || {
31
+ language: '',
32
+ framework: '',
33
+ buildTool: '',
34
+ testFramework: '',
35
+ };
36
+ return {
37
+ taskId: task.id,
38
+ parentTaskId: task.parentId,
39
+ title: task.title,
40
+ description: task.description,
41
+ taskType: TYPE_MAP[task.type] || 'other',
42
+ designContext: {
43
+ designDocRef: state.phases.design?.designDoc || '',
44
+ relevantSpecs: [],
45
+ architectureNotes: '',
46
+ },
47
+ input: {
48
+ files: (task.files || []).map((f) => ({
49
+ path: f.path,
50
+ content: '',
51
+ action: f.action,
52
+ })),
53
+ dependencies: task.dependencies || [],
54
+ environment: env,
55
+ },
56
+ output: {
57
+ expectedArtifacts: (task.expectedArtifacts || []).map((a) => ({
58
+ type: a.type,
59
+ description: a.description,
60
+ pathHint: a.pathHint,
61
+ validation: a.validation,
62
+ })),
63
+ constraints: task.constraints || { mustPassTests: true },
64
+ },
65
+ acceptanceCriteria: task.acceptance || [],
66
+ guardConditions: {
67
+ requireReview: true,
68
+ requireTests: true,
69
+ blocking: task.blocking !== false,
70
+ },
71
+ metadata: {
72
+ createdBy: 'nova-build',
73
+ createdAt: new Date().toISOString(),
74
+ priority: task.priority || 'medium',
75
+ estimatedComplexity: task.estimatedComplexity || 5,
76
+ },
77
+ };
78
+ }
79
+ }
80
+ exports.ContextGenerator = ContextGenerator;
81
+ //# sourceMappingURL=context-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-generator.js","sourceRoot":"","sources":["../../src/cli-core/context-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { PlatformClient } from './platform-client';
2
+ import { DispatchRequest, DispatchResult } from './types';
3
+ export declare class Dispatcher {
4
+ private client;
5
+ constructor(client: PlatformClient);
6
+ static create(cwd?: string): Promise<Dispatcher>;
7
+ execute(request: DispatchRequest): Promise<DispatchResult>;
8
+ private parseOutput;
9
+ private validateOutput;
10
+ private sleep;
11
+ }
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Dispatcher = void 0;
4
+ const platform_client_1 = require("./platform-client");
5
+ function generateTraceId() {
6
+ const ts = Date.now().toString(36);
7
+ const rand = Math.random().toString(36).slice(2, 9);
8
+ return `nova-${ts}-${rand}`;
9
+ }
10
+ function buildPrompt(agent, context) {
11
+ const lines = [];
12
+ // 1. 指令(最核心)
13
+ if (context.description) {
14
+ lines.push(context.description);
15
+ lines.push('');
16
+ }
17
+ // 2. 输入文件(如有)
18
+ if (context.input.files.length > 0) {
19
+ lines.push('## Relevant Files');
20
+ for (const f of context.input.files) {
21
+ lines.push(`- ${f.path} (${f.action})${f.content ? `\n content: ${f.content}` : ''}`);
22
+ }
23
+ lines.push('');
24
+ }
25
+ // 3. 验收标准(仅当 description 未包含时追加)
26
+ if (context.acceptanceCriteria.length > 0 && !context.description.includes('Acceptance Criteria')) {
27
+ lines.push('## Acceptance Criteria');
28
+ for (const c of context.acceptanceCriteria) {
29
+ lines.push(`- ${c}`);
30
+ }
31
+ lines.push('');
32
+ }
33
+ return lines.join('\n');
34
+ }
35
+ class Dispatcher {
36
+ constructor(client) {
37
+ this.client = client;
38
+ }
39
+ static async create(cwd) {
40
+ const client = await (0, platform_client_1.resolvePlatformClient)(cwd);
41
+ return new Dispatcher(client);
42
+ }
43
+ async execute(request) {
44
+ const traceId = generateTraceId();
45
+ const startTime = new Date();
46
+ const maxAttempts = request.retry?.maxAttempts ?? 1;
47
+ const backoff = request.retry?.backoff ?? 'fixed';
48
+ const errors = [];
49
+ let lastRawOutput;
50
+ const prompt = buildPrompt(request.agent, request.context);
51
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
52
+ try {
53
+ const response = await this.client.sendPrompt(prompt, {
54
+ timeout: request.timeout,
55
+ model: request.model || 'sonnet',
56
+ effort: request.effort || 'low',
57
+ });
58
+ const output = this.parseOutput(response.content);
59
+ if (request.outputSchema) {
60
+ const valid = this.validateOutput(output, request.outputSchema);
61
+ if (!valid) {
62
+ return {
63
+ traceId,
64
+ agent: request.agent,
65
+ status: 'validation_error',
66
+ output,
67
+ rawOutput: response.content,
68
+ metadata: {
69
+ startTime,
70
+ endTime: new Date(),
71
+ attempts: attempt,
72
+ tokenUsage: response.tokenUsage,
73
+ },
74
+ errors: [{ message: `Output failed schema validation: ${request.outputSchema}` }],
75
+ };
76
+ }
77
+ }
78
+ return {
79
+ traceId,
80
+ agent: request.agent,
81
+ status: 'success',
82
+ output,
83
+ rawOutput: response.content,
84
+ metadata: {
85
+ startTime,
86
+ endTime: new Date(),
87
+ attempts: attempt,
88
+ tokenUsage: response.tokenUsage,
89
+ },
90
+ };
91
+ }
92
+ catch (err) {
93
+ errors.push({ message: err.message, code: err.code });
94
+ if (attempt < maxAttempts) {
95
+ await this.sleep(attempt, backoff);
96
+ }
97
+ }
98
+ }
99
+ return {
100
+ traceId,
101
+ agent: request.agent,
102
+ status: 'failed',
103
+ rawOutput: lastRawOutput,
104
+ metadata: {
105
+ startTime,
106
+ endTime: new Date(),
107
+ attempts: maxAttempts,
108
+ },
109
+ errors,
110
+ };
111
+ }
112
+ parseOutput(content) {
113
+ try {
114
+ return JSON.parse(content);
115
+ }
116
+ catch {
117
+ return { result: content };
118
+ }
119
+ }
120
+ validateOutput(output, schema) {
121
+ if (output == null)
122
+ return false;
123
+ switch (schema) {
124
+ case 'task-result': {
125
+ return typeof output === 'object' && 'result' in output;
126
+ }
127
+ case 'proposal': {
128
+ if (typeof output === 'string')
129
+ return output.length > 50;
130
+ if (typeof output === 'object') {
131
+ const o = output;
132
+ return typeof o.result === 'string' && o.result.length > 50;
133
+ }
134
+ return false;
135
+ }
136
+ case 'design': {
137
+ if (typeof output === 'string')
138
+ return output.length > 100;
139
+ if (typeof output === 'object') {
140
+ const o = output;
141
+ return typeof o.result === 'string' && o.result.length > 100;
142
+ }
143
+ return false;
144
+ }
145
+ case 'review': {
146
+ return typeof output === 'object' && 'verdict' in output;
147
+ }
148
+ default: {
149
+ // 逗号分隔字段名: 检查对象是否包含所有字段
150
+ if (typeof output === 'object') {
151
+ const required = schema.split(',').map(s => s.trim()).filter(Boolean);
152
+ if (required.length > 0) {
153
+ const o = output;
154
+ return required.every(field => field in o);
155
+ }
156
+ }
157
+ return typeof output === 'object' || (typeof output === 'string' && output.length > 0);
158
+ }
159
+ }
160
+ }
161
+ sleep(attempt, backoff) {
162
+ const ms = backoff === 'exponential'
163
+ ? Math.min(1000 * Math.pow(2, attempt - 1), 30000)
164
+ : 1000;
165
+ return new Promise((resolve) => setTimeout(resolve, ms));
166
+ }
167
+ }
168
+ exports.Dispatcher = Dispatcher;
169
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../src/cli-core/dispatcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function guardPhaseTransition(from: string, to: string): Promise<boolean>;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.guardPhaseTransition = guardPhaseTransition;
4
+ const state_1 = require("./state");
5
+ const TRANSITION_RULES = {
6
+ 'open:design': [
7
+ { label: 'Proposal phase is done', check: (s) => s.phases.open?.status === 'done' },
8
+ { label: 'Proposal document exists', check: (s) => !!s.phases.open?.proposal },
9
+ ],
10
+ 'design:build': [
11
+ { label: 'Design phase is done', check: (s) => s.phases.design?.status === 'done' },
12
+ { label: 'Design document exists', check: (s) => !!s.phases.design?.designDoc },
13
+ {
14
+ label: 'Task list is non-empty',
15
+ check: (s) => Array.isArray(s.phases.design?.tasks) && s.phases.design.tasks.length > 0,
16
+ },
17
+ ],
18
+ 'build:verify': [
19
+ { label: 'Build phase is done', check: (s) => s.phases.build?.status === 'done' },
20
+ {
21
+ label: 'All tasks completed or ECC review passed',
22
+ check: (s) => {
23
+ if (s.phases.build?.eccReviewPassed)
24
+ return true;
25
+ const tasks = s.phases.build?.tasks || {};
26
+ const entries = Object.values(tasks);
27
+ return entries.length > 0 && entries.every((t) => t.status === 'done');
28
+ },
29
+ },
30
+ ],
31
+ 'verify:archive': [
32
+ { label: 'Verify phase is done', check: (s) => s.phases.verify?.status === 'done' },
33
+ ],
34
+ // Rollback transitions — always allowed (iteration is expected)
35
+ 'build:design': [
36
+ { label: 'Build phase has started (rollback)', check: (s) => s.phases.build?.status !== 'pending' },
37
+ ],
38
+ 'verify:build': [
39
+ { label: 'Verify phase has started (rollback)', check: (s) => s.phases.verify?.status !== 'pending' },
40
+ ],
41
+ 'verify:design': [
42
+ { label: 'Verify phase has started (rollback to design)', check: (s) => s.phases.verify?.status !== 'pending' },
43
+ ],
44
+ 'design:open': [
45
+ { label: 'Design phase has started (rollback)', check: (s) => s.phases.design?.status !== 'pending' },
46
+ ],
47
+ };
48
+ async function guardPhaseTransition(from, to) {
49
+ const state = await state_1.StateManager.load();
50
+ const key = `${from}:${to}`;
51
+ const rules = TRANSITION_RULES[key];
52
+ if (!rules) {
53
+ return true;
54
+ }
55
+ return rules.every((rule) => rule.check(state));
56
+ }
57
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/cli-core/guard.ts"],"names":[],"mappings":";;AAmDA,oDAUC;AA7DD,mCAAuC;AAOvC,MAAM,gBAAgB,GAAiC;IACrD,aAAa,EAAE;QACb,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,EAAE;QACnF,EAAE,KAAK,EAAE,0BAA0B,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE;KAC/E;IACD,cAAc,EAAE;QACd,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE;QACnF,EAAE,KAAK,EAAE,wBAAwB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE;QAC/E;YACE,KAAK,EAAE,wBAAwB;YAC/B,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CACX,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;SAC5E;KACF;IACD,cAAc,EAAE;QACd,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE;QACjF;YACE,KAAK,EAAE,0CAA0C;YACjD,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;gBACX,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,eAAe;oBAAE,OAAO,IAAI,CAAC;gBACjD,MAAM,KAAK,GAAwB,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;gBAC/D,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACrC,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;YAC9E,CAAC;SACF;KACF;IACD,gBAAgB,EAAE;QAChB,EAAE,KAAK,EAAE,sBAAsB,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE;KACpF;IACD,gEAAgE;IAChE,cAAc,EAAE;QACd,EAAE,KAAK,EAAE,oCAAoC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,EAAE;KACpG;IACD,cAAc,EAAE;QACd,EAAE,KAAK,EAAE,qCAAqC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,EAAE;KACtG;IACD,eAAe,EAAE;QACf,EAAE,KAAK,EAAE,+CAA+C,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,EAAE;KAChH;IACD,aAAa,EAAE;QACb,EAAE,KAAK,EAAE,qCAAqC,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,KAAK,SAAS,EAAE;KACtG;CACF,CAAC;AAEK,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,EAAU;IACjE,MAAM,KAAK,GAAG,MAAM,oBAAY,CAAC,IAAI,EAAE,CAAC;IACxC,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAEpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC"}