opencode-goopspec 0.1.3 → 0.1.4

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 (53) hide show
  1. package/README.md +253 -331
  2. package/agents/goop-debugger.md +175 -172
  3. package/agents/goop-designer.md +232 -160
  4. package/agents/goop-executor.md +197 -127
  5. package/agents/goop-explorer.md +148 -150
  6. package/agents/goop-librarian.md +218 -164
  7. package/agents/goop-orchestrator.md +364 -338
  8. package/agents/goop-planner.md +331 -153
  9. package/agents/goop-researcher.md +198 -126
  10. package/agents/goop-tester.md +277 -202
  11. package/agents/goop-verifier.md +191 -201
  12. package/agents/goop-writer.md +241 -133
  13. package/agents/memory-distiller.md +228 -136
  14. package/commands/goop-accept.md +430 -36
  15. package/commands/goop-amend.md +13 -0
  16. package/commands/goop-complete.md +13 -0
  17. package/commands/goop-debug.md +13 -0
  18. package/commands/goop-discuss.md +419 -7
  19. package/commands/goop-execute.md +386 -37
  20. package/commands/goop-help.md +11 -0
  21. package/commands/goop-map-codebase.md +13 -0
  22. package/commands/goop-memory.md +11 -0
  23. package/commands/goop-milestone.md +13 -0
  24. package/commands/goop-pause.md +12 -0
  25. package/commands/goop-plan.md +320 -266
  26. package/commands/goop-quick.md +12 -0
  27. package/commands/goop-recall.md +11 -0
  28. package/commands/goop-remember.md +12 -0
  29. package/commands/goop-research.md +13 -0
  30. package/commands/goop-resume.md +12 -0
  31. package/commands/goop-setup.md +18 -8
  32. package/commands/goop-specify.md +315 -39
  33. package/commands/goop-status.md +276 -28
  34. package/dist/index.js +328 -15
  35. package/package.json +1 -1
  36. package/references/context-injection.md +307 -0
  37. package/references/discovery-interview.md +278 -0
  38. package/references/enforcement-system.md +213 -0
  39. package/references/handoff-protocol.md +290 -0
  40. package/references/model-profiles.md +1 -1
  41. package/references/phase-gates.md +360 -0
  42. package/references/plugin-architecture.md +212 -0
  43. package/references/response-format.md +41 -9
  44. package/references/subagent-protocol.md +83 -33
  45. package/references/visual-style.md +199 -0
  46. package/references/xml-response-schema.md +236 -0
  47. package/templates/blueprint.md +88 -41
  48. package/templates/chronicle.md +130 -16
  49. package/templates/handoff.md +140 -0
  50. package/templates/project.md +114 -0
  51. package/templates/requirements.md +121 -0
  52. package/templates/spec.md +85 -20
  53. package/templates/state.md +103 -0
package/dist/index.js CHANGED
@@ -14067,6 +14067,8 @@ function createDefaultState(projectName = "unnamed") {
14067
14067
  researchOptIn: false,
14068
14068
  specLocked: false,
14069
14069
  acceptanceConfirmed: false,
14070
+ interviewComplete: false,
14071
+ interviewCompletedAt: null,
14070
14072
  currentWave: 0,
14071
14073
  totalWaves: 0,
14072
14074
  lastActivity: now,
@@ -14106,6 +14108,8 @@ function migrateOldState(oldState, projectName) {
14106
14108
  researchOptIn: existingWorkflow?.researchOptIn || false,
14107
14109
  specLocked: existingWorkflow?.specLocked || false,
14108
14110
  acceptanceConfirmed: existingWorkflow?.acceptanceConfirmed || false,
14111
+ interviewComplete: existingWorkflow?.interviewComplete || oldState.interview_complete || false,
14112
+ interviewCompletedAt: existingWorkflow?.interviewCompletedAt || oldState.interview_completed_at || null,
14109
14113
  currentWave: existingWorkflow?.currentWave || 0,
14110
14114
  totalWaves: existingWorkflow?.totalWaves || 0,
14111
14115
  lastActivity: existingWorkflow?.lastActivity || new Date().toISOString(),
@@ -14405,6 +14409,19 @@ This file tracks architectural decisions, deviations, and observations made duri
14405
14409
  saveState(newState);
14406
14410
  log("Spec locked");
14407
14411
  }
14412
+ function unlockSpec() {
14413
+ const current = loadState();
14414
+ const newState = {
14415
+ ...current,
14416
+ workflow: {
14417
+ ...current.workflow,
14418
+ specLocked: false,
14419
+ lastActivity: new Date().toISOString()
14420
+ }
14421
+ };
14422
+ saveState(newState);
14423
+ log("Spec unlocked");
14424
+ }
14408
14425
  function confirmAcceptance() {
14409
14426
  const current = loadState();
14410
14427
  const newState = {
@@ -14418,6 +14435,48 @@ This file tracks architectural decisions, deviations, and observations made duri
14418
14435
  saveState(newState);
14419
14436
  log("Acceptance confirmed");
14420
14437
  }
14438
+ function resetAcceptance() {
14439
+ const current = loadState();
14440
+ const newState = {
14441
+ ...current,
14442
+ workflow: {
14443
+ ...current.workflow,
14444
+ acceptanceConfirmed: false,
14445
+ lastActivity: new Date().toISOString()
14446
+ }
14447
+ };
14448
+ saveState(newState);
14449
+ log("Acceptance reset");
14450
+ }
14451
+ function completeInterview() {
14452
+ const current = loadState();
14453
+ const now = new Date().toISOString();
14454
+ const newState = {
14455
+ ...current,
14456
+ workflow: {
14457
+ ...current.workflow,
14458
+ interviewComplete: true,
14459
+ interviewCompletedAt: now,
14460
+ lastActivity: now
14461
+ }
14462
+ };
14463
+ saveState(newState);
14464
+ log("Interview completed");
14465
+ }
14466
+ function resetInterview() {
14467
+ const current = loadState();
14468
+ const newState = {
14469
+ ...current,
14470
+ workflow: {
14471
+ ...current.workflow,
14472
+ interviewComplete: false,
14473
+ interviewCompletedAt: null,
14474
+ lastActivity: new Date().toISOString()
14475
+ }
14476
+ };
14477
+ saveState(newState);
14478
+ log("Interview reset");
14479
+ }
14421
14480
  function setMode(mode) {
14422
14481
  const current = loadState();
14423
14482
  const newState = {
@@ -14445,15 +14504,49 @@ This file tracks architectural decisions, deviations, and observations made duri
14445
14504
  saveState(newState);
14446
14505
  log("Wave progress updated", { currentWave, totalWaves });
14447
14506
  }
14507
+ function resetWorkflow() {
14508
+ const current = loadState();
14509
+ const now = new Date().toISOString();
14510
+ const newState = {
14511
+ ...current,
14512
+ workflow: {
14513
+ currentPhase: null,
14514
+ phase: "idle",
14515
+ mode: "standard",
14516
+ depth: "standard",
14517
+ researchOptIn: false,
14518
+ specLocked: false,
14519
+ acceptanceConfirmed: false,
14520
+ interviewComplete: false,
14521
+ interviewCompletedAt: null,
14522
+ currentWave: 0,
14523
+ totalWaves: 0,
14524
+ lastActivity: now,
14525
+ status: "idle"
14526
+ },
14527
+ execution: {
14528
+ ...current.execution,
14529
+ completedPhases: [],
14530
+ pendingTasks: []
14531
+ }
14532
+ };
14533
+ saveState(newState);
14534
+ log("Workflow reset");
14535
+ }
14448
14536
  return {
14449
14537
  getState,
14450
14538
  setState,
14451
14539
  updateWorkflow,
14452
14540
  transitionPhase,
14453
14541
  lockSpec,
14542
+ unlockSpec,
14454
14543
  confirmAcceptance,
14544
+ resetAcceptance,
14545
+ completeInterview,
14546
+ resetInterview,
14455
14547
  setMode,
14456
14548
  updateWaveProgress,
14549
+ resetWorkflow,
14457
14550
  getADL,
14458
14551
  appendADL,
14459
14552
  saveCheckpoint,
@@ -27160,19 +27253,24 @@ function formatNextSteps(guidance) {
27160
27253
  }
27161
27254
  function formatStatus(state, verbose, ctx) {
27162
27255
  const lines = [];
27163
- lines.push(`# GoopSpec Status
27164
- `);
27165
27256
  if (!state) {
27166
- lines.push("**Status:** Not initialized");
27167
- lines.push("\nRun `/goop-plan` to start a new project.");
27257
+ lines.push("## \uD83D\uDD2E GoopSpec \xB7 Status");
27258
+ lines.push("");
27259
+ lines.push("\u23F3 Not initialized");
27260
+ lines.push("");
27261
+ lines.push("\u2192 Run `/goop-discuss` to start a new project.");
27262
+ lines.push("");
27263
+ lines.push("---");
27168
27264
  return lines.join(`
27169
27265
  `);
27170
27266
  }
27171
27267
  const projectName = state.project?.name || "Unknown";
27172
27268
  const initialized = state.project?.initialized || "Not set";
27269
+ lines.push("## \uD83D\uDD2E GoopSpec \xB7 Status");
27270
+ lines.push("");
27173
27271
  lines.push(`**Project:** ${projectName}`);
27174
- lines.push(`**Initialized:** ${initialized}
27175
- `);
27272
+ lines.push(`**Initialized:** ${initialized}`);
27273
+ lines.push("");
27176
27274
  const workflow = state.workflow || {
27177
27275
  phase: "idle",
27178
27276
  mode: "standard",
@@ -27203,6 +27301,8 @@ function formatStatus(state, verbose, ctx) {
27203
27301
  };
27204
27302
  const modeIcon = modeIcons[workflow.mode] || "\uD83D\uDCE6";
27205
27303
  lines.push(`- **Mode:** ${modeIcon} ${workflow.mode || "standard"}`);
27304
+ const interviewComplete = workflow.interviewComplete;
27305
+ lines.push(`- **Interview Complete:** ${interviewComplete ? "\u2705 Yes" : "\u23F3 No"}`);
27206
27306
  lines.push(`- **Spec Locked:** ${workflow.specLocked ? "\uD83D\uDD12 Yes" : "\uD83D\uDD13 No"}`);
27207
27307
  lines.push(`- **Accepted:** ${workflow.acceptanceConfirmed ? "\u2705 Yes" : "\u23F3 Pending"}`);
27208
27308
  if (workflow.totalWaves > 0) {
@@ -27244,7 +27344,7 @@ function formatStatus(state, verbose, ctx) {
27244
27344
  lines.push("- Use `memory_search` to find relevant context");
27245
27345
  }
27246
27346
  lines.push(`
27247
- ## Next Steps`);
27347
+ \u2550\u2550\u2550 Next Steps \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550`);
27248
27348
  const guidance = getPhaseGuidance(workflow.phase, workflow.specLocked);
27249
27349
  const nextSteps = formatNextSteps(guidance);
27250
27350
  for (const step of nextSteps) {
@@ -30279,14 +30379,14 @@ var AGENT_MODEL_SUGGESTIONS = {
30279
30379
  suggestions: [
30280
30380
  "openai/gpt-5.2-codex",
30281
30381
  "anthropic/claude-opus-4-5",
30282
- "opencode/kimi-k2.5-free"
30382
+ "kimi-for-coding/k2p5"
30283
30383
  ],
30284
30384
  description: "Systematic debugging with hypothesis testing"
30285
30385
  },
30286
30386
  "goop-designer": {
30287
30387
  suggestions: [
30288
30388
  "anthropic/claude-opus-4-5",
30289
- "opencode/kimi-k2.5-free",
30389
+ "kimi-for-coding/k2p5",
30290
30390
  "google/antigravity-gemini-3-pro-high"
30291
30391
  ],
30292
30392
  description: "Visual design planning and UI/UX reasoning"
@@ -30296,7 +30396,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30296
30396
  "openai/gpt-5.2-codex",
30297
30397
  "anthropic/claude-opus-4-5",
30298
30398
  "anthropic/claude-sonnet-4-5",
30299
- "opencode/kimi-k2.5-free",
30399
+ "kimi-for-coding/k2p5",
30300
30400
  "google/antigravity-gemini-3-pro-high",
30301
30401
  "opencode/glm-4.7-free"
30302
30402
  ],
@@ -30322,7 +30422,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30322
30422
  suggestions: [
30323
30423
  "openai/gpt-5.2-codex",
30324
30424
  "anthropic/claude-opus-4-5",
30325
- "opencode/kimi-k2.5-free",
30425
+ "kimi-for-coding/k2p5",
30326
30426
  "anthropic/claude-sonnet-4-5"
30327
30427
  ],
30328
30428
  description: "Primary orchestrator - spec clarity and wave execution"
@@ -30331,7 +30431,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30331
30431
  suggestions: [
30332
30432
  "openai/gpt-5.2-codex",
30333
30433
  "anthropic/claude-opus-4-5",
30334
- "opencode/kimi-k2.5-free",
30434
+ "kimi-for-coding/k2p5",
30335
30435
  "anthropic/claude-sonnet-4-5"
30336
30436
  ],
30337
30437
  description: "Detailed execution plans with architectural precision"
@@ -30340,7 +30440,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30340
30440
  suggestions: [
30341
30441
  "openai/gpt-5.2",
30342
30442
  "anthropic/claude-sonnet-4-5",
30343
- "opencode/kimi-k2.5-free",
30443
+ "kimi-for-coding/k2p5",
30344
30444
  "opencode/glm-4.7-free"
30345
30445
  ],
30346
30446
  description: "Comprehensive ecosystem research"
@@ -30348,7 +30448,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30348
30448
  "goop-tester": {
30349
30449
  suggestions: [
30350
30450
  "anthropic/claude-sonnet-4-5",
30351
- "opencode/kimi-k2.5-free",
30451
+ "kimi-for-coding/k2p5",
30352
30452
  "google/antigravity-gemini-3-flash"
30353
30453
  ],
30354
30454
  description: "Web frontend testing with Playwright"
@@ -30363,7 +30463,7 @@ var AGENT_MODEL_SUGGESTIONS = {
30363
30463
  "goop-writer": {
30364
30464
  suggestions: [
30365
30465
  "google/antigravity-gemini-3-pro-high",
30366
- "opencode/kimi-k2.5-free",
30466
+ "kimi-for-coding/k2p5",
30367
30467
  "anthropic/claude-sonnet-4-5"
30368
30468
  ],
30369
30469
  description: "Comprehensive documentation generation"
@@ -30793,6 +30893,218 @@ function createGoopSetupTool(_ctx) {
30793
30893
  });
30794
30894
  }
30795
30895
 
30896
+ // src/tools/goop-state/index.ts
30897
+ var VALID_PHASES = ["idle", "plan", "research", "specify", "execute", "accept"];
30898
+ var VALID_MODES = ["quick", "standard", "comprehensive", "milestone"];
30899
+ var VALID_DEPTHS = ["shallow", "standard", "deep"];
30900
+ function createGoopStateTool(ctx) {
30901
+ return tool({
30902
+ description: `Safe atomic state operations for GoopSpec workflow. Use this instead of directly editing state.json.
30903
+
30904
+ Actions:
30905
+ - 'get': Read current state (returns full state object)
30906
+ - 'transition': Change workflow phase (validates transitions)
30907
+ - 'complete-interview': Mark discovery interview as complete
30908
+ - 'reset-interview': Reset interview status (for starting fresh)
30909
+ - 'lock-spec': Lock the specification contract
30910
+ - 'unlock-spec': Unlock the specification (use with caution)
30911
+ - 'confirm-acceptance': Confirm work acceptance
30912
+ - 'reset-acceptance': Reset acceptance status
30913
+ - 'set-mode': Set task mode (quick/standard/comprehensive/milestone)
30914
+ - 'set-depth': Set workflow depth (shallow/standard/deep)
30915
+ - 'update-wave': Update wave progress
30916
+ - 'reset': Reset entire workflow to idle state
30917
+
30918
+ IMPORTANT: Always use this tool instead of Read/Edit on state.json to avoid conflicts.`,
30919
+ args: {
30920
+ action: tool.schema.enum([
30921
+ "get",
30922
+ "transition",
30923
+ "complete-interview",
30924
+ "reset-interview",
30925
+ "lock-spec",
30926
+ "unlock-spec",
30927
+ "confirm-acceptance",
30928
+ "reset-acceptance",
30929
+ "set-mode",
30930
+ "set-depth",
30931
+ "update-wave",
30932
+ "reset"
30933
+ ]),
30934
+ phase: tool.schema.string().optional(),
30935
+ mode: tool.schema.string().optional(),
30936
+ depth: tool.schema.string().optional(),
30937
+ currentWave: tool.schema.number().optional(),
30938
+ totalWaves: tool.schema.number().optional(),
30939
+ force: tool.schema.boolean().optional()
30940
+ },
30941
+ async execute(args, _context) {
30942
+ const { action } = args;
30943
+ log("goop_state action", { action, args });
30944
+ switch (action) {
30945
+ case "get": {
30946
+ const state = ctx.stateManager.getState();
30947
+ const workflow = state.workflow;
30948
+ const phaseIcons = {
30949
+ idle: "\uD83D\uDD2E",
30950
+ plan: "\uD83D\uDCCB",
30951
+ research: "\uD83D\uDD2C",
30952
+ specify: "\uD83D\uDCDC",
30953
+ execute: "\u26A1",
30954
+ accept: "\u2705"
30955
+ };
30956
+ const phaseIcon = phaseIcons[workflow.phase] || "\uD83D\uDD2E";
30957
+ return `## \uD83D\uDD2E GoopSpec \xB7 State
30958
+
30959
+ ### Project
30960
+ - **Name:** ${state.project.name}
30961
+ - **Initialized:** ${state.project.initialized}
30962
+
30963
+ ### Workflow
30964
+ - **Phase:** ${phaseIcon} ${workflow.phase}
30965
+ - **Mode:** ${workflow.mode}
30966
+ - **Depth:** ${workflow.depth}
30967
+ - **Interview:** ${workflow.interviewComplete ? "\u2713 Complete" : "\u23F3 Pending"}${workflow.interviewCompletedAt ? ` (${workflow.interviewCompletedAt})` : ""}
30968
+ - **Spec:** ${workflow.specLocked ? "\uD83D\uDD12 Locked" : "\uD83D\uDD13 Unlocked"}
30969
+ - **Acceptance:** ${workflow.acceptanceConfirmed ? "\u2713 Confirmed" : "\u23F3 Pending"}
30970
+ - **Wave:** ${workflow.currentWave}/${workflow.totalWaves}
30971
+ - **Last Activity:** ${workflow.lastActivity}
30972
+
30973
+ ### Execution
30974
+ - **Checkpoint:** ${state.execution.activeCheckpointId || "None"}
30975
+ - **Completed:** ${state.execution.completedPhases.length > 0 ? state.execution.completedPhases.join(" \u2192 ") : "None"}
30976
+ - **Pending Tasks:** ${state.execution.pendingTasks.length}
30977
+
30978
+ ---`;
30979
+ }
30980
+ case "transition": {
30981
+ if (!args.phase) {
30982
+ return `Error: 'phase' is required for transition action.
30983
+
30984
+ Valid phases: ` + VALID_PHASES.join(", ");
30985
+ }
30986
+ const phase = args.phase;
30987
+ if (!VALID_PHASES.includes(phase)) {
30988
+ return `Error: Invalid phase '${args.phase}'.
30989
+
30990
+ Valid phases: ${VALID_PHASES.join(", ")}`;
30991
+ }
30992
+ const success3 = ctx.stateManager.transitionPhase(phase, args.force ?? false);
30993
+ if (success3) {
30994
+ const state = ctx.stateManager.getState();
30995
+ return `Phase transitioned to: ${phase}
30996
+
30997
+ Current state:
30998
+ - Phase: ${state.workflow.phase}
30999
+ - Interview Complete: ${state.workflow.interviewComplete}
31000
+ - Spec Locked: ${state.workflow.specLocked}`;
31001
+ } else {
31002
+ const currentState = ctx.stateManager.getState();
31003
+ return `Error: Invalid phase transition from '${currentState.workflow.phase}' to '${phase}'.
31004
+
31005
+ Use force=true to override (not recommended).
31006
+
31007
+ Valid transitions from '${currentState.workflow.phase}': Check workflow documentation.`;
31008
+ }
31009
+ }
31010
+ case "complete-interview": {
31011
+ ctx.stateManager.completeInterview();
31012
+ return `\u2713 Interview marked as complete.
31013
+
31014
+ \u2192 Proceed to planning with \`/goop-plan\``;
31015
+ }
31016
+ case "reset-interview": {
31017
+ ctx.stateManager.resetInterview();
31018
+ return `\u2713 Interview status reset.
31019
+
31020
+ \u2192 Run \`/goop-discuss\` to start a new discovery interview.`;
31021
+ }
31022
+ case "lock-spec": {
31023
+ ctx.stateManager.lockSpec();
31024
+ return `\uD83D\uDD12 Specification locked.
31025
+
31026
+ The spec is now a contract. Execution can proceed.
31027
+
31028
+ \u2192 Run \`/goop-execute\` to begin implementation.`;
31029
+ }
31030
+ case "unlock-spec": {
31031
+ ctx.stateManager.unlockSpec();
31032
+ return `\uD83D\uDD13 Specification unlocked.
31033
+
31034
+ \u26A0\uFE0F Warning: Unlocking the spec should only be done when amendments are needed.`;
31035
+ }
31036
+ case "confirm-acceptance": {
31037
+ ctx.stateManager.confirmAcceptance();
31038
+ return `\u2713 Acceptance confirmed.
31039
+
31040
+ Work has been verified and accepted.
31041
+
31042
+ \u2192 Use \`/goop-complete\` to finalize.`;
31043
+ }
31044
+ case "reset-acceptance": {
31045
+ ctx.stateManager.resetAcceptance();
31046
+ return `\u2713 Acceptance status reset.
31047
+
31048
+ Work needs to be re-verified.`;
31049
+ }
31050
+ case "set-mode": {
31051
+ if (!args.mode) {
31052
+ return `\u2717 Error: 'mode' is required for set-mode action.
31053
+
31054
+ Valid modes: ` + VALID_MODES.join(", ");
31055
+ }
31056
+ const mode = args.mode;
31057
+ if (!VALID_MODES.includes(mode)) {
31058
+ return `\u2717 Error: Invalid mode '${args.mode}'.
31059
+
31060
+ Valid modes: ${VALID_MODES.join(", ")}`;
31061
+ }
31062
+ ctx.stateManager.setMode(mode);
31063
+ return `\u2713 Task mode set to: ${mode}`;
31064
+ }
31065
+ case "set-depth": {
31066
+ if (!args.depth) {
31067
+ return `\u2717 Error: 'depth' is required for set-depth action.
31068
+
31069
+ Valid depths: ` + VALID_DEPTHS.join(", ");
31070
+ }
31071
+ const depth = args.depth;
31072
+ if (!VALID_DEPTHS.includes(depth)) {
31073
+ return `\u2717 Error: Invalid depth '${args.depth}'.
31074
+
31075
+ Valid depths: ${VALID_DEPTHS.join(", ")}`;
31076
+ }
31077
+ ctx.stateManager.updateWorkflow({ depth });
31078
+ return `\u2713 Workflow depth set to: ${depth}`;
31079
+ }
31080
+ case "update-wave": {
31081
+ if (args.currentWave === undefined || args.totalWaves === undefined) {
31082
+ return "\u2717 Error: Both 'currentWave' and 'totalWaves' are required for update-wave action.";
31083
+ }
31084
+ if (args.currentWave < 0 || args.totalWaves < 0) {
31085
+ return "\u2717 Error: Wave numbers must be non-negative.";
31086
+ }
31087
+ if (args.currentWave > args.totalWaves) {
31088
+ return "\u2717 Error: currentWave cannot be greater than totalWaves.";
31089
+ }
31090
+ ctx.stateManager.updateWaveProgress(args.currentWave, args.totalWaves);
31091
+ return `\u2713 Wave progress: ${args.currentWave}/${args.totalWaves}`;
31092
+ }
31093
+ case "reset": {
31094
+ ctx.stateManager.resetWorkflow();
31095
+ return `\u2713 Workflow reset to idle state.
31096
+
31097
+ All workflow flags cleared. Ready for a new task.
31098
+
31099
+ \u2192 Run \`/goop-discuss\` to start.`;
31100
+ }
31101
+ default:
31102
+ return "Unknown action. Valid actions: get, transition, complete-interview, reset-interview, lock-spec, unlock-spec, confirm-acceptance, reset-acceptance, set-mode, set-depth, update-wave, reset";
31103
+ }
31104
+ }
31105
+ });
31106
+ }
31107
+
30796
31108
  // src/tools/memory-save/index.ts
30797
31109
  function normalizeImportance(value) {
30798
31110
  if (value === undefined) {
@@ -31316,6 +31628,7 @@ Available types: tool_call, phase_change, checkpoint, decision`;
31316
31628
  function createTools(ctx) {
31317
31629
  return {
31318
31630
  goop_status: createGoopStatusTool(ctx),
31631
+ goop_state: createGoopStateTool(ctx),
31319
31632
  goop_adl: createGoopAdlTool(ctx),
31320
31633
  goop_spec: createGoopSpecTool(ctx),
31321
31634
  goop_checkpoint: createGoopCheckpointTool(ctx),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-goopspec",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A spec-driven development plugin for OpenCode with user-guided planning, wave execution, and verification",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",