@nova286/nova-workflow 0.2.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/commands/archive.js +3 -3
- package/dist/cli/commands/archive.js.map +1 -1
- package/dist/cli/commands/guard.js +12 -2
- package/dist/cli/commands/guard.js.map +1 -1
- package/dist/cli/commands/status.js +8 -8
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/index.js +0 -0
- package/dist/cli-core/__tests__/adapters.test.d.ts +1 -0
- package/dist/cli-core/__tests__/adapters.test.js +123 -0
- package/dist/cli-core/__tests__/adapters.test.js.map +1 -0
- package/dist/cli-core/__tests__/guard.test.js +51 -13
- package/dist/cli-core/__tests__/guard.test.js.map +1 -1
- package/dist/cli-core/__tests__/init-manager.test.js +3 -3
- package/dist/cli-core/__tests__/init-manager.test.js.map +1 -1
- package/dist/cli-core/__tests__/platform-client.test.d.ts +1 -0
- package/dist/cli-core/__tests__/platform-client.test.js +157 -0
- package/dist/cli-core/__tests__/platform-client.test.js.map +1 -0
- package/dist/cli-core/__tests__/quality-check.test.d.ts +1 -0
- package/dist/cli-core/__tests__/quality-check.test.js +138 -0
- package/dist/cli-core/__tests__/quality-check.test.js.map +1 -0
- package/dist/cli-core/__tests__/state-manager.test.js +7 -7
- package/dist/cli-core/__tests__/state-manager.test.js.map +1 -1
- package/dist/cli-core/adapters/claude-code.js +8 -8
- package/dist/cli-core/adapters/codex.d.ts +5 -0
- package/dist/cli-core/adapters/codex.js +118 -0
- package/dist/cli-core/adapters/codex.js.map +1 -0
- package/dist/cli-core/adapters/hermes-agent.d.ts +5 -0
- package/dist/cli-core/adapters/hermes-agent.js +113 -0
- package/dist/cli-core/adapters/hermes-agent.js.map +1 -0
- package/dist/cli-core/adapters/openclaw.d.ts +5 -0
- package/dist/cli-core/adapters/openclaw.js +115 -0
- package/dist/cli-core/adapters/openclaw.js.map +1 -0
- package/dist/cli-core/adapters/opencode.d.ts +5 -0
- package/dist/cli-core/adapters/opencode.js +116 -0
- package/dist/cli-core/adapters/opencode.js.map +1 -0
- package/dist/cli-core/guard.d.ts +9 -1
- package/dist/cli-core/guard.js +48 -16
- package/dist/cli-core/guard.js.map +1 -1
- package/dist/cli-core/init-manager.d.ts +1 -0
- package/dist/cli-core/init-manager.js +48 -8
- package/dist/cli-core/init-manager.js.map +1 -1
- package/dist/cli-core/platform-client.d.ts +12 -0
- package/dist/cli-core/platform-client.js +150 -9
- package/dist/cli-core/platform-client.js.map +1 -1
- package/dist/cli-core/quality-check.d.ts +8 -0
- package/dist/cli-core/quality-check.js +67 -0
- package/dist/cli-core/quality-check.js.map +1 -0
- package/dist/cli-core/types.d.ts +1 -0
- package/package.json +17 -4
|
@@ -0,0 +1,157 @@
|
|
|
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
|
+
const events_1 = require("events");
|
|
37
|
+
const child_process = __importStar(require("child_process"));
|
|
38
|
+
// Mock child_process before importing platform-client
|
|
39
|
+
jest.mock('child_process');
|
|
40
|
+
const platform_client_1 = require("../platform-client");
|
|
41
|
+
function createMockChild(exitCode = 0, stdout = 'mock output', stderr = '') {
|
|
42
|
+
const child = new events_1.EventEmitter();
|
|
43
|
+
child.stdin = { write: jest.fn(), end: jest.fn() };
|
|
44
|
+
child.stdout = new events_1.EventEmitter();
|
|
45
|
+
child.stderr = new events_1.EventEmitter();
|
|
46
|
+
child.pid = 12345;
|
|
47
|
+
process.nextTick(() => {
|
|
48
|
+
child.stdout.emit('data', Buffer.from(stdout));
|
|
49
|
+
child.stderr.emit('data', Buffer.from(stderr));
|
|
50
|
+
child.emit('close', exitCode);
|
|
51
|
+
});
|
|
52
|
+
return child;
|
|
53
|
+
}
|
|
54
|
+
describe('PlatformClient implementations', () => {
|
|
55
|
+
beforeEach(() => {
|
|
56
|
+
jest.clearAllMocks();
|
|
57
|
+
});
|
|
58
|
+
describe('CodexClient', () => {
|
|
59
|
+
test('calls codex --quiet via stdin', async () => {
|
|
60
|
+
const child = createMockChild(0, 'codex response');
|
|
61
|
+
child_process.spawn.mockReturnValue(child);
|
|
62
|
+
const client = new platform_client_1.CodexClient();
|
|
63
|
+
const result = await client.sendPrompt('test prompt');
|
|
64
|
+
expect(child_process.spawn).toHaveBeenCalledWith('codex', ['--quiet'], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
65
|
+
expect(child.stdin.write).toHaveBeenCalledWith('test prompt');
|
|
66
|
+
expect(child.stdin.end).toHaveBeenCalled();
|
|
67
|
+
expect(result.content).toBe('codex response');
|
|
68
|
+
});
|
|
69
|
+
test('passes --model flag when specified', async () => {
|
|
70
|
+
const child = createMockChild(0, 'output');
|
|
71
|
+
child_process.spawn.mockReturnValue(child);
|
|
72
|
+
const client = new platform_client_1.CodexClient();
|
|
73
|
+
await client.sendPrompt('prompt', { model: 'o4-mini' });
|
|
74
|
+
expect(child_process.spawn).toHaveBeenCalledWith('codex', ['--quiet', '--model', 'o4-mini'], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
75
|
+
});
|
|
76
|
+
test('rejects on non-zero exit code', async () => {
|
|
77
|
+
const child = createMockChild(1, '', 'error message');
|
|
78
|
+
child_process.spawn.mockReturnValue(child);
|
|
79
|
+
const client = new platform_client_1.CodexClient();
|
|
80
|
+
await expect(client.sendPrompt('prompt')).rejects.toThrow('Codex CLI exit 1');
|
|
81
|
+
});
|
|
82
|
+
test('rejects on spawn error', async () => {
|
|
83
|
+
const child = new events_1.EventEmitter();
|
|
84
|
+
child.stdin = { write: jest.fn(), end: jest.fn() };
|
|
85
|
+
child.stdout = new events_1.EventEmitter();
|
|
86
|
+
child.stderr = new events_1.EventEmitter();
|
|
87
|
+
child_process.spawn.mockReturnValue(child);
|
|
88
|
+
process.nextTick(() => child.emit('error', new Error('ENOENT')));
|
|
89
|
+
const client = new platform_client_1.CodexClient();
|
|
90
|
+
await expect(client.sendPrompt('prompt')).rejects.toThrow('ENOENT');
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
describe('OpenClawClient', () => {
|
|
94
|
+
test('calls openclaw --print via stdin', async () => {
|
|
95
|
+
const child = createMockChild(0, 'openclaw response');
|
|
96
|
+
child_process.spawn.mockReturnValue(child);
|
|
97
|
+
const client = new platform_client_1.OpenClawClient();
|
|
98
|
+
const result = await client.sendPrompt('test prompt');
|
|
99
|
+
expect(child_process.spawn).toHaveBeenCalledWith('openclaw', ['--print'], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
100
|
+
expect(result.content).toBe('openclaw response');
|
|
101
|
+
});
|
|
102
|
+
test('rejects on non-zero exit code', async () => {
|
|
103
|
+
const child = createMockChild(1, '', 'err');
|
|
104
|
+
child_process.spawn.mockReturnValue(child);
|
|
105
|
+
const client = new platform_client_1.OpenClawClient();
|
|
106
|
+
await expect(client.sendPrompt('p')).rejects.toThrow('OpenClaw CLI exit 1');
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('HermesAgentClient', () => {
|
|
110
|
+
test('calls hermes-agent --print via stdin', async () => {
|
|
111
|
+
const child = createMockChild(0, 'hermes response');
|
|
112
|
+
child_process.spawn.mockReturnValue(child);
|
|
113
|
+
const client = new platform_client_1.HermesAgentClient();
|
|
114
|
+
const result = await client.sendPrompt('test prompt');
|
|
115
|
+
expect(child_process.spawn).toHaveBeenCalledWith('hermes-agent', ['--print'], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
116
|
+
expect(result.content).toBe('hermes response');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
describe('OpenCodeClient', () => {
|
|
120
|
+
test('calls opencode with run subcommand (not stdin)', async () => {
|
|
121
|
+
const child = createMockChild(0, 'opencode response');
|
|
122
|
+
child_process.spawn.mockReturnValue(child);
|
|
123
|
+
const client = new platform_client_1.OpenCodeClient();
|
|
124
|
+
const result = await client.sendPrompt('test prompt');
|
|
125
|
+
expect(child_process.spawn).toHaveBeenCalledWith('opencode', ['run', 'test prompt'], { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
126
|
+
expect(child.stdin.write).not.toHaveBeenCalled();
|
|
127
|
+
expect(result.content).toBe('opencode response');
|
|
128
|
+
});
|
|
129
|
+
test('rejects on non-zero exit code', async () => {
|
|
130
|
+
const child = createMockChild(1, '', 'err');
|
|
131
|
+
child_process.spawn.mockReturnValue(child);
|
|
132
|
+
const client = new platform_client_1.OpenCodeClient();
|
|
133
|
+
await expect(client.sendPrompt('p')).rejects.toThrow('OpenCode CLI exit 1');
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe('resolvePlatformClient', () => {
|
|
138
|
+
const fs = require('fs/promises');
|
|
139
|
+
beforeEach(() => {
|
|
140
|
+
jest.restoreAllMocks();
|
|
141
|
+
});
|
|
142
|
+
test('returns ClaudeCodeClient by default', async () => {
|
|
143
|
+
jest.spyOn(fs, 'readFile').mockRejectedValue(new Error('ENOENT'));
|
|
144
|
+
const client = await (0, platform_client_1.resolvePlatformClient)('/tmp');
|
|
145
|
+
expect(client).toBeInstanceOf(platform_client_1.ClaudeCodeClient);
|
|
146
|
+
});
|
|
147
|
+
test('returns CodexClient when environment is codex', async () => {
|
|
148
|
+
jest.spyOn(fs, 'readFile').mockResolvedValue('version: 1\nenvironment:\n - codex\n');
|
|
149
|
+
const client = await (0, platform_client_1.resolvePlatformClient)('/tmp');
|
|
150
|
+
expect(client).toBeInstanceOf(platform_client_1.CodexClient);
|
|
151
|
+
});
|
|
152
|
+
test('throws on unsupported environment', async () => {
|
|
153
|
+
jest.spyOn(fs, 'readFile').mockResolvedValue('version: 1\nenvironment:\n - unknown-platform\n');
|
|
154
|
+
await expect((0, platform_client_1.resolvePlatformClient)('/tmp')).rejects.toThrow('Unsupported environment');
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
//# sourceMappingURL=platform-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-client.test.js","sourceRoot":"","sources":["../../../src/cli-core/__tests__/platform-client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const quality_check_1 = require("../quality-check");
|
|
4
|
+
describe('validateTaskSchema', () => {
|
|
5
|
+
test('passes when all tasks have required fields', () => {
|
|
6
|
+
const tasks = [
|
|
7
|
+
{ id: 'task-1', title: 'Do thing', type: 'implementation', files: [{ path: 'x.ts', action: 'create' }], acceptance: ['Works'] },
|
|
8
|
+
];
|
|
9
|
+
expect((0, quality_check_1.validateTaskSchema)(tasks).pass).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
test('fails when a task is missing id', () => {
|
|
12
|
+
const tasks = [
|
|
13
|
+
{ title: 'No ID', type: 'implementation', files: [], acceptance: [] },
|
|
14
|
+
];
|
|
15
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
16
|
+
expect(r.pass).toBe(false);
|
|
17
|
+
expect(r.errors.some(e => e.includes('missing') && e.includes('id'))).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
test('fails when a task is missing files', () => {
|
|
20
|
+
const tasks = [
|
|
21
|
+
{ id: 't1', title: 'X', type: 'implementation', acceptance: ['Works'] },
|
|
22
|
+
];
|
|
23
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
24
|
+
expect(r.pass).toBe(false);
|
|
25
|
+
expect(r.errors.some(e => e.includes('files'))).toBe(true);
|
|
26
|
+
});
|
|
27
|
+
test('fails when a task is missing acceptance', () => {
|
|
28
|
+
const tasks = [
|
|
29
|
+
{ id: 't1', title: 'X', type: 'implementation', files: [{ path: 'x.ts', action: 'create' }] },
|
|
30
|
+
];
|
|
31
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
32
|
+
expect(r.pass).toBe(false);
|
|
33
|
+
expect(r.errors.some(e => e.includes('acceptance'))).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
test('reports all failing tasks', () => {
|
|
36
|
+
const tasks = [
|
|
37
|
+
{ title: 'No ID 1', type: 'implementation', files: [], acceptance: [] },
|
|
38
|
+
{ title: 'No ID 2', type: 'testing', files: [], acceptance: [] },
|
|
39
|
+
];
|
|
40
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
41
|
+
expect(r.pass).toBe(false);
|
|
42
|
+
expect(r.errors.length).toBe(2);
|
|
43
|
+
});
|
|
44
|
+
test('fails when a task is missing title', () => {
|
|
45
|
+
const tasks = [
|
|
46
|
+
{ id: 't1', type: 'implementation', files: [{ path: 'x.ts', action: 'create' }], acceptance: ['Works'] },
|
|
47
|
+
];
|
|
48
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
49
|
+
expect(r.pass).toBe(false);
|
|
50
|
+
expect(r.errors.some(e => e.includes('missing') && e.includes('title'))).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
test('fails when a task is missing type', () => {
|
|
53
|
+
const tasks = [
|
|
54
|
+
{ id: 't1', title: 'X', files: [{ path: 'x.ts', action: 'create' }], acceptance: ['Works'] },
|
|
55
|
+
];
|
|
56
|
+
const r = (0, quality_check_1.validateTaskSchema)(tasks);
|
|
57
|
+
expect(r.pass).toBe(false);
|
|
58
|
+
expect(r.errors.some(e => e.includes('missing') && e.includes('type'))).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
describe('validateTaskIds', () => {
|
|
62
|
+
test('passes when all ids are unique kebab-case', () => {
|
|
63
|
+
const tasks = [
|
|
64
|
+
{ id: 'task-one' }, { id: 'task-two' }, { id: 'task-3' },
|
|
65
|
+
];
|
|
66
|
+
expect((0, quality_check_1.validateTaskIds)(tasks).pass).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
test('fails on duplicate ids', () => {
|
|
69
|
+
const tasks = [
|
|
70
|
+
{ id: 'task-one' }, { id: 'task-one' },
|
|
71
|
+
];
|
|
72
|
+
const r = (0, quality_check_1.validateTaskIds)(tasks);
|
|
73
|
+
expect(r.pass).toBe(false);
|
|
74
|
+
expect(r.errors[0]).toContain('duplicate');
|
|
75
|
+
});
|
|
76
|
+
test('fails on non-kebab-case ids', () => {
|
|
77
|
+
const tasks = [
|
|
78
|
+
{ id: 'task_one' }, { id: 'TaskTwo' },
|
|
79
|
+
];
|
|
80
|
+
const r = (0, quality_check_1.validateTaskIds)(tasks);
|
|
81
|
+
expect(r.pass).toBe(false);
|
|
82
|
+
expect(r.errors.length).toBe(2);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
describe('validateAcceptance', () => {
|
|
86
|
+
test('passes when all tasks have non-empty acceptance arrays', () => {
|
|
87
|
+
const tasks = [
|
|
88
|
+
{ id: 't1', acceptance: ['Must work'] },
|
|
89
|
+
{ id: 't2', acceptance: ['A', 'B'] },
|
|
90
|
+
];
|
|
91
|
+
expect((0, quality_check_1.validateAcceptance)(tasks).pass).toBe(true);
|
|
92
|
+
});
|
|
93
|
+
test('fails when acceptance is empty array', () => {
|
|
94
|
+
const tasks = [
|
|
95
|
+
{ id: 't1', acceptance: [] },
|
|
96
|
+
];
|
|
97
|
+
const r = (0, quality_check_1.validateAcceptance)(tasks);
|
|
98
|
+
expect(r.pass).toBe(false);
|
|
99
|
+
expect(r.errors[0]).toContain('empty');
|
|
100
|
+
});
|
|
101
|
+
test('fails when acceptance is missing', () => {
|
|
102
|
+
const tasks = [{ id: 't1' }];
|
|
103
|
+
const r = (0, quality_check_1.validateAcceptance)(tasks);
|
|
104
|
+
expect(r.pass).toBe(false);
|
|
105
|
+
expect(r.errors[0]).toContain('missing');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
describe('validateFiles', () => {
|
|
109
|
+
test('passes when all tasks have files with path and action', () => {
|
|
110
|
+
const tasks = [
|
|
111
|
+
{ id: 't1', files: [{ path: 'a.ts', action: 'create' }] },
|
|
112
|
+
];
|
|
113
|
+
expect((0, quality_check_1.validateFiles)(tasks).pass).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
test('fails when files is empty', () => {
|
|
116
|
+
const tasks = [{ id: 't1', files: [] }];
|
|
117
|
+
const r = (0, quality_check_1.validateFiles)(tasks);
|
|
118
|
+
expect(r.pass).toBe(false);
|
|
119
|
+
expect(r.errors[0]).toContain('empty');
|
|
120
|
+
});
|
|
121
|
+
test('fails when a file entry is missing action', () => {
|
|
122
|
+
const tasks = [
|
|
123
|
+
{ id: 't1', files: [{ path: 'a.ts' }] },
|
|
124
|
+
];
|
|
125
|
+
const r = (0, quality_check_1.validateFiles)(tasks);
|
|
126
|
+
expect(r.pass).toBe(false);
|
|
127
|
+
expect(r.errors[0]).toContain('action');
|
|
128
|
+
});
|
|
129
|
+
test('fails when a file entry is missing path', () => {
|
|
130
|
+
const tasks = [
|
|
131
|
+
{ id: 't1', files: [{ action: 'create' }] },
|
|
132
|
+
];
|
|
133
|
+
const r = (0, quality_check_1.validateFiles)(tasks);
|
|
134
|
+
expect(r.pass).toBe(false);
|
|
135
|
+
expect(r.errors[0]).toContain('path');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=quality-check.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-check.test.js","sourceRoot":"","sources":["../../../src/cli-core/__tests__/quality-check.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,9 +46,9 @@ describe('StateManager', () => {
|
|
|
46
46
|
project: 'test-project',
|
|
47
47
|
environment: ['claude-code'],
|
|
48
48
|
phases: {
|
|
49
|
-
|
|
49
|
+
propose: { status: 'pending', proposal: '' },
|
|
50
50
|
design: { status: 'pending', designDoc: '', tasks: [] },
|
|
51
|
-
|
|
51
|
+
implement: { status: 'pending', tasks: {} },
|
|
52
52
|
verify: { status: 'pending', pipelineResult: null },
|
|
53
53
|
archive: { status: 'pending' },
|
|
54
54
|
},
|
|
@@ -75,21 +75,21 @@ describe('StateManager', () => {
|
|
|
75
75
|
test('update atomically modifies state', async () => {
|
|
76
76
|
await writeState(baseState);
|
|
77
77
|
const next = await state_1.StateManager.update((s) => {
|
|
78
|
-
s.phases.
|
|
78
|
+
s.phases.propose.status = 'done';
|
|
79
79
|
return s;
|
|
80
80
|
});
|
|
81
|
-
expect(next.phases.
|
|
81
|
+
expect(next.phases.propose.status).toBe('done');
|
|
82
82
|
expect(next.metadata.stateVersion).toBe(1);
|
|
83
83
|
expect(next.metadata.lastModified).toBeTruthy();
|
|
84
84
|
const raw = await fs.readFile('.nova.yaml', 'utf-8');
|
|
85
85
|
const disk = yaml.parse(raw);
|
|
86
|
-
expect(disk.phases.
|
|
86
|
+
expect(disk.phases.propose.status).toBe('done');
|
|
87
87
|
});
|
|
88
88
|
test('setPhaseField updates a single phase field', async () => {
|
|
89
89
|
await writeState(baseState);
|
|
90
|
-
await state_1.StateManager.setPhaseField('
|
|
90
|
+
await state_1.StateManager.setPhaseField('implement', 'status', 'in-progress');
|
|
91
91
|
const state = await state_1.StateManager.load();
|
|
92
|
-
expect(state.phases.
|
|
92
|
+
expect(state.phases.implement.status).toBe('in-progress');
|
|
93
93
|
});
|
|
94
94
|
test('getTask finds task by id', async () => {
|
|
95
95
|
const stateWithTasks = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-manager.test.js","sourceRoot":"","sources":["../../../src/cli-core/__tests__/state-manager.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,2CAA6B;AAC7B,uCAAyB;AACzB,2CAA6B;AAC7B,oCAAwC;AAExC,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,OAAe,CAAC;IACpB,IAAI,WAAmB,CAAC;IAExB,MAAM,SAAS,GAAG;QAChB,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,CAAC,aAAa,CAAC;QAC5B,MAAM,EAAE;YACN,
|
|
1
|
+
{"version":3,"file":"state-manager.test.js","sourceRoot":"","sources":["../../../src/cli-core/__tests__/state-manager.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,2CAA6B;AAC7B,uCAAyB;AACzB,2CAA6B;AAC7B,oCAAwC;AAExC,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAI,OAAe,CAAC;IACpB,IAAI,WAAmB,CAAC;IAExB,MAAM,SAAS,GAAG;QAChB,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,cAAc;QACvB,WAAW,EAAE,CAAC,aAAa,CAAC;QAC5B,MAAM,EAAE;YACN,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE;YAC5C,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YACvD,SAAS,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE;YAC3C,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE;YACnD,OAAO,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE;SAC/B;QACD,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;KAC7D,CAAC;IAEF,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC;QAClE,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAC3B,MAAM,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,KAAK,UAAU,UAAU,CAAC,IAAS;QACjC,MAAM,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,IAAI,CAAC,uBAAuB,EAAE,KAAK,IAAI,EAAE;QACvC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,KAAK,GAAG,MAAM,oBAAY,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,oBAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;YACjC,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,UAAU,EAAE,CAAC;QAEhD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,oBAAY,CAAC,aAAa,CAAC,WAAW,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;QAEvE,MAAM,KAAK,GAAG,MAAM,oBAAY,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;QAC1C,MAAM,cAAc,GAAG;YACrB,GAAG,SAAS;YACZ,MAAM,EAAE;gBACN,GAAG,SAAS,CAAC,MAAM;gBACnB,MAAM,EAAE;oBACN,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM;oBAC1B,KAAK,EAAE;wBACL,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE;wBACrC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE;qBACvC;iBACF;aACF;SACF,CAAC;QACF,MAAM,UAAU,CAAC,cAAc,CAAC,CAAC;QAEjC,MAAM,IAAI,GAAG,MAAM,oBAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClD,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC;QAC5B,MAAM,IAAI,GAAG,MAAM,oBAAY,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACvD,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -88,7 +88,7 @@ You are executing the **propose phase** of a Nova workflow. Your role is to
|
|
|
88
88
|
orchestrate requirements exploration and produce a structured proposal document.
|
|
89
89
|
|
|
90
90
|
## Step 1: Verify State
|
|
91
|
-
Read \`.nova.yaml\`. Check \`phases.
|
|
91
|
+
Read \`.nova.yaml\`. Check \`phases.propose.status\`. If pending, update to
|
|
92
92
|
\`in-progress\` and set \`startedAt\`.
|
|
93
93
|
|
|
94
94
|
## Step 2: Gather Context
|
|
@@ -106,8 +106,8 @@ User Stories (prioritized), Scope & Deliverables (in/out), Success Criteria
|
|
|
106
106
|
(measurable), Risks & Constraints.
|
|
107
107
|
|
|
108
108
|
## Step 5: Update State
|
|
109
|
-
Set \`phases.
|
|
110
|
-
\`phases.
|
|
109
|
+
Set \`phases.propose.status = 'in-progress'\`,
|
|
110
|
+
\`phases.propose.proposal = 'docs/proposals/proposal.md'\`.
|
|
111
111
|
|
|
112
112
|
## Constraints
|
|
113
113
|
- Read any file for context. Write only to \`docs/proposals/\` and \`.nova.yaml\`.
|
|
@@ -124,11 +124,11 @@ orchestrate architecture exploration and produce a design document with an
|
|
|
124
124
|
actionable task list.
|
|
125
125
|
|
|
126
126
|
## Step 1: Verify State
|
|
127
|
-
Read \`.nova.yaml\`. Require \`phases.
|
|
127
|
+
Read \`.nova.yaml\`. Require \`phases.propose.status: done\` with a non-empty proposal.
|
|
128
128
|
Update \`phases.design.status\` to \`in-progress\` and set \`startedAt\`.
|
|
129
129
|
|
|
130
130
|
## Step 2: Load Context
|
|
131
|
-
Read the proposal (\`phases.
|
|
131
|
+
Read the proposal (\`phases.propose.proposal\`), \`AGENTS.md\`, \`package.json\`, \`src/\`.
|
|
132
132
|
|
|
133
133
|
## Step 3: Explore Architecture Options
|
|
134
134
|
Use the **brainstorming skill** to explore at least 2 architectural approaches.
|
|
@@ -162,7 +162,7 @@ execute each task from the design phase, routing by task type.
|
|
|
162
162
|
|
|
163
163
|
## Step 1: Verify State
|
|
164
164
|
Read \`.nova.yaml\`. Require \`phases.design.status: done\` with non-empty tasks.
|
|
165
|
-
Update \`phases.
|
|
165
|
+
Update \`phases.implement.status\` to \`in-progress\` and set \`startedAt\`.
|
|
166
166
|
|
|
167
167
|
## Step 2: Load Task List
|
|
168
168
|
Show task summary (id, title, type, priority). Ask user to confirm before
|
|
@@ -189,7 +189,7 @@ On failure, ask user: abort, skip, or retry.
|
|
|
189
189
|
Run full test suite and type check. Report summary.
|
|
190
190
|
|
|
191
191
|
## Step 5: Update State
|
|
192
|
-
Set \`phases.
|
|
192
|
+
Set \`phases.implement.status = 'done'\`.
|
|
193
193
|
|
|
194
194
|
## Constraints
|
|
195
195
|
- Follow existing project conventions. Never leave TODOs or stubs.
|
|
@@ -205,7 +205,7 @@ You are executing the **verify phase** of a Nova workflow. Your role is to
|
|
|
205
205
|
orchestrate a verification pipeline using ECC review skills.
|
|
206
206
|
|
|
207
207
|
## Step 1: Verify State
|
|
208
|
-
Read \`.nova.yaml\`. Require \`phases.
|
|
208
|
+
Read \`.nova.yaml\`. Require \`phases.implement.status: done\`.
|
|
209
209
|
Update \`phases.verify.status\` to \`in-progress\` and set \`startedAt\`.
|
|
210
210
|
|
|
211
211
|
## Step 2: Gather Context
|
|
@@ -0,0 +1,118 @@
|
|
|
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.CodexAdapter = void 0;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const CODEX_INSTRUCTIONS = `# Nova Workflow
|
|
40
|
+
|
|
41
|
+
This project uses Nova — an AI-assisted development workflow with 5 phases.
|
|
42
|
+
All state is in \`.nova.yaml\`. Always read it first.
|
|
43
|
+
|
|
44
|
+
## How to Use
|
|
45
|
+
|
|
46
|
+
### Check Status
|
|
47
|
+
\`\`\`
|
|
48
|
+
读取 .nova.yaml,告诉我当前在哪个阶段,下一步该做什么
|
|
49
|
+
\`\`\`
|
|
50
|
+
|
|
51
|
+
### Phase 1: Propose (提案)
|
|
52
|
+
\`\`\`
|
|
53
|
+
帮我为"{你的需求描述}"写一个 proposal。
|
|
54
|
+
1. 先读 .nova.yaml 和已有代码了解项目
|
|
55
|
+
2. 问 3-4 个澄清问题
|
|
56
|
+
3. 写入 docs/proposals/proposal.md
|
|
57
|
+
4. 更新 .nova.yaml: phases.propose.status = done
|
|
58
|
+
\`\`\`
|
|
59
|
+
|
|
60
|
+
### Phase 2: Design (设计)
|
|
61
|
+
\`\`\`
|
|
62
|
+
读取 docs/proposals/proposal.md,生成技术设计文档。
|
|
63
|
+
1. 读 proposal 和 src/ 了解架构
|
|
64
|
+
2. 写入 docs/designs/design.md,包含架构、组件、YAML 任务列表
|
|
65
|
+
3. 更新 .nova.yaml: phases.design.status = done, tasks = 解析后的列表
|
|
66
|
+
\`\`\`
|
|
67
|
+
|
|
68
|
+
### Phase 3: Implement (实现)
|
|
69
|
+
\`\`\`
|
|
70
|
+
读取 .nova.yaml 中的 tasks,逐个实现:
|
|
71
|
+
1. 按 priority 排序执行
|
|
72
|
+
2. 每个任务:写代码 → tsc --noEmit → npm test → 更新 task status = done
|
|
73
|
+
3. 失败时问用户:abort / skip / retry
|
|
74
|
+
4. 全部完成后更新 phases.implement.status = done
|
|
75
|
+
\`\`\`
|
|
76
|
+
|
|
77
|
+
### Phase 4: Verify (验证)
|
|
78
|
+
\`\`\`
|
|
79
|
+
对已修改的文件做 code review + security review:
|
|
80
|
+
1. Code review: 正确性、错误处理、类型安全、测试覆盖
|
|
81
|
+
2. Security review: 注入、密钥暴露、路径遍历
|
|
82
|
+
3. 写入 docs/designs/verification-report.md
|
|
83
|
+
4. 更新 phases.verify.status = done
|
|
84
|
+
\`\`\`
|
|
85
|
+
|
|
86
|
+
### Phase 5: Archive (归档)
|
|
87
|
+
\`\`\`
|
|
88
|
+
运行 nova archive 合并产物并清理
|
|
89
|
+
\`\`\`
|
|
90
|
+
|
|
91
|
+
### Iteration (回退)
|
|
92
|
+
\`\`\`
|
|
93
|
+
我想回退到 {propose/design/implement} 阶段重新做
|
|
94
|
+
\`\`\`
|
|
95
|
+
|
|
96
|
+
## Key Rules
|
|
97
|
+
|
|
98
|
+
- Always read \`.nova.yaml\` before any action
|
|
99
|
+
- After each task, run \`npx tsc --noEmit\` and \`npm test\`
|
|
100
|
+
- Never leave TODOs or stubs
|
|
101
|
+
- Update \`.nova.yaml\` status after each phase transition
|
|
102
|
+
`;
|
|
103
|
+
class CodexAdapter {
|
|
104
|
+
constructor() {
|
|
105
|
+
this.name = 'codex';
|
|
106
|
+
}
|
|
107
|
+
async setup(cwd) {
|
|
108
|
+
const filePath = path.join(cwd, 'CODEX.md');
|
|
109
|
+
try {
|
|
110
|
+
await fs.access(filePath);
|
|
111
|
+
return; // don't overwrite
|
|
112
|
+
}
|
|
113
|
+
catch { }
|
|
114
|
+
await fs.writeFile(filePath, CODEX_INSTRUCTIONS, 'utf-8');
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.CodexAdapter = CodexAdapter;
|
|
118
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/cli-core/adapters/codex.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAAkC;AAClC,2CAA6B;AAG7B,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+D1B,CAAC;AAEF,MAAa,YAAY;IAAzB;QACE,SAAI,GAAG,OAAO,CAAC;IAUjB,CAAC;IARC,KAAK,CAAC,KAAK,CAAC,GAAW;QACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC1B,OAAO,CAAC,kBAAkB;QAC5B,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;CACF;AAXD,oCAWC"}
|