gsd-antigravity-kit 2.0.1 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agent/skills/gsd/SKILL.md +26 -4
- package/.agent/skills/gsd/VERSION +1 -1
- package/.agent/skills/gsd/assets/templates/AI-SPEC.md +246 -0
- package/.agent/skills/gsd/assets/templates/DEBUG.md +7 -2
- package/.agent/skills/gsd/assets/templates/config.json +56 -48
- package/.agent/skills/gsd/assets/templates/research.md +40 -0
- package/.agent/skills/gsd/assets/templates/spec.md +307 -0
- package/.agent/skills/gsd/assets/templates/state.md +8 -0
- package/.agent/skills/gsd/bin/gsd-tools.cjs +212 -11
- package/.agent/skills/gsd/bin/help-manifest.json +8 -2
- package/.agent/skills/gsd/bin/hooks/gsd-check-update-worker.js +108 -0
- package/.agent/skills/gsd/bin/hooks/gsd-check-update.js +14 -89
- package/.agent/skills/gsd/bin/hooks/gsd-context-monitor.js +34 -5
- package/.agent/skills/gsd/bin/hooks/gsd-phase-boundary.sh +1 -0
- package/.agent/skills/gsd/bin/hooks/gsd-prompt-guard.js +1 -1
- package/.agent/skills/gsd/bin/hooks/gsd-read-guard.js +6 -1
- package/.agent/skills/gsd/bin/hooks/gsd-session-state.sh +1 -0
- package/.agent/skills/gsd/bin/hooks/gsd-statusline.js +150 -16
- package/.agent/skills/gsd/bin/hooks/gsd-validate-commit.sh +1 -0
- package/.agent/skills/gsd/bin/hooks/gsd-workflow-guard.js +1 -1
- package/.agent/skills/gsd/bin/lib/audit.cjs +757 -0
- package/.agent/skills/gsd/bin/lib/commands.cjs +17 -7
- package/.agent/skills/gsd/bin/lib/config.cjs +66 -20
- package/.agent/skills/gsd/bin/lib/core.cjs +212 -12
- package/.agent/skills/gsd/bin/lib/frontmatter.cjs +6 -8
- package/.agent/skills/gsd/bin/lib/graphify.cjs +494 -0
- package/.agent/skills/gsd/bin/lib/gsd2-import.cjs +511 -0
- package/.agent/skills/gsd/bin/lib/init.cjs +371 -18
- package/.agent/skills/gsd/bin/lib/intel.cjs +9 -30
- package/.agent/skills/gsd/bin/lib/milestone.cjs +18 -17
- package/.agent/skills/gsd/bin/lib/model-profiles.cjs +1 -0
- package/.agent/skills/gsd/bin/lib/phase.cjs +225 -98
- package/.agent/skills/gsd/bin/lib/profile-output.cjs +17 -5
- package/.agent/skills/gsd/bin/lib/roadmap.cjs +12 -5
- package/.agent/skills/gsd/bin/lib/state.cjs +394 -129
- package/.agent/skills/gsd/bin/lib/template.cjs +8 -4
- package/.agent/skills/gsd/bin/lib/uat.cjs +2 -1
- package/.agent/skills/gsd/bin/lib/verify.cjs +111 -42
- package/.agent/skills/gsd/migration_report.md +2 -2
- package/.agent/skills/gsd/references/agents/gsd-advisor-researcher.md +23 -0
- package/.agent/skills/gsd/references/agents/gsd-ai-researcher.md +133 -0
- package/.agent/skills/gsd/references/agents/gsd-code-fixer.md +11 -10
- package/.agent/skills/gsd/references/agents/gsd-code-reviewer.md +2 -2
- package/.agent/skills/gsd/references/agents/gsd-codebase-mapper.md +13 -2
- package/.agent/skills/gsd/references/agents/gsd-debug-session-manager.md +314 -0
- package/.agent/skills/gsd/references/agents/gsd-debugger.md +147 -76
- package/.agent/skills/gsd/references/agents/gsd-doc-verifier.md +1 -1
- package/.agent/skills/gsd/references/agents/gsd-doc-writer.md +615 -602
- package/.agent/skills/gsd/references/agents/gsd-domain-researcher.md +153 -0
- package/.agent/skills/gsd/references/agents/gsd-eval-auditor.md +175 -0
- package/.agent/skills/gsd/references/agents/gsd-eval-planner.md +154 -0
- package/.agent/skills/gsd/references/agents/gsd-executor.md +108 -38
- package/.agent/skills/gsd/references/agents/gsd-framework-selector.md +160 -0
- package/.agent/skills/gsd/references/agents/gsd-integration-checker.md +454 -443
- package/.agent/skills/gsd/references/agents/gsd-intel-updater.md +40 -20
- package/.agent/skills/gsd/references/agents/gsd-nyquist-auditor.md +187 -176
- package/.agent/skills/gsd/references/agents/gsd-pattern-mapper.md +335 -0
- package/.agent/skills/gsd/references/agents/gsd-phase-researcher.md +112 -13
- package/.agent/skills/gsd/references/agents/gsd-plan-checker.md +104 -10
- package/.agent/skills/gsd/references/agents/gsd-planner.md +125 -167
- package/.agent/skills/gsd/references/agents/gsd-project-researcher.md +25 -2
- package/.agent/skills/gsd/references/agents/gsd-research-synthesizer.md +3 -3
- package/.agent/skills/gsd/references/agents/gsd-roadmapper.md +12 -1
- package/.agent/skills/gsd/references/agents/gsd-security-auditor.md +139 -128
- package/.agent/skills/gsd/references/agents/gsd-ui-auditor.md +3 -3
- package/.agent/skills/gsd/references/agents/gsd-ui-checker.md +11 -2
- package/.agent/skills/gsd/references/agents/gsd-ui-researcher.md +27 -4
- package/.agent/skills/gsd/references/agents/gsd-verifier.md +13 -19
- package/.agent/skills/gsd/references/commands/atomic/add-todo.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/check-todos.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/cleanup.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/do.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/help.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/join-discord.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/note.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/session-report.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/ship.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/stats.md +2 -2
- package/.agent/skills/gsd/references/commands/atomic/thread.md +141 -41
- package/.agent/skills/gsd/references/commands/atomic/undo.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/add-backlog.md +15 -12
- package/.agent/skills/gsd/references/commands/milestone/audit-milestone.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/complete-milestone.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/milestone-summary.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/new-milestone.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/plan-milestone-gaps.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/plant-seed.md +2 -2
- package/.agent/skills/gsd/references/commands/milestone/review-backlog.md +4 -4
- package/.agent/skills/gsd/references/commands/misc/ai-integration-phase.md +38 -0
- package/.agent/skills/gsd/references/commands/misc/audit-fix.md +2 -2
- package/.agent/skills/gsd/references/commands/misc/audit-uat.md +2 -2
- package/.agent/skills/gsd/references/commands/misc/eval-review.md +34 -0
- package/.agent/skills/gsd/references/commands/misc/extract_learnings.md +24 -0
- package/.agent/skills/gsd/references/commands/misc/from-gsd2.md +49 -0
- package/.agent/skills/gsd/references/commands/misc/graphify.md +203 -0
- package/.agent/skills/gsd/references/commands/misc/inbox.md +40 -0
- package/.agent/skills/gsd/references/commands/misc/next.md +5 -3
- package/.agent/skills/gsd/references/commands/misc/progress.md +4 -3
- package/.agent/skills/gsd/references/commands/misc/sketch-wrap-up.md +33 -0
- package/.agent/skills/gsd/references/commands/misc/sketch.md +47 -0
- package/.agent/skills/gsd/references/commands/misc/spec-phase.md +64 -0
- package/.agent/skills/gsd/references/commands/misc/spike-wrap-up.md +33 -0
- package/.agent/skills/gsd/references/commands/misc/spike.md +43 -0
- package/.agent/skills/gsd/references/commands/misc/verify-work.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/add-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/add-tests.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/discuss-phase.md +5 -5
- package/.agent/skills/gsd/references/commands/phase/execute-phase.md +4 -4
- package/.agent/skills/gsd/references/commands/phase/insert-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/list-phase-assumptions.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/plan-phase.md +3 -3
- package/.agent/skills/gsd/references/commands/phase/remove-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/research-phase.md +5 -5
- package/.agent/skills/gsd/references/commands/phase/secure-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/ui-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/ui-review.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/validate-phase.md +2 -2
- package/.agent/skills/gsd/references/commands/phase/workstreams.md +9 -9
- package/.agent/skills/gsd/references/commands/project/analyze-dependencies.md +2 -2
- package/.agent/skills/gsd/references/commands/project/explore.md +2 -2
- package/.agent/skills/gsd/references/commands/project/import.md +2 -2
- package/.agent/skills/gsd/references/commands/project/intel.md +10 -10
- package/.agent/skills/gsd/references/commands/project/list-workspaces.md +2 -2
- package/.agent/skills/gsd/references/commands/project/map-codebase.md +2 -2
- package/.agent/skills/gsd/references/commands/project/new-project.md +2 -2
- package/.agent/skills/gsd/references/commands/project/new-workspace.md +2 -2
- package/.agent/skills/gsd/references/commands/project/remove-workspace.md +2 -2
- package/.agent/skills/gsd/references/commands/project/scan.md +2 -2
- package/.agent/skills/gsd/references/commands/system/autonomous.md +4 -3
- package/.agent/skills/gsd/references/commands/system/code-review-fix.md +3 -3
- package/.agent/skills/gsd/references/commands/system/code-review.md +3 -3
- package/.agent/skills/gsd/references/commands/system/debug.md +177 -100
- package/.agent/skills/gsd/references/commands/system/docs-update.md +2 -2
- package/.agent/skills/gsd/references/commands/system/fast.md +2 -2
- package/.agent/skills/gsd/references/commands/system/forensics.md +2 -2
- package/.agent/skills/gsd/references/commands/system/gsd-tools.md +153 -6
- package/.agent/skills/gsd/references/commands/system/health.md +2 -2
- package/.agent/skills/gsd/references/commands/system/manager.md +3 -3
- package/.agent/skills/gsd/references/commands/system/pause-work.md +2 -2
- package/.agent/skills/gsd/references/commands/system/pr-branch.md +2 -2
- package/.agent/skills/gsd/references/commands/system/profile-user.md +2 -2
- package/.agent/skills/gsd/references/commands/system/quick.md +127 -3
- package/.agent/skills/gsd/references/commands/system/reapply-patches.md +45 -6
- package/.agent/skills/gsd/references/commands/system/resume-work.md +2 -2
- package/.agent/skills/gsd/references/commands/system/review.md +6 -4
- package/.agent/skills/gsd/references/commands/system/set-profile.md +3 -3
- package/.agent/skills/gsd/references/commands/system/settings.md +2 -2
- package/.agent/skills/gsd/references/commands/system/update.md +2 -2
- package/.agent/skills/gsd/references/docs/ai-evals.md +156 -0
- package/.agent/skills/gsd/references/docs/ai-frameworks.md +186 -0
- package/.agent/skills/gsd/references/docs/artifact-types.md +18 -0
- package/.agent/skills/gsd/references/docs/autonomous-smart-discuss.md +277 -0
- package/.agent/skills/gsd/references/docs/checkpoints.md +30 -0
- package/.agent/skills/gsd/references/docs/common-bug-patterns.md +49 -49
- package/.agent/skills/gsd/references/docs/continuation-format.md +11 -7
- package/.agent/skills/gsd/references/docs/debugger-philosophy.md +76 -0
- package/.agent/skills/gsd/references/docs/decimal-phase-calculation.md +64 -64
- package/.agent/skills/gsd/references/docs/executor-examples.md +110 -0
- package/.agent/skills/gsd/references/docs/git-integration.md +4 -4
- package/.agent/skills/gsd/references/docs/git-planning-commit.md +40 -38
- package/.agent/skills/gsd/references/docs/ios-scaffold.md +123 -0
- package/.agent/skills/gsd/references/docs/mandatory-initial-read.md +2 -0
- package/.agent/skills/gsd/references/docs/phase-argument-parsing.md +61 -61
- package/.agent/skills/gsd/references/docs/planner-antipatterns.md +89 -0
- package/.agent/skills/gsd/references/docs/planner-revision.md +87 -87
- package/.agent/skills/gsd/references/docs/planner-source-audit.md +73 -0
- package/.agent/skills/gsd/references/docs/planning-config.md +33 -8
- package/.agent/skills/gsd/references/docs/project-skills-discovery.md +19 -0
- package/.agent/skills/gsd/references/docs/sketch-interactivity.md +41 -0
- package/.agent/skills/gsd/references/docs/sketch-theme-system.md +94 -0
- package/.agent/skills/gsd/references/docs/sketch-tooling.md +45 -0
- package/.agent/skills/gsd/references/docs/sketch-variant-patterns.md +81 -0
- package/.agent/skills/gsd/references/docs/tdd.md +67 -0
- package/.agent/skills/gsd/references/docs/universal-anti-patterns.md +5 -0
- package/.agent/skills/gsd/references/docs/workstream-flag.md +11 -11
- package/.agent/skills/gsd/references/mapping.md +1 -1
- package/.agent/skills/gsd/references/workflows/add-phase.md +112 -112
- package/.agent/skills/gsd/references/workflows/add-tests.md +6 -3
- package/.agent/skills/gsd/references/workflows/add-todo.md +5 -3
- package/.agent/skills/gsd/references/workflows/ai-integration-phase.md +284 -0
- package/.agent/skills/gsd/references/workflows/audit-fix.md +157 -157
- package/.agent/skills/gsd/references/workflows/audit-milestone.md +340 -340
- package/.agent/skills/gsd/references/workflows/audit-uat.md +109 -109
- package/.agent/skills/gsd/references/workflows/autonomous.md +20 -288
- package/.agent/skills/gsd/references/workflows/check-todos.md +4 -2
- package/.agent/skills/gsd/references/workflows/cleanup.md +3 -1
- package/.agent/skills/gsd/references/workflows/code-review-fix.md +497 -497
- package/.agent/skills/gsd/references/workflows/code-review.md +515 -515
- package/.agent/skills/gsd/references/workflows/complete-milestone.md +97 -24
- package/.agent/skills/gsd/references/workflows/diagnose-issues.md +238 -238
- package/.agent/skills/gsd/references/workflows/discovery-phase.md +2 -0
- package/.agent/skills/gsd/references/workflows/discuss-phase-assumptions.md +11 -11
- package/.agent/skills/gsd/references/workflows/discuss-phase.md +143 -19
- package/.agent/skills/gsd/references/workflows/do.md +8 -2
- package/.agent/skills/gsd/references/workflows/docs-update.md +5 -3
- package/.agent/skills/gsd/references/workflows/eval-review.md +155 -0
- package/.agent/skills/gsd/references/workflows/execute-phase.md +338 -54
- package/.agent/skills/gsd/references/workflows/execute-plan.md +80 -104
- package/.agent/skills/gsd/references/workflows/explore.md +3 -1
- package/.agent/skills/gsd/references/workflows/extract_learnings.md +232 -0
- package/.agent/skills/gsd/references/workflows/forensics.md +3 -3
- package/.agent/skills/gsd/references/workflows/health.md +2 -2
- package/.agent/skills/gsd/references/workflows/help.md +59 -1
- package/.agent/skills/gsd/references/workflows/import.md +3 -1
- package/.agent/skills/gsd/references/workflows/inbox.md +387 -384
- package/.agent/skills/gsd/references/workflows/insert-phase.md +130 -130
- package/.agent/skills/gsd/references/workflows/list-workspaces.md +56 -56
- package/.agent/skills/gsd/references/workflows/manager.md +5 -3
- package/.agent/skills/gsd/references/workflows/map-codebase.md +19 -5
- package/.agent/skills/gsd/references/workflows/milestone-summary.md +6 -6
- package/.agent/skills/gsd/references/workflows/new-milestone.md +63 -9
- package/.agent/skills/gsd/references/workflows/new-project.md +126 -22
- package/.agent/skills/gsd/references/workflows/new-workspace.md +6 -4
- package/.agent/skills/gsd/references/workflows/next.md +220 -153
- package/.agent/skills/gsd/references/workflows/note.md +2 -0
- package/.agent/skills/gsd/references/workflows/pause-work.md +11 -7
- package/.agent/skills/gsd/references/workflows/plan-milestone-gaps.md +273 -273
- package/.agent/skills/gsd/references/workflows/plan-phase.md +281 -62
- package/.agent/skills/gsd/references/workflows/plant-seed.md +4 -1
- package/.agent/skills/gsd/references/workflows/pr-branch.md +41 -13
- package/.agent/skills/gsd/references/workflows/profile-user.md +15 -13
- package/.agent/skills/gsd/references/workflows/progress.md +133 -21
- package/.agent/skills/gsd/references/workflows/quick.md +67 -27
- package/.agent/skills/gsd/references/workflows/remove-phase.md +155 -155
- package/.agent/skills/gsd/references/workflows/remove-workspace.md +4 -2
- package/.agent/skills/gsd/references/workflows/research-phase.md +3 -3
- package/.agent/skills/gsd/references/workflows/resume-project.md +3 -3
- package/.agent/skills/gsd/references/workflows/review.md +71 -8
- package/.agent/skills/gsd/references/workflows/scan.md +102 -102
- package/.agent/skills/gsd/references/workflows/secure-phase.md +7 -5
- package/.agent/skills/gsd/references/workflows/settings.md +24 -7
- package/.agent/skills/gsd/references/workflows/ship.md +71 -6
- package/.agent/skills/gsd/references/workflows/sketch-wrap-up.md +283 -0
- package/.agent/skills/gsd/references/workflows/sketch.md +263 -0
- package/.agent/skills/gsd/references/workflows/spec-phase.md +262 -0
- package/.agent/skills/gsd/references/workflows/spike-wrap-up.md +273 -0
- package/.agent/skills/gsd/references/workflows/spike.md +270 -0
- package/.agent/skills/gsd/references/workflows/stats.md +60 -60
- package/.agent/skills/gsd/references/workflows/transition.md +671 -671
- package/.agent/skills/gsd/references/workflows/ui-phase.md +33 -12
- package/.agent/skills/gsd/references/workflows/ui-review.md +6 -4
- package/.agent/skills/gsd/references/workflows/undo.md +3 -1
- package/.agent/skills/gsd/references/workflows/update.md +113 -2
- package/.agent/skills/gsd/references/workflows/validate-phase.md +7 -5
- package/.agent/skills/gsd/references/workflows/verify-phase.md +93 -10
- package/.agent/skills/gsd/references/workflows/verify-work.md +50 -10
- package/.agent/skills/gsd-converter/references/mapping.md +1 -1
- package/.agent/skills/gsd-converter/scripts/convert.py +36 -17
- package/.agent/skills/gsd-converter/scripts/regression_test.py +68 -33
- package/README.md +3 -2
- package/package.json +1 -1
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Phase Spec Template
|
|
2
|
+
|
|
3
|
+
Template for `.planning/phases/XX-name/{phase_num}-SPEC.md` — locks requirements before discuss-phase.
|
|
4
|
+
|
|
5
|
+
**Purpose:** Capture WHAT a phase delivers and WHY, with enough precision that requirements are falsifiable. discuss-phase reads this file and focuses on HOW to implement (skipping "what/why" questions already answered here).
|
|
6
|
+
|
|
7
|
+
**Key principle:** Every requirement must be falsifiable — you can write a test or check that proves it was met or not. Vague requirements like "improve performance" are not allowed.
|
|
8
|
+
|
|
9
|
+
**Downstream consumers:**
|
|
10
|
+
- `discuss-phase` — reads SPEC.md at startup; treats Requirements, Boundaries, and Acceptance Criteria as locked; skips "what/why" questions
|
|
11
|
+
- `gsd-planner` — reads locked requirements to constrain plan scope
|
|
12
|
+
- `gsd-verifier` — uses acceptance criteria as explicit pass/fail checks
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## File Template
|
|
17
|
+
|
|
18
|
+
```markdown
|
|
19
|
+
# Phase [X]: [Name] — Specification
|
|
20
|
+
|
|
21
|
+
**Created:** [date]
|
|
22
|
+
**Ambiguity score:** [score] (gate: ≤ 0.20)
|
|
23
|
+
**Requirements:** [N] locked
|
|
24
|
+
|
|
25
|
+
## Goal
|
|
26
|
+
|
|
27
|
+
[One precise sentence — specific and measurable. NOT "improve X" — instead "X changes from A to B".]
|
|
28
|
+
|
|
29
|
+
## Background
|
|
30
|
+
|
|
31
|
+
[Current state from codebase — what exists today, what's broken or missing, what triggers this work. Grounded in code reality, not abstract description.]
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
1. **[Short label]**: [Specific, testable statement.]
|
|
36
|
+
- Current: [what exists or does NOT exist today]
|
|
37
|
+
- Target: [what it should become after this phase]
|
|
38
|
+
- Acceptance: [concrete pass/fail check — how a verifier confirms this was met]
|
|
39
|
+
|
|
40
|
+
2. **[Short label]**: [Specific, testable statement.]
|
|
41
|
+
- Current: [what exists or does NOT exist today]
|
|
42
|
+
- Target: [what it should become after this phase]
|
|
43
|
+
- Acceptance: [concrete pass/fail check]
|
|
44
|
+
|
|
45
|
+
[Continue for all requirements. Each must have Current/Target/Acceptance.]
|
|
46
|
+
|
|
47
|
+
## Boundaries
|
|
48
|
+
|
|
49
|
+
**In scope:**
|
|
50
|
+
- [Explicit list of what this phase produces]
|
|
51
|
+
- [Each item is a concrete deliverable or behavior]
|
|
52
|
+
|
|
53
|
+
**Out of scope:**
|
|
54
|
+
- [Explicit list of what this phase does NOT do] — [brief reason why it's excluded]
|
|
55
|
+
- [Adjacent problems excluded from this phase] — [brief reason]
|
|
56
|
+
|
|
57
|
+
## Constraints
|
|
58
|
+
|
|
59
|
+
[Performance, compatibility, data volume, dependency, or platform constraints.
|
|
60
|
+
If none: "No additional constraints beyond standard project conventions."]
|
|
61
|
+
|
|
62
|
+
## Acceptance Criteria
|
|
63
|
+
|
|
64
|
+
- [ ] [Pass/fail criterion — unambiguous, verifiable]
|
|
65
|
+
- [ ] [Pass/fail criterion]
|
|
66
|
+
- [ ] [Pass/fail criterion]
|
|
67
|
+
|
|
68
|
+
[Every acceptance criterion must be a checkbox that resolves to PASS or FAIL.
|
|
69
|
+
No "should feel good", "looks reasonable", or "generally works" — those are not checkboxes.]
|
|
70
|
+
|
|
71
|
+
## Ambiguity Report
|
|
72
|
+
|
|
73
|
+
| Dimension | Score | Min | Status | Notes |
|
|
74
|
+
|--------------------|-------|------|--------|------------------------------------|
|
|
75
|
+
| Goal Clarity | | 0.75 | | |
|
|
76
|
+
| Boundary Clarity | | 0.70 | | |
|
|
77
|
+
| Constraint Clarity | | 0.65 | | |
|
|
78
|
+
| Acceptance Criteria| | 0.70 | | |
|
|
79
|
+
| **Ambiguity** | | ≤0.20| | |
|
|
80
|
+
|
|
81
|
+
Status: ✓ = met minimum, ⚠ = below minimum (planner treats as assumption)
|
|
82
|
+
|
|
83
|
+
## Interview Log
|
|
84
|
+
|
|
85
|
+
[Key decisions made during the Socratic interview. Format: round → question → answer → decision locked.]
|
|
86
|
+
|
|
87
|
+
| Round | Perspective | Question summary | Decision locked |
|
|
88
|
+
|-------|----------------|-------------------------|------------------------------------|
|
|
89
|
+
| 1 | Researcher | [what was asked] | [what was decided] |
|
|
90
|
+
| 2 | Simplifier | [what was asked] | [what was decided] |
|
|
91
|
+
| 3 | Boundary Keeper| [what was asked] | [what was decided] |
|
|
92
|
+
|
|
93
|
+
[If --auto mode: note "auto-selected" decisions with the reasoning Antigravity used.]
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
*Phase: [XX-name]*
|
|
98
|
+
*Spec created: [date]*
|
|
99
|
+
*Next step: /gsd-discuss-phase [X] — implementation decisions (how to build what's specified above)*
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
<good_examples>
|
|
103
|
+
|
|
104
|
+
**Example 1: Feature addition (Post Feed)**
|
|
105
|
+
|
|
106
|
+
```markdown
|
|
107
|
+
# Phase 3: Post Feed — Specification
|
|
108
|
+
|
|
109
|
+
**Created:** 2025-01-20
|
|
110
|
+
**Ambiguity score:** 0.12
|
|
111
|
+
**Requirements:** 4 locked
|
|
112
|
+
|
|
113
|
+
## Goal
|
|
114
|
+
|
|
115
|
+
Users can scroll through posts from accounts they follow, with new posts available after pull-to-refresh.
|
|
116
|
+
|
|
117
|
+
## Background
|
|
118
|
+
|
|
119
|
+
The database has a `posts` table and `follows` table. No feed query or feed UI exists today. The home screen shows a placeholder "Your feed will appear here." This phase builds the feed query, API endpoint, and the feed list component.
|
|
120
|
+
|
|
121
|
+
## Requirements
|
|
122
|
+
|
|
123
|
+
1. **Feed query**: Returns posts from followed accounts ordered by creation time, descending.
|
|
124
|
+
- Current: No feed query exists — `posts` table is queried directly only from profile pages
|
|
125
|
+
- Target: `GET /api/feed` returns paginated posts from followed accounts, newest first, max 20 per page
|
|
126
|
+
- Acceptance: Query returns correct posts for a user who follows 3 accounts with known post counts; cursor-based pagination advances correctly
|
|
127
|
+
|
|
128
|
+
2. **Feed display**: Posts display in a scrollable card list.
|
|
129
|
+
- Current: Home screen shows static placeholder text
|
|
130
|
+
- Target: Home screen renders feed cards with author, timestamp, post content, and reaction count
|
|
131
|
+
- Acceptance: Feed renders without error for 0 posts (empty state shown), 1 post, and 20+ posts
|
|
132
|
+
|
|
133
|
+
3. **Pull-to-refresh**: User can refresh the feed manually.
|
|
134
|
+
- Current: No refresh mechanism exists
|
|
135
|
+
- Target: Pull-down gesture triggers refetch; new posts appear at top of list
|
|
136
|
+
- Acceptance: After a new post is created in test, pull-to-refresh shows the new post without full app restart
|
|
137
|
+
|
|
138
|
+
4. **New posts indicator**: When new posts arrive, a banner appears instead of auto-scrolling.
|
|
139
|
+
- Current: No such mechanism
|
|
140
|
+
- Target: "3 new posts" banner appears when refetch returns posts newer than the oldest visible post; tapping banner scrolls to top and shows new posts
|
|
141
|
+
- Acceptance: Banner appears for ≥1 new post, does not appear when no new posts, tap navigates to top
|
|
142
|
+
|
|
143
|
+
## Boundaries
|
|
144
|
+
|
|
145
|
+
**In scope:**
|
|
146
|
+
- Feed query (backend) — posts from followed accounts, paginated
|
|
147
|
+
- Feed list UI (frontend) — post cards with author, timestamp, content, reaction counts
|
|
148
|
+
- Pull-to-refresh gesture
|
|
149
|
+
- New posts indicator banner
|
|
150
|
+
- Empty state when user follows no one or no posts exist
|
|
151
|
+
|
|
152
|
+
**Out of scope:**
|
|
153
|
+
- Creating posts — that is Phase 4
|
|
154
|
+
- Reacting to posts — that is Phase 5
|
|
155
|
+
- Following/unfollowing accounts — that is Phase 2 (already done)
|
|
156
|
+
- Push notifications for new posts — separate backlog item
|
|
157
|
+
|
|
158
|
+
## Constraints
|
|
159
|
+
|
|
160
|
+
- Feed query must use cursor-based pagination (not offset) — the database has 500K+ posts and offset pagination is unacceptably slow beyond page 3
|
|
161
|
+
- The feed card component must reuse the existing `<AvatarImage>` component from Phase 2
|
|
162
|
+
|
|
163
|
+
## Acceptance Criteria
|
|
164
|
+
|
|
165
|
+
- [ ] `GET /api/feed` returns posts only from followed accounts (not all posts)
|
|
166
|
+
- [ ] `GET /api/feed` supports `cursor` parameter for pagination
|
|
167
|
+
- [ ] Feed renders correctly at 0, 1, and 20+ posts
|
|
168
|
+
- [ ] Pull-to-refresh triggers refetch
|
|
169
|
+
- [ ] New posts indicator appears when posts newer than current view exist
|
|
170
|
+
- [ ] Empty state renders when user follows no one
|
|
171
|
+
|
|
172
|
+
## Ambiguity Report
|
|
173
|
+
|
|
174
|
+
| Dimension | Score | Min | Status | Notes |
|
|
175
|
+
|--------------------|-------|------|--------|----------------------------------|
|
|
176
|
+
| Goal Clarity | 0.92 | 0.75 | ✓ | |
|
|
177
|
+
| Boundary Clarity | 0.95 | 0.70 | ✓ | Explicit out-of-scope list |
|
|
178
|
+
| Constraint Clarity | 0.80 | 0.65 | ✓ | Cursor pagination required |
|
|
179
|
+
| Acceptance Criteria| 0.85 | 0.70 | ✓ | 6 pass/fail criteria |
|
|
180
|
+
| **Ambiguity** | 0.12 | ≤0.20| ✓ | |
|
|
181
|
+
|
|
182
|
+
## Interview Log
|
|
183
|
+
|
|
184
|
+
| Round | Perspective | Question summary | Decision locked |
|
|
185
|
+
|-------|-----------------|------------------------------|-----------------------------------------|
|
|
186
|
+
| 1 | Researcher | What exists in posts today? | posts + follows tables exist, no feed |
|
|
187
|
+
| 2 | Simplifier | Minimum viable feed? | Cards + pull-refresh, no auto-scroll |
|
|
188
|
+
| 3 | Boundary Keeper | What's NOT this phase? | Creating posts, reactions out of scope |
|
|
189
|
+
| 3 | Boundary Keeper | What does done look like? | Scrollable feed with 4 card fields |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
*Phase: 03-post-feed*
|
|
194
|
+
*Spec created: 2025-01-20*
|
|
195
|
+
*Next step: /gsd-discuss-phase 3 — implementation decisions (card layout, loading skeleton, etc.)*
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**Example 2: CLI tool (Database backup)**
|
|
199
|
+
|
|
200
|
+
```markdown
|
|
201
|
+
# Phase 2: Backup Command — Specification
|
|
202
|
+
|
|
203
|
+
**Created:** 2025-01-20
|
|
204
|
+
**Ambiguity score:** 0.15
|
|
205
|
+
**Requirements:** 3 locked
|
|
206
|
+
|
|
207
|
+
## Goal
|
|
208
|
+
|
|
209
|
+
A `gsd backup` CLI command creates a reproducible database snapshot that can be restored by `gsd restore` (a separate phase).
|
|
210
|
+
|
|
211
|
+
## Background
|
|
212
|
+
|
|
213
|
+
No backup tooling exists. The project uses PostgreSQL. Developers currently use `pg_dump` manually — there is no standardized process, no output naming convention, and no CI integration. Three incidents in the last quarter involved restoring from wrong or corrupt dumps.
|
|
214
|
+
|
|
215
|
+
## Requirements
|
|
216
|
+
|
|
217
|
+
1. **Backup creation**: CLI command executes a full database backup.
|
|
218
|
+
- Current: No `backup` subcommand exists in the CLI
|
|
219
|
+
- Target: `gsd backup` connects to the database (via `DATABASE_URL` env or `--db` flag), runs pg_dump, writes output to `./backups/YYYY-MM-DD_HH-MM-SS.dump`
|
|
220
|
+
- Acceptance: Running `gsd backup` on a test database creates a `.dump` file; running `pg_restore` on that file recreates the database without error
|
|
221
|
+
|
|
222
|
+
2. **Network retry**: Transient network failures are retried automatically.
|
|
223
|
+
- Current: pg_dump fails immediately on network error
|
|
224
|
+
- Target: Backup retries up to 3 times with 5-second delay; 4th failure exits with code 1 and a message to stderr
|
|
225
|
+
- Acceptance: Simulating 2 sequential network failures causes 2 retries then success; simulating 4 failures causes exit code 1 and stderr message
|
|
226
|
+
|
|
227
|
+
3. **Partial cleanup**: Failed backups do not leave corrupt files.
|
|
228
|
+
- Current: Manual pg_dump leaves partial files on failure
|
|
229
|
+
- Target: If backup fails after starting, the partial `.dump` file is deleted before exit
|
|
230
|
+
- Acceptance: After a simulated failure mid-dump, no `.dump` file exists in `./backups/`
|
|
231
|
+
|
|
232
|
+
## Boundaries
|
|
233
|
+
|
|
234
|
+
**In scope:**
|
|
235
|
+
- `gsd backup` subcommand (full dump only)
|
|
236
|
+
- Output to `./backups/` directory (created if missing)
|
|
237
|
+
- Network retry (3 attempts)
|
|
238
|
+
- Partial file cleanup on failure
|
|
239
|
+
|
|
240
|
+
**Out of scope:**
|
|
241
|
+
- `gsd restore` — that is Phase 3
|
|
242
|
+
- Incremental backups — separate backlog item (full dump only for now)
|
|
243
|
+
- S3 or remote storage — separate backlog item
|
|
244
|
+
- Encryption — separate backlog item
|
|
245
|
+
- Scheduled/cron backups — separate backlog item
|
|
246
|
+
|
|
247
|
+
## Constraints
|
|
248
|
+
|
|
249
|
+
- Must use `pg_dump` (not a custom query) — ensures compatibility with standard `pg_restore`
|
|
250
|
+
- `--no-retry` flag must be available for CI use (fail fast, no retries)
|
|
251
|
+
|
|
252
|
+
## Acceptance Criteria
|
|
253
|
+
|
|
254
|
+
- [ ] `gsd backup` creates a `.dump` file in `./backups/YYYY-MM-DD_HH-MM-SS.dump` format
|
|
255
|
+
- [ ] `gsd backup` uses `DATABASE_URL` env var or `--db` flag for connection
|
|
256
|
+
- [ ] 3 retries on network failure, then exit code 1 with stderr message
|
|
257
|
+
- [ ] `--no-retry` flag skips retries and fails immediately on first error
|
|
258
|
+
- [ ] No partial `.dump` file left after a failed backup
|
|
259
|
+
|
|
260
|
+
## Ambiguity Report
|
|
261
|
+
|
|
262
|
+
| Dimension | Score | Min | Status | Notes |
|
|
263
|
+
|--------------------|-------|------|--------|--------------------------------|
|
|
264
|
+
| Goal Clarity | 0.90 | 0.75 | ✓ | |
|
|
265
|
+
| Boundary Clarity | 0.95 | 0.70 | ✓ | Explicit out-of-scope list |
|
|
266
|
+
| Constraint Clarity | 0.75 | 0.65 | ✓ | pg_dump required |
|
|
267
|
+
| Acceptance Criteria| 0.80 | 0.70 | ✓ | 5 pass/fail criteria |
|
|
268
|
+
| **Ambiguity** | 0.15 | ≤0.20| ✓ | |
|
|
269
|
+
|
|
270
|
+
## Interview Log
|
|
271
|
+
|
|
272
|
+
| Round | Perspective | Question summary | Decision locked |
|
|
273
|
+
|-------|-----------------|------------------------------|-----------------------------------------|
|
|
274
|
+
| 1 | Researcher | What backup tooling exists? | None — pg_dump manual only |
|
|
275
|
+
| 2 | Simplifier | Minimum viable backup? | Full dump only, local only |
|
|
276
|
+
| 3 | Boundary Keeper | What's NOT this phase? | Restore, S3, encryption excluded |
|
|
277
|
+
| 4 | Failure Analyst | What goes wrong on failure? | Partial files, CI fail-fast needed |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
*Phase: 02-backup-command*
|
|
282
|
+
*Spec created: 2025-01-20*
|
|
283
|
+
*Next step: /gsd-discuss-phase 2 — implementation decisions (progress reporting, flag design, etc.)*
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
</good_examples>
|
|
287
|
+
|
|
288
|
+
<guidelines>
|
|
289
|
+
**Every requirement needs all three fields:**
|
|
290
|
+
- Current: grounds the requirement in reality — what exists today?
|
|
291
|
+
- Target: the concrete change — not "improve X" but "X becomes Y"
|
|
292
|
+
- Acceptance: the falsifiable check — how does a verifier confirm this?
|
|
293
|
+
|
|
294
|
+
**Ambiguity Report must reflect the actual interview.** If a dimension is below minimum, mark it ⚠ — the planner knows to treat it as an assumption rather than a locked requirement.
|
|
295
|
+
|
|
296
|
+
**Interview Log is evidence of rigor.** Don't skip it. It shows that requirements came from discovery, not assumption.
|
|
297
|
+
|
|
298
|
+
**Boundaries protect the phase from scope creep.** The out-of-scope list with reasoning is as important as the in-scope list. Future phases that touch adjacent areas can point to this SPEC.md to understand what was intentionally excluded.
|
|
299
|
+
|
|
300
|
+
**SPEC.md is a one-way door for requirements.** discuss-phase will treat these as locked. If requirements change after SPEC.md is written, the user should update SPEC.md first, then re-run discuss-phase.
|
|
301
|
+
|
|
302
|
+
**SPEC.md does NOT replace CONTEXT.md.** They serve different purposes:
|
|
303
|
+
- SPEC.md: what the phase delivers (requirements, boundaries, acceptance criteria)
|
|
304
|
+
- CONTEXT.md: how the phase will be implemented (decisions, patterns, tradeoffs)
|
|
305
|
+
|
|
306
|
+
discuss-phase generates CONTEXT.md after reading SPEC.md.
|
|
307
|
+
</guidelines>
|
|
@@ -66,6 +66,14 @@ None yet.
|
|
|
66
66
|
|
|
67
67
|
None yet.
|
|
68
68
|
|
|
69
|
+
## Deferred Items
|
|
70
|
+
|
|
71
|
+
Items acknowledged and carried forward from previous milestone close:
|
|
72
|
+
|
|
73
|
+
| Category | Item | Status | Deferred At |
|
|
74
|
+
|----------|------|--------|-------------|
|
|
75
|
+
| *(none)* | | | |
|
|
76
|
+
|
|
69
77
|
## Session Continuity
|
|
70
78
|
|
|
71
79
|
Last session: [YYYY-MM-DD HH:MM]
|
|
@@ -182,6 +182,17 @@ async function main() {
|
|
|
182
182
|
args.splice(pickIdx, 2);
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
// --default <value>: for config-get, return this value instead of erroring
|
|
186
|
+
// when the key is absent. Allows workflows to express optional config reads
|
|
187
|
+
// without defensive `2>/dev/null || true` boilerplate (#1893).
|
|
188
|
+
const defaultIdx = args.indexOf('--default');
|
|
189
|
+
let defaultValue = undefined;
|
|
190
|
+
if (defaultIdx !== -1) {
|
|
191
|
+
defaultValue = args[defaultIdx + 1];
|
|
192
|
+
if (defaultValue === undefined) defaultValue = '';
|
|
193
|
+
args.splice(defaultIdx, 2);
|
|
194
|
+
}
|
|
195
|
+
|
|
185
196
|
const command = args[0];
|
|
186
197
|
|
|
187
198
|
if (!command) {
|
|
@@ -203,7 +214,7 @@ async function main() {
|
|
|
203
214
|
// filesystem traversal on every invocation.
|
|
204
215
|
const SKIP_ROOT_RESOLUTION = new Set([
|
|
205
216
|
'generate-slug', 'current-timestamp', 'verify-path-exists',
|
|
206
|
-
'verify-summary', 'template', 'frontmatter',
|
|
217
|
+
'verify-summary', 'template', 'frontmatter', 'detect-custom-files',
|
|
207
218
|
]);
|
|
208
219
|
if (!SKIP_ROOT_RESOLUTION.has(command)) {
|
|
209
220
|
cwd = findProjectRoot(cwd);
|
|
@@ -234,7 +245,7 @@ async function main() {
|
|
|
234
245
|
}
|
|
235
246
|
};
|
|
236
247
|
try {
|
|
237
|
-
await runCommand(command, args, cwd, raw);
|
|
248
|
+
await runCommand(command, args, cwd, raw, defaultValue);
|
|
238
249
|
cleanup();
|
|
239
250
|
} catch (e) {
|
|
240
251
|
fs.writeSync = origWriteSync;
|
|
@@ -243,7 +254,27 @@ async function main() {
|
|
|
243
254
|
return;
|
|
244
255
|
}
|
|
245
256
|
|
|
246
|
-
|
|
257
|
+
// Intercept stdout to transparently resolve @file: references (#1891).
|
|
258
|
+
// core.cjs output() writes @file:<path> when JSON > 50KB. The --pick path
|
|
259
|
+
// already resolves this, but the normal path wrote @file: to stdout, forcing
|
|
260
|
+
// every workflow to have a bash-specific `if [[ "$INIT" == @file:* ]]` check
|
|
261
|
+
// that breaks on PowerShell and other non-bash shells.
|
|
262
|
+
const origWriteSync2 = fs.writeSync;
|
|
263
|
+
const outChunks = [];
|
|
264
|
+
fs.writeSync = function (fd, data, ...rest) {
|
|
265
|
+
if (fd === 1) { outChunks.push(String(data)); return; }
|
|
266
|
+
return origWriteSync2.call(fs, fd, data, ...rest);
|
|
267
|
+
};
|
|
268
|
+
try {
|
|
269
|
+
await runCommand(command, args, cwd, raw, defaultValue);
|
|
270
|
+
} finally {
|
|
271
|
+
fs.writeSync = origWriteSync2;
|
|
272
|
+
}
|
|
273
|
+
let captured = outChunks.join('');
|
|
274
|
+
if (captured.startsWith('@file:')) {
|
|
275
|
+
captured = fs.readFileSync(captured.slice(6), 'utf-8');
|
|
276
|
+
}
|
|
277
|
+
origWriteSync2.call(fs, 1, captured);
|
|
247
278
|
}
|
|
248
279
|
|
|
249
280
|
/**
|
|
@@ -269,7 +300,7 @@ function extractField(obj, fieldPath) {
|
|
|
269
300
|
return current;
|
|
270
301
|
}
|
|
271
302
|
|
|
272
|
-
async function runCommand(command, args, cwd, raw) {
|
|
303
|
+
async function runCommand(command, args, cwd, raw, defaultValue) {
|
|
273
304
|
switch (command) {
|
|
274
305
|
case 'state': {
|
|
275
306
|
const subcommand = args[1];
|
|
@@ -323,6 +354,9 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
323
354
|
} else if (subcommand === 'sync') {
|
|
324
355
|
const { verify } = parseNamedArgs(args, [], ['verify']);
|
|
325
356
|
state.cmdStateSync(cwd, { verify }, raw);
|
|
357
|
+
} else if (subcommand === 'prune') {
|
|
358
|
+
const { 'keep-recent': keepRecent, 'dry-run': dryRun } = parseNamedArgs(args, ['keep-recent'], ['dry-run']);
|
|
359
|
+
state.cmdStatePrune(cwd, { keepRecent: keepRecent || '3', dryRun: !!dryRun }, raw);
|
|
326
360
|
} else {
|
|
327
361
|
state.cmdStateLoad(cwd, raw);
|
|
328
362
|
}
|
|
@@ -477,7 +511,7 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
477
511
|
}
|
|
478
512
|
|
|
479
513
|
case 'config-get': {
|
|
480
|
-
config.cmdConfigGet(cwd, args[1], raw);
|
|
514
|
+
config.cmdConfigGet(cwd, args[1], raw, defaultValue);
|
|
481
515
|
break;
|
|
482
516
|
}
|
|
483
517
|
|
|
@@ -486,11 +520,21 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
486
520
|
break;
|
|
487
521
|
}
|
|
488
522
|
|
|
523
|
+
case 'config-path': {
|
|
524
|
+
config.cmdConfigPath(cwd, raw);
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
|
|
489
528
|
case 'agent-skills': {
|
|
490
529
|
init.cmdAgentSkills(cwd, args[1], raw);
|
|
491
530
|
break;
|
|
492
531
|
}
|
|
493
532
|
|
|
533
|
+
case 'skill-manifest': {
|
|
534
|
+
init.cmdSkillManifest(cwd, args, raw);
|
|
535
|
+
break;
|
|
536
|
+
}
|
|
537
|
+
|
|
494
538
|
case 'history-digest': {
|
|
495
539
|
commands.cmdHistoryDigest(cwd, raw);
|
|
496
540
|
break;
|
|
@@ -556,6 +600,16 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
556
600
|
}
|
|
557
601
|
}
|
|
558
602
|
phase.cmdPhaseAdd(cwd, descArgs.join(' '), raw, customId);
|
|
603
|
+
} else if (subcommand === 'add-batch') {
|
|
604
|
+
// Accepts JSON array of descriptions via --descriptions '[...]' or positional args
|
|
605
|
+
const descFlagIdx = args.indexOf('--descriptions');
|
|
606
|
+
let descriptions;
|
|
607
|
+
if (descFlagIdx !== -1 && args[descFlagIdx + 1]) {
|
|
608
|
+
try { descriptions = JSON.parse(args[descFlagIdx + 1]); } catch (e) { error('--descriptions must be a JSON array'); }
|
|
609
|
+
} else {
|
|
610
|
+
descriptions = args.slice(2).filter(a => a !== '--raw');
|
|
611
|
+
}
|
|
612
|
+
phase.cmdPhaseAddBatch(cwd, descriptions, raw);
|
|
559
613
|
} else if (subcommand === 'insert') {
|
|
560
614
|
phase.cmdPhaseInsert(cwd, args[2], args.slice(3).join(' '), raw);
|
|
561
615
|
} else if (subcommand === 'remove') {
|
|
@@ -564,7 +618,7 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
564
618
|
} else if (subcommand === 'complete') {
|
|
565
619
|
phase.cmdPhaseComplete(cwd, args[2], raw);
|
|
566
620
|
} else {
|
|
567
|
-
error('Unknown phase subcommand. Available: next-decimal, add, insert, remove, complete');
|
|
621
|
+
error('Unknown phase subcommand. Available: next-decimal, add, add-batch, insert, remove, complete');
|
|
568
622
|
}
|
|
569
623
|
break;
|
|
570
624
|
}
|
|
@@ -608,6 +662,18 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
608
662
|
break;
|
|
609
663
|
}
|
|
610
664
|
|
|
665
|
+
case 'audit-open': {
|
|
666
|
+
const { auditOpenArtifacts, formatAuditReport } = require('./lib/audit.cjs');
|
|
667
|
+
const includeRaw = args.includes('--json');
|
|
668
|
+
const result = auditOpenArtifacts(cwd);
|
|
669
|
+
if (includeRaw) {
|
|
670
|
+
core.output(result, raw);
|
|
671
|
+
} else {
|
|
672
|
+
core.output(formatAuditReport(result), raw);
|
|
673
|
+
}
|
|
674
|
+
break;
|
|
675
|
+
}
|
|
676
|
+
|
|
611
677
|
case 'uat': {
|
|
612
678
|
const subcommand = args[1];
|
|
613
679
|
const uat = require('./lib/uat.cjs');
|
|
@@ -653,13 +719,13 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
653
719
|
const includes = parseIncludeFlag(args);
|
|
654
720
|
switch (workflow) {
|
|
655
721
|
case 'execute-phase': {
|
|
656
|
-
const { validate: epValidate } = parseNamedArgs(args, [], ['validate']);
|
|
657
|
-
init.cmdInitExecutePhase(cwd, args[2], includes, raw, { validate: epValidate });
|
|
722
|
+
const { validate: epValidate, tdd: epTdd } = parseNamedArgs(args, [], ['validate', 'tdd']);
|
|
723
|
+
init.cmdInitExecutePhase(cwd, args[2], includes, raw, { validate: epValidate, tdd: epTdd });
|
|
658
724
|
break;
|
|
659
725
|
}
|
|
660
726
|
case 'plan-phase': {
|
|
661
|
-
const { validate: ppValidate } = parseNamedArgs(args, [], ['validate']);
|
|
662
|
-
init.cmdInitPlanPhase(cwd, args[2], includes, raw, { validate: ppValidate });
|
|
727
|
+
const { validate: ppValidate, tdd: ppTdd } = parseNamedArgs(args, [], ['validate', 'tdd']);
|
|
728
|
+
init.cmdInitPlanPhase(cwd, args[2], includes, raw, { validate: ppValidate, tdd: ppTdd });
|
|
663
729
|
break;
|
|
664
730
|
}
|
|
665
731
|
case 'new-project':
|
|
@@ -866,7 +932,15 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
866
932
|
core.output(intel.intelQuery(term, planningDir), raw);
|
|
867
933
|
} else if (subcommand === 'status') {
|
|
868
934
|
const planningDir = path.join(cwd, '.planning');
|
|
869
|
-
|
|
935
|
+
const status = intel.intelStatus(planningDir);
|
|
936
|
+
if (!raw && status.files) {
|
|
937
|
+
for (const file of Object.values(status.files)) {
|
|
938
|
+
if (file.updated_at) {
|
|
939
|
+
file.updated_at = core.timeAgo(new Date(file.updated_at));
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
core.output(status, raw);
|
|
870
944
|
} else if (subcommand === 'diff') {
|
|
871
945
|
const planningDir = path.join(cwd, '.planning');
|
|
872
946
|
core.output(intel.intelDiff(planningDir), raw);
|
|
@@ -893,6 +967,33 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
893
967
|
break;
|
|
894
968
|
}
|
|
895
969
|
|
|
970
|
+
// ─── Graphify ──────────────────────────────────────────────────────────
|
|
971
|
+
|
|
972
|
+
case 'graphify': {
|
|
973
|
+
const graphify = require('./lib/graphify.cjs');
|
|
974
|
+
const subcommand = args[1];
|
|
975
|
+
if (subcommand === 'query') {
|
|
976
|
+
const term = args[2];
|
|
977
|
+
if (!term) error('Usage: gsd-tools graphify query <term>');
|
|
978
|
+
const budgetIdx = args.indexOf('--budget');
|
|
979
|
+
const budget = budgetIdx !== -1 ? parseInt(args[budgetIdx + 1], 10) : null;
|
|
980
|
+
core.output(graphify.graphifyQuery(cwd, term, { budget }), raw);
|
|
981
|
+
} else if (subcommand === 'status') {
|
|
982
|
+
core.output(graphify.graphifyStatus(cwd), raw);
|
|
983
|
+
} else if (subcommand === 'diff') {
|
|
984
|
+
core.output(graphify.graphifyDiff(cwd), raw);
|
|
985
|
+
} else if (subcommand === 'build') {
|
|
986
|
+
if (args[2] === 'snapshot') {
|
|
987
|
+
core.output(graphify.writeSnapshot(cwd), raw);
|
|
988
|
+
} else {
|
|
989
|
+
core.output(graphify.graphifyBuild(cwd), raw);
|
|
990
|
+
}
|
|
991
|
+
} else {
|
|
992
|
+
error('Unknown graphify subcommand. Available: build, query, status, diff');
|
|
993
|
+
}
|
|
994
|
+
break;
|
|
995
|
+
}
|
|
996
|
+
|
|
896
997
|
// ─── Documentation ────────────────────────────────────────────────────
|
|
897
998
|
|
|
898
999
|
case 'docs-init': {
|
|
@@ -928,6 +1029,106 @@ async function runCommand(command, args, cwd, raw) {
|
|
|
928
1029
|
break;
|
|
929
1030
|
}
|
|
930
1031
|
|
|
1032
|
+
// ─── detect-custom-files ───────────────────────────────────────────────
|
|
1033
|
+
// Detect user-added files inside GSD-managed directories that are not
|
|
1034
|
+
// tracked in gsd-file-manifest.json. Used by the update workflow to back
|
|
1035
|
+
// up custom files before the installer wipes those directories.
|
|
1036
|
+
//
|
|
1037
|
+
// This replaces the fragile bash pattern:
|
|
1038
|
+
// MANIFEST_FILES=$(node -e "require('$RUNTIME_DIR/...')" 2>/dev/null)
|
|
1039
|
+
// ${filepath#$RUNTIME_DIR/} # unreliable path stripping
|
|
1040
|
+
// which silently returns CUSTOM_COUNT=0 when $RUNTIME_DIR is unset or
|
|
1041
|
+
// when the stripped path does not match the manifest key format (#1997).
|
|
1042
|
+
|
|
1043
|
+
case 'detect-custom-files': {
|
|
1044
|
+
const configDirIdx = args.indexOf('--config-dir');
|
|
1045
|
+
const configDir = configDirIdx !== -1 ? args[configDirIdx + 1] : null;
|
|
1046
|
+
if (!configDir) {
|
|
1047
|
+
error('Usage: gsd-tools detect-custom-files --config-dir <path>');
|
|
1048
|
+
}
|
|
1049
|
+
const resolvedConfigDir = path.resolve(configDir);
|
|
1050
|
+
if (!fs.existsSync(resolvedConfigDir)) {
|
|
1051
|
+
error(`Config directory not found: ${resolvedConfigDir}`);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
const manifestPath = path.join(resolvedConfigDir, 'gsd-file-manifest.json');
|
|
1055
|
+
if (!fs.existsSync(manifestPath)) {
|
|
1056
|
+
// No manifest — cannot determine what is custom. Return empty list
|
|
1057
|
+
// (same behaviour as saveLocalPatches in install.js when no manifest).
|
|
1058
|
+
const out = { custom_files: [], custom_count: 0, manifest_found: false };
|
|
1059
|
+
process.stdout.write(JSON.stringify(out, null, 2));
|
|
1060
|
+
break;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
let manifest;
|
|
1064
|
+
try {
|
|
1065
|
+
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
1066
|
+
} catch {
|
|
1067
|
+
const out = { custom_files: [], custom_count: 0, manifest_found: false, error: 'manifest parse error' };
|
|
1068
|
+
process.stdout.write(JSON.stringify(out, null, 2));
|
|
1069
|
+
break;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
const manifestKeys = new Set(Object.keys(manifest.files || {}));
|
|
1073
|
+
|
|
1074
|
+
// GSD-managed directories to scan for user-added files.
|
|
1075
|
+
// These are the directories the installer wipes on update.
|
|
1076
|
+
const GSD_MANAGED_DIRS = [
|
|
1077
|
+
'get-shit-done',
|
|
1078
|
+
'agents',
|
|
1079
|
+
path.join('commands', 'gsd'),
|
|
1080
|
+
'hooks',
|
|
1081
|
+
// OpenCode/Kilo flat command dir
|
|
1082
|
+
'command',
|
|
1083
|
+
// Codex/Copilot skills dir
|
|
1084
|
+
'skills',
|
|
1085
|
+
];
|
|
1086
|
+
|
|
1087
|
+
function walkDir(dir, baseDir) {
|
|
1088
|
+
const results = [];
|
|
1089
|
+
if (!fs.existsSync(dir)) return results;
|
|
1090
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
1091
|
+
const fullPath = path.join(dir, entry.name);
|
|
1092
|
+
if (entry.isDirectory()) {
|
|
1093
|
+
results.push(...walkDir(fullPath, baseDir));
|
|
1094
|
+
} else {
|
|
1095
|
+
// Use forward slashes for cross-platform manifest key compatibility
|
|
1096
|
+
const relPath = path.relative(baseDir, fullPath).replace(/\\/g, '/');
|
|
1097
|
+
results.push(relPath);
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
return results;
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
const customFiles = [];
|
|
1104
|
+
for (const managedDir of GSD_MANAGED_DIRS) {
|
|
1105
|
+
const absDir = path.join(resolvedConfigDir, managedDir);
|
|
1106
|
+
if (!fs.existsSync(absDir)) continue;
|
|
1107
|
+
for (const relPath of walkDir(absDir, resolvedConfigDir)) {
|
|
1108
|
+
if (!manifestKeys.has(relPath)) {
|
|
1109
|
+
customFiles.push(relPath);
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
const out = {
|
|
1115
|
+
custom_files: customFiles,
|
|
1116
|
+
custom_count: customFiles.length,
|
|
1117
|
+
manifest_found: true,
|
|
1118
|
+
manifest_version: manifest.version || null,
|
|
1119
|
+
};
|
|
1120
|
+
process.stdout.write(JSON.stringify(out, null, 2));
|
|
1121
|
+
break;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
// ─── GSD-2 Reverse Migration ───────────────────────────────────────────
|
|
1125
|
+
|
|
1126
|
+
case 'from-gsd2': {
|
|
1127
|
+
const gsd2Import = require('./lib/gsd2-import.cjs');
|
|
1128
|
+
gsd2Import.cmdFromGsd2(args.slice(1), cwd, raw);
|
|
1129
|
+
break;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
931
1132
|
default:
|
|
932
1133
|
error(`Unknown command: ${command}`);
|
|
933
1134
|
}
|