spets 0.1.0 → 0.1.2

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
@@ -5,23 +5,27 @@ Spec Driven Development Execution Framework - 유저가 정의한 스텝대로 S
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
+ # 글로벌 설치 (선택)
8
9
  npm install -g spets
10
+
11
+ # 또는 npx로 바로 사용 (설치 불필요)
12
+ npx spets init
9
13
  ```
10
14
 
11
15
  ## Quick Start
12
16
 
13
17
  ```bash
14
18
  # 프로젝트에서 초기화
15
- spets init
19
+ npx spets init
16
20
 
17
21
  # 워크플로우 시작
18
- spets start "TODO 앱 만들어줘"
22
+ npx spets start "TODO 앱 만들어줘"
19
23
 
20
24
  # 상태 확인
21
- spets status
25
+ npx spets status
22
26
 
23
27
  # 중단된 워크플로우 재개
24
- spets resume
28
+ npx spets resume
25
29
  ```
26
30
 
27
31
  ## How it Works
@@ -56,10 +60,10 @@ PR/Issue 코멘트로 워크플로우 제어:
56
60
 
57
61
  ```bash
58
62
  # GitHub Actions 워크플로우 포함해서 초기화
59
- spets init --github
63
+ npx spets init --github
60
64
 
61
65
  # GitHub 플랫폼으로 시작
62
- spets start "task" --platform github --owner myorg --repo myrepo --issue 42
66
+ npx spets start "task" --platform github --owner myorg --repo myrepo --issue 42
63
67
  ```
64
68
 
65
69
  코멘트 명령어:
@@ -71,12 +75,14 @@ spets start "task" --platform github --owner myorg --repo myrepo --issue 42
71
75
 
72
76
  ```bash
73
77
  # Claude Code 스킬 설치
74
- spets plugin install claude
78
+ npx spets plugin install claude
75
79
 
76
80
  # Claude Code에서 사용
77
81
  /spets start "task description"
78
82
  ```
79
83
 
84
+ 스킬이 설치되면 Claude Code 내에서 `npx spets` 명령어를 자동으로 실행합니다. 글로벌 설치 없이도 동작합니다.
85
+
80
86
  ## Configuration
81
87
 
82
88
  `.sept/config.yml`:
@@ -7,28 +7,28 @@ import matter from "gray-matter";
7
7
  import { readFileSync, existsSync } from "fs";
8
8
  import { join } from "path";
9
9
  import { parse as parseYaml } from "yaml";
10
- var SEPT_DIR = ".sept";
10
+ var SPETS_DIR = ".spets";
11
11
  var CONFIG_FILE = "config.yml";
12
12
  var STEPS_DIR = "steps";
13
- function getSeptDir(cwd = process.cwd()) {
14
- return join(cwd, SEPT_DIR);
13
+ function getSpetsDir(cwd = process.cwd()) {
14
+ return join(cwd, SPETS_DIR);
15
15
  }
16
16
  function getConfigPath(cwd = process.cwd()) {
17
- return join(getSeptDir(cwd), CONFIG_FILE);
17
+ return join(getSpetsDir(cwd), CONFIG_FILE);
18
18
  }
19
19
  function getStepsDir(cwd = process.cwd()) {
20
- return join(getSeptDir(cwd), STEPS_DIR);
20
+ return join(getSpetsDir(cwd), STEPS_DIR);
21
21
  }
22
22
  function getOutputsDir(cwd = process.cwd()) {
23
- return join(getSeptDir(cwd), "outputs");
23
+ return join(getSpetsDir(cwd), "outputs");
24
24
  }
25
- function septExists(cwd = process.cwd()) {
25
+ function spetsExists(cwd = process.cwd()) {
26
26
  return existsSync(getConfigPath(cwd));
27
27
  }
28
28
  function loadConfig(cwd = process.cwd()) {
29
29
  const configPath = getConfigPath(cwd);
30
30
  if (!existsSync(configPath)) {
31
- throw new Error(`Sept config not found. Run 'sept init' first.`);
31
+ throw new Error(`Spets config not found. Run 'spets init' first.`);
32
32
  }
33
33
  const content = readFileSync(configPath, "utf-8");
34
34
  const config = parseYaml(content);
@@ -52,6 +52,10 @@ function loadStepDefinition(stepName, cwd = process.cwd()) {
52
52
  template
53
53
  };
54
54
  }
55
+ function getGitHubConfig(cwd = process.cwd()) {
56
+ const config = loadConfig(cwd);
57
+ return config.github;
58
+ }
55
59
 
56
60
  // src/core/state.ts
57
61
  function generateTaskId() {
@@ -190,10 +194,11 @@ function loadTaskMetadata(taskId, cwd = process.cwd()) {
190
194
  }
191
195
 
192
196
  export {
193
- getSeptDir,
194
- septExists,
197
+ getSpetsDir,
198
+ spetsExists,
195
199
  loadConfig,
196
200
  loadStepDefinition,
201
+ getGitHubConfig,
197
202
  generateTaskId,
198
203
  getTaskDir,
199
204
  getOutputPath,
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  generateTaskId,
4
+ getGitHubConfig,
4
5
  getOutputPath,
5
- getSeptDir,
6
+ getSpetsDir,
6
7
  getWorkflowState,
7
8
  listTasks,
8
9
  loadConfig,
@@ -11,9 +12,9 @@ import {
11
12
  loadTaskMetadata,
12
13
  saveDocument,
13
14
  saveTaskMetadata,
14
- septExists,
15
+ spetsExists,
15
16
  updateDocumentStatus
16
- } from "./chunk-KZQ5KNMC.js";
17
+ } from "./chunk-XYU22TND.js";
17
18
 
18
19
  // src/index.ts
19
20
  import { Command } from "commander";
@@ -25,32 +26,32 @@ import { fileURLToPath } from "url";
25
26
  var __dirname = dirname(fileURLToPath(import.meta.url));
26
27
  async function initCommand(options) {
27
28
  const cwd = process.cwd();
28
- const septDir = getSeptDir(cwd);
29
- if (septExists(cwd) && !options.force) {
29
+ const spetsDir = getSpetsDir(cwd);
30
+ if (spetsExists(cwd) && !options.force) {
30
31
  console.error("Spets already initialized. Use --force to overwrite.");
31
32
  process.exit(1);
32
33
  }
33
- mkdirSync(septDir, { recursive: true });
34
- mkdirSync(join(septDir, "steps"), { recursive: true });
35
- mkdirSync(join(septDir, "outputs"), { recursive: true });
36
- mkdirSync(join(septDir, "hooks"), { recursive: true });
34
+ mkdirSync(spetsDir, { recursive: true });
35
+ mkdirSync(join(spetsDir, "steps"), { recursive: true });
36
+ mkdirSync(join(spetsDir, "outputs"), { recursive: true });
37
+ mkdirSync(join(spetsDir, "hooks"), { recursive: true });
37
38
  const templatesDir = join(__dirname, "..", "templates");
38
- writeFileSync(join(septDir, "config.yml"), getDefaultConfig());
39
- createDefaultSteps(septDir);
40
- console.log("Initialized spets in .sept/");
39
+ writeFileSync(join(spetsDir, "config.yml"), getDefaultConfig());
40
+ createDefaultSteps(spetsDir);
41
+ console.log("Initialized spets in .spets/");
41
42
  console.log("");
42
43
  console.log("Created:");
43
- console.log(" .sept/config.yml - Workflow configuration");
44
- console.log(" .sept/steps/01-plan/ - Planning step");
45
- console.log(" .sept/steps/02-implement/ - Implementation step");
44
+ console.log(" .spets/config.yml - Workflow configuration");
45
+ console.log(" .spets/steps/01-plan/ - Planning step");
46
+ console.log(" .spets/steps/02-implement/ - Implementation step");
46
47
  if (options.github) {
47
48
  createGitHubWorkflow(cwd);
48
- console.log(" .github/workflows/sept.yml - GitHub Actions workflow");
49
+ console.log(" .github/workflows/spets.yml - GitHub Actions workflow");
49
50
  }
50
51
  console.log("");
51
52
  console.log("Next steps:");
52
- console.log(" 1. Edit .sept/config.yml to customize your workflow");
53
- console.log(" 2. Customize step instructions in .sept/steps/");
53
+ console.log(" 1. Edit .spets/config.yml to customize your workflow");
54
+ console.log(" 2. Customize step instructions in .spets/steps/");
54
55
  if (options.github) {
55
56
  console.log(" 3. Add ANTHROPIC_API_KEY to your repo secrets");
56
57
  console.log(' 4. Run: spets start "task" --platform github --owner <owner> --repo <repo> --issue <n>');
@@ -75,12 +76,12 @@ steps:
75
76
  # onComplete: "./hooks/on-complete.sh"
76
77
  `;
77
78
  }
78
- function createDefaultSteps(septDir) {
79
- const planDir = join(septDir, "steps", "01-plan");
79
+ function createDefaultSteps(spetsDir) {
80
+ const planDir = join(spetsDir, "steps", "01-plan");
80
81
  mkdirSync(planDir, { recursive: true });
81
82
  writeFileSync(join(planDir, "instruction.md"), getPlanInstruction());
82
83
  writeFileSync(join(planDir, "template.md"), getPlanTemplate());
83
- const implementDir = join(septDir, "steps", "02-implement");
84
+ const implementDir = join(spetsDir, "steps", "02-implement");
84
85
  mkdirSync(implementDir, { recursive: true });
85
86
  writeFileSync(join(implementDir, "instruction.md"), getImplementInstruction());
86
87
  writeFileSync(join(implementDir, "template.md"), getImplementTemplate());
@@ -239,7 +240,7 @@ None / List any deviations with justification.
239
240
  function createGitHubWorkflow(cwd) {
240
241
  const workflowDir = join(cwd, ".github", "workflows");
241
242
  mkdirSync(workflowDir, { recursive: true });
242
- writeFileSync(join(workflowDir, "sept.yml"), getGitHubWorkflow());
243
+ writeFileSync(join(workflowDir, "spets.yml"), getGitHubWorkflow());
243
244
  }
244
245
  function getGitHubWorkflow() {
245
246
  const gh = (expr) => `\${{ ${expr} }}`;
@@ -253,8 +254,8 @@ on:
253
254
  types: [created]
254
255
 
255
256
  jobs:
256
- handle-sept-command:
257
- # Only run if comment contains a sept command
257
+ handle-spets-command:
258
+ # Only run if comment contains a spets command
258
259
  if: |
259
260
  contains(github.event.comment.body, '/approve') ||
260
261
  contains(github.event.comment.body, '/revise') ||
@@ -303,7 +304,7 @@ jobs:
303
304
 
304
305
  Instructions:
305
306
  1. Parse the command from the comment (/approve, /revise, /reject, or /answer)
306
- 2. Find the active sept task in .sept/outputs/
307
+ 2. Find the active spets task in .spets/outputs/
307
308
  3. Execute the appropriate action:
308
309
  - /approve: Mark current step as approved, generate next step
309
310
  - /revise <feedback>: Regenerate current step with feedback
@@ -325,7 +326,7 @@ jobs:
325
326
  git config user.name "github-actions[bot]"
326
327
  git config user.email "github-actions[bot]@users.noreply.github.com"
327
328
  git add -A
328
- git diff --staged --quiet || git commit -m "Sept: Update from workflow"
329
+ git diff --staged --quiet || git commit -m "Spets: Update from workflow"
329
330
  git push
330
331
  env:
331
332
  GH_TOKEN: ${gh("secrets.GITHUB_TOKEN")}
@@ -335,7 +336,7 @@ jobs:
335
336
  // src/commands/status.ts
336
337
  async function statusCommand(options) {
337
338
  const cwd = process.cwd();
338
- if (!septExists(cwd)) {
339
+ if (!spetsExists(cwd)) {
339
340
  console.error('Spets not initialized. Run "spets init" first.');
340
341
  process.exit(1);
341
342
  }
@@ -373,7 +374,7 @@ function showAllTasks(config, cwd) {
373
374
  if (tasks.length === 0) {
374
375
  console.log("No tasks found.");
375
376
  console.log("");
376
- console.log('Start a new task with: sept start "your task description"');
377
+ console.log('Start a new task with: spets start "your task description"');
377
378
  return;
378
379
  }
379
380
  console.log("Tasks:");
@@ -393,7 +394,7 @@ function showAllTasks(config, cwd) {
393
394
  console.log(` ... and ${tasks.length - 10} more tasks`);
394
395
  }
395
396
  console.log("");
396
- console.log('Use "sept status -t <taskId>" for details');
397
+ console.log('Use "spets status -t <taskId>" for details');
397
398
  }
398
399
  function formatStatus(status) {
399
400
  const icons = {
@@ -418,18 +419,18 @@ import { spawn } from "child_process";
418
419
  import { existsSync as existsSync2 } from "fs";
419
420
  import { join as join2, isAbsolute } from "path";
420
421
  async function runHook(hookPath, context, cwd = process.cwd()) {
421
- const resolvedPath = isAbsolute(hookPath) ? hookPath : join2(getSeptDir(cwd), hookPath);
422
+ const resolvedPath = isAbsolute(hookPath) ? hookPath : join2(getSpetsDir(cwd), hookPath);
422
423
  if (!existsSync2(resolvedPath)) {
423
424
  console.warn(`Hook not found: ${resolvedPath}`);
424
425
  return;
425
426
  }
426
427
  const env = {
427
428
  ...process.env,
428
- SEPT_TASK_ID: context.taskId,
429
- SEPT_STEP_NAME: context.stepName,
430
- SEPT_STEP_INDEX: String(context.stepIndex),
431
- SEPT_OUTPUT_PATH: context.outputPath,
432
- SEPT_CWD: cwd
429
+ SPETS_TASK_ID: context.taskId,
430
+ SPETS_STEP_NAME: context.stepName,
431
+ SPETS_STEP_INDEX: String(context.stepIndex),
432
+ SPETS_OUTPUT_PATH: context.outputPath,
433
+ SPETS_CWD: cwd
433
434
  };
434
435
  return new Promise((resolve, reject) => {
435
436
  const proc = spawn(resolvedPath, [], {
@@ -516,7 +517,7 @@ var Executor = class {
516
517
  return;
517
518
  }
518
519
  if (result.paused) {
519
- console.log("\n\u23F8\uFE0F Workflow paused. Resume with: sept resume");
520
+ console.log("\n\u23F8\uFE0F Workflow paused. Resume with: spets resume");
520
521
  return;
521
522
  }
522
523
  if (result.approved) {
@@ -591,7 +592,7 @@ var Executor = class {
591
592
  };
592
593
 
593
594
  // src/platform/cli.ts
594
- import { spawn as spawn2 } from "child_process";
595
+ import { spawn as spawn2, execSync } from "child_process";
595
596
  import { input, select, confirm } from "@inquirer/prompts";
596
597
 
597
598
  // src/platform/interface.ts
@@ -710,9 +711,15 @@ var CliPlatform = class extends BasePlatform {
710
711
  }
711
712
  async callClaude(prompt) {
712
713
  return new Promise((resolve, reject) => {
713
- const proc = spawn2(this.claudeCommand, ["-p", prompt], {
714
+ const proc = spawn2(this.claudeCommand, [
715
+ "--print",
716
+ "--permission-mode",
717
+ "bypassPermissions"
718
+ ], {
714
719
  stdio: ["pipe", "pipe", "pipe"]
715
720
  });
721
+ proc.stdin.write(prompt);
722
+ proc.stdin.end();
716
723
  let stdout = "";
717
724
  let stderr = "";
718
725
  proc.stdout.on("data", (data) => {
@@ -734,6 +741,24 @@ var CliPlatform = class extends BasePlatform {
734
741
  });
735
742
  });
736
743
  }
744
+ isClaudeInstalled() {
745
+ try {
746
+ const command = process.platform === "win32" ? "where" : "which";
747
+ execSync(`${command} claude`, { stdio: "ignore" });
748
+ return true;
749
+ } catch {
750
+ return false;
751
+ }
752
+ }
753
+ getClaudeExecutable() {
754
+ if (this.claudeCommand !== "claude") {
755
+ return { command: this.claudeCommand, args: [] };
756
+ }
757
+ if (this.isClaudeInstalled()) {
758
+ return { command: "claude", args: [] };
759
+ }
760
+ return { command: "npx", args: ["--yes", "@anthropic-ai/claude-code"] };
761
+ }
737
762
  parseResponse(response) {
738
763
  const questions = [];
739
764
  const questionMatch = response.match(/```questions\n([\s\S]*?)```/);
@@ -834,7 +859,7 @@ var GitHubPlatform = class extends BasePlatform {
834
859
  }
835
860
  formatQuestionsComment(questions, taskId) {
836
861
  const lines = [
837
- "## \u{1F4CB} Sept: Questions Need Answers",
862
+ "## \u{1F4CB} Spets: Questions Need Answers",
838
863
  "",
839
864
  `> Task ID: \`${taskId}\``,
840
865
  "",
@@ -861,7 +886,7 @@ var GitHubPlatform = class extends BasePlatform {
861
886
  }
862
887
  formatApprovalComment(doc, stepName, taskId) {
863
888
  const lines = [
864
- `## \u{1F4C4} Sept: ${stepName} - Review Required`,
889
+ `## \u{1F4C4} Spets: ${stepName} - Review Required`,
865
890
  "",
866
891
  `> Task ID: \`${taskId}\``,
867
892
  "",
@@ -945,7 +970,13 @@ var GitHubPlatform = class extends BasePlatform {
945
970
  }
946
971
  async callClaude(prompt) {
947
972
  return new Promise((resolve, reject) => {
948
- const proc = spawn3("claude", ["-p", prompt], { stdio: ["pipe", "pipe", "pipe"] });
973
+ const proc = spawn3("claude", [
974
+ "--print",
975
+ "--permission-mode",
976
+ "bypassPermissions"
977
+ ], { stdio: ["pipe", "pipe", "pipe"] });
978
+ proc.stdin.write(prompt);
979
+ proc.stdin.end();
949
980
  let stdout = "";
950
981
  let stderr = "";
951
982
  proc.stdout.on("data", (data) => {
@@ -990,7 +1021,7 @@ var GitHubPlatform = class extends BasePlatform {
990
1021
  // src/commands/start.ts
991
1022
  async function startCommand(query, options) {
992
1023
  const cwd = process.cwd();
993
- if (!septExists(cwd)) {
1024
+ if (!spetsExists(cwd)) {
994
1025
  console.error('Spets not initialized. Run "spets init" first.');
995
1026
  process.exit(1);
996
1027
  }
@@ -1003,19 +1034,24 @@ async function startCommand(query, options) {
1003
1034
  saveTaskMetadata(taskId, query, cwd);
1004
1035
  let platform;
1005
1036
  if (options.platform === "github") {
1006
- if (!options.owner || !options.repo) {
1007
- console.error("GitHub platform requires --owner and --repo");
1037
+ const githubConfig = getGitHubConfig(cwd);
1038
+ const owner = options.owner || githubConfig?.owner;
1039
+ const repo = options.repo || githubConfig?.repo;
1040
+ const pr = options.pr || (githubConfig?.defaultPr ? String(githubConfig.defaultPr) : void 0);
1041
+ const issue = options.issue || (githubConfig?.defaultIssue ? String(githubConfig.defaultIssue) : void 0);
1042
+ if (!owner || !repo) {
1043
+ console.error("GitHub platform requires --owner and --repo (or set in .spets/config.yml)");
1008
1044
  process.exit(1);
1009
1045
  }
1010
- if (!options.pr && !options.issue) {
1011
- console.error("GitHub platform requires --pr or --issue");
1046
+ if (!pr && !issue) {
1047
+ console.error("GitHub platform requires --pr or --issue (or set defaultPr/defaultIssue in .spets/config.yml)");
1012
1048
  process.exit(1);
1013
1049
  }
1014
1050
  platform = new GitHubPlatform({
1015
- owner: options.owner,
1016
- repo: options.repo,
1017
- prNumber: options.pr ? parseInt(options.pr, 10) : void 0,
1018
- issueNumber: options.issue ? parseInt(options.issue, 10) : void 0
1051
+ owner,
1052
+ repo,
1053
+ prNumber: pr ? parseInt(pr, 10) : void 0,
1054
+ issueNumber: issue ? parseInt(issue, 10) : void 0
1019
1055
  });
1020
1056
  } else {
1021
1057
  platform = new CliPlatform();
@@ -1038,7 +1074,7 @@ async function startCommand(query, options) {
1038
1074
  import { select as select2 } from "@inquirer/prompts";
1039
1075
  async function resumeCommand(options) {
1040
1076
  const cwd = process.cwd();
1041
- if (!septExists(cwd)) {
1077
+ if (!spetsExists(cwd)) {
1042
1078
  console.error('Spets not initialized. Run "spets init" first.');
1043
1079
  process.exit(1);
1044
1080
  }
@@ -1060,7 +1096,7 @@ async function resumeCommand(options) {
1060
1096
  }
1061
1097
  if (resumableTasks.length === 0) {
1062
1098
  console.log("No tasks to resume.");
1063
- console.log('Start a new task with: sept start "your task description"');
1099
+ console.log('Start a new task with: spets start "your task description"');
1064
1100
  return;
1065
1101
  }
1066
1102
  if (resumableTasks.length === 1) {
@@ -1176,6 +1212,8 @@ function installClaudePlugin() {
1176
1212
  console.log(' /spets start "your task description"');
1177
1213
  console.log(" /spets status");
1178
1214
  console.log(" /spets resume");
1215
+ console.log("");
1216
+ console.log("Note: The plugin uses npx to run spets, so global installation is not required.");
1179
1217
  }
1180
1218
  async function uninstallPlugin(name) {
1181
1219
  if (name === "claude") {
@@ -1226,21 +1264,23 @@ When the user invokes this command:
1226
1264
  2. Execute the appropriate spets CLI command using Bash
1227
1265
  3. For 'start', read the generated documents and help iterate
1228
1266
 
1267
+ **Important**: Use \`npx spets\` to run commands. This ensures the command works even if spets is not globally installed.
1268
+
1229
1269
  ### Start Flow
1230
1270
 
1231
- 1. Run: \`spets start "<query>"\`
1232
- 2. Read the generated plan document from .sept/outputs/<taskId>/
1271
+ 1. Run: \`npx spets start "<query>"\`
1272
+ 2. Read the generated plan document from .spets/outputs/<taskId>/
1233
1273
  3. Present the plan to the user
1234
1274
  4. If user approves, continue. If they want changes, provide feedback.
1235
1275
 
1236
1276
  ### Status Flow
1237
1277
 
1238
- 1. Run: \`spets status\`
1278
+ 1. Run: \`npx spets status\`
1239
1279
  2. Present the current workflow state
1240
1280
 
1241
1281
  ### Resume Flow
1242
1282
 
1243
- 1. Run: \`spets resume\`
1283
+ 1. Run: \`npx spets resume\`
1244
1284
  2. Continue the workflow from where it paused
1245
1285
 
1246
1286
  ## Example Session
@@ -1248,11 +1288,11 @@ When the user invokes this command:
1248
1288
  User: /spets start "Create a REST API for user management"
1249
1289
 
1250
1290
  Claude:
1251
- 1. Runs \`spets start "Create a REST API for user management"\`
1291
+ 1. Runs \`npx spets start "Create a REST API for user management"\`
1252
1292
  2. Reads the generated plan
1253
1293
  3. Asks user: "Here's the plan. [shows plan] Would you like to approve or revise?"
1254
- 4. On approve: \`spets resume --approve\`
1255
- 5. On revise: \`spets resume --revise "user feedback"\`
1294
+ 4. On approve: \`npx spets resume --approve\`
1295
+ 5. On revise: \`npx spets resume --revise "user feedback"\`
1256
1296
 
1257
1297
  $ARGUMENTS
1258
1298
  command: The spets command to run (start, status, resume)
@@ -1263,18 +1303,27 @@ args: Additional arguments for the command
1263
1303
  // src/commands/github.ts
1264
1304
  async function githubCommand(options) {
1265
1305
  const cwd = process.cwd();
1266
- if (!septExists(cwd)) {
1306
+ if (!spetsExists(cwd)) {
1267
1307
  console.error("Spets not initialized.");
1268
1308
  process.exit(1);
1269
1309
  }
1270
- const { owner, repo, pr, issue, comment, task } = options;
1310
+ const configGitHub = getGitHubConfig(cwd);
1311
+ const owner = options.owner || configGitHub?.owner;
1312
+ const repo = options.repo || configGitHub?.repo;
1313
+ const pr = options.pr || (configGitHub?.defaultPr ? String(configGitHub.defaultPr) : void 0);
1314
+ const issue = options.issue || (configGitHub?.defaultIssue ? String(configGitHub.defaultIssue) : void 0);
1315
+ const { comment, task } = options;
1316
+ if (!owner || !repo) {
1317
+ console.error("GitHub requires --owner and --repo (or set in .spets/config.yml)");
1318
+ process.exit(1);
1319
+ }
1271
1320
  if (!pr && !issue) {
1272
- console.error("Either --pr or --issue is required");
1321
+ console.error("Either --pr or --issue is required (or set defaultPr/defaultIssue in .spets/config.yml)");
1273
1322
  process.exit(1);
1274
1323
  }
1275
1324
  const parsed = parseGitHubCommand(comment);
1276
1325
  if (!parsed.command) {
1277
- console.log("No sept command found in comment. Ignoring.");
1326
+ console.log("No spets command found in comment. Ignoring.");
1278
1327
  return;
1279
1328
  }
1280
1329
  console.log(`Received command: ${parsed.command}`);
@@ -1287,7 +1336,7 @@ async function githubCommand(options) {
1287
1336
  }
1288
1337
  if (!taskId) {
1289
1338
  const config2 = loadConfig(cwd);
1290
- const { listTasks: listTasks2 } = await import("./state-MCFJFWJC.js");
1339
+ const { listTasks: listTasks2 } = await import("./state-H2GQS43T.js");
1291
1340
  const tasks = listTasks2(cwd);
1292
1341
  for (const tid of tasks) {
1293
1342
  const state2 = getWorkflowState(tid, config2, cwd);
@@ -1415,10 +1464,10 @@ async function postComment(config, body) {
1415
1464
  // src/index.ts
1416
1465
  var program = new Command();
1417
1466
  program.name("spets").description("Spec Driven Development Execution Framework").version("0.1.0");
1418
- program.command("init").description("Initialize sept in current directory").option("-f, --force", "Overwrite existing config").option("--github", "Add GitHub Actions workflow for PR/Issue integration").action(initCommand);
1467
+ program.command("init").description("Initialize spets in current directory").option("-f, --force", "Overwrite existing config").option("--github", "Add GitHub Actions workflow for PR/Issue integration").action(initCommand);
1419
1468
  program.command("status").description("Show current workflow status").option("-t, --task <taskId>", "Show status for specific task").action(statusCommand);
1420
1469
  program.command("start").description("Start a new workflow").argument("<query>", "User query describing the task").option("-p, --platform <platform>", "Platform to use (cli, github)", "cli").option("--owner <owner>", "GitHub owner (for github platform)").option("--repo <repo>", "GitHub repo (for github platform)").option("--pr <number>", "GitHub PR number (for github platform)").option("--issue <number>", "GitHub issue number (for github platform)").action(startCommand);
1421
1470
  program.command("resume").description("Resume paused workflow").option("-t, --task <taskId>", "Resume specific task").option("--approve", "Approve current document and proceed").option("--revise <feedback>", "Request revision with feedback").action(resumeCommand);
1422
- program.command("github").description("Handle GitHub Action callback (internal)").requiredOption("--owner <owner>", "GitHub owner").requiredOption("--repo <repo>", "GitHub repo").option("--pr <number>", "PR number").option("--issue <number>", "Issue number").option("-t, --task <taskId>", "Task ID").requiredOption("--comment <comment>", "Comment body").action(githubCommand);
1471
+ program.command("github").description("Handle GitHub Action callback (internal)").option("--owner <owner>", "GitHub owner (or set in .spets/config.yml)").option("--repo <repo>", "GitHub repo (or set in .spets/config.yml)").option("--pr <number>", "PR number (or set defaultPr in .spets/config.yml)").option("--issue <number>", "Issue number (or set defaultIssue in .spets/config.yml)").option("-t, --task <taskId>", "Task ID").requiredOption("--comment <comment>", "Comment body").action(githubCommand);
1423
1472
  program.command("plugin").description("Manage plugins").argument("<action>", "Action: install, uninstall, list").argument("[name]", "Plugin name").action(pluginCommand);
1424
1473
  program.parse();
@@ -12,7 +12,7 @@ import {
12
12
  saveDocument,
13
13
  saveTaskMetadata,
14
14
  updateDocumentStatus
15
- } from "./chunk-KZQ5KNMC.js";
15
+ } from "./chunk-XYU22TND.js";
16
16
  export {
17
17
  createDocument,
18
18
  ensureTaskDir,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spets",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Spec Driven Development Execution Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",