gsd-opencode 1.30.0 → 1.33.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 (113) hide show
  1. package/agents/gsd-debugger.md +0 -1
  2. package/agents/gsd-doc-verifier.md +207 -0
  3. package/agents/gsd-doc-writer.md +608 -0
  4. package/agents/gsd-executor.md +22 -1
  5. package/agents/gsd-phase-researcher.md +41 -0
  6. package/agents/gsd-plan-checker.md +82 -0
  7. package/agents/gsd-planner.md +123 -194
  8. package/agents/gsd-security-auditor.md +129 -0
  9. package/agents/gsd-ui-auditor.md +40 -0
  10. package/agents/gsd-user-profiler.md +2 -2
  11. package/agents/gsd-verifier.md +84 -18
  12. package/commands/gsd/gsd-add-backlog.md +1 -1
  13. package/commands/gsd/gsd-analyze-dependencies.md +34 -0
  14. package/commands/gsd/gsd-autonomous.md +6 -2
  15. package/commands/gsd/gsd-cleanup.md +5 -0
  16. package/commands/gsd/gsd-debug.md +24 -21
  17. package/commands/gsd/gsd-discuss-phase.md +7 -2
  18. package/commands/gsd/gsd-docs-update.md +48 -0
  19. package/commands/gsd/gsd-execute-phase.md +4 -0
  20. package/commands/gsd/gsd-help.md +2 -0
  21. package/commands/gsd/gsd-join-discord.md +2 -1
  22. package/commands/gsd/gsd-manager.md +1 -0
  23. package/commands/gsd/gsd-new-project.md +4 -0
  24. package/commands/gsd/gsd-plan-phase.md +5 -0
  25. package/commands/gsd/gsd-quick.md +5 -3
  26. package/commands/gsd/gsd-reapply-patches.md +171 -39
  27. package/commands/gsd/gsd-research-phase.md +2 -12
  28. package/commands/gsd/gsd-review-backlog.md +1 -0
  29. package/commands/gsd/gsd-review.md +3 -2
  30. package/commands/gsd/gsd-secure-phase.md +35 -0
  31. package/commands/gsd/gsd-set-profile.md +0 -1
  32. package/commands/gsd/gsd-thread.md +1 -1
  33. package/commands/gsd/gsd-workstreams.md +7 -2
  34. package/get-shit-done/bin/gsd-tools.cjs +42 -8
  35. package/get-shit-done/bin/lib/commands.cjs +68 -14
  36. package/get-shit-done/bin/lib/config.cjs +18 -10
  37. package/get-shit-done/bin/lib/core.cjs +383 -80
  38. package/get-shit-done/bin/lib/docs.cjs +267 -0
  39. package/get-shit-done/bin/lib/frontmatter.cjs +47 -2
  40. package/get-shit-done/bin/lib/init.cjs +85 -5
  41. package/get-shit-done/bin/lib/milestone.cjs +21 -0
  42. package/get-shit-done/bin/lib/model-profiles.cjs +2 -0
  43. package/get-shit-done/bin/lib/phase.cjs +232 -189
  44. package/get-shit-done/bin/lib/profile-output.cjs +97 -1
  45. package/get-shit-done/bin/lib/roadmap.cjs +137 -113
  46. package/get-shit-done/bin/lib/schema-detect.cjs +238 -0
  47. package/get-shit-done/bin/lib/security.cjs +5 -3
  48. package/get-shit-done/bin/lib/state.cjs +366 -44
  49. package/get-shit-done/bin/lib/verify.cjs +158 -14
  50. package/get-shit-done/bin/lib/workstream.cjs +6 -2
  51. package/get-shit-done/references/agent-contracts.md +79 -0
  52. package/get-shit-done/references/artifact-types.md +113 -0
  53. package/get-shit-done/references/context-budget.md +49 -0
  54. package/get-shit-done/references/continuation-format.md +15 -15
  55. package/get-shit-done/references/domain-probes.md +125 -0
  56. package/get-shit-done/references/gate-prompts.md +100 -0
  57. package/get-shit-done/references/model-profiles.md +2 -2
  58. package/get-shit-done/references/planner-gap-closure.md +62 -0
  59. package/get-shit-done/references/planner-reviews.md +39 -0
  60. package/get-shit-done/references/planner-revision.md +87 -0
  61. package/get-shit-done/references/planning-config.md +15 -0
  62. package/get-shit-done/references/revision-loop.md +97 -0
  63. package/get-shit-done/references/ui-brand.md +2 -2
  64. package/get-shit-done/references/universal-anti-patterns.md +58 -0
  65. package/get-shit-done/references/workstream-flag.md +56 -3
  66. package/get-shit-done/templates/SECURITY.md +61 -0
  67. package/get-shit-done/templates/VALIDATION.md +3 -3
  68. package/get-shit-done/templates/claude-md.md +27 -4
  69. package/get-shit-done/templates/config.json +4 -0
  70. package/get-shit-done/templates/debug-subagent-prompt.md +2 -6
  71. package/get-shit-done/templates/planner-subagent-prompt.md +2 -10
  72. package/get-shit-done/workflows/add-phase.md +2 -2
  73. package/get-shit-done/workflows/add-todo.md +1 -1
  74. package/get-shit-done/workflows/analyze-dependencies.md +96 -0
  75. package/get-shit-done/workflows/audit-milestone.md +8 -12
  76. package/get-shit-done/workflows/autonomous.md +158 -13
  77. package/get-shit-done/workflows/check-todos.md +2 -2
  78. package/get-shit-done/workflows/complete-milestone.md +13 -4
  79. package/get-shit-done/workflows/diagnose-issues.md +8 -6
  80. package/get-shit-done/workflows/discovery-phase.md +1 -1
  81. package/get-shit-done/workflows/discuss-phase-assumptions.md +24 -6
  82. package/get-shit-done/workflows/discuss-phase-power.md +291 -0
  83. package/get-shit-done/workflows/discuss-phase.md +153 -20
  84. package/get-shit-done/workflows/docs-update.md +1093 -0
  85. package/get-shit-done/workflows/execute-phase.md +362 -66
  86. package/get-shit-done/workflows/execute-plan.md +1 -1
  87. package/get-shit-done/workflows/help.md +9 -6
  88. package/get-shit-done/workflows/insert-phase.md +2 -2
  89. package/get-shit-done/workflows/manager.md +27 -26
  90. package/get-shit-done/workflows/map-codebase.md +10 -32
  91. package/get-shit-done/workflows/new-milestone.md +14 -8
  92. package/get-shit-done/workflows/new-project.md +48 -25
  93. package/get-shit-done/workflows/next.md +1 -1
  94. package/get-shit-done/workflows/note.md +1 -1
  95. package/get-shit-done/workflows/pause-work.md +73 -10
  96. package/get-shit-done/workflows/plan-milestone-gaps.md +2 -2
  97. package/get-shit-done/workflows/plan-phase.md +184 -32
  98. package/get-shit-done/workflows/progress.md +20 -20
  99. package/get-shit-done/workflows/quick.md +102 -84
  100. package/get-shit-done/workflows/research-phase.md +2 -6
  101. package/get-shit-done/workflows/resume-project.md +4 -4
  102. package/get-shit-done/workflows/review.md +56 -3
  103. package/get-shit-done/workflows/secure-phase.md +154 -0
  104. package/get-shit-done/workflows/settings.md +13 -2
  105. package/get-shit-done/workflows/ship.md +13 -4
  106. package/get-shit-done/workflows/transition.md +6 -6
  107. package/get-shit-done/workflows/ui-phase.md +4 -14
  108. package/get-shit-done/workflows/ui-review.md +25 -7
  109. package/get-shit-done/workflows/update.md +165 -16
  110. package/get-shit-done/workflows/validate-phase.md +1 -11
  111. package/get-shit-done/workflows/verify-phase.md +127 -6
  112. package/get-shit-done/workflows/verify-work.md +69 -21
  113. package/package.json +1 -1
@@ -8,6 +8,33 @@ const { safeReadFile, loadConfig, isGitIgnored, execGit, normalizePhaseName, com
8
8
  const { extractFrontmatter } = require('./frontmatter.cjs');
9
9
  const { MODEL_PROFILES } = require('./model-profiles.cjs');
10
10
 
11
+ /**
12
+ * Determine phase status by checking plan/summary counts AND verification state.
13
+ * Introduces "Executed" for phases with all summaries but no passing verification.
14
+ */
15
+ function determinePhaseStatus(plans, summaries, phaseDir, defaultPending) {
16
+ if (plans === 0) return defaultPending;
17
+ if (summaries < plans && summaries > 0) return 'In Progress';
18
+ if (summaries < plans) return 'Planned';
19
+
20
+ // summaries >= plans — check verification
21
+ try {
22
+ const files = fs.readdirSync(phaseDir);
23
+ const verificationFile = files.find(f => f === 'VERIFICATION.md' || f.endsWith('-VERIFICATION.md'));
24
+ if (verificationFile) {
25
+ const content = fs.readFileSync(path.join(phaseDir, verificationFile), 'utf-8');
26
+ if (/status:\s*passed/i.test(content)) return 'Complete';
27
+ if (/status:\s*human_needed/i.test(content)) return 'Needs Review';
28
+ if (/status:\s*gaps_found/i.test(content)) return 'Executed';
29
+ // Verification exists but unrecognized status — treat as executed
30
+ return 'Executed';
31
+ }
32
+ } catch { /* directory read failed — fall through */ }
33
+
34
+ // No verification file — executed but not verified
35
+ return 'Executed';
36
+ }
37
+
11
38
  function cmdGenerateSlug(text, raw) {
12
39
  if (!text) {
13
40
  error('text required for slug generation');
@@ -16,7 +43,8 @@ function cmdGenerateSlug(text, raw) {
16
43
  const slug = text
17
44
  .toLowerCase()
18
45
  .replace(/[^a-z0-9]+/g, '-')
19
- .replace(/^-+|-+$/g, '');
46
+ .replace(/^-+|-+$/g, '')
47
+ .substring(0, 60);
20
48
 
21
49
  const result = { slug };
22
50
  output(result, raw, slug);
@@ -254,7 +282,7 @@ function cmdCommit(cwd, message, files, raw, amend, noVerify) {
254
282
  let branchName = null;
255
283
  if (config.branching_strategy === 'phase') {
256
284
  // Determine which phase we're committing for from the file paths
257
- const phaseMatch = (files || []).join(' ').match(/(\d+)-/);
285
+ const phaseMatch = (files || []).join(' ').match(/(\d+(?:\.\d+)*)-/);
258
286
  if (phaseMatch) {
259
287
  const phaseNum = phaseMatch[1];
260
288
  const phaseInfo = findPhaseInternal(cwd, phaseNum);
@@ -528,11 +556,7 @@ function cmdProgressRender(cwd, format, raw) {
528
556
  totalPlans += plans;
529
557
  totalSummaries += summaries;
530
558
 
531
- let status;
532
- if (plans === 0) status = 'Pending';
533
- else if (summaries >= plans) status = 'Complete';
534
- else if (summaries > 0) status = 'In Progress';
535
- else status = 'Planned';
559
+ const status = determinePhaseStatus(plans, summaries, path.join(phasesDir, dir), 'Pending');
536
560
 
537
561
  phases.push({ number: phaseNum, name: phaseName, plans, summaries, status });
538
562
  }
@@ -828,18 +852,14 @@ function cmdStats(cwd, format, raw) {
828
852
  totalPlans += plans;
829
853
  totalSummaries += summaries;
830
854
 
831
- let status;
832
- if (plans === 0) status = 'Not Started';
833
- else if (summaries >= plans) status = 'Complete';
834
- else if (summaries > 0) status = 'In Progress';
835
- else status = 'Planned';
855
+ const status = determinePhaseStatus(plans, summaries, path.join(phasesDir, dir), 'Not Started');
836
856
 
837
857
  const existing = phasesByNumber.get(phaseNum);
838
858
  phasesByNumber.set(phaseNum, {
839
859
  number: phaseNum,
840
860
  name: existing?.name || phaseName,
841
- plans,
842
- summaries,
861
+ plans: (existing?.plans || 0) + plans,
862
+ summaries: (existing?.summaries || 0) + summaries,
843
863
  status,
844
864
  });
845
865
  }
@@ -940,6 +960,39 @@ function cmdStats(cwd, format, raw) {
940
960
  }
941
961
  }
942
962
 
963
+ /**
964
+ * Check whether a commit should be allowed based on commit_docs config.
965
+ * When commit_docs is false, rejects commits that stage .planning/ files.
966
+ * Intended for use as a pre-commit hook guard.
967
+ */
968
+ function cmdCheckCommit(cwd, raw) {
969
+ const config = loadConfig(cwd);
970
+
971
+ // If commit_docs is true (or not set), allow all commits
972
+ if (config.commit_docs !== false) {
973
+ output({ allowed: true, reason: 'commit_docs_enabled' }, raw, 'allowed');
974
+ return;
975
+ }
976
+
977
+ // commit_docs is false — check if any .planning/ files are staged
978
+ try {
979
+ const staged = execSync('git diff --cached --name-only', { cwd, encoding: 'utf-8' }).trim();
980
+ const planningFiles = staged.split('\n').filter(f => f.startsWith('.planning/') || f.startsWith('.planning\\'));
981
+
982
+ if (planningFiles.length > 0) {
983
+ error(
984
+ `commit_docs is false but ${planningFiles.length} .planning/ file(s) are staged:\n` +
985
+ planningFiles.map(f => ` ${f}`).join('\n') +
986
+ `\n\nTo unstage: git reset HEAD ${planningFiles.join(' ')}`
987
+ );
988
+ }
989
+ } catch {
990
+ // git diff --cached failed (no staged files or not a git repo) — allow
991
+ }
992
+
993
+ output({ allowed: true, reason: 'no_planning_files_staged' }, raw, 'allowed');
994
+ }
995
+
943
996
  module.exports = {
944
997
  cmdGenerateSlug,
945
998
  cmdCurrentTimestamp,
@@ -956,4 +1009,5 @@ module.exports = {
956
1009
  cmdTodoMatchPhase,
957
1010
  cmdScaffold,
958
1011
  cmdStats,
1012
+ cmdCheckCommit,
959
1013
  };
@@ -4,7 +4,7 @@
4
4
 
5
5
  const fs = require('fs');
6
6
  const path = require('path');
7
- const { output, error, planningRoot } = require('./core.cjs');
7
+ const { output, error, planningRoot, CONFIG_DEFAULTS } = require('./core.cjs');
8
8
  const {
9
9
  VALID_PROFILES,
10
10
  getAgentToModelMapForProfile,
@@ -22,9 +22,14 @@ const VALID_CONFIG_KEYS = new Set([
22
22
  'workflow.discuss_mode',
23
23
  'workflow.skip_discuss',
24
24
  'workflow._auto_chain_active',
25
- 'git.branching_strategy', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
25
+ 'workflow.use_worktrees',
26
+ 'git.branching_strategy', 'git.base_branch', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
26
27
  'planning.commit_docs', 'planning.search_gitignored',
28
+ 'workflow.subagent_timeout',
27
29
  'hooks.context_warnings',
30
+ 'project_code', 'phase_naming',
31
+ 'manager.flags.discuss', 'manager.flags.plan', 'manager.flags.execute',
32
+ 'response_language',
28
33
  ]);
29
34
 
30
35
  /**
@@ -101,18 +106,18 @@ function buildNewProjectConfig(userChoices) {
101
106
  }
102
107
 
103
108
  const hardcoded = {
104
- model_profile: 'balanced',
105
- commit_docs: true,
106
- parallelization: true,
107
- search_gitignored: false,
109
+ model_profile: CONFIG_DEFAULTS.model_profile,
110
+ commit_docs: CONFIG_DEFAULTS.commit_docs,
111
+ parallelization: CONFIG_DEFAULTS.parallelization,
112
+ search_gitignored: CONFIG_DEFAULTS.search_gitignored,
108
113
  brave_search: hasBraveSearch,
109
114
  firecrawl: hasFirecrawl,
110
115
  exa_search: hasExaSearch,
111
116
  git: {
112
- branching_strategy: 'none',
113
- phase_branch_template: 'gsd/phase-{phase}-{slug}',
114
- milestone_branch_template: 'gsd/{milestone}-{slug}',
115
- quick_branch_template: null,
117
+ branching_strategy: CONFIG_DEFAULTS.branching_strategy,
118
+ phase_branch_template: CONFIG_DEFAULTS.phase_branch_template,
119
+ milestone_branch_template: CONFIG_DEFAULTS.milestone_branch_template,
120
+ quick_branch_template: CONFIG_DEFAULTS.quick_branch_template,
116
121
  },
117
122
  workflow: {
118
123
  research: true,
@@ -132,6 +137,8 @@ function buildNewProjectConfig(userChoices) {
132
137
  hooks: {
133
138
  context_warnings: true,
134
139
  },
140
+ project_code: null,
141
+ phase_naming: 'sequential',
135
142
  agent_skills: {},
136
143
  };
137
144
 
@@ -434,6 +441,7 @@ function getCmdConfigSetModelProfileResultMessage(
434
441
  }
435
442
 
436
443
  module.exports = {
444
+ VALID_CONFIG_KEYS,
437
445
  cmdConfigEnsureSection,
438
446
  cmdConfigSet,
439
447
  cmdConfigGet,