spets 0.1.49 → 0.1.50

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 (2) hide show
  1. package/dist/index.js +264 -32
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  // src/index.ts
4
4
  import { Command } from "commander";
5
- import { readFileSync as readFileSync12 } from "fs";
6
- import { dirname as dirname6, join as join11 } from "path";
5
+ import { readFileSync as readFileSync13 } from "fs";
6
+ import { dirname as dirname7, join as join11 } from "path";
7
7
  import { fileURLToPath as fileURLToPath2 } from "url";
8
8
 
9
9
  // src/commands/init.ts
@@ -3095,6 +3095,135 @@ function createCodexAdapter(codexCommand = "codex") {
3095
3095
  };
3096
3096
  }
3097
3097
 
3098
+ // src/adapters/opencode.ts
3099
+ import { spawn as spawn4 } from "child_process";
3100
+ import { readFileSync as readFileSync10, existsSync as existsSync10, mkdirSync as mkdirSync7 } from "fs";
3101
+ import { dirname as dirname6 } from "path";
3102
+ var OpenCodeAIAdapter = class {
3103
+ opencodeCommand;
3104
+ constructor(opencodeCommand = "opencode") {
3105
+ this.opencodeCommand = opencodeCommand;
3106
+ }
3107
+ async execute(params) {
3108
+ console.log(`
3109
+ \u{1F4DD} Generating...`);
3110
+ if (params.outputPath) {
3111
+ const outputDir = dirname6(params.outputPath);
3112
+ if (!existsSync10(outputDir)) {
3113
+ mkdirSync7(outputDir, { recursive: true });
3114
+ }
3115
+ }
3116
+ const stdout = await this.callOpenCode(params.prompt);
3117
+ if (params.outputPath && existsSync10(params.outputPath)) {
3118
+ return readFileSync10(params.outputPath, "utf-8");
3119
+ }
3120
+ return stdout;
3121
+ }
3122
+ async callOpenCode(prompt, showSpinner = true) {
3123
+ return new Promise((resolve, reject) => {
3124
+ const proc = spawn4(this.opencodeCommand, [
3125
+ "run"
3126
+ ], {
3127
+ stdio: ["pipe", "pipe", "pipe"]
3128
+ });
3129
+ proc.stdin.write(prompt);
3130
+ proc.stdin.end();
3131
+ let stdout = "";
3132
+ let stderr = "";
3133
+ let spinner;
3134
+ if (showSpinner) {
3135
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3136
+ let frameIndex = 0;
3137
+ spinner = setInterval(() => {
3138
+ process.stdout.write(`\r${frames[frameIndex++ % frames.length]} OpenCode is working...`);
3139
+ }, 100);
3140
+ }
3141
+ const stopSpinner = (success) => {
3142
+ if (spinner) {
3143
+ clearInterval(spinner);
3144
+ process.stdout.write(`\r${success ? "\u2713" : "\u2717"} OpenCode ${success ? "done" : "failed"}
3145
+ `);
3146
+ }
3147
+ };
3148
+ proc.stdout.on("data", (data) => {
3149
+ stdout += data.toString();
3150
+ });
3151
+ proc.stderr.on("data", (data) => {
3152
+ stderr += data.toString();
3153
+ });
3154
+ proc.on("close", (code) => {
3155
+ stopSpinner(code === 0);
3156
+ if (code !== 0) {
3157
+ reject(new Error(`OpenCode CLI exited with code ${code}: ${stderr}`));
3158
+ } else {
3159
+ resolve(stdout);
3160
+ }
3161
+ });
3162
+ proc.on("error", (err) => {
3163
+ stopSpinner(false);
3164
+ reject(new Error(`Failed to run OpenCode CLI: ${err.message}`));
3165
+ });
3166
+ });
3167
+ }
3168
+ /**
3169
+ * Execute multiple prompts in parallel with shared progress display
3170
+ */
3171
+ async executeParallel(params) {
3172
+ const total = params.length;
3173
+ let completed = 0;
3174
+ const results = /* @__PURE__ */ new Map();
3175
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3176
+ let frameIndex = 0;
3177
+ const spinner = setInterval(() => {
3178
+ const progress = `${completed}/${total}`;
3179
+ process.stdout.write(`\r${frames[frameIndex++ % frames.length]} Generating sections in parallel... [${progress}]`);
3180
+ }, 100);
3181
+ const stopSpinner = (success) => {
3182
+ clearInterval(spinner);
3183
+ const status = success ? "\u2713" : "\u2717";
3184
+ const message = success ? `All ${total} sections generated` : `Generation completed with errors`;
3185
+ process.stdout.write(`\r${status} ${message}
3186
+ `);
3187
+ };
3188
+ await Promise.all(
3189
+ params.map(async (p) => {
3190
+ const id = p.id || p.outputPath;
3191
+ try {
3192
+ if (p.outputPath) {
3193
+ const outputDir = dirname6(p.outputPath);
3194
+ if (!existsSync10(outputDir)) {
3195
+ mkdirSync7(outputDir, { recursive: true });
3196
+ }
3197
+ }
3198
+ await this.callOpenCode(p.prompt, false);
3199
+ let result = "";
3200
+ if (p.outputPath && existsSync10(p.outputPath)) {
3201
+ result = readFileSync10(p.outputPath, "utf-8");
3202
+ }
3203
+ completed++;
3204
+ results.set(id, { id, success: true, result });
3205
+ } catch (error) {
3206
+ completed++;
3207
+ results.set(id, {
3208
+ id,
3209
+ success: false,
3210
+ error: error instanceof Error ? error.message : String(error)
3211
+ });
3212
+ }
3213
+ })
3214
+ );
3215
+ stopSpinner(Array.from(results.values()).every((r) => r.success));
3216
+ return params.map((p) => results.get(p.id || p.outputPath));
3217
+ }
3218
+ };
3219
+ function createOpenCodeAdapter(opencodeCommand = "opencode") {
3220
+ return {
3221
+ ai: new OpenCodeAIAdapter(opencodeCommand),
3222
+ io: new CLIIOAdapter(),
3223
+ system: new CLISystemAdapter()
3224
+ };
3225
+ }
3226
+
3098
3227
  // src/commands/start.ts
3099
3228
  function getGitHubInfo(cwd) {
3100
3229
  const config = getGitHubConfig(cwd);
@@ -3166,6 +3295,9 @@ async function startCommand(query, options) {
3166
3295
  if (agentType === "codex") {
3167
3296
  adapter = createCodexAdapter();
3168
3297
  console.log("Platform: cli (codex)");
3298
+ } else if (agentType === "opencode") {
3299
+ adapter = createOpenCodeAdapter();
3300
+ console.log("Platform: cli (opencode)");
3169
3301
  } else {
3170
3302
  adapter = createCLIAdapter();
3171
3303
  console.log("Platform: cli (claude)");
@@ -3349,15 +3481,15 @@ Resume with: spets resume --task ${taskId}`);
3349
3481
 
3350
3482
  // src/commands/resume.ts
3351
3483
  import { select as select2 } from "@inquirer/prompts";
3352
- import { existsSync as existsSync10, readdirSync as readdirSync2, readFileSync as readFileSync10 } from "fs";
3484
+ import { existsSync as existsSync11, readdirSync as readdirSync2, readFileSync as readFileSync11 } from "fs";
3353
3485
  import { join as join7 } from "path";
3354
3486
  import { spawnSync as spawnSync3 } from "child_process";
3355
3487
  async function createPR(cwd, taskId, outputs) {
3356
3488
  const outputContents = [];
3357
3489
  for (const outputPath of outputs) {
3358
3490
  const fullPath = join7(cwd, outputPath);
3359
- if (existsSync10(fullPath)) {
3360
- const content = readFileSync10(fullPath, "utf-8");
3491
+ if (existsSync11(fullPath)) {
3492
+ const content = readFileSync11(fullPath, "utf-8");
3361
3493
  outputContents.push(`## ${outputPath}
3362
3494
 
3363
3495
  ${content}`);
@@ -3379,7 +3511,7 @@ ${outputContents.join("\n\n---\n\n")}`;
3379
3511
  }
3380
3512
  function listResumableTasks(cwd) {
3381
3513
  const outputsDir = getOutputsDir(cwd);
3382
- if (!existsSync10(outputsDir)) {
3514
+ if (!existsSync11(outputsDir)) {
3383
3515
  return [];
3384
3516
  }
3385
3517
  const tasks = [];
@@ -3387,7 +3519,7 @@ function listResumableTasks(cwd) {
3387
3519
  const orchestrator = new Orchestrator(cwd);
3388
3520
  for (const taskId of taskDirs) {
3389
3521
  const stateFile = join7(outputsDir, taskId, ".state.json");
3390
- if (!existsSync10(stateFile)) continue;
3522
+ if (!existsSync11(stateFile)) continue;
3391
3523
  try {
3392
3524
  const response = orchestrator.cmdStatus(taskId);
3393
3525
  if (response.type === "error") continue;
@@ -3638,7 +3770,7 @@ Resume with: spets resume --task ${taskId}`);
3638
3770
  }
3639
3771
 
3640
3772
  // src/commands/plugin.ts
3641
- import { existsSync as existsSync11, mkdirSync as mkdirSync7, writeFileSync as writeFileSync7, rmSync, readdirSync as readdirSync3 } from "fs";
3773
+ import { existsSync as existsSync12, mkdirSync as mkdirSync8, writeFileSync as writeFileSync7, rmSync, readdirSync as readdirSync3 } from "fs";
3642
3774
  import { join as join8 } from "path";
3643
3775
  import { homedir } from "os";
3644
3776
  async function pluginCommand(action, name) {
@@ -3671,12 +3803,13 @@ async function pluginCommand(action, name) {
3671
3803
  async function installPlugin(name) {
3672
3804
  const plugins = {
3673
3805
  claude: installClaudePlugin,
3674
- codex: installCodexPlugin
3806
+ codex: installCodexPlugin,
3807
+ opencode: installOpenCodePlugin
3675
3808
  };
3676
3809
  const installer = plugins[name];
3677
3810
  if (!installer) {
3678
3811
  console.error(`Unknown plugin: ${name}`);
3679
- console.error("Available plugins: claude, codex");
3812
+ console.error("Available plugins: claude, codex, opencode");
3680
3813
  process.exit(1);
3681
3814
  }
3682
3815
  installer();
@@ -3684,7 +3817,7 @@ async function installPlugin(name) {
3684
3817
  function installClaudePlugin() {
3685
3818
  const claudeDir = join8(homedir(), ".claude");
3686
3819
  const commandsDir = join8(claudeDir, "commands");
3687
- mkdirSync7(commandsDir, { recursive: true });
3820
+ mkdirSync8(commandsDir, { recursive: true });
3688
3821
  const skillPath = join8(commandsDir, "spets.md");
3689
3822
  writeFileSync7(skillPath, getClaudeSkillContent());
3690
3823
  console.log("Installed Claude Code plugin.");
@@ -3700,7 +3833,7 @@ function installCodexPlugin() {
3700
3833
  const codexDir = join8(homedir(), ".codex");
3701
3834
  const skillsDir = join8(codexDir, "skills");
3702
3835
  const spetsDir = join8(skillsDir, "spets");
3703
- mkdirSync7(spetsDir, { recursive: true });
3836
+ mkdirSync8(spetsDir, { recursive: true });
3704
3837
  const skillPath = join8(spetsDir, "SKILL.md");
3705
3838
  writeFileSync7(skillPath, getCodexSkillContent());
3706
3839
  console.log("Installed Codex CLI plugin.");
@@ -3712,16 +3845,32 @@ function installCodexPlugin() {
3712
3845
  console.log("This skill runs deterministically within your Codex CLI session.");
3713
3846
  console.log("No additional Codex processes are spawned.");
3714
3847
  }
3848
+ function installOpenCodePlugin() {
3849
+ const configDir = join8(homedir(), ".config", "opencode");
3850
+ const skillsDir = join8(configDir, "skills");
3851
+ const spetsDir = join8(skillsDir, "spets");
3852
+ mkdirSync8(spetsDir, { recursive: true });
3853
+ const skillPath = join8(spetsDir, "SKILL.md");
3854
+ writeFileSync7(skillPath, getOpenCodeSkillContent());
3855
+ console.log("Installed OpenCode plugin.");
3856
+ console.log(`Location: ${skillPath}`);
3857
+ console.log("");
3858
+ console.log("Usage in OpenCode:");
3859
+ console.log(" Use the spets skill in your OpenCode session");
3860
+ console.log("");
3861
+ console.log("This skill runs deterministically within your OpenCode session.");
3862
+ console.log("No additional OpenCode processes are spawned.");
3863
+ }
3715
3864
  async function uninstallPlugin(name) {
3716
3865
  if (name === "claude") {
3717
3866
  const skillPath = join8(homedir(), ".claude", "commands", "spets.md");
3718
3867
  const legacySkillPath = join8(homedir(), ".claude", "commands", "sdd-do.md");
3719
3868
  let uninstalled = false;
3720
- if (existsSync11(skillPath)) {
3869
+ if (existsSync12(skillPath)) {
3721
3870
  rmSync(skillPath);
3722
3871
  uninstalled = true;
3723
3872
  }
3724
- if (existsSync11(legacySkillPath)) {
3873
+ if (existsSync12(legacySkillPath)) {
3725
3874
  rmSync(legacySkillPath);
3726
3875
  uninstalled = true;
3727
3876
  }
@@ -3734,7 +3883,7 @@ async function uninstallPlugin(name) {
3734
3883
  }
3735
3884
  if (name === "codex") {
3736
3885
  const skillPath = join8(homedir(), ".codex", "skills", "spets", "SKILL.md");
3737
- if (existsSync11(skillPath)) {
3886
+ if (existsSync12(skillPath)) {
3738
3887
  rmSync(skillPath);
3739
3888
  try {
3740
3889
  const skillDir = join8(homedir(), ".codex", "skills", "spets");
@@ -3752,24 +3901,48 @@ async function uninstallPlugin(name) {
3752
3901
  }
3753
3902
  return;
3754
3903
  }
3904
+ if (name === "opencode") {
3905
+ const skillPath = join8(homedir(), ".config", "opencode", "skills", "spets", "SKILL.md");
3906
+ if (existsSync12(skillPath)) {
3907
+ rmSync(skillPath);
3908
+ try {
3909
+ const skillDir = join8(homedir(), ".config", "opencode", "skills", "spets");
3910
+ const skillsDir = join8(homedir(), ".config", "opencode", "skills");
3911
+ rmSync(skillDir, { recursive: true });
3912
+ const remaining = readdirSync3(skillsDir);
3913
+ if (remaining.length === 0) {
3914
+ rmSync(skillsDir);
3915
+ }
3916
+ } catch {
3917
+ }
3918
+ console.log("Uninstalled OpenCode plugin.");
3919
+ } else {
3920
+ console.log("OpenCode plugin not installed.");
3921
+ }
3922
+ return;
3923
+ }
3755
3924
  console.error(`Unknown plugin: ${name}`);
3756
3925
  process.exit(1);
3757
3926
  }
3758
3927
  async function listPlugins() {
3759
3928
  console.log("Available plugins:");
3760
3929
  console.log("");
3761
- console.log(" claude - Claude Code /spets skill");
3762
- console.log(" codex - Codex CLI $spets skill");
3930
+ console.log(" claude - Claude Code /spets skill");
3931
+ console.log(" codex - Codex CLI $spets skill");
3932
+ console.log(" opencode - OpenCode spets skill");
3763
3933
  console.log("");
3764
3934
  const claudeSkillPath = join8(homedir(), ".claude", "commands", "spets.md");
3765
3935
  const claudeLegacySkillPath = join8(homedir(), ".claude", "commands", "sdd-do.md");
3766
- const claudeInstalled = existsSync11(claudeSkillPath) || existsSync11(claudeLegacySkillPath);
3936
+ const claudeInstalled = existsSync12(claudeSkillPath) || existsSync12(claudeLegacySkillPath);
3767
3937
  const codexSkillPath = join8(homedir(), ".codex", "skills", "spets", "SKILL.md");
3768
- const codexInstalled = existsSync11(codexSkillPath);
3938
+ const codexInstalled = existsSync12(codexSkillPath);
3939
+ const opencodeSkillPath = join8(homedir(), ".config", "opencode", "skills", "spets", "SKILL.md");
3940
+ const opencodeInstalled = existsSync12(opencodeSkillPath);
3769
3941
  console.log("Installed:");
3770
3942
  const installed = [];
3771
3943
  if (claudeInstalled) installed.push("claude");
3772
3944
  if (codexInstalled) installed.push("codex");
3945
+ if (opencodeInstalled) installed.push("opencode");
3773
3946
  if (installed.length > 0) {
3774
3947
  for (const plugin of installed) {
3775
3948
  console.log(` - ${plugin}`);
@@ -4058,23 +4231,82 @@ npx spets orchestrate revise <taskId> "<feedback>"
4058
4231
  npx spets orchestrate reject <taskId>
4059
4232
  npx spets orchestrate stop <taskId>
4060
4233
 
4234
+ $ARGUMENTS
4235
+ description: Task description for the workflow
4236
+ `;
4237
+ }
4238
+ function getOpenCodeSkillContent() {
4239
+ return `---
4240
+ name: spets
4241
+ description: SDD workflow executor - runs spec-driven development workflows within OpenCode
4242
+ ---
4243
+
4244
+ # Spets Command Executor
4245
+
4246
+ Execute orchestrator commands. Parse JSON response and execute matching action.
4247
+
4248
+ ## Start
4249
+
4250
+ Run: npx spets orchestrate init "$ARGUMENTS"
4251
+
4252
+ Parse JSON response, then execute action from table below, loop until type: "complete" or "error".
4253
+
4254
+ ## Command Table
4255
+
4256
+ ### type: "phase"
4257
+
4258
+ | phase | Action |
4259
+ |-------|--------|
4260
+ | explore | Follow response.prompt to explore codebase |
4261
+ | clarify | Follow response.prompt to generate questions |
4262
+ | execute | Follow response.prompt to write document |
4263
+ | verify | Follow response.prompt to validate document |
4264
+
4265
+ ### type: "checkpoint"
4266
+
4267
+ | checkpoint | Action |
4268
+ |------------|--------|
4269
+ | clarify | Ask user questions, collect answers |
4270
+ | approve | Ask user to review document |
4271
+
4272
+ ### type: "complete"
4273
+
4274
+ Print completion status and outputs.
4275
+
4276
+ ### type: "error"
4277
+
4278
+ Print error and stop.
4279
+
4280
+ ## Orchestrator Commands
4281
+
4282
+ npx spets orchestrate init "<description>"
4283
+ npx spets orchestrate explore-done <taskId> '<json>'
4284
+ npx spets orchestrate clarify-done <taskId> '<json>'
4285
+ npx spets orchestrate clarified <taskId> '<json>'
4286
+ npx spets orchestrate execute-done <taskId>
4287
+ npx spets orchestrate verify-done <taskId> '<json>'
4288
+ npx spets orchestrate approve <taskId>
4289
+ npx spets orchestrate revise <taskId> "<feedback>"
4290
+ npx spets orchestrate reject <taskId>
4291
+ npx spets orchestrate stop <taskId>
4292
+
4061
4293
  $ARGUMENTS
4062
4294
  description: Task description for the workflow
4063
4295
  `;
4064
4296
  }
4065
4297
 
4066
4298
  // src/commands/github.ts
4067
- import { execSync as execSync4, spawn as spawn5, spawnSync as spawnSync4 } from "child_process";
4068
- import { readdirSync as readdirSync4, readFileSync as readFileSync11, existsSync as existsSync13 } from "fs";
4299
+ import { execSync as execSync4, spawn as spawn6, spawnSync as spawnSync4 } from "child_process";
4300
+ import { readdirSync as readdirSync4, readFileSync as readFileSync12, existsSync as existsSync14 } from "fs";
4069
4301
  import { join as join10 } from "path";
4070
4302
 
4071
4303
  // src/hooks/runner.ts
4072
- import { spawn as spawn4 } from "child_process";
4073
- import { existsSync as existsSync12 } from "fs";
4304
+ import { spawn as spawn5 } from "child_process";
4305
+ import { existsSync as existsSync13 } from "fs";
4074
4306
  import { join as join9, isAbsolute } from "path";
4075
4307
  async function runHook(hookPath, context, cwd = process.cwd()) {
4076
4308
  const resolvedPath = isAbsolute(hookPath) ? hookPath : join9(getSpetsDir(cwd), hookPath);
4077
- if (!existsSync12(resolvedPath)) {
4309
+ if (!existsSync13(resolvedPath)) {
4078
4310
  console.warn(`Hook not found: ${resolvedPath}`);
4079
4311
  return;
4080
4312
  }
@@ -4088,7 +4320,7 @@ async function runHook(hookPath, context, cwd = process.cwd()) {
4088
4320
  SPETS_CWD: cwd
4089
4321
  };
4090
4322
  return new Promise((resolve, reject) => {
4091
- const proc = spawn4(resolvedPath, [], {
4323
+ const proc = spawn5(resolvedPath, [], {
4092
4324
  cwd,
4093
4325
  env,
4094
4326
  stdio: "inherit",
@@ -4185,7 +4417,7 @@ function findTaskId(cwd, owner, repo, issueOrPr) {
4185
4417
  }
4186
4418
  }
4187
4419
  const outputsDir = getOutputsDir(cwd);
4188
- if (existsSync13(outputsDir)) {
4420
+ if (existsSync14(outputsDir)) {
4189
4421
  const taskDirs = readdirSync4(outputsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name).sort().reverse();
4190
4422
  if (taskDirs.length > 0) {
4191
4423
  return taskDirs[0];
@@ -4418,7 +4650,7 @@ async function postComment(config, body) {
4418
4650
  const { owner, repo, prNumber, issueNumber } = config;
4419
4651
  const args = prNumber ? ["pr", "comment", String(prNumber), "--body", body, "-R", `${owner}/${repo}`] : ["issue", "comment", String(issueNumber), "--body", body, "-R", `${owner}/${repo}`];
4420
4652
  return new Promise((resolve, reject) => {
4421
- const proc = spawn5("gh", args, { stdio: "inherit" });
4653
+ const proc = spawn6("gh", args, { stdio: "inherit" });
4422
4654
  proc.on("close", (code) => {
4423
4655
  if (code !== 0) reject(new Error(`gh failed with code ${code}`));
4424
4656
  else resolve();
@@ -4430,10 +4662,10 @@ async function createPullRequestWithAI(config, taskId, userQuery, cwd) {
4430
4662
  const { owner, repo, issueNumber } = config;
4431
4663
  const outputsDir = join10(getOutputsDir(cwd), taskId);
4432
4664
  const outputs = [];
4433
- if (existsSync13(outputsDir)) {
4665
+ if (existsSync14(outputsDir)) {
4434
4666
  const files = readdirSync4(outputsDir).filter((f) => f.endsWith(".md"));
4435
4667
  for (const file of files) {
4436
- const content = readFileSync11(join10(outputsDir, file), "utf-8");
4668
+ const content = readFileSync12(join10(outputsDir, file), "utf-8");
4437
4669
  outputs.push({ step: file.replace(".md", ""), content });
4438
4670
  }
4439
4671
  }
@@ -4519,7 +4751,7 @@ Closes #${issueNumber}`;
4519
4751
  }
4520
4752
  async function callClaude(prompt) {
4521
4753
  return new Promise((resolve, reject) => {
4522
- const proc = spawn5("claude", ["--print"], { stdio: ["pipe", "pipe", "pipe"] });
4754
+ const proc = spawn6("claude", ["--print"], { stdio: ["pipe", "pipe", "pipe"] });
4523
4755
  let stdout = "";
4524
4756
  let stderr = "";
4525
4757
  proc.stdout.on("data", (data) => {
@@ -4799,8 +5031,8 @@ async function orchestrateCommand(action, args) {
4799
5031
  }
4800
5032
 
4801
5033
  // src/index.ts
4802
- var __dirname2 = dirname6(fileURLToPath2(import.meta.url));
4803
- var pkg = JSON.parse(readFileSync12(join11(__dirname2, "..", "package.json"), "utf-8"));
5034
+ var __dirname2 = dirname7(fileURLToPath2(import.meta.url));
5035
+ var pkg = JSON.parse(readFileSync13(join11(__dirname2, "..", "package.json"), "utf-8"));
4804
5036
  var program = new Command();
4805
5037
  program.name("spets").description("Spec Driven Development Execution Framework").version(pkg.version);
4806
5038
  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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spets",
3
- "version": "0.1.49",
3
+ "version": "0.1.50",
4
4
  "description": "Spec Driven Development Execution Framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",