gsd-antigravity-kit 1.30.1 → 1.32.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 (164) hide show
  1. package/.agent/skills/gsd/SKILL.md +152 -123
  2. package/.agent/skills/gsd/VERSION +1 -0
  3. package/.agent/skills/gsd/assets/templates/user-profile.md +8 -8
  4. package/.agent/skills/gsd/bin/gsd-tools.cjs +81 -3
  5. package/.agent/skills/gsd/bin/help-manifest.json +24 -1
  6. package/.agent/skills/gsd/bin/hooks/gsd-check-update.js +15 -5
  7. package/.agent/skills/gsd/bin/hooks/gsd-context-monitor.js +1 -1
  8. package/.agent/skills/gsd/bin/hooks/gsd-phase-boundary.sh +27 -0
  9. package/.agent/skills/gsd/bin/hooks/gsd-prompt-guard.js +2 -1
  10. package/.agent/skills/gsd/bin/hooks/gsd-read-guard.js +1 -1
  11. package/.agent/skills/gsd/bin/hooks/gsd-session-state.sh +33 -0
  12. package/.agent/skills/gsd/bin/hooks/gsd-statusline.js +5 -5
  13. package/.agent/skills/gsd/bin/hooks/gsd-validate-commit.sh +47 -0
  14. package/.agent/skills/gsd/bin/hooks/gsd-workflow-guard.js +1 -1
  15. package/.agent/skills/gsd/bin/lib/config.cjs +31 -10
  16. package/.agent/skills/gsd/bin/lib/core.cjs +48 -13
  17. package/.agent/skills/gsd/bin/lib/frontmatter.cjs +34 -2
  18. package/.agent/skills/gsd/bin/lib/intel.cjs +660 -0
  19. package/.agent/skills/gsd/bin/lib/learnings.cjs +378 -0
  20. package/.agent/skills/gsd/bin/lib/milestone.cjs +13 -4
  21. package/.agent/skills/gsd/bin/lib/model-profiles.cjs +17 -17
  22. package/.agent/skills/gsd/bin/lib/profile-output.cjs +31 -31
  23. package/.agent/skills/gsd/bin/lib/security.cjs +119 -0
  24. package/.agent/skills/gsd/bin/lib/verify.cjs +15 -15
  25. package/.agent/skills/gsd/migration_report.md +7 -0
  26. package/.agent/skills/gsd/references/agents/gsd-code-fixer.md +516 -0
  27. package/.agent/skills/gsd/references/agents/gsd-code-reviewer.md +355 -0
  28. package/.agent/skills/gsd/references/agents/gsd-debugger.md +10 -1
  29. package/.agent/skills/gsd/references/agents/gsd-executor.md +3 -0
  30. package/.agent/skills/gsd/references/agents/gsd-intel-updater.md +314 -0
  31. package/.agent/skills/gsd/references/agents/gsd-phase-researcher.md +3 -0
  32. package/.agent/skills/gsd/references/agents/gsd-plan-checker.md +16 -4
  33. package/.agent/skills/gsd/references/agents/gsd-planner.md +7 -0
  34. package/.agent/skills/gsd/references/agents/gsd-user-profiler.md +5 -5
  35. package/.agent/skills/gsd/references/agents/gsd-verifier.md +55 -1
  36. package/.agent/skills/gsd/references/agents/profiles/dev.md +21 -0
  37. package/.agent/skills/gsd/references/agents/profiles/research.md +22 -0
  38. package/.agent/skills/gsd/references/agents/profiles/review.md +22 -0
  39. package/.agent/skills/gsd/references/commands/{gsd-add-todo.md → atomic/add-todo.md} +5 -4
  40. package/.agent/skills/gsd/references/commands/{gsd-check-todos.md → atomic/check-todos.md} +5 -4
  41. package/.agent/skills/gsd/references/commands/{gsd-cleanup.md → atomic/cleanup.md} +4 -3
  42. package/.agent/skills/gsd/references/commands/{gsd-do.md → atomic/do.md} +4 -3
  43. package/.agent/skills/gsd/references/commands/{gsd-help.md → atomic/help.md} +4 -3
  44. package/.agent/skills/gsd/references/commands/{gsd-join-discord.md → atomic/join-discord.md} +21 -19
  45. package/.agent/skills/gsd/references/commands/{gsd-note.md → atomic/note.md} +4 -3
  46. package/.agent/skills/gsd/references/commands/{gsd-session-report.md → atomic/session-report.md} +4 -3
  47. package/.agent/skills/gsd/references/commands/{gsd-ship.md → atomic/ship.md} +4 -3
  48. package/.agent/skills/gsd/references/commands/{gsd-stats.md → atomic/stats.md} +4 -3
  49. package/.agent/skills/gsd/references/commands/{gsd-thread.md → atomic/thread.md} +7 -6
  50. package/.agent/skills/gsd/references/commands/atomic/undo.md +36 -0
  51. package/.agent/skills/gsd/references/commands/{gsd-add-backlog.md → milestone/add-backlog.md} +8 -7
  52. package/.agent/skills/gsd/references/commands/{gsd-audit-milestone.md → milestone/audit-milestone.md} +4 -3
  53. package/.agent/skills/gsd/references/commands/{gsd-complete-milestone.md → milestone/complete-milestone.md} +6 -4
  54. package/.agent/skills/gsd/references/commands/{gsd-milestone-summary.md → milestone/milestone-summary.md} +5 -3
  55. package/.agent/skills/gsd/references/commands/{gsd-new-milestone.md → milestone/new-milestone.md} +4 -3
  56. package/.agent/skills/gsd/references/commands/{gsd-plan-milestone-gaps.md → milestone/plan-milestone-gaps.md} +4 -3
  57. package/.agent/skills/gsd/references/commands/{gsd-plant-seed.md → milestone/plant-seed.md} +4 -3
  58. package/.agent/skills/gsd/references/commands/{gsd-review-backlog.md → milestone/review-backlog.md} +6 -5
  59. package/.agent/skills/gsd/references/commands/misc/audit-fix.md +35 -0
  60. package/.agent/skills/gsd/references/commands/{gsd-audit-uat.md → misc/audit-uat.md} +4 -3
  61. package/.agent/skills/gsd/references/commands/{gsd-next.md → misc/next.md} +6 -3
  62. package/.agent/skills/gsd/references/commands/{gsd-progress.md → misc/progress.md} +4 -3
  63. package/.agent/skills/gsd/references/commands/{gsd-verify-work.md → misc/verify-work.md} +4 -3
  64. package/.agent/skills/gsd/references/commands/{gsd-add-phase.md → phase/add-phase.md} +5 -4
  65. package/.agent/skills/gsd/references/commands/{gsd-add-tests.md → phase/add-tests.md} +8 -3
  66. package/.agent/skills/gsd/references/commands/{gsd-discuss-phase.md → phase/discuss-phase.md} +5 -4
  67. package/.agent/skills/gsd/references/commands/{gsd-execute-phase.md → phase/execute-phase.md} +4 -3
  68. package/.agent/skills/gsd/references/commands/{gsd-insert-phase.md → phase/insert-phase.md} +5 -4
  69. package/.agent/skills/gsd/references/commands/{gsd-list-phase-assumptions.md → phase/list-phase-assumptions.md} +4 -3
  70. package/.agent/skills/gsd/references/commands/{gsd-plan-phase.md → phase/plan-phase.md} +4 -3
  71. package/.agent/skills/gsd/references/commands/{gsd-remove-phase.md → phase/remove-phase.md} +5 -4
  72. package/.agent/skills/gsd/references/commands/{gsd-research-phase.md → phase/research-phase.md} +7 -6
  73. package/.agent/skills/gsd/references/commands/{gsd-secure-phase.md → phase/secure-phase.md} +4 -3
  74. package/.agent/skills/gsd/references/commands/{gsd-ui-phase.md → phase/ui-phase.md} +4 -3
  75. package/.agent/skills/gsd/references/commands/{gsd-ui-review.md → phase/ui-review.md} +4 -3
  76. package/.agent/skills/gsd/references/commands/{gsd-validate-phase.md → phase/validate-phase.md} +4 -3
  77. package/.agent/skills/gsd/references/commands/{gsd-workstreams.md → phase/workstreams.md} +71 -70
  78. package/.agent/skills/gsd/references/commands/{gsd-analyze-dependencies.md → project/analyze-dependencies.md} +5 -4
  79. package/.agent/skills/gsd/references/commands/project/explore.md +29 -0
  80. package/.agent/skills/gsd/references/commands/project/import.md +38 -0
  81. package/.agent/skills/gsd/references/commands/project/intel.md +181 -0
  82. package/.agent/skills/gsd/references/commands/{gsd-list-workspaces.md → project/list-workspaces.md} +4 -3
  83. package/.agent/skills/gsd/references/commands/{gsd-map-codebase.md → project/map-codebase.md} +4 -3
  84. package/.agent/skills/gsd/references/commands/{gsd-new-project.md → project/new-project.md} +4 -3
  85. package/.agent/skills/gsd/references/commands/{gsd-new-workspace.md → project/new-workspace.md} +4 -3
  86. package/.agent/skills/gsd/references/commands/{gsd-remove-workspace.md → project/remove-workspace.md} +4 -3
  87. package/.agent/skills/gsd/references/commands/project/scan.md +28 -0
  88. package/.agent/skills/gsd/references/commands/{gsd-autonomous.md → system/autonomous.md} +4 -3
  89. package/.agent/skills/gsd/references/commands/system/code-review-fix.md +54 -0
  90. package/.agent/skills/gsd/references/commands/system/code-review.md +57 -0
  91. package/.agent/skills/gsd/references/commands/{gsd-debug.md → system/debug.md} +7 -6
  92. package/.agent/skills/gsd/references/commands/{gsd-docs-update.md → system/docs-update.md} +4 -3
  93. package/.agent/skills/gsd/references/commands/{gsd-fast.md → system/fast.md} +4 -3
  94. package/.agent/skills/gsd/references/commands/{gsd-forensics.md → system/forensics.md} +5 -3
  95. package/.agent/skills/gsd/references/commands/{gsd-health.md → system/health.md} +5 -4
  96. package/.agent/skills/gsd/references/commands/{gsd-manager.md → system/manager.md} +4 -3
  97. package/.agent/skills/gsd/references/commands/{gsd-pause-work.md → system/pause-work.md} +4 -3
  98. package/.agent/skills/gsd/references/commands/{gsd-pr-branch.md → system/pr-branch.md} +4 -3
  99. package/.agent/skills/gsd/references/commands/{gsd-profile-user.md → system/profile-user.md} +4 -3
  100. package/.agent/skills/gsd/references/commands/{gsd-quick.md → system/quick.md} +4 -3
  101. package/.agent/skills/gsd/references/commands/{gsd-reapply-patches.md → system/reapply-patches.md} +25 -7
  102. package/.agent/skills/gsd/references/commands/{gsd-resume-work.md → system/resume-work.md} +4 -3
  103. package/.agent/skills/gsd/references/commands/{gsd-review.md → system/review.md} +4 -3
  104. package/.agent/skills/gsd/references/commands/system/set-profile.md +14 -0
  105. package/.agent/skills/gsd/references/commands/{gsd-settings.md → system/settings.md} +4 -3
  106. package/.agent/skills/gsd/references/commands/{gsd-update.md → system/update.md} +4 -3
  107. package/.agent/skills/gsd/references/docs/agent-contracts.md +79 -0
  108. package/.agent/skills/gsd/references/docs/common-bug-patterns.md +114 -0
  109. package/.agent/skills/gsd/references/docs/context-budget.md +49 -0
  110. package/.agent/skills/gsd/references/docs/domain-probes.md +125 -0
  111. package/.agent/skills/gsd/references/docs/few-shot-examples/plan-checker.md +73 -0
  112. package/.agent/skills/gsd/references/docs/few-shot-examples/verifier.md +109 -0
  113. package/.agent/skills/gsd/references/docs/gate-prompts.md +100 -0
  114. package/.agent/skills/gsd/references/docs/gates.md +70 -0
  115. package/.agent/skills/gsd/references/docs/model-profile-resolution.md +2 -0
  116. package/.agent/skills/gsd/references/docs/model-profiles.md +20 -14
  117. package/.agent/skills/gsd/references/docs/planning-config.md +216 -1
  118. package/.agent/skills/gsd/references/docs/revision-loop.md +97 -0
  119. package/.agent/skills/gsd/references/docs/thinking-models-debug.md +44 -0
  120. package/.agent/skills/gsd/references/docs/thinking-models-execution.md +50 -0
  121. package/.agent/skills/gsd/references/docs/thinking-models-planning.md +62 -0
  122. package/.agent/skills/gsd/references/docs/thinking-models-research.md +50 -0
  123. package/.agent/skills/gsd/references/docs/thinking-models-verification.md +55 -0
  124. package/.agent/skills/gsd/references/docs/thinking-partner.md +96 -0
  125. package/.agent/skills/gsd/references/docs/universal-anti-patterns.md +58 -0
  126. package/.agent/skills/gsd/references/docs/user-profiling.md +10 -10
  127. package/.agent/skills/gsd/references/docs/verification-overrides.md +227 -0
  128. package/.agent/skills/gsd/references/docs/workstream-flag.md +2 -2
  129. package/.agent/skills/gsd/references/mapping.md +11 -21
  130. package/.agent/skills/gsd/references/workflows/analyze-dependencies.md +3 -3
  131. package/.agent/skills/gsd/references/workflows/audit-fix.md +157 -0
  132. package/.agent/skills/gsd/references/workflows/autonomous.md +22 -1
  133. package/.agent/skills/gsd/references/workflows/code-review-fix.md +497 -0
  134. package/.agent/skills/gsd/references/workflows/code-review.md +515 -0
  135. package/.agent/skills/gsd/references/workflows/discuss-phase-power.md +3 -3
  136. package/.agent/skills/gsd/references/workflows/discuss-phase.md +20 -0
  137. package/.agent/skills/gsd/references/workflows/execute-phase.md +103 -0
  138. package/.agent/skills/gsd/references/workflows/explore.md +139 -0
  139. package/.agent/skills/gsd/references/workflows/import.md +274 -0
  140. package/.agent/skills/gsd/references/workflows/inbox.md +384 -0
  141. package/.agent/skills/gsd/references/workflows/manager.md +5 -5
  142. package/.agent/skills/gsd/references/workflows/new-milestone.md +1 -1
  143. package/.agent/skills/gsd/references/workflows/next.md +56 -0
  144. package/.agent/skills/gsd/references/workflows/plan-phase.md +48 -1
  145. package/.agent/skills/gsd/references/workflows/quick.md +96 -2
  146. package/.agent/skills/gsd/references/workflows/review.md +23 -3
  147. package/.agent/skills/gsd/references/workflows/scan.md +102 -0
  148. package/.agent/skills/gsd/references/workflows/settings.md +1 -1
  149. package/.agent/skills/gsd/references/workflows/ui-review.md +2 -2
  150. package/.agent/skills/gsd/references/workflows/undo.md +312 -0
  151. package/.agent/skills/gsd/references/workflows/update.md +5 -5
  152. package/.agent/skills/gsd-converter/SKILL.md +67 -59
  153. package/.agent/skills/gsd-converter/assets/migration-manifest.json +74 -0
  154. package/.agent/skills/gsd-converter/references/mapping.md +6 -16
  155. package/.agent/skills/gsd-converter/scripts/convert.py +419 -80
  156. package/.agent/skills/gsd-converter/scripts/regression_test.py +33 -0
  157. package/.agent/skills/release-manager/scripts/release.ps1 +152 -110
  158. package/.agent/skills/selectpaste-update/SKILL.md +46 -0
  159. package/.agent/skills/selectpaste-update/scripts/sync-commands.py +317 -0
  160. package/README.md +5 -2
  161. package/package.json +1 -1
  162. package/.agent/skills/gsd/references/commands/gsd-set-profile.md +0 -12
  163. package/bin/install.js +0 -116
  164. /package/.agent/skills/gsd/references/commands/{gsd-tools.md → system/gsd-tools.md} +0 -0
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+ # gsd-phase-boundary.sh — PostToolUse hook: detect .planning/ file writes
3
+ # Outputs a reminder when planning files are modified outside normal workflow.
4
+ # Uses Node.js for JSON parsing (always available in GSD projects, no jq dependency).
5
+ #
6
+ # OPT-IN: This hook is a no-op unless config.json has hooks.community: true.
7
+ # Enable with: "hooks": { "community": true } in .planning/config.json
8
+
9
+ # Check opt-in config — exit silently if not enabled
10
+ if [ -f .planning/config.json ]; then
11
+ ENABLED=$(node -e "try{const c=require('./.planning/config.json');process.stdout.write(c.hooks?.community===true?'1':'0')}catch{process.stdout.write('0')}" 2>/dev/null)
12
+ if [ "$ENABLED" != "1" ]; then exit 0; fi
13
+ else
14
+ exit 0
15
+ fi
16
+
17
+ INPUT=$(cat)
18
+
19
+ # Extract file_path from JSON using Node (handles escaping correctly)
20
+ FILE=$(echo "$INPUT" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{process.stdout.write(JSON.parse(d).tool_input?.file_path||'')}catch{}})" 2>/dev/null)
21
+
22
+ if [[ "$FILE" == *.planning/* ]] || [[ "$FILE" == .planning/* ]]; then
23
+ echo ".planning/ file modified: $FILE"
24
+ echo "Check: Should STATE.md be updated to reflect this change?"
25
+ fi
26
+
27
+ exit 0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // gsd-hook-version: 1.32.0
2
+ // gsd-hook-version: 1.34.2
3
3
  // GSD Prompt Injection Guard — PreToolUse hook
4
4
  // Scans file content being written to .planning/ for prompt injection patterns.
5
5
  // Defense-in-depth: catches injected instructions before they enter agent context.
@@ -22,6 +22,7 @@ const INJECTION_PATTERNS = [
22
22
  /forget\s+(all\s+)?(your\s+)?instructions/i,
23
23
  /override\s+(system|previous)\s+(prompt|instructions)/i,
24
24
  /you\s+are\s+now\s+(?:a|an|the)\s+/i,
25
+ /act\s+as\s+(?:a|an|the)\s+(?!plan|phase|wave)/i,
25
26
  /pretend\s+(?:you(?:'re| are)\s+|to\s+be\s+)/i,
26
27
  /from\s+now\s+on,?\s+you\s+(?:are|will|should|must)/i,
27
28
  /(?:print|output|reveal|show|display|repeat)\s+(?:your\s+)?(?:system\s+)?(?:prompt|instructions)/i,
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // gsd-hook-version: 1.32.0
2
+ // gsd-hook-version: 1.34.2
3
3
  // GSD Read Guard — PreToolUse hook
4
4
  // Injects advisory guidance when Write/Edit targets an existing file,
5
5
  // reminding the model to Read the file first.
@@ -0,0 +1,33 @@
1
+ #!/bin/bash
2
+ # gsd-session-state.sh — SessionStart hook: inject project state reminder
3
+ # Outputs STATE.md head on every session start for orientation.
4
+ #
5
+ # OPT-IN: This hook is a no-op unless config.json has hooks.community: true.
6
+ # Enable with: "hooks": { "community": true } in .planning/config.json
7
+
8
+ # Check opt-in config — exit silently if not enabled
9
+ if [ -f .planning/config.json ]; then
10
+ ENABLED=$(node -e "try{const c=require('./.planning/config.json');process.stdout.write(c.hooks?.community===true?'1':'0')}catch{process.stdout.write('0')}" 2>/dev/null)
11
+ if [ "$ENABLED" != "1" ]; then exit 0; fi
12
+ else
13
+ exit 0
14
+ fi
15
+
16
+ echo '## Project State Reminder'
17
+ echo ''
18
+
19
+ if [ -f .planning/STATE.md ]; then
20
+ echo 'STATE.md exists - check for blockers and current phase.'
21
+ head -20 .planning/STATE.md
22
+ else
23
+ echo 'No .planning/ found - suggest /gsd-new-project if starting new work.'
24
+ fi
25
+
26
+ echo ''
27
+
28
+ if [ -f .planning/config.json ]; then
29
+ MODE=$(grep -o '"mode"[[:space:]]*:[[:space:]]*"[^"]*"' .planning/config.json 2>/dev/null || echo '"mode": "unknown"')
30
+ echo "Config: $MODE"
31
+ fi
32
+
33
+ exit 0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // gsd-hook-version: 1.32.0
2
+ // gsd-hook-version: 1.34.2
3
3
  // Antigravity Statusline - GSD Edition
4
4
  // Shows: model | current task | directory | context usage
5
5
 
@@ -72,9 +72,9 @@ process.stdin.on('end', () => {
72
72
  // Current task from todos
73
73
  let task = '';
74
74
  const homeDir = os.homedir();
75
- // Respect CLAUDE_CONFIG_DIR for custom config directory setups (#870)
76
- const claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(homeDir, '.antigravity');
77
- const todosDir = path.join(claudeDir, 'todos');
75
+ // Respect ANTIGRAVITY_CONFIG_DIR for custom config directory setups (#870)
76
+ const antigravityDir = process.env.ANTIGRAVITY_CONFIG_DIR || path.join(homeDir, '.antigravity');
77
+ const todosDir = path.join(antigravityDir, 'todos');
78
78
  if (session && fs.existsSync(todosDir)) {
79
79
  try {
80
80
  const files = fs.readdirSync(todosDir)
@@ -99,7 +99,7 @@ process.stdin.on('end', () => {
99
99
  // backward compatibility with older gsd-check-update.js versions.
100
100
  let gsdUpdate = '';
101
101
  const sharedCacheFile = path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json');
102
- const legacyCacheFile = path.join(claudeDir, 'cache', 'gsd-update-check.json');
102
+ const legacyCacheFile = path.join(antigravityDir, 'cache', 'gsd-update-check.json');
103
103
  const cacheFile = fs.existsSync(sharedCacheFile) ? sharedCacheFile : legacyCacheFile;
104
104
  if (fs.existsSync(cacheFile)) {
105
105
  try {
@@ -0,0 +1,47 @@
1
+ #!/bin/bash
2
+ # gsd-validate-commit.sh — PreToolUse hook: enforce Conventional Commits format
3
+ # Blocks git commit commands with non-conforming messages (exit 2).
4
+ # Allows conforming messages and all non-commit commands (exit 0).
5
+ # Uses Node.js for JSON parsing (always available in GSD projects, no jq dependency).
6
+ #
7
+ # OPT-IN: This hook is a no-op unless config.json has hooks.community: true.
8
+ # Enable with: "hooks": { "community": true } in .planning/config.json
9
+
10
+ # Check opt-in config — exit silently if not enabled
11
+ if [ -f .planning/config.json ]; then
12
+ ENABLED=$(node -e "try{const c=require('./.planning/config.json');process.stdout.write(c.hooks?.community===true?'1':'0')}catch{process.stdout.write('0')}" 2>/dev/null)
13
+ if [ "$ENABLED" != "1" ]; then exit 0; fi
14
+ else
15
+ exit 0
16
+ fi
17
+
18
+ INPUT=$(cat)
19
+
20
+ # Extract command from JSON using Node (handles escaping correctly, no jq needed)
21
+ CMD=$(echo "$INPUT" | node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{process.stdout.write(JSON.parse(d).tool_input?.command||'')}catch{}})" 2>/dev/null)
22
+
23
+ # Only check git commit commands
24
+ if [[ "$CMD" =~ ^git[[:space:]]+commit ]]; then
25
+ # Extract message from -m flag
26
+ MSG=""
27
+ if [[ "$CMD" =~ -m[[:space:]]+\"([^\"]+)\" ]]; then
28
+ MSG="${BASH_REMATCH[1]}"
29
+ elif [[ "$CMD" =~ -m[[:space:]]+\'([^\']+)\' ]]; then
30
+ MSG="${BASH_REMATCH[1]}"
31
+ fi
32
+
33
+ if [ -n "$MSG" ]; then
34
+ SUBJECT=$(echo "$MSG" | head -1)
35
+ # Validate Conventional Commits format
36
+ if ! [[ "$SUBJECT" =~ ^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\(.+\))?:[[:space:]].+ ]]; then
37
+ echo '{"decision": "block", "reason": "Commit message must follow Conventional Commits: <type>(<scope>): <subject>. Valid types: feat, fix, docs, style, refactor, perf, test, build, ci, chore. Subject must be <=72 chars, lowercase, imperative mood, no trailing period."}'
38
+ exit 2
39
+ fi
40
+ if [ ${#SUBJECT} -gt 72 ]; then
41
+ echo '{"decision": "block", "reason": "Commit subject must be 72 characters or less."}'
42
+ exit 2
43
+ fi
44
+ fi
45
+ fi
46
+
47
+ exit 0
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // gsd-hook-version: 1.32.0
2
+ // gsd-hook-version: 1.34.2
3
3
  // GSD Workflow Guard — PreToolUse hook
4
4
  // Detects when Antigravity attempts file edits outside a GSD workflow context
5
5
  // (no active /gsd- skill or Task subagent) and injects an advisory warning.
@@ -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,
@@ -23,10 +23,16 @@ const VALID_CONFIG_KEYS = new Set([
23
23
  'workflow.skip_discuss',
24
24
  'workflow._auto_chain_active',
25
25
  'workflow.use_worktrees',
26
+ 'workflow.code_review',
27
+ 'workflow.code_review_depth',
26
28
  'git.branching_strategy', 'git.base_branch', 'git.phase_branch_template', 'git.milestone_branch_template', 'git.quick_branch_template',
27
29
  'planning.commit_docs', 'planning.search_gitignored',
28
30
  'workflow.subagent_timeout',
29
31
  'hooks.context_warnings',
32
+ 'features.thinking_partner',
33
+ 'context',
34
+ 'features.global_learnings',
35
+ 'learnings.max_inject',
30
36
  'project_code', 'phase_naming',
31
37
  'manager.flags.discuss', 'manager.flags.plan', 'manager.flags.execute',
32
38
  'response_language',
@@ -41,6 +47,10 @@ function isValidConfigKey(keyPath) {
41
47
  if (VALID_CONFIG_KEYS.has(keyPath)) return true;
42
48
  // Allow agent_skills.<agent-type> with any agent type string
43
49
  if (/^agent_skills\.[a-zA-Z0-9_-]+$/.test(keyPath)) return true;
50
+ // Allow features.<feature_name> — dynamic namespace for feature flags.
51
+ // Intentionally open-ended so new flags (e.g., features.global_learnings) work
52
+ // without updating VALID_CONFIG_KEYS each time.
53
+ if (/^features\.[a-zA-Z0-9_]+$/.test(keyPath)) return true;
44
54
  return false;
45
55
  }
46
56
 
@@ -50,6 +60,10 @@ const CONFIG_KEY_SUGGESTIONS = {
50
60
  'nyquist.validation_enabled': 'workflow.nyquist_validation',
51
61
  'hooks.research_questions': 'workflow.research_before_questions',
52
62
  'workflow.research_questions': 'workflow.research_before_questions',
63
+ 'workflow.codereview': 'workflow.code_review',
64
+ 'workflow.review': 'workflow.code_review',
65
+ 'workflow.code_review_level': 'workflow.code_review_depth',
66
+ 'workflow.review_depth': 'workflow.code_review_depth',
53
67
  };
54
68
 
55
69
  function validateKnownConfigKeyPath(keyPath) {
@@ -106,18 +120,18 @@ function buildNewProjectConfig(userChoices) {
106
120
  }
107
121
 
108
122
  const hardcoded = {
109
- model_profile: 'balanced',
110
- commit_docs: true,
111
- parallelization: true,
112
- search_gitignored: false,
123
+ model_profile: CONFIG_DEFAULTS.model_profile,
124
+ commit_docs: CONFIG_DEFAULTS.commit_docs,
125
+ parallelization: CONFIG_DEFAULTS.parallelization,
126
+ search_gitignored: CONFIG_DEFAULTS.search_gitignored,
113
127
  brave_search: hasBraveSearch,
114
128
  firecrawl: hasFirecrawl,
115
129
  exa_search: hasExaSearch,
116
130
  git: {
117
- branching_strategy: 'none',
118
- phase_branch_template: 'gsd/phase-{phase}-{slug}',
119
- milestone_branch_template: 'gsd/{milestone}-{slug}',
120
- quick_branch_template: null,
131
+ branching_strategy: CONFIG_DEFAULTS.branching_strategy,
132
+ phase_branch_template: CONFIG_DEFAULTS.phase_branch_template,
133
+ milestone_branch_template: CONFIG_DEFAULTS.milestone_branch_template,
134
+ quick_branch_template: CONFIG_DEFAULTS.quick_branch_template,
121
135
  },
122
136
  workflow: {
123
137
  research: true,
@@ -133,6 +147,8 @@ function buildNewProjectConfig(userChoices) {
133
147
  research_before_questions: false,
134
148
  discuss_mode: 'discuss',
135
149
  skip_discuss: false,
150
+ code_review: true,
151
+ code_review_depth: 'standard',
136
152
  },
137
153
  hooks: {
138
154
  context_warnings: true,
@@ -324,7 +340,7 @@ function cmdConfigSet(cwd, keyPath, value, raw) {
324
340
  validateKnownConfigKeyPath(keyPath);
325
341
 
326
342
  if (!isValidConfigKey(keyPath)) {
327
- error(`Unknown config key: "${keyPath}". Valid keys: ${[...VALID_CONFIG_KEYS].sort().join(', ')}, agent_skills.<agent-type>`);
343
+ error(`Unknown config key: "${keyPath}". Valid keys: ${[...VALID_CONFIG_KEYS].sort().join(', ')}, agent_skills.<agent-type>, features.<feature_name>`);
328
344
  }
329
345
 
330
346
  // Parse value (handle booleans, numbers, and JSON arrays/objects)
@@ -336,6 +352,11 @@ function cmdConfigSet(cwd, keyPath, value, raw) {
336
352
  try { parsedValue = JSON.parse(value); } catch { /* keep as string */ }
337
353
  }
338
354
 
355
+ const VALID_CONTEXT_VALUES = ['dev', 'research', 'review'];
356
+ if (keyPath === 'context' && !VALID_CONTEXT_VALUES.includes(String(parsedValue))) {
357
+ error(`Invalid context value '${value}'. Valid values: ${VALID_CONTEXT_VALUES.join(', ')}`);
358
+ }
359
+
339
360
  const setConfigValueResult = setConfigValue(cwd, keyPath, parsedValue);
340
361
  output(setConfigValueResult, raw, `${keyPath}=${parsedValue}`);
341
362
  }
@@ -12,8 +12,8 @@ const { MODEL_PROFILES } = require('./model-profiles.cjs');
12
12
  const WORKSTREAM_SESSION_ENV_KEYS = [
13
13
  'GSD_SESSION_KEY',
14
14
  'CODEX_THREAD_ID',
15
- 'CLAUDE_SESSION_ID',
16
- 'CLAUDE_CODE_SSE_PORT',
15
+ 'ANTIGRAVITY_SESSION_ID',
16
+ 'ANTIGRAVITY_SSE_PORT',
17
17
  'OPENCODE_SESSION_ID',
18
18
  'GEMINI_SESSION_ID',
19
19
  'CURSOR_SESSION_ID',
@@ -269,9 +269,10 @@ function safeReadFile(filePath) {
269
269
  }
270
270
  }
271
271
 
272
- function loadConfig(cwd) {
273
- const configPath = path.join(planningDir(cwd), 'config.json');
274
- const defaults = {
272
+ /**
273
+ * Canonical config defaults. Single source of truth — imported by config.cjs and verify.cjs.
274
+ */
275
+ const CONFIG_DEFAULTS = {
275
276
  model_profile: 'balanced',
276
277
  commit_docs: true,
277
278
  search_gitignored: false,
@@ -294,7 +295,11 @@ function loadConfig(cwd) {
294
295
  phase_naming: 'sequential', // 'sequential' (default, auto-increment) or 'custom' (arbitrary string IDs)
295
296
  project_code: null, // optional short prefix for phase dirs (e.g., 'CK' → 'CK-01-foundation')
296
297
  subagent_timeout: 300000, // 5 min default; increase for large codebases or slower models (ms)
297
- };
298
+ };
299
+
300
+ function loadConfig(cwd) {
301
+ const configPath = path.join(planningDir(cwd), 'config.json');
302
+ const defaults = CONFIG_DEFAULTS;
298
303
 
299
304
  try {
300
305
  const raw = fs.readFileSync(configPath, 'utf-8');
@@ -350,7 +355,7 @@ function loadConfig(cwd) {
350
355
  // Extract top-level key names from dot-notation paths (e.g., 'workflow.research' → 'workflow')
351
356
  ...[...VALID_CONFIG_KEYS].map(k => k.split('.')[0]),
352
357
  // Section containers that hold nested sub-keys
353
- 'git', 'workflow', 'planning', 'hooks',
358
+ 'git', 'workflow', 'planning', 'hooks', 'features',
354
359
  // Internal keys loadConfig reads but config-set doesn't expose
355
360
  'model_overrides', 'agent_skills', 'context_window', 'resolve_model_ids',
356
361
  // Deprecated keys (still accepted for migration, not in config-set)
@@ -415,7 +420,36 @@ function loadConfig(cwd) {
415
420
  response_language: get('response_language') || null,
416
421
  };
417
422
  } catch {
418
- return defaults;
423
+ // Fall back to ~/.gsd/defaults.json only for truly pre-project contexts (#1683)
424
+ // If .planning/ exists, the project is initialized — just missing config.json
425
+ if (fs.existsSync(planningDir(cwd))) {
426
+ return defaults;
427
+ }
428
+ try {
429
+ const home = process.env.GSD_HOME || os.homedir();
430
+ const globalDefaultsPath = path.join(home, '.gsd', 'defaults.json');
431
+ const raw = fs.readFileSync(globalDefaultsPath, 'utf-8');
432
+ const globalDefaults = JSON.parse(raw);
433
+ return {
434
+ ...defaults,
435
+ model_profile: globalDefaults.model_profile ?? defaults.model_profile,
436
+ commit_docs: globalDefaults.commit_docs ?? defaults.commit_docs,
437
+ research: globalDefaults.research ?? defaults.research,
438
+ plan_checker: globalDefaults.plan_checker ?? defaults.plan_checker,
439
+ verifier: globalDefaults.verifier ?? defaults.verifier,
440
+ nyquist_validation: globalDefaults.nyquist_validation ?? defaults.nyquist_validation,
441
+ parallelization: globalDefaults.parallelization ?? defaults.parallelization,
442
+ text_mode: globalDefaults.text_mode ?? defaults.text_mode,
443
+ resolve_model_ids: globalDefaults.resolve_model_ids ?? defaults.resolve_model_ids,
444
+ context_window: globalDefaults.context_window ?? defaults.context_window,
445
+ subagent_timeout: globalDefaults.subagent_timeout ?? defaults.subagent_timeout,
446
+ model_overrides: globalDefaults.model_overrides || null,
447
+ agent_skills: globalDefaults.agent_skills || {},
448
+ response_language: globalDefaults.response_language || null,
449
+ };
450
+ } catch {
451
+ return defaults;
452
+ }
419
453
  }
420
454
  }
421
455
 
@@ -636,8 +670,8 @@ function withPlanningLock(cwd, fn) {
636
670
  }
637
671
  } catch { continue; }
638
672
 
639
- // Wait and retry
640
- spawnSync('sleep', ['0.1'], { stdio: 'ignore' });
673
+ // Wait and retry (cross-platform, no shell dependency)
674
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 100);
641
675
  continue;
642
676
  }
643
677
  throw err;
@@ -1313,9 +1347,9 @@ function checkAgentsInstalled() {
1313
1347
  * Users can override with model_overrides in config.json for custom/latest models.
1314
1348
  */
1315
1349
  const MODEL_ALIAS_MAP = {
1316
- 'opus': 'antigravity-opus-4-0',
1317
- 'sonnet': 'antigravity-sonnet-4-5',
1318
- 'haiku': 'antigravity-haiku-3-5',
1350
+ 'opus': 'antigravity-opus-4-6',
1351
+ 'sonnet': 'antigravity-sonnet-4-6',
1352
+ 'haiku': 'antigravity-haiku-4-5',
1319
1353
  };
1320
1354
 
1321
1355
  function resolveModelInternal(cwd, agentType) {
@@ -1543,6 +1577,7 @@ module.exports = {
1543
1577
  detectSubRepos,
1544
1578
  reapStaleTempFiles,
1545
1579
  MODEL_ALIAS_MAP,
1580
+ CONFIG_DEFAULTS,
1546
1581
  planningDir,
1547
1582
  planningRoot,
1548
1583
  planningPaths,
@@ -8,6 +8,38 @@ const { safeReadFile, normalizeMd, output, error } = require('./core.cjs');
8
8
 
9
9
  // ─── Parsing engine ───────────────────────────────────────────────────────────
10
10
 
11
+ /**
12
+ * Split a YAML inline array body on commas, respecting quoted strings.
13
+ * e.g. '"a, b", c' → ['a, b', 'c']
14
+ */
15
+ function splitInlineArray(body) {
16
+ const items = [];
17
+ let current = '';
18
+ let inQuote = null; // null | '"' | "'"
19
+
20
+ for (let i = 0; i < body.length; i++) {
21
+ const ch = body[i];
22
+ if (inQuote) {
23
+ if (ch === inQuote) {
24
+ inQuote = null;
25
+ } else {
26
+ current += ch;
27
+ }
28
+ } else if (ch === '"' || ch === "'") {
29
+ inQuote = ch;
30
+ } else if (ch === ',') {
31
+ const trimmed = current.trim();
32
+ if (trimmed) items.push(trimmed);
33
+ current = '';
34
+ } else {
35
+ current += ch;
36
+ }
37
+ }
38
+ const trimmed = current.trim();
39
+ if (trimmed) items.push(trimmed);
40
+ return items;
41
+ }
42
+
11
43
  function extractFrontmatter(content) {
12
44
  const frontmatter = {};
13
45
  // Find ALL frontmatter blocks at the start of the file.
@@ -53,8 +85,8 @@ function extractFrontmatter(content) {
53
85
  // Push new context for potential nested content
54
86
  stack.push({ obj: current.obj[key], key: null, indent });
55
87
  } else if (value.startsWith('[') && value.endsWith(']')) {
56
- // Inline array: key: [a, b, c]
57
- current.obj[key] = value.slice(1, -1).split(',').map(s => s.trim().replace(/^["']|["']$/g, '')).filter(Boolean);
88
+ // Inline array: key: [a, b, c] — quote-aware split (REG-04 fix)
89
+ current.obj[key] = splitInlineArray(value.slice(1, -1));
58
90
  current.key = null;
59
91
  } else {
60
92
  // Simple key: value