spets 0.2.5 → 0.2.7

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 CHANGED
@@ -17,26 +17,25 @@ npx spets init
17
17
  # 프로젝트에서 초기화
18
18
  npx spets init
19
19
 
20
- # 워크플로우 시작
21
- npx spets start "TODO 앱 만들어줘"
20
+ # 인터랙티브 셋업 (AI 에이전트 선택 포함)
21
+ npx spets init -i
22
22
 
23
- # 다른 AI 에이전트 사용
24
- npx spets start "task" --agent gemini # Google Gemini CLI
25
- npx spets start "task" --agent codex # OpenAI Codex CLI
23
+ # 워크플로우 시작 (Claude Code 안에서)
24
+ /spets "TODO 만들어줘"
26
25
 
27
26
  # 상태 확인
28
27
  npx spets status
29
28
 
30
- # 중단된 워크플로우 재개
31
- npx spets resume
29
+ # 대시보드
30
+ npx spets dashboard
32
31
  ```
33
32
 
34
33
  ## How it Works
35
34
 
36
35
  1. **spets init** - `.spets/` 폴더에 설정과 스텝 템플릿 생성
37
- 2. **spets start** - 유저 쿼리로 워크플로우 시작, Claude가 각 스텝 문서 생성
38
- 3. **approve/revise/reject** - 스텝마다 유저가 검토하고 승인
39
- 4. **반복** - 모든 스텝 완료까지 진행
36
+ 2. **spets orchestrate init "task"** - 유저 쿼리로 워크플로우 시작
37
+ 3. 스텝은 5단계 실행: Explore Clarify → Execute → Verify → Review
38
+ 4. 모든 스텝 완료까지 진행
40
39
 
41
40
  ## Directory Structure
42
41
 
@@ -45,75 +44,17 @@ npx spets resume
45
44
  ├── config.yml # 워크플로우 설정
46
45
  ├── steps/
47
46
  │ ├── 01-plan/
48
- │ │ ├── instruction.md # Claude에게 주는 지시
49
47
  │ │ └── template.md # 출력 템플릿
50
48
  │ └── 02-implement/
51
- │ ├── instruction.md
52
49
  │ └── template.md
53
50
  ├── outputs/ # 생성된 문서들
54
51
  │ └── <taskId>/
55
52
  │ ├── 01-plan.md
56
53
  │ └── 02-implement.md
57
- └── hooks/ # 훅 스크립트
54
+ ├── hooks/ # 훅 스크립트
55
+ └── knowledge/ # 학습된 지식 파일
58
56
  ```
59
57
 
60
- ## GitHub Integration
61
-
62
- GitHub Issue/PR과 연동하여 워크플로우를 실행합니다.
63
-
64
- ### 설정
65
-
66
- ```bash
67
- # GitHub Actions + Issue 템플릿 포함해서 초기화
68
- npx spets init --github
69
- ```
70
-
71
- 이 명령어는 다음을 생성합니다:
72
- - `.github/workflows/spets.yml` - GitHub Actions 워크플로우
73
- - `.github/ISSUE_TEMPLATE/spets-task.yml` - Issue 템플릿
74
- - `.spets/config.yml`에 `github.owner`, `github.repo` 자동 설정 (git remote에서 파싱)
75
-
76
- ### Issue로 워크플로우 시작
77
-
78
- 1. GitHub에서 **New Issue** → **Spets Task** 템플릿 선택
79
- 2. Task Description 입력 (예: "사용자 인증 기능 추가")
80
- 3. Branch Name 입력 (선택, 비워두면 `spets/<issue-number>` 자동 생성)
81
- 4. Issue 생성 → GitHub Actions 자동 트리거
82
-
83
- ### CLI로 워크플로우 시작
84
-
85
- ```bash
86
- # GitHub 모드 (기존 Issue/PR 자동 감지)
87
- npx spets start "task" --github
88
-
89
- # 새 Issue 생성하면서 시작
90
- npx spets start "task" --issue
91
-
92
- # 기존 Issue에 연결
93
- npx spets start "task" --issue 42
94
-
95
- # 새 PR 생성하면서 시작 (브랜치도 자동 생성)
96
- npx spets start "task" --pr
97
-
98
- # 기존 PR에 연결
99
- npx spets start "task" --pr 42
100
- ```
101
-
102
- ### 코멘트 명령어
103
-
104
- Issue/PR 코멘트로 워크플로우를 제어합니다:
105
-
106
- - `/approve` - 현재 스텝 승인하고 다음 스텝 진행
107
- - `/approve --pr` - 승인하고 Pull Request 생성
108
- - `/approve --issue` - 승인하고 Issue 생성/업데이트
109
- - `/revise <feedback>` - 피드백과 함께 현재 스텝 재생성
110
- - `/reject` - 워크플로우 중단
111
-
112
- ### 필요 설정
113
-
114
- Repository Secrets에 추가:
115
- - `CLAUDE_CODE_OAUTH_TOKEN` - Claude 인증 토큰 (`claude setup-token`으로 생성)
116
-
117
58
  ## AI CLI Plugins
118
59
 
119
60
  Spets provides skill/command definitions for use within AI CLI sessions:
@@ -125,7 +66,7 @@ Spets provides skill/command definitions for use within AI CLI sessions:
125
66
  npx spets plugin install claude
126
67
 
127
68
  # Claude Code에서 사용
128
- /spets start "task description"
69
+ /spets "task description"
129
70
  ```
130
71
 
131
72
  ### Gemini CLI
@@ -147,7 +88,7 @@ The Gemini CLI command is installed at `.gemini/commands/spets.md` (project-leve
147
88
  npx spets plugin install codex
148
89
 
149
90
  # Codex에서 사용
150
- /spets start "task description"
91
+ /spets "task description"
151
92
  ```
152
93
 
153
94
  ## Configuration
@@ -159,10 +100,8 @@ steps:
159
100
  - 01-plan
160
101
  - 02-implement
161
102
 
162
- # GitHub 연동 (spets init --github 시 자동 설정)
163
- github:
164
- owner: your-org
165
- repo: your-repo
103
+ # AI 에이전트 선택
104
+ agent: claude # claude, codex, gemini
166
105
 
167
106
  # 훅 (선택)
168
107
  hooks:
@@ -172,18 +111,6 @@ hooks:
172
111
  onComplete: "./hooks/on-complete.sh"
173
112
  ```
174
113
 
175
- ### Branch Cleanup
176
-
177
- Automatically delete workflow branches when issues close or workflows complete:
178
-
179
- ```yaml
180
- hooks:
181
- onComplete: "./hooks/cleanup-branch.sh"
182
- onReject: "./hooks/cleanup-branch.sh"
183
- ```
184
-
185
- The `cleanup-branch.sh` hook is automatically created by `spets init`.
186
-
187
114
  **Environment Variables Available in Hooks:**
188
115
  - `SPETS_TASK_ID` - Current task ID
189
116
  - `SPETS_STEP_NAME` - Current step name
@@ -194,17 +121,14 @@ The `cleanup-branch.sh` hook is automatically created by `spets init`.
194
121
 
195
122
  ## Supported AI Agents
196
123
 
197
- Spets supports multiple AI agents via the `--agent` flag:
198
-
199
- | Agent | Command | Auto-approve Flag |
200
- |-------|---------|-------------------|
201
- | Claude (default) | `claude` | `--permission-mode bypassPermissions` |
202
- | Gemini | `gemini` | `--yolo` |
203
- | Codex | `codex` | `exec --full-auto` |
124
+ | Agent | Config Value |
125
+ |-------|-------------|
126
+ | Claude (default) | `claude` |
127
+ | Gemini | `gemini` |
128
+ | Codex | `codex` |
204
129
 
205
- ```bash
130
+ ```yaml
206
131
  # Set default agent in config
207
- # .spets/config.yml
208
132
  agent: gemini # or claude, codex
209
133
  ```
210
134
 
@@ -212,10 +136,9 @@ agent: gemini # or claude, codex
212
136
 
213
137
  - Node.js >= 18
214
138
  - One of the following AI CLIs:
215
- - Claude CLI (`claude` command) - default
216
- - Gemini CLI (`gemini` command) - `--agent gemini`
217
- - Codex CLI (`codex` command) - `--agent codex`
218
- - GitHub CLI (`gh`) - GitHub 연동 사용 시
139
+ - Claude Code (`claude` command) - default
140
+ - Gemini CLI (`gemini` command)
141
+ - Codex CLI (`codex` command)
219
142
 
220
143
  ## License
221
144
 
@@ -114,10 +114,6 @@ function loadStepDefinition(stepName, cwd = process.cwd()) {
114
114
  function loadAllSteps(config, cwd = process.cwd()) {
115
115
  return config.steps.map((stepName) => loadStepDefinition(stepName, cwd));
116
116
  }
117
- function getGitHubConfig(cwd = process.cwd()) {
118
- const config = loadConfig(cwd);
119
- return config.github;
120
- }
121
117
 
122
118
  export {
123
119
  getSpetsDir,
@@ -127,6 +123,5 @@ export {
127
123
  spetsExists,
128
124
  loadConfig,
129
125
  clearConfigCache,
130
- loadAllSteps,
131
- getGitHubConfig
126
+ loadAllSteps
132
127
  };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getSpetsDir,
3
3
  getStepsDir
4
- } from "./chunk-2MUV3F53.js";
4
+ } from "./chunk-63Q6RNKK.js";
5
5
 
6
6
  // src/ui/sections/docs.ts
7
7
  import { readFileSync, existsSync, readdirSync } from "fs";
@@ -2,7 +2,7 @@ import {
2
2
  getOutputsDir,
3
3
  loadConfig,
4
4
  spetsExists
5
- } from "./chunk-2MUV3F53.js";
5
+ } from "./chunk-63Q6RNKK.js";
6
6
 
7
7
  // src/ui/sections/tasks.ts
8
8
  import { select as select2 } from "@inquirer/prompts";
@@ -314,7 +314,7 @@ var CLIDashboardRenderer = class {
314
314
  if (tasks.length === 0) {
315
315
  lines.push("No tasks found.");
316
316
  lines.push("");
317
- lines.push('Start a new task with: spets start "your task description"');
317
+ lines.push('Start a new task with: spets orchestrate init "your task description"');
318
318
  return lines.join("\n");
319
319
  }
320
320
  lines.push("Tasks:");
@@ -378,7 +378,7 @@ var CLIDashboardRenderer = class {
378
378
  const { tasks } = response;
379
379
  if (tasks.length === 0) {
380
380
  console.log("\nNo tasks found.");
381
- console.log('Start a new task with: spets start "your task description"');
381
+ console.log('Start a new task with: spets orchestrate init "your task description"');
382
382
  break;
383
383
  }
384
384
  const choices = tasks.map((task) => {
@@ -417,7 +417,7 @@ var CLIDashboardRenderer = class {
417
417
  if (action === "resume") {
418
418
  console.log(`
419
419
  To resume this task, run:`);
420
- console.log(` spets resume -t ${selected}`);
420
+ console.log(` spets orchestrate resume ${selected}`);
421
421
  break;
422
422
  }
423
423
  }
@@ -476,7 +476,7 @@ async function runTasksInteractive(cwd = process.cwd()) {
476
476
  const { tasks } = response;
477
477
  if (tasks.length === 0) {
478
478
  console.log("\nNo tasks found.");
479
- console.log('Start a new task with: spets start "your task description"');
479
+ console.log('Start a new task with: spets orchestrate init "your task description"');
480
480
  break;
481
481
  }
482
482
  const STATUS_ICONS2 = {
@@ -521,7 +521,7 @@ async function runTasksInteractive(cwd = process.cwd()) {
521
521
  if (action === "resume") {
522
522
  console.log(`
523
523
  To resume this task, run:`);
524
- console.log(` spets resume -t ${selected}`);
524
+ console.log(` spets orchestrate resume ${selected}`);
525
525
  break;
526
526
  }
527
527
  }
@@ -535,8 +535,8 @@ export {
535
535
  getWorkflowState,
536
536
  loadTaskMetadata,
537
537
  DashboardClient,
538
- JSONDashboardRenderer,
539
538
  CLIDashboardRenderer,
539
+ JSONDashboardRenderer,
540
540
  renderTasksJSON,
541
541
  runTasksInteractive
542
542
  };
@@ -2,7 +2,7 @@ import {
2
2
  clearConfigCache,
3
3
  getConfigPath,
4
4
  loadConfig
5
- } from "./chunk-2MUV3F53.js";
5
+ } from "./chunk-63Q6RNKK.js";
6
6
 
7
7
  // src/ui/sections/config.ts
8
8
  import { writeFileSync } from "fs";
@@ -12,11 +12,10 @@ import { stringify as yamlStringify } from "yaml";
12
12
  function getEditableFields() {
13
13
  return [
14
14
  { field: "steps", type: "array", description: "Workflow steps (ordered list)" },
15
+ { field: "agent", type: "select", description: "AI agent (claude, codex, gemini)" },
15
16
  { field: "output.path", type: "string", description: "Output directory path" },
16
17
  { field: "knowledge.enabled", type: "boolean", description: "Enable knowledge saving" },
17
- { field: "knowledge.inject", type: "boolean", description: "Inject knowledge into prompts" },
18
- { field: "github.owner", type: "string", description: "GitHub repository owner" },
19
- { field: "github.repo", type: "string", description: "GitHub repository name" }
18
+ { field: "knowledge.inject", type: "boolean", description: "Inject knowledge into prompts" }
20
19
  ];
21
20
  }
22
21
  function renderConfigJSON(cwd = process.cwd()) {
@@ -79,9 +78,9 @@ async function runConfigInteractive(cwd = process.cwd()) {
79
78
  choices: [
80
79
  { value: "view", name: "\u{1F4CB} View current config" },
81
80
  { value: "steps", name: "\u{1F4DD} Edit steps" },
81
+ { value: "agent", name: "\u{1F916} Edit AI agent" },
82
82
  { value: "output", name: "\u{1F4C1} Edit output path" },
83
83
  { value: "knowledge", name: "\u{1F9E0} Edit knowledge settings" },
84
- { value: "github", name: "\u{1F419} Edit GitHub settings" },
85
84
  { value: "edit", name: "\u270F\uFE0F Open in editor" },
86
85
  { value: "back", name: "\u2190 Back to main menu" }
87
86
  ]
@@ -111,6 +110,20 @@ async function runConfigInteractive(cwd = process.cwd()) {
111
110
  console.log(result.message);
112
111
  continue;
113
112
  }
113
+ if (action === "agent") {
114
+ const agent = await select({
115
+ message: "Which AI agent?",
116
+ choices: [
117
+ { value: "claude", name: "Claude (Anthropic)" },
118
+ { value: "codex", name: "Codex (OpenAI)" },
119
+ { value: "gemini", name: "Gemini (Google)" }
120
+ ],
121
+ default: config.agent
122
+ });
123
+ const result = setConfigField("agent", JSON.stringify(agent), cwd);
124
+ console.log(result.message);
125
+ continue;
126
+ }
114
127
  if (action === "output") {
115
128
  const currentPath = config.output?.path || ".spets/outputs";
116
129
  const newPath = await input({
@@ -135,24 +148,6 @@ async function runConfigInteractive(cwd = process.cwd()) {
135
148
  console.log(result.message);
136
149
  continue;
137
150
  }
138
- if (action === "github") {
139
- const owner = await input({
140
- message: "GitHub owner:",
141
- default: config.github?.owner || ""
142
- });
143
- if (owner) {
144
- setConfigField("github.owner", JSON.stringify(owner), cwd);
145
- }
146
- const repo = await input({
147
- message: "GitHub repo:",
148
- default: config.github?.repo || ""
149
- });
150
- if (repo) {
151
- const result = setConfigField("github.repo", JSON.stringify(repo), cwd);
152
- console.log(result.message);
153
- }
154
- continue;
155
- }
156
151
  }
157
152
  }
158
153
 
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getSpetsDir
3
- } from "./chunk-2MUV3F53.js";
3
+ } from "./chunk-63Q6RNKK.js";
4
4
 
5
5
  // src/ui/sections/knowledge.ts
6
6
  import { spawnSync } from "child_process";
@@ -3,8 +3,8 @@ import {
3
3
  renderConfigJSON,
4
4
  runConfigInteractive,
5
5
  setConfigField
6
- } from "./chunk-BCOGSLCX.js";
7
- import "./chunk-2MUV3F53.js";
6
+ } from "./chunk-P3GQOSMU.js";
7
+ import "./chunk-63Q6RNKK.js";
8
8
  export {
9
9
  openConfigInEditor,
10
10
  renderConfigJSON,
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  renderDocsJSON,
3
3
  runDocsInteractive
4
- } from "./chunk-3JIHGW47.js";
5
- import "./chunk-2MUV3F53.js";
4
+ } from "./chunk-6FL7APE6.js";
5
+ import "./chunk-63Q6RNKK.js";
6
6
  export {
7
7
  renderDocsJSON,
8
8
  runDocsInteractive