@pixel613/spec 1.0.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.
Files changed (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +174 -0
  3. package/dist/bin/pxs.d.ts +2 -0
  4. package/dist/bin/pxs.js +5 -0
  5. package/dist/bin/pxs.js.map +1 -0
  6. package/dist/src/backends/claude.d.ts +9 -0
  7. package/dist/src/backends/claude.js +80 -0
  8. package/dist/src/backends/claude.js.map +1 -0
  9. package/dist/src/backends/codex.d.ts +9 -0
  10. package/dist/src/backends/codex.js +72 -0
  11. package/dist/src/backends/codex.js.map +1 -0
  12. package/dist/src/backends/factory.d.ts +2 -0
  13. package/dist/src/backends/factory.js +14 -0
  14. package/dist/src/backends/factory.js.map +1 -0
  15. package/dist/src/backends/interface.d.ts +15 -0
  16. package/dist/src/backends/interface.js +2 -0
  17. package/dist/src/backends/interface.js.map +1 -0
  18. package/dist/src/cli.d.ts +2 -0
  19. package/dist/src/cli.js +79 -0
  20. package/dist/src/cli.js.map +1 -0
  21. package/dist/src/commands/clarify.d.ts +5 -0
  22. package/dist/src/commands/clarify.js +46 -0
  23. package/dist/src/commands/clarify.js.map +1 -0
  24. package/dist/src/commands/implement.d.ts +9 -0
  25. package/dist/src/commands/implement.js +244 -0
  26. package/dist/src/commands/implement.js.map +1 -0
  27. package/dist/src/commands/init.d.ts +6 -0
  28. package/dist/src/commands/init.js +177 -0
  29. package/dist/src/commands/init.js.map +1 -0
  30. package/dist/src/commands/new.d.ts +5 -0
  31. package/dist/src/commands/new.js +143 -0
  32. package/dist/src/commands/new.js.map +1 -0
  33. package/dist/src/commands/refine.d.ts +8 -0
  34. package/dist/src/commands/refine.js +158 -0
  35. package/dist/src/commands/refine.js.map +1 -0
  36. package/dist/src/commands/review.d.ts +4 -0
  37. package/dist/src/commands/review.js +70 -0
  38. package/dist/src/commands/review.js.map +1 -0
  39. package/dist/src/commands/status.d.ts +1 -0
  40. package/dist/src/commands/status.js +53 -0
  41. package/dist/src/commands/status.js.map +1 -0
  42. package/dist/src/discovery/project.d.ts +7 -0
  43. package/dist/src/discovery/project.js +90 -0
  44. package/dist/src/discovery/project.js.map +1 -0
  45. package/dist/src/git/operations.d.ts +10 -0
  46. package/dist/src/git/operations.js +56 -0
  47. package/dist/src/git/operations.js.map +1 -0
  48. package/dist/src/parsers/arguments.d.ts +18 -0
  49. package/dist/src/parsers/arguments.js +43 -0
  50. package/dist/src/parsers/arguments.js.map +1 -0
  51. package/dist/src/parsers/plan.d.ts +23 -0
  52. package/dist/src/parsers/plan.js +117 -0
  53. package/dist/src/parsers/plan.js.map +1 -0
  54. package/dist/src/parsers/spec.d.ts +10 -0
  55. package/dist/src/parsers/spec.js +46 -0
  56. package/dist/src/parsers/spec.js.map +1 -0
  57. package/dist/src/state/manager.d.ts +24 -0
  58. package/dist/src/state/manager.js +103 -0
  59. package/dist/src/state/manager.js.map +1 -0
  60. package/dist/src/state/types.d.ts +47 -0
  61. package/dist/src/state/types.js +21 -0
  62. package/dist/src/state/types.js.map +1 -0
  63. package/dist/src/utils/display.d.ts +7 -0
  64. package/dist/src/utils/display.js +42 -0
  65. package/dist/src/utils/display.js.map +1 -0
  66. package/dist/src/utils/prompt.d.ts +31 -0
  67. package/dist/src/utils/prompt.js +81 -0
  68. package/dist/src/utils/prompt.js.map +1 -0
  69. package/package.json +52 -0
  70. package/templates/agents-md-snippet.md +20 -0
  71. package/templates/architectures/clean/csharp-aspnet.md +56 -0
  72. package/templates/architectures/clean/go-gin.md +50 -0
  73. package/templates/architectures/clean/go-std.md +49 -0
  74. package/templates/architectures/clean/python-fastapi.md +49 -0
  75. package/templates/architectures/clean/typescript-express.md +60 -0
  76. package/templates/architectures/clean/typescript-nestjs.md +61 -0
  77. package/templates/architectures/ddd/csharp-aspnet.md +55 -0
  78. package/templates/architectures/ddd/go-gin.md +53 -0
  79. package/templates/architectures/ddd/python-fastapi.md +52 -0
  80. package/templates/architectures/ddd/typescript-nestjs.md +62 -0
  81. package/templates/architectures/hexagonal/csharp-aspnet.md +45 -0
  82. package/templates/architectures/hexagonal/go-gin.md +47 -0
  83. package/templates/architectures/hexagonal/python-fastapi.md +43 -0
  84. package/templates/architectures/hexagonal/typescript-nestjs.md +44 -0
  85. package/templates/architectures/layered/csharp-aspnet.md +45 -0
  86. package/templates/architectures/layered/go-gin.md +41 -0
  87. package/templates/architectures/layered/python-fastapi.md +42 -0
  88. package/templates/architectures/layered/typescript-nestjs.md +48 -0
  89. package/templates/architectures/modular/csharp-aspnet.md +45 -0
  90. package/templates/architectures/modular/go-gin.md +47 -0
  91. package/templates/architectures/modular/python-fastapi.md +45 -0
  92. package/templates/architectures/modular/typescript-nestjs.md +48 -0
  93. package/templates/claude-commands/sf.clarify.md +18 -0
  94. package/templates/claude-commands/sf.implement.md +79 -0
  95. package/templates/claude-commands/sf.new.md +22 -0
  96. package/templates/claude-commands/sf.refine.md +47 -0
  97. package/templates/claude-commands/sf.review.md +17 -0
  98. package/templates/claude-commands/sf.status.md +12 -0
  99. package/templates/workflow/config.yaml +17 -0
  100. package/templates/workflow/prompts/clarify.md +39 -0
  101. package/templates/workflow/prompts/final-review.md +30 -0
  102. package/templates/workflow/prompts/implement-tdd.md +35 -0
  103. package/templates/workflow/prompts/implement.md +43 -0
  104. package/templates/workflow/prompts/refine.md +52 -0
  105. package/templates/workflow/prompts/review.md +34 -0
  106. package/templates/workflow/prompts/test.md +14 -0
  107. package/templates/workflow/templates/spec-template.md +13 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pixel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,174 @@
1
+ # @pixel613/spec (pxs)
2
+
3
+ Spec-driven development CLI for Claude Code. Write a spec, refine a plan, implement task by task — all powered by AI.
4
+
5
+ `@pixel613/spec` 是一套為 Claude Code 設計的規格驅動開發 CLI。撰寫規格、拆解計畫、逐步實作,全程 AI 驅動。
6
+
7
+ > **Supported backend: Claude Code only**
8
+
9
+ ---
10
+
11
+ ## Installation / 安裝
12
+
13
+ ```bash
14
+ npm install -g @pixel613/spec
15
+ ```
16
+
17
+ ## Quick Start / 快速開始
18
+
19
+ ```bash
20
+ # 1. Initialize workflow in your project / 初始化工作流
21
+ pxs init
22
+
23
+ # 2. Create a spec / 建立規格
24
+ pxs new login-feature --desc "Add JWT login endpoint"
25
+
26
+ # 3. Refine spec into implementation plan / 拆解為實作計畫
27
+ pxs refine login-feature
28
+
29
+ # 4. Implement task by task / 逐步實作
30
+ pxs implement login-feature
31
+
32
+ # 5. Check status / 查看狀態
33
+ pxs status login-feature
34
+ ```
35
+
36
+ ## Commands / 指令
37
+
38
+ ### `pxs init`
39
+
40
+ Initialize `.workflow/` directory and Claude Code slash commands for your project.
41
+
42
+ 在專案中初始化 `.workflow/` 目錄與 Claude Code slash commands。
43
+
44
+ | Option | Description |
45
+ |--------|-------------|
46
+ | `--force` | Overwrite existing `.workflow/` / 覆蓋現有目錄 |
47
+ | `--arch <pattern>` | Architecture pattern: `clean` \| `hexagonal` \| `ddd` \| `layered` \| `modular` \| `custom` |
48
+ | `--lang <lang>` | Language-framework override (e.g. `go`, `typescript`, `go-gin`) |
49
+
50
+ ### `pxs new <name>`
51
+
52
+ Create a new spec file under `.workflow/specs/`.
53
+
54
+ 建立新的規格檔案。
55
+
56
+ | Option | Description |
57
+ |--------|-------------|
58
+ | `--desc <text>` | Generate spec from text description / 從文字描述產生規格 |
59
+ | `--jira <tickets...>` | Import from Jira tickets / 從 Jira ticket 匯入 |
60
+ | `-i, --interactive` | Interactive Q&A mode / 互動問答模式 |
61
+
62
+ ### `pxs refine <name>`
63
+
64
+ Refine spec and decompose into a step-by-step implementation plan.
65
+
66
+ 精煉規格並拆解為逐步實作計畫。
67
+
68
+ | Option | Description |
69
+ |--------|-------------|
70
+ | `--skip-clarify` | Skip requirement clarification / 跳過需求釐清 |
71
+ | `--clarify <n>` | Max clarification rounds / 最大釐清輪數 |
72
+ | `@agent /skill` | Pass agents or skills to assist / 指定 agent 或 skill 協助 |
73
+
74
+ ### `pxs clarify <name>`
75
+
76
+ Run requirement clarification on a spec independently.
77
+
78
+ 獨立執行需求釐清。
79
+
80
+ ### `pxs implement <name>`
81
+
82
+ Implement code task by task with AI. Each task goes through: implement → commit → test (optional) → AI review → user approval.
83
+
84
+ AI 逐步實作。每個 task 流程:實作 → commit → 測試(可選)→ AI review → 使用者審核。
85
+
86
+ After all tasks complete, a **final branch code review** runs automatically against the full diff, spec, and plan.
87
+
88
+ 所有 task 完成後,自動執行**整個 branch 的完整 code review**。
89
+
90
+ | Option | Description |
91
+ |--------|-------------|
92
+ | `--skip-review` | Skip final branch code review / 跳過最終 code review |
93
+ | `@agent /skill` | Pass agents or skills to assist review / 指定 agent 或 skill 協助 review |
94
+
95
+ **Test strategies / 測試策略:**
96
+
97
+ | Flag | Behavior |
98
+ |------|----------|
99
+ | `--test tdd` | TDD: write failing tests → implement → pass → refactor |
100
+ | `--test intg` | Post-hoc integration tests / 整合測試 |
101
+ | `--test tdd intg` | TDD + integration tests |
102
+ | `--test` | Post-hoc unit tests / 單元測試 |
103
+ | *(none)* | No tests / 不產生測試 |
104
+
105
+ ### `pxs review <name>`
106
+
107
+ View review records.
108
+
109
+ 查看 review 紀錄。
110
+
111
+ | Option | Description |
112
+ |--------|-------------|
113
+ | `--step <n>` | View specific task review / 查看特定 task 的 review |
114
+ | `--summary` | Summary overview of all tasks / 所有 task 的摘要 |
115
+ | *(default)* | Shows final branch review if completed, otherwise latest task review / 預設顯示 final review 或最新的 task review |
116
+
117
+ ### `pxs status [name]`
118
+
119
+ View workflow status. Without `<name>`, lists all features.
120
+
121
+ 查看工作流狀態。不帶 `<name>` 則列出所有 feature。
122
+
123
+ ## Workflow / 工作流程
124
+
125
+ ```
126
+ pxs init → pxs new → pxs refine → pxs implement → merge
127
+
128
+ pxs clarify (optional)
129
+ ```
130
+
131
+ ```
132
+ implement 流程:
133
+
134
+ Task 1 → commit → [test] → AI review → approve/skip
135
+ Task 2 → commit → [test] → AI review → approve/skip
136
+ ...
137
+ All tasks complete
138
+
139
+ Final Code Review (full branch diff vs spec + plan)
140
+
141
+ merge / squash-merge / keep-branch
142
+ ```
143
+
144
+ ## Claude Code Integration
145
+
146
+ After `pxs init`, the following slash commands are available in Claude Code:
147
+
148
+ 執行 `pxs init` 後,可在 Claude Code 中使用以下 slash commands:
149
+
150
+ | Slash Command | Description |
151
+ |---------------|-------------|
152
+ | `/pxs:new` | Create a new spec / 建立規格 |
153
+ | `/pxs:refine` | Refine spec into plan / 拆解計畫 |
154
+ | `/pxs:clarify` | Clarify requirements / 釐清需求 |
155
+ | `/pxs:implement` | Implement task by task / 逐步實作 |
156
+ | `/pxs:review` | View reviews / 查看 review |
157
+ | `/pxs:status` | Check status / 查看狀態 |
158
+
159
+ ## Project Structure / 專案結構
160
+
161
+ ```
162
+ .workflow/
163
+ ├── state.yaml # Workflow state / 工作流狀態
164
+ ├── config.yaml # Project config / 專案設定
165
+ ├── architecture.md # Architecture constraints (if --arch) / 架構約束
166
+ ├── specs/ # Feature specs / 功能規格
167
+ ├── plans/ # Implementation plans / 實作計畫
168
+ ├── reviews/ # AI review records / AI review 紀錄
169
+ └── prompts/ # Prompt templates / Prompt 模板
170
+ ```
171
+
172
+ ## License
173
+
174
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { createProgram } from '../src/cli.js';
3
+ const program = createProgram();
4
+ program.parse(process.argv);
5
+ //# sourceMappingURL=pxs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pxs.js","sourceRoot":"","sources":["../../bin/pxs.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,MAAM,OAAO,GAAG,aAAa,EAAE,CAAC;AAChC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { AIBackend, ExecuteOptions, ExecuteResult } from './interface.js';
2
+ export declare class ClaudeBackend implements AIBackend {
3
+ name: string;
4
+ isAvailable(): Promise<boolean>;
5
+ execute(prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
6
+ resume(sessionId: string, prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
7
+ private _run;
8
+ private _parseStreamJson;
9
+ }
@@ -0,0 +1,80 @@
1
+ import { spawn, execFileSync } from 'node:child_process';
2
+ export class ClaudeBackend {
3
+ name = 'claude';
4
+ async isAvailable() {
5
+ try {
6
+ execFileSync('which', ['claude'], { encoding: 'utf-8' });
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ async execute(prompt, opts) {
14
+ return this._run(['claude', '-p', prompt, '--output-format', 'stream-json'], opts);
15
+ }
16
+ async resume(sessionId, prompt, opts) {
17
+ return this._run(['claude', '-p', prompt, '--resume', sessionId, '--output-format', 'stream-json'], opts);
18
+ }
19
+ _run(args, opts) {
20
+ const [cmd, ...cmdArgs] = args;
21
+ return new Promise((resolve, reject) => {
22
+ const child = spawn(cmd, cmdArgs, {
23
+ cwd: opts?.cwd ?? process.cwd(),
24
+ stdio: ['ignore', 'pipe', 'pipe'],
25
+ timeout: opts?.timeout,
26
+ });
27
+ let stdout = '';
28
+ let stderr = '';
29
+ child.stdout.on('data', (data) => {
30
+ stdout += data.toString();
31
+ });
32
+ child.stderr.on('data', (data) => {
33
+ stderr += data.toString();
34
+ });
35
+ child.on('close', (code) => {
36
+ const result = this._parseStreamJson(stdout);
37
+ resolve({
38
+ output: result.output,
39
+ sessionId: result.sessionId,
40
+ exitCode: code ?? 1,
41
+ });
42
+ });
43
+ child.on('error', (err) => {
44
+ reject(new Error(`Claude CLI error: ${err.message}`));
45
+ });
46
+ });
47
+ }
48
+ _parseStreamJson(raw) {
49
+ let output = '';
50
+ let sessionId = '';
51
+ const lines = raw.split('\n').filter((l) => l.trim());
52
+ for (const line of lines) {
53
+ try {
54
+ const json = JSON.parse(line);
55
+ if (json.type === 'assistant' && json.message?.content) {
56
+ for (const block of json.message.content) {
57
+ if (block.type === 'text') {
58
+ output += block.text;
59
+ }
60
+ }
61
+ }
62
+ if (json.session_id) {
63
+ sessionId = json.session_id;
64
+ }
65
+ // Also check result message
66
+ if (json.type === 'result' && json.result) {
67
+ output = json.result;
68
+ }
69
+ if (json.type === 'result' && json.session_id) {
70
+ sessionId = json.session_id;
71
+ }
72
+ }
73
+ catch {
74
+ // Not JSON, skip
75
+ }
76
+ }
77
+ return { output, sessionId };
78
+ }
79
+ }
80
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../src/backends/claude.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { AIBackend, ExecuteOptions, ExecuteResult } from './interface.js';
2
+ export declare class CodexBackend implements AIBackend {
3
+ name: string;
4
+ isAvailable(): Promise<boolean>;
5
+ execute(prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
6
+ resume(sessionId: string, prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
7
+ private _run;
8
+ private _parseJsonl;
9
+ }
@@ -0,0 +1,72 @@
1
+ import { spawn, execFileSync } from 'node:child_process';
2
+ export class CodexBackend {
3
+ name = 'codex';
4
+ async isAvailable() {
5
+ try {
6
+ execFileSync('which', ['codex'], { encoding: 'utf-8' });
7
+ return true;
8
+ }
9
+ catch {
10
+ return false;
11
+ }
12
+ }
13
+ async execute(prompt, opts) {
14
+ return this._run(['codex', 'exec', prompt, '--json'], opts);
15
+ }
16
+ async resume(sessionId, prompt, opts) {
17
+ return this._run(['codex', 'exec', 'resume', sessionId, prompt], opts);
18
+ }
19
+ _run(args, opts) {
20
+ const [cmd, ...cmdArgs] = args;
21
+ return new Promise((resolve, reject) => {
22
+ const child = spawn(cmd, cmdArgs, {
23
+ cwd: opts?.cwd ?? process.cwd(),
24
+ stdio: ['ignore', 'pipe', 'pipe'],
25
+ timeout: opts?.timeout,
26
+ });
27
+ let stdout = '';
28
+ let stderr = '';
29
+ child.stdout.on('data', (data) => {
30
+ stdout += data.toString();
31
+ });
32
+ child.stderr.on('data', (data) => {
33
+ stderr += data.toString();
34
+ });
35
+ child.on('close', (code) => {
36
+ const result = this._parseJsonl(stdout);
37
+ resolve({
38
+ output: result.output,
39
+ sessionId: result.sessionId,
40
+ exitCode: code ?? 1,
41
+ });
42
+ });
43
+ child.on('error', (err) => {
44
+ reject(new Error(`Codex CLI error: ${err.message}`));
45
+ });
46
+ });
47
+ }
48
+ _parseJsonl(raw) {
49
+ let output = '';
50
+ let sessionId = '';
51
+ const lines = raw.split('\n').filter((l) => l.trim());
52
+ for (const line of lines) {
53
+ try {
54
+ const json = JSON.parse(line);
55
+ if (json.output)
56
+ output += json.output;
57
+ if (json.text)
58
+ output += json.text;
59
+ if (json.session_id)
60
+ sessionId = json.session_id;
61
+ if (json.id)
62
+ sessionId = json.id;
63
+ }
64
+ catch {
65
+ // Plain text fallback
66
+ output += line + '\n';
67
+ }
68
+ }
69
+ return { output: output.trim(), sessionId };
70
+ }
71
+ }
72
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/backends/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { AIBackend } from './interface.js';
2
+ export declare function createBackend(name: string): AIBackend;
@@ -0,0 +1,14 @@
1
+ import { ClaudeBackend } from './claude.js';
2
+ import { CodexBackend } from './codex.js';
3
+ const backends = {
4
+ claude: () => new ClaudeBackend(),
5
+ codex: () => new CodexBackend(),
6
+ };
7
+ export function createBackend(name) {
8
+ const factory = backends[name];
9
+ if (!factory) {
10
+ throw new Error(`Unknown backend: "${name}". Available: ${Object.keys(backends).join(', ')}`);
11
+ }
12
+ return factory();
13
+ }
14
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/backends/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,QAAQ,GAAoC;IAChD,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE;IACjC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,YAAY,EAAE;CAChC,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,iBAAiB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChG,CAAC;IACD,OAAO,OAAO,EAAE,CAAC;AACnB,CAAC"}
@@ -0,0 +1,15 @@
1
+ export interface ExecuteOptions {
2
+ cwd?: string;
3
+ timeout?: number;
4
+ }
5
+ export interface ExecuteResult {
6
+ output: string;
7
+ sessionId: string;
8
+ exitCode: number;
9
+ }
10
+ export interface AIBackend {
11
+ name: string;
12
+ isAvailable(): Promise<boolean>;
13
+ execute(prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
14
+ resume(sessionId: string, prompt: string, opts?: ExecuteOptions): Promise<ExecuteResult>;
15
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/backends/interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function createProgram(): Command;
@@ -0,0 +1,79 @@
1
+ import { Command } from 'commander';
2
+ import { initCommand } from './commands/init.js';
3
+ import { newCommand } from './commands/new.js';
4
+ import { refineCommand } from './commands/refine.js';
5
+ import { clarifyCommand } from './commands/clarify.js';
6
+ import { implementCommand } from './commands/implement.js';
7
+ import { reviewCommand } from './commands/review.js';
8
+ import { statusCommand } from './commands/status.js';
9
+ import { parseArgs } from './parsers/arguments.js';
10
+ export function createProgram() {
11
+ const program = new Command();
12
+ program
13
+ .name('pxs')
14
+ .description('Spec-driven development CLI')
15
+ .version('1.0.0');
16
+ program
17
+ .command('init')
18
+ .description('Initialize pxs workflow for this project')
19
+ .option('--force', 'Overwrite existing .workflow/')
20
+ .option('--arch <architecture>', 'Architecture pattern (clean|hexagonal|ddd|layered|modular|custom)')
21
+ .option('--lang <lang-framework>', 'Language-framework (overrides auto-detect)')
22
+ .action(initCommand);
23
+ program
24
+ .command('new <name>')
25
+ .description('Create a new spec file')
26
+ .option('--desc <text>', 'Generate spec from text description')
27
+ .option('--jira <tickets...>', 'Import from Jira tickets')
28
+ .option('-i, --interactive', 'Interactive Q&A mode')
29
+ .action(newCommand);
30
+ program
31
+ .command('refine <name>')
32
+ .description('Refine spec and decompose implementation plan')
33
+ .option('--skip-clarify', 'Skip requirement clarification')
34
+ .option('--clarify <n>', 'Max clarification rounds', parseInt)
35
+ .allowUnknownOption()
36
+ .action((name, options, cmd) => {
37
+ const rawArgs = cmd.args ?? [];
38
+ const parsed = parseArgs(rawArgs);
39
+ return refineCommand(name, parsed, options);
40
+ });
41
+ program
42
+ .command('clarify <name>')
43
+ .description('Run requirement clarification on a spec')
44
+ .allowUnknownOption()
45
+ .action((name, _options, cmd) => {
46
+ const rawArgs = cmd.args ?? [];
47
+ const parsed = parseArgs(rawArgs);
48
+ return clarifyCommand(name, parsed);
49
+ });
50
+ program
51
+ .command('implement <name>')
52
+ .description('Implement code task by task')
53
+ .option('--backend <name>', 'AI backend (claude | codex)')
54
+ .option('--test [types...]', 'Test strategy')
55
+ .option('--skip-review', 'Skip final branch code review')
56
+ .allowUnknownOption()
57
+ .action((name, options, cmd) => {
58
+ const rawArgs = cmd.args ?? [];
59
+ const parsed = parseArgs(rawArgs);
60
+ return implementCommand(name, parsed, options);
61
+ });
62
+ program
63
+ .command('review <name>')
64
+ .description('View review records')
65
+ .option('--step <n>', 'View specific task review', parseInt)
66
+ .option('--summary', 'Summary overview of all tasks')
67
+ .allowUnknownOption()
68
+ .action((name, options) => {
69
+ return reviewCommand(name, options);
70
+ });
71
+ program
72
+ .command('status [name]')
73
+ .description('View workflow status')
74
+ .action((name) => {
75
+ return statusCommand(name);
76
+ });
77
+ return program;
78
+ }
79
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function clarifyCommand(name: string, args: {
2
+ agents: string[];
3
+ skills: string[];
4
+ text: string;
5
+ }): Promise<void>;
@@ -0,0 +1,46 @@
1
+ import fs from 'node:fs';
2
+ import { StateManager } from '../state/manager.js';
3
+ import { createBackend } from '../backends/factory.js';
4
+ import { assemblePrompt } from '../utils/prompt.js';
5
+ import * as display from '../utils/display.js';
6
+ export async function clarifyCommand(name, args) {
7
+ const state = new StateManager();
8
+ state.ensureWorkflow();
9
+ state.checkPhaseGuard('clarify', name);
10
+ const specPath = state.specPath(name);
11
+ if (!fs.existsSync(specPath)) {
12
+ display.error(`Spec "${name}" not found. Run \`pxs new ${name}\` first.`);
13
+ return;
14
+ }
15
+ const specContent = fs.readFileSync(specPath, 'utf-8');
16
+ const config = state.readConfig();
17
+ const backend = createBackend(config.backend.default);
18
+ if (!(await backend.isAvailable())) {
19
+ display.error(`Backend "${config.backend.default}" not available.`);
20
+ return;
21
+ }
22
+ display.heading(`Clarifying: ${name}`);
23
+ const prompt = assemblePrompt({
24
+ templateName: 'clarify',
25
+ vars: { spec_content: specContent },
26
+ agents: args.agents,
27
+ skills: args.skills,
28
+ extraText: args.text,
29
+ });
30
+ const feature = state.getFeature(name);
31
+ let result;
32
+ if (feature?.session?.id) {
33
+ result = await backend.resume(feature.session.id, prompt);
34
+ }
35
+ else {
36
+ result = await backend.execute(prompt);
37
+ }
38
+ console.log('\n' + result.output);
39
+ // Update state
40
+ if (feature) {
41
+ feature.phase = 'clarifying';
42
+ feature.session = { backend: config.backend.default, id: result.sessionId };
43
+ state.upsertFeature(feature);
44
+ }
45
+ }
46
+ //# sourceMappingURL=clarify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clarify.js","sourceRoot":"","sources":["../../../src/commands/clarify.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,IAA0D;IAE1D,MAAM,KAAK,GAAG,IAAI,YAAY,EAAE,CAAC;IACjC,KAAK,CAAC,cAAc,EAAE,CAAC;IACvB,KAAK,CAAC,eAAe,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAEvC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,KAAK,CAAC,SAAS,IAAI,8BAA8B,IAAI,WAAW,CAAC,CAAC;QAC1E,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,EAAE,CAAC;IAClC,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEtD,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QACnC,OAAO,CAAC,KAAK,CAAC,YAAY,MAAM,CAAC,OAAO,CAAC,OAAO,kBAAkB,CAAC,CAAC;QACpE,OAAO;IACT,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC;IAEvC,MAAM,MAAM,GAAG,cAAc,CAAC;QAC5B,YAAY,EAAE,SAAS;QACvB,IAAI,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE;QACnC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,IAAI,CAAC,IAAI;KACrB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC;IACX,IAAI,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACzB,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAElC,eAAe;IACf,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC;QAC7B,OAAO,CAAC,OAAO,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC;QAC5E,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,9 @@
1
+ export declare function implementCommand(name: string, args: {
2
+ agents: string[];
3
+ skills: string[];
4
+ text: string;
5
+ }, options: {
6
+ backend?: string;
7
+ test?: string[] | boolean;
8
+ skipReview?: boolean;
9
+ }): Promise<void>;