gsd-remix 1.0.2 → 1.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/README.md +13 -81
- package/README.zh-CN.md +13 -57
- package/agents/gsd-debugger.md +0 -3
- package/agents/gsd-executor.md +5 -11
- package/agents/gsd-phase-researcher.md +3 -107
- package/agents/gsd-plan-checker.md +0 -61
- package/agents/gsd-planner.md +4 -63
- package/agents/gsd-roadmapper.md +0 -29
- package/agents/gsd-security-auditor.md +62 -114
- package/agents/gsd-verifier.md +0 -3
- package/bin/install.js +20 -118
- package/commands/gsd/complete-milestone.md +0 -22
- package/commands/gsd/plan-phase.md +1 -2
- package/get-shit-done/bin/gsd-tools.cjs +5 -224
- package/get-shit-done/bin/lib/claude-md.cjs +427 -0
- package/get-shit-done/bin/lib/config-schema.cjs +2 -12
- package/get-shit-done/bin/lib/config.cjs +3 -12
- package/get-shit-done/bin/lib/core.cjs +4 -5
- package/get-shit-done/bin/lib/init.cjs +0 -163
- package/get-shit-done/bin/lib/model-profiles.cjs +12 -18
- package/get-shit-done/bin/lib/verify.cjs +0 -66
- package/get-shit-done/references/agent-contracts.md +0 -6
- package/get-shit-done/references/artifact-types.md +0 -30
- package/get-shit-done/references/continuation-format.md +0 -1
- package/get-shit-done/references/model-profiles.md +39 -37
- package/get-shit-done/references/planning-config.md +7 -12
- package/get-shit-done/references/verification-overrides.md +1 -1
- package/get-shit-done/templates/README.md +2 -9
- package/get-shit-done/templates/claude-md.md +0 -14
- package/get-shit-done/templates/config.json +5 -19
- package/get-shit-done/workflows/autonomous.md +9 -141
- package/get-shit-done/workflows/complete-milestone.md +3 -4
- package/get-shit-done/workflows/discuss-phase-assumptions.md +1 -18
- package/get-shit-done/workflows/discuss-phase.md +10 -104
- package/get-shit-done/workflows/do.md +1 -5
- package/get-shit-done/workflows/execute-phase.md +53 -103
- package/get-shit-done/workflows/execute-plan.md +4 -4
- package/get-shit-done/workflows/health.md +2 -5
- package/get-shit-done/workflows/help.md +0 -165
- package/get-shit-done/workflows/new-milestone.md +0 -51
- package/get-shit-done/workflows/new-project.md +2 -63
- package/get-shit-done/workflows/next.md +0 -23
- package/get-shit-done/workflows/pause-work.md +7 -15
- package/get-shit-done/workflows/plan-phase.md +20 -304
- package/get-shit-done/workflows/pr-branch.md +0 -1
- package/get-shit-done/workflows/progress.md +1 -68
- package/get-shit-done/workflows/quick.md +0 -3
- package/get-shit-done/workflows/research-phase.md +0 -1
- package/get-shit-done/workflows/settings.md +1 -57
- package/get-shit-done/workflows/transition.md +3 -86
- package/get-shit-done/workflows/verify-work.md +0 -64
- package/package.json +1 -1
- package/scripts/build-hooks.js +0 -2
- package/sdk/prompts/agents/gsd-executor.md +2 -0
- package/sdk/prompts/agents/gsd-plan-checker.md +0 -3
- package/sdk/prompts/agents/gsd-roadmapper.md +0 -29
- package/sdk/src/config.ts +4 -5
- package/sdk/src/golden/golden-integration-covered.ts +0 -2
- package/sdk/src/golden/golden-policy.ts +1 -1
- package/sdk/src/golden/golden.integration.test.ts +0 -27
- package/sdk/src/golden/read-only-golden-rows.ts +0 -15
- package/sdk/src/query/QUERY-HANDLERS.md +3 -34
- package/sdk/src/query/claude-md.ts +421 -0
- package/sdk/src/query/commit.test.ts +155 -1
- package/sdk/src/query/commit.ts +71 -17
- package/sdk/src/query/config-gates.test.ts +1 -2
- package/sdk/src/query/config-gates.ts +1 -5
- package/sdk/src/query/config-mutation.test.ts +0 -1
- package/sdk/src/query/config-mutation.ts +5 -6
- package/sdk/src/query/config-query.test.ts +2 -2
- package/sdk/src/query/config-query.ts +12 -18
- package/sdk/src/query/decomposed-handlers.test.ts +0 -64
- package/sdk/src/query/index.ts +4 -68
- package/sdk/src/query/init.test.ts +0 -64
- package/sdk/src/query/init.ts +0 -189
- package/sdk/src/query/normalize-query-command.ts +0 -2
- package/sdk/src/query/profile.test.ts +0 -43
- package/sdk/src/query/profile.ts +1 -141
- package/sdk/src/query/state-mutation.ts +18 -0
- package/sdk/src/runtime-health.ts +3 -3
- package/agents/gsd-ai-researcher.md +0 -133
- package/agents/gsd-doc-classifier.md +0 -168
- package/agents/gsd-doc-synthesizer.md +0 -204
- package/agents/gsd-doc-verifier.md +0 -217
- package/agents/gsd-doc-writer.md +0 -615
- package/agents/gsd-domain-researcher.md +0 -153
- package/agents/gsd-eval-auditor.md +0 -191
- package/agents/gsd-eval-planner.md +0 -154
- package/agents/gsd-framework-selector.md +0 -160
- package/agents/gsd-intel-updater.md +0 -334
- package/agents/gsd-nyquist-auditor.md +0 -203
- package/agents/gsd-ui-auditor.md +0 -495
- package/agents/gsd-ui-checker.md +0 -309
- package/agents/gsd-ui-researcher.md +0 -380
- package/agents/gsd-user-profiler.md +0 -171
- package/commands/gsd/ai-integration-phase.md +0 -36
- package/commands/gsd/analyze-dependencies.md +0 -34
- package/commands/gsd/audit-fix.md +0 -33
- package/commands/gsd/audit-milestone.md +0 -36
- package/commands/gsd/audit-uat.md +0 -24
- package/commands/gsd/docs-update.md +0 -48
- package/commands/gsd/eval-review.md +0 -32
- package/commands/gsd/explore.md +0 -27
- package/commands/gsd/extract_learnings.md +0 -22
- package/commands/gsd/forensics.md +0 -56
- package/commands/gsd/from-gsd2.md +0 -47
- package/commands/gsd/graphify.md +0 -201
- package/commands/gsd/import.md +0 -37
- package/commands/gsd/inbox.md +0 -38
- package/commands/gsd/ingest-docs.md +0 -42
- package/commands/gsd/intel.md +0 -179
- package/commands/gsd/join-discord.md +0 -19
- package/commands/gsd/list-phase-assumptions.md +0 -46
- package/commands/gsd/list-workspaces.md +0 -19
- package/commands/gsd/manager.md +0 -40
- package/commands/gsd/milestone-summary.md +0 -51
- package/commands/gsd/new-workspace.md +0 -44
- package/commands/gsd/plan-milestone-gaps.md +0 -34
- package/commands/gsd/plan-review-convergence.md +0 -52
- package/commands/gsd/plant-seed.md +0 -28
- package/commands/gsd/profile-user.md +0 -46
- package/commands/gsd/reapply-patches.md +0 -331
- package/commands/gsd/remove-workspace.md +0 -26
- package/commands/gsd/review.md +0 -40
- package/commands/gsd/scan.md +0 -26
- package/commands/gsd/secure-phase.md +0 -35
- package/commands/gsd/session-report.md +0 -19
- package/commands/gsd/set-profile.md +0 -12
- package/commands/gsd/ship.md +0 -23
- package/commands/gsd/sketch-wrap-up.md +0 -31
- package/commands/gsd/sketch.md +0 -49
- package/commands/gsd/spec-phase.md +0 -62
- package/commands/gsd/spike-wrap-up.md +0 -31
- package/commands/gsd/spike.md +0 -46
- package/commands/gsd/stats.md +0 -18
- package/commands/gsd/sync-skills.md +0 -19
- package/commands/gsd/thread.md +0 -227
- package/commands/gsd/ui-phase.md +0 -34
- package/commands/gsd/ui-review.md +0 -32
- package/commands/gsd/ultraplan-phase.md +0 -33
- package/commands/gsd/update.md +0 -37
- package/commands/gsd/validate-phase.md +0 -35
- package/commands/gsd/workstreams.md +0 -69
- package/get-shit-done/bin/lib/docs.cjs +0 -267
- package/get-shit-done/bin/lib/graphify.cjs +0 -494
- package/get-shit-done/bin/lib/gsd2-import.cjs +0 -511
- package/get-shit-done/bin/lib/intel.cjs +0 -639
- package/get-shit-done/bin/lib/profile-output.cjs +0 -1080
- package/get-shit-done/bin/lib/profile-pipeline.cjs +0 -539
- package/get-shit-done/bin/lib/workstream.cjs +0 -495
- package/get-shit-done/references/ai-evals.md +0 -156
- package/get-shit-done/references/ai-frameworks.md +0 -186
- package/get-shit-done/references/doc-conflict-engine.md +0 -91
- package/get-shit-done/references/model-profile-resolution.md +0 -38
- package/get-shit-done/references/planner-reviews.md +0 -39
- package/get-shit-done/references/sketch-interactivity.md +0 -41
- package/get-shit-done/references/sketch-theme-system.md +0 -94
- package/get-shit-done/references/sketch-tooling.md +0 -45
- package/get-shit-done/references/sketch-variant-patterns.md +0 -81
- package/get-shit-done/references/thinking-models-debug.md +0 -44
- package/get-shit-done/references/thinking-models-execution.md +0 -50
- package/get-shit-done/references/thinking-models-planning.md +0 -62
- package/get-shit-done/references/thinking-models-research.md +0 -50
- package/get-shit-done/references/thinking-models-verification.md +0 -55
- package/get-shit-done/references/thinking-partner.md +0 -96
- package/get-shit-done/references/user-profiling.md +0 -681
- package/get-shit-done/references/workstream-flag.md +0 -111
- package/get-shit-done/templates/AI-SPEC.md +0 -246
- package/get-shit-done/templates/SECURITY.md +0 -61
- package/get-shit-done/templates/UI-SPEC.md +0 -100
- package/get-shit-done/templates/VALIDATION.md +0 -76
- package/get-shit-done/templates/dev-preferences.md +0 -21
- package/get-shit-done/templates/user-profile.md +0 -146
- package/get-shit-done/workflows/ai-integration-phase.md +0 -284
- package/get-shit-done/workflows/analyze-dependencies.md +0 -96
- package/get-shit-done/workflows/audit-fix.md +0 -175
- package/get-shit-done/workflows/audit-milestone.md +0 -340
- package/get-shit-done/workflows/audit-uat.md +0 -109
- package/get-shit-done/workflows/docs-update.md +0 -1155
- package/get-shit-done/workflows/eval-review.md +0 -155
- package/get-shit-done/workflows/explore.md +0 -141
- package/get-shit-done/workflows/extract_learnings.md +0 -242
- package/get-shit-done/workflows/forensics.md +0 -265
- package/get-shit-done/workflows/import.md +0 -246
- package/get-shit-done/workflows/inbox.md +0 -387
- package/get-shit-done/workflows/ingest-docs.md +0 -328
- package/get-shit-done/workflows/list-phase-assumptions.md +0 -178
- package/get-shit-done/workflows/list-workspaces.md +0 -56
- package/get-shit-done/workflows/manager.md +0 -365
- package/get-shit-done/workflows/milestone-summary.md +0 -223
- package/get-shit-done/workflows/new-workspace.md +0 -239
- package/get-shit-done/workflows/plan-milestone-gaps.md +0 -273
- package/get-shit-done/workflows/plan-review-convergence.md +0 -254
- package/get-shit-done/workflows/plant-seed.md +0 -172
- package/get-shit-done/workflows/profile-user.md +0 -452
- package/get-shit-done/workflows/remove-workspace.md +0 -92
- package/get-shit-done/workflows/review.md +0 -344
- package/get-shit-done/workflows/scan.md +0 -102
- package/get-shit-done/workflows/secure-phase.md +0 -166
- package/get-shit-done/workflows/session-report.md +0 -146
- package/get-shit-done/workflows/ship.md +0 -302
- package/get-shit-done/workflows/sketch-wrap-up.md +0 -283
- package/get-shit-done/workflows/sketch.md +0 -286
- package/get-shit-done/workflows/spec-phase.md +0 -262
- package/get-shit-done/workflows/spike-wrap-up.md +0 -281
- package/get-shit-done/workflows/spike.md +0 -362
- package/get-shit-done/workflows/stats.md +0 -60
- package/get-shit-done/workflows/sync-skills.md +0 -182
- package/get-shit-done/workflows/ui-phase.md +0 -323
- package/get-shit-done/workflows/ui-review.md +0 -190
- package/get-shit-done/workflows/ultraplan-phase.md +0 -189
- package/get-shit-done/workflows/update.md +0 -587
- package/get-shit-done/workflows/validate-phase.md +0 -176
- package/hooks/dist/gsd-check-update-worker.js +0 -108
- package/hooks/dist/gsd-check-update.js +0 -63
- package/hooks/gsd-check-update-worker.js +0 -108
- package/hooks/gsd-check-update.js +0 -63
- package/sdk/src/golden/fixtures/profile-sample-sessions/demo-project/sample.jsonl +0 -3
- package/sdk/src/query/docs-init.ts +0 -257
- package/sdk/src/query/intel.test.ts +0 -90
- package/sdk/src/query/intel.ts +0 -404
- package/sdk/src/query/profile-extract-messages.ts +0 -247
- package/sdk/src/query/profile-output.ts +0 -908
- package/sdk/src/query/profile-questionnaire-data.ts +0 -181
- package/sdk/src/query/profile-sample.ts +0 -184
- package/sdk/src/query/profile-scan-sessions.ts +0 -174
- package/sdk/src/query/workspace.test.ts +0 -119
- package/sdk/src/query/workspace.ts +0 -131
- package/sdk/src/query/workstream.test.ts +0 -51
- package/sdk/src/query/workstream.ts +0 -434
package/agents/gsd-planner.md
CHANGED
|
@@ -18,7 +18,6 @@ Spawned by:
|
|
|
18
18
|
- `/gsd-plan-phase` orchestrator (standard phase planning)
|
|
19
19
|
- `/gsd-plan-phase --gaps` orchestrator (gap closure from verification failures)
|
|
20
20
|
- `/gsd-plan-phase` in revision mode (updating plans based on checker feedback)
|
|
21
|
-
- `/gsd-plan-phase --reviews` orchestrator (replanning with cross-AI review feedback)
|
|
22
21
|
|
|
23
22
|
Your job: Produce PLAN.md files that Claude executors can implement without interpretation. Plans are prompts, not documents that become prompts.
|
|
24
23
|
|
|
@@ -438,20 +437,6 @@ Output: [Artifacts created]
|
|
|
438
437
|
|
|
439
438
|
</tasks>
|
|
440
439
|
|
|
441
|
-
<threat_model>
|
|
442
|
-
## Trust Boundaries
|
|
443
|
-
|
|
444
|
-
| Boundary | Description |
|
|
445
|
-
|----------|-------------|
|
|
446
|
-
| {e.g., client→API} | {untrusted input crosses here} |
|
|
447
|
-
|
|
448
|
-
## STRIDE Threat Register
|
|
449
|
-
|
|
450
|
-
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
|
451
|
-
|-----------|----------|-----------|-------------|-----------------|
|
|
452
|
-
| T-{phase}-01 | {S/T/R/I/D/E} | {function/endpoint/file} | mitigate | {specific: e.g., "validate input with zod at route entry"} |
|
|
453
|
-
| T-{phase}-02 | {category} | {component} | accept | {rationale: e.g., "no PII, low-value target"} |
|
|
454
|
-
</threat_model>
|
|
455
440
|
|
|
456
441
|
<verification>
|
|
457
442
|
[Overall phase checks]
|
|
@@ -584,7 +569,6 @@ Only include what Claude literally cannot do.
|
|
|
584
569
|
**Step 0: Extract Requirement IDs**
|
|
585
570
|
Read ROADMAP.md `**Requirements:**` line for this phase. Strip brackets if present (e.g., `[AUTH-01, AUTH-02]` → `AUTH-01, AUTH-02`). Distribute requirement IDs across plans — each plan's `requirements` frontmatter field lists the IDs its tasks address. Every requirement ID MUST appear in at least one plan. Plans with an empty `requirements` field are invalid.
|
|
586
571
|
|
|
587
|
-
**Security (when `security_enforcement` enabled — absent = enabled):** Identify trust boundaries in this phase's scope. Map STRIDE categories to applicable tech stack from RESEARCH.md security domain. For each threat: assign disposition (mitigate if ASVS L1 requires it, accept if low risk, transfer if third-party). Every plan MUST include `<threat_model>` when security_enforcement is enabled.
|
|
588
572
|
|
|
589
573
|
**Step 1: State the Goal**
|
|
590
574
|
Take phase goal from ROADMAP.md. Must be outcome-shaped, not task-shaped.
|
|
@@ -795,11 +779,6 @@ See `get-shit-done/references/planner-revision.md`. Load this file at the
|
|
|
795
779
|
start of execution when `<revision_context>` is provided by the orchestrator.
|
|
796
780
|
</revision_mode>
|
|
797
781
|
|
|
798
|
-
<reviews_mode>
|
|
799
|
-
See `get-shit-done/references/planner-reviews.md`. Load this file at the
|
|
800
|
-
start of execution when `--reviews` flag is present or reviews mode is active.
|
|
801
|
-
</reviews_mode>
|
|
802
|
-
|
|
803
782
|
<execution_flow>
|
|
804
783
|
|
|
805
784
|
<step name="load_project_state" priority="first">
|
|
@@ -826,7 +805,6 @@ Check the invocation mode and load the relevant reference file:
|
|
|
826
805
|
|
|
827
806
|
- If `--gaps` flag or gap_closure context present: Read `get-shit-done/references/planner-gap-closure.md`
|
|
828
807
|
- If `<revision_context>` provided by orchestrator: Read `get-shit-done/references/planner-revision.md`
|
|
829
|
-
- If `--reviews` flag present or reviews mode active: Read `get-shit-done/references/planner-reviews.md`
|
|
830
808
|
- Standard planning mode: no additional file to read
|
|
831
809
|
|
|
832
810
|
Load the file before proceeding to planning steps. The reference file contains the full
|
|
@@ -854,42 +832,6 @@ If exists, load relevant documents by phase type:
|
|
|
854
832
|
| (default) | STACK.md, ARCHITECTURE.md |
|
|
855
833
|
</step>
|
|
856
834
|
|
|
857
|
-
<step name="load_graph_context">
|
|
858
|
-
Check for knowledge graph:
|
|
859
|
-
|
|
860
|
-
```bash
|
|
861
|
-
ls .planning/graphs/graph.json 2>/dev/null
|
|
862
|
-
```
|
|
863
|
-
|
|
864
|
-
If graph.json exists, check freshness:
|
|
865
|
-
|
|
866
|
-
```bash
|
|
867
|
-
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" graphify status
|
|
868
|
-
```
|
|
869
|
-
|
|
870
|
-
If the status response has `stale: true`, note for later: "Graph is {age_hours}h old -- treat semantic relationships as approximate." Include this annotation inline with any graph context injected below.
|
|
871
|
-
|
|
872
|
-
Query the graph for phase-relevant dependency context (single query per D-06):
|
|
873
|
-
|
|
874
|
-
```bash
|
|
875
|
-
node "$HOME/.claude/get-shit-done/bin/gsd-tools.cjs" graphify query "<phase-goal-keyword>" --budget 2000
|
|
876
|
-
```
|
|
877
|
-
|
|
878
|
-
(graphify is not exposed on `gsd-remix-sdk query` yet; use `gsd-tools.cjs` for graphify only.)
|
|
879
|
-
|
|
880
|
-
Use the keyword that best captures the phase goal. Examples:
|
|
881
|
-
- Phase "User Authentication" -> query term "auth"
|
|
882
|
-
- Phase "Payment Integration" -> query term "payment"
|
|
883
|
-
- Phase "Database Migration" -> query term "migration"
|
|
884
|
-
|
|
885
|
-
If the query returns nodes and edges, incorporate as dependency context for planning:
|
|
886
|
-
- Which modules/files are semantically related to this phase's domain
|
|
887
|
-
- Which subsystems may be affected by changes in this phase
|
|
888
|
-
- Cross-document relationships that inform task ordering and wave structure
|
|
889
|
-
|
|
890
|
-
If no results or graph.json absent, continue without graph context.
|
|
891
|
-
</step>
|
|
892
|
-
|
|
893
835
|
<step name="identify_phase">
|
|
894
836
|
```bash
|
|
895
837
|
cat .planning/ROADMAP.md
|
|
@@ -973,13 +915,14 @@ cat "$phase_dir"/*-DISCOVERY.md 2>/dev/null # From mandatory discovery
|
|
|
973
915
|
|
|
974
916
|
**If RESEARCH.md exists (has_research=true from init):** Use standard_stack, architecture_patterns, dont_hand_roll, common_pitfalls.
|
|
975
917
|
|
|
918
|
+
**[NEEDS DECISION] protocol:** Before finalizing the plan, read ALL `[NEEDS DECISION]` items and LOW-confidence recommendations from RESEARCH.md/SUMMARY.md. For each: either (a) create a `checkpoint:decision` task to resolve it, or (b) document why the risk is acceptable in the plan's deviation notes. LOW-confidence items that are silently accepted become undocumented technical debt.
|
|
919
|
+
|
|
920
|
+
**Gap-closure root cause rule (--gaps plans):** Before writing a fix plan, apply a single "why" round: Why did this gap occur? Was it a plan deficiency (wrong task), an execution miss (correct task, wrong implementation), or a changed assumption (environment/dependency shift)? The fix plan must target the root cause category, not just the symptom.
|
|
921
|
+
|
|
976
922
|
**Architectural Responsibility Map sanity check:** If RESEARCH.md has an `## Architectural Responsibility Map`, cross-reference each task against it — fix tier misassignments before finalizing.
|
|
977
923
|
</step>
|
|
978
924
|
|
|
979
925
|
<step name="break_into_tasks">
|
|
980
|
-
At decision points during plan creation, apply structured reasoning:
|
|
981
|
-
@~/.claude/get-shit-done/references/thinking-models-planning.md
|
|
982
|
-
|
|
983
926
|
Decompose phase into tasks. **Think dependencies first, not sequence.**
|
|
984
927
|
|
|
985
928
|
For each task:
|
|
@@ -1232,8 +1175,6 @@ Phase planning complete when:
|
|
|
1232
1175
|
- [ ] Wave structure maximizes parallelism
|
|
1233
1176
|
- [ ] PLAN file(s) committed to git
|
|
1234
1177
|
- [ ] User knows next steps and wave structure
|
|
1235
|
-
- [ ] `<threat_model>` present with STRIDE register (when `security_enforcement` enabled)
|
|
1236
|
-
- [ ] Every threat has a disposition (mitigate / accept / transfer)
|
|
1237
1178
|
- [ ] Mitigations reference specific implementation (not generic advice)
|
|
1238
1179
|
|
|
1239
1180
|
## Gap Closure Mode
|
package/agents/gsd-roadmapper.md
CHANGED
|
@@ -336,35 +336,6 @@ After roadmap creation, REQUIREMENTS.md gets updated with phase mappings:
|
|
|
336
336
|
|
|
337
337
|
**The `### Phase X:` headers are parsed by downstream tools.** If you only write the summary checklist, phase lookups will fail.
|
|
338
338
|
|
|
339
|
-
### UI Phase Detection
|
|
340
|
-
|
|
341
|
-
After writing phase details, scan each phase's goal, name, requirements, and success criteria for UI/frontend keywords. If a phase matches, add a `**UI hint**: yes` annotation to that phase's detail section (after `**Plans**`).
|
|
342
|
-
|
|
343
|
-
**Detection keywords** (case-insensitive):
|
|
344
|
-
|
|
345
|
-
```
|
|
346
|
-
UI, interface, frontend, component, layout, page, screen, view, form,
|
|
347
|
-
dashboard, widget, CSS, styling, responsive, navigation, menu, modal,
|
|
348
|
-
sidebar, header, footer, theme, design system, Tailwind, React, Vue,
|
|
349
|
-
Svelte, Next.js, Nuxt
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
**Example annotated phase:**
|
|
353
|
-
|
|
354
|
-
```markdown
|
|
355
|
-
### Phase 3: Dashboard & Analytics
|
|
356
|
-
**Goal**: Users can view activity metrics and manage settings
|
|
357
|
-
**Depends on**: Phase 2
|
|
358
|
-
**Requirements**: DASH-01, DASH-02
|
|
359
|
-
**Success Criteria** (what must be TRUE):
|
|
360
|
-
1. User can view a dashboard with key metrics
|
|
361
|
-
2. User can filter analytics by date range
|
|
362
|
-
**Plans**: TBD
|
|
363
|
-
**UI hint**: yes
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
This annotation is consumed by downstream workflows (`new-project`, `progress`) to suggest `/gsd-ui-phase` at the right time. Phases without UI indicators omit the annotation entirely.
|
|
367
|
-
|
|
368
339
|
### 3. Progress Table
|
|
369
340
|
|
|
370
341
|
```markdown
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gsd-security-auditor
|
|
3
|
-
description:
|
|
3
|
+
description: Reviews a phase's real diff for security issues (OWASP-style), producing severity-graded findings. Advisory fallback reviewer spawned by execute-phase security_review_gate when no company security skill is available.
|
|
4
4
|
tools:
|
|
5
5
|
- Read
|
|
6
|
-
- Write
|
|
7
|
-
- Edit
|
|
8
6
|
- Bash
|
|
9
7
|
- Glob
|
|
10
8
|
- Grep
|
|
@@ -12,144 +10,94 @@ color: "#EF4444"
|
|
|
12
10
|
---
|
|
13
11
|
|
|
14
12
|
<role>
|
|
15
|
-
|
|
13
|
+
You are a diff-scoped security reviewer. Your input is a changed-file list and the corresponding git diff for one phase of work. Review exactly what changed — not the whole codebase — for security defects, and return severity-graded findings.
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
You are the generic fallback reviewer: you run only when no dedicated security-review skill is installed in the user's environment. You are advisory — your findings inform the developer; they never block execution flow.
|
|
18
16
|
|
|
19
17
|
**Mandatory Initial Read:** If prompt contains `<required_reading>`, load ALL listed files before any action.
|
|
20
18
|
|
|
21
|
-
**Implementation files are READ-ONLY.**
|
|
19
|
+
**Implementation files are READ-ONLY.** You never patch code. Findings are your only output.
|
|
22
20
|
</role>
|
|
23
21
|
|
|
22
|
+
<inputs>
|
|
23
|
+
The orchestrator provides:
|
|
24
|
+
- `<changed_files>` — the phase's changed-file list (resolution order upstream: --files > SUMMARY.md files_modified > git diff --name-only)
|
|
25
|
+
- `<diff>` — the unified git diff for those files, or a ref to run `git diff` against
|
|
26
|
+
- `<trigger_reason>` — why this review fired (hard rule | semantic signal | security_review: "always")
|
|
27
|
+
- Optional `<summary_surface>` — the executor SUMMARY's "Security-Relevant Surface" section, if present
|
|
28
|
+
</inputs>
|
|
29
|
+
|
|
24
30
|
<adversarial_stance>
|
|
25
|
-
**FORCE stance:** Assume
|
|
31
|
+
**FORCE stance:** Assume the diff introduces at least one security defect until the review proves otherwise. Your starting hypothesis: the change is unsafe. Surface every confirmed and plausible issue — advisory does not mean lenient.
|
|
26
32
|
|
|
27
|
-
**Common failure modes — how
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
+
**Common failure modes — how diff reviewers go soft:**
|
|
34
|
+
- Skimming large diffs and reviewing only the first few hunks
|
|
35
|
+
- Accepting a sanitization call as sufficient without checking it covers the actual sink
|
|
36
|
+
- Treating framework defaults as protection without confirming they apply to this code path
|
|
37
|
+
- Downgrading a finding because "the author probably knew" — judge the code, not the intent
|
|
38
|
+
- Reporting nothing because reachability was hard to confirm, instead of reporting with stated uncertainty
|
|
33
39
|
|
|
34
40
|
**Required finding classification:**
|
|
35
|
-
- **BLOCKER** —
|
|
36
|
-
- **WARNING** —
|
|
37
|
-
Every
|
|
41
|
+
- **BLOCKER** — critical/high severity: exploitable under realistic conditions; recommend fixing before merge/ship
|
|
42
|
+
- **WARNING** — medium/low severity: weakened control, precondition-gated issue, or hardening gap
|
|
43
|
+
Every reviewed hunk resolves to: clean, WARNING, or BLOCKER.
|
|
38
44
|
</adversarial_stance>
|
|
39
45
|
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Read ALL files from `<required_reading>`. Extract:
|
|
44
|
-
- PLAN.md `<threat_model>` block: full threat register with IDs, categories, dispositions, mitigation plans
|
|
45
|
-
- SUMMARY.md `## Threat Flags` section: new attack surface detected by executor during implementation
|
|
46
|
-
- `<config>` block: `asvs_level` (1/2/3), `block_on` (open / unregistered / none)
|
|
47
|
-
- Implementation files: exports, auth patterns, input handling, data flows
|
|
48
|
-
|
|
49
|
-
**Context budget:** Load project skills first (lightweight). Read implementation files incrementally — load only what each check requires, not the full codebase upfront.
|
|
50
|
-
|
|
51
|
-
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists:
|
|
52
|
-
1. List available skills (subdirectories)
|
|
53
|
-
2. Read `SKILL.md` for each skill (lightweight index ~130 lines)
|
|
54
|
-
3. Load specific `rules/*.md` files as needed during implementation
|
|
55
|
-
4. Do NOT load full `AGENTS.md` files (100KB+ context cost)
|
|
56
|
-
5. Apply skill rules to identify project-specific security patterns, required wrappers, and forbidden patterns.
|
|
57
|
-
|
|
58
|
-
This ensures project-specific patterns, conventions, and best practices are applied during execution.
|
|
59
|
-
</step>
|
|
60
|
-
|
|
61
|
-
<step name="analyze_threats">
|
|
62
|
-
For each threat in `<threat_model>`, determine verification method by disposition:
|
|
46
|
+
<project_context>
|
|
47
|
+
**Project skills:** Check `.claude/skills/` or `.agents/skills/` directory if either exists: read each skill's `SKILL.md` (lightweight index) and load specific `rules/*.md` only as needed. Do NOT load full AGENTS.md files. Apply skill rules to recognize project-specific security patterns, required wrappers, and forbidden patterns.
|
|
48
|
+
</project_context>
|
|
63
49
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
| `mitigate` | Grep for mitigation pattern in files cited in mitigation plan |
|
|
67
|
-
| `accept` | Verify entry present in SECURITY.md accepted risks log |
|
|
68
|
-
| `transfer` | Verify transfer documentation present (insurance, vendor SLA, etc.) |
|
|
50
|
+
<review_protocol>
|
|
51
|
+
1. **Anchor on the diff.** Read the diff first. Open a full file with Read only when the diff lacks the context to judge a hunk (e.g., to see how a variable is sourced or where a function is called).
|
|
69
52
|
|
|
70
|
-
|
|
71
|
-
|
|
53
|
+
2. **Review each hunk against the OWASP-style checklist:**
|
|
54
|
+
- Injection: SQL/NoSQL/command/path concatenation from non-constant input; template injection
|
|
55
|
+
- Broken auth/authz: missing or weakened checks on new/changed endpoints; session handling changes; privilege checks removed or bypassed
|
|
56
|
+
- Sensitive data exposure: secrets/PII/credentials written to logs, error messages, or responses; secrets committed in config
|
|
57
|
+
- XSS / unsafe rendering: unescaped interpolation into HTML, `dangerouslySetInnerHTML`, `innerHTML`, `v-html`
|
|
58
|
+
- SSRF: outbound requests to URLs influenced by user input (BFF/proxy patterns especially)
|
|
59
|
+
- Unsafe deserialization / file upload handling / archive extraction
|
|
60
|
+
- Open redirects: redirect targets from user input without allowlisting
|
|
61
|
+
- CORS / Cookie / security-header weakening: wildcards added, `HttpOnly`/`Secure`/`SameSite` removed
|
|
62
|
+
- Crypto misuse: hand-rolled crypto, weak algorithms, static IVs/salts, non-constant-time comparisons
|
|
63
|
+
- Dependency risk: newly added packages — flag unfamiliar or typosquat-suspect names and pinned-to-`latest` installs
|
|
64
|
+
- Multi-tenant boundaries: tenant/org/account scoping missing from new queries or endpoints
|
|
65
|
+
- Webhook/callback verification: signature checks absent or bypassable
|
|
66
|
+
- CI/build/container changes: new capabilities, mounted secrets, curl-pipe-sh, privilege escalation in Dockerfile/CI configs
|
|
72
67
|
|
|
73
|
-
|
|
74
|
-
For each `mitigate` threat: grep for declared mitigation pattern in cited files → found = `CLOSED`, not found = `OPEN`.
|
|
75
|
-
For `accept` threats: check SECURITY.md accepted risks log → entry present = `CLOSED`, absent = `OPEN`.
|
|
76
|
-
For `transfer` threats: check for transfer documentation → present = `CLOSED`, absent = `OPEN`.
|
|
68
|
+
3. **Judge in context.** A pattern match is not a finding. Confirm the tainted data can actually reach the sink, and name the entry point in the finding. If reachability cannot be confirmed from the diff plus a few file reads, report at lower severity with the uncertainty stated.
|
|
77
69
|
|
|
78
|
-
|
|
70
|
+
4. **Stay in scope.** Pre-existing issues in untouched code are out of scope unless the diff makes them exploitable. Do not expand into a whole-repo audit.
|
|
71
|
+
</review_protocol>
|
|
79
72
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
</execution_flow>
|
|
84
|
-
|
|
85
|
-
<structured_returns>
|
|
86
|
-
|
|
87
|
-
## SECURED
|
|
73
|
+
<output_format>
|
|
74
|
+
Return findings directly as your final message (the orchestrator relays them; you do not write files):
|
|
88
75
|
|
|
89
76
|
```markdown
|
|
90
|
-
##
|
|
77
|
+
## Security Review — Phase {N}
|
|
91
78
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
**ASVS Level:** {1/2/3}
|
|
79
|
+
Trigger: {trigger_reason}
|
|
80
|
+
Scope: {file count} files, {diff line count} diff lines
|
|
95
81
|
|
|
96
|
-
###
|
|
97
|
-
| Threat ID | Category | Disposition | Evidence |
|
|
98
|
-
|-----------|----------|-------------|----------|
|
|
99
|
-
| {id} | {category} | {mitigate/accept/transfer} | {file:line or doc reference} |
|
|
82
|
+
### Findings
|
|
100
83
|
|
|
101
|
-
|
|
102
|
-
|
|
84
|
+
| # | Severity | File:Line | Category | Finding | Suggested Fix |
|
|
85
|
+
|---|----------|-----------|----------|---------|---------------|
|
|
86
|
+
| 1 | critical / high / medium / low | src/x.ts:42 | Injection | {what and why exploitable} | {concrete fix} |
|
|
103
87
|
|
|
104
|
-
|
|
88
|
+
### Notes
|
|
89
|
+
- {uncertainties, unreachable-but-suspicious patterns, out-of-scope observations worth a ticket}
|
|
105
90
|
```
|
|
106
91
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
```markdown
|
|
110
|
-
## OPEN_THREATS
|
|
111
|
-
|
|
112
|
-
**Phase:** {N} — {name}
|
|
113
|
-
**Closed:** {M}/{total} | **Open:** {K}/{total}
|
|
114
|
-
**ASVS Level:** {1/2/3}
|
|
115
|
-
|
|
116
|
-
### Closed
|
|
117
|
-
| Threat ID | Category | Disposition | Evidence |
|
|
118
|
-
|-----------|----------|-------------|----------|
|
|
119
|
-
| {id} | {category} | {disposition} | {evidence} |
|
|
120
|
-
|
|
121
|
-
### Open
|
|
122
|
-
| Threat ID | Category | Mitigation Expected | Files Searched |
|
|
123
|
-
|-----------|----------|---------------------|----------------|
|
|
124
|
-
| {id} | {category} | {pattern not found} | {file paths} |
|
|
125
|
-
|
|
126
|
-
Next: Implement mitigations or document as accepted in SECURITY.md accepted risks log, then re-run /gsd-secure-phase.
|
|
127
|
-
|
|
128
|
-
SECURITY.md: {path}
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## ESCALATE
|
|
132
|
-
|
|
133
|
-
```markdown
|
|
134
|
-
## ESCALATE
|
|
135
|
-
|
|
136
|
-
**Phase:** {N} — {name}
|
|
137
|
-
**Closed:** 0/{total}
|
|
138
|
-
|
|
139
|
-
### Details
|
|
140
|
-
| Threat ID | Reason Blocked | Suggested Action |
|
|
141
|
-
|-----------|----------------|------------------|
|
|
142
|
-
| {id} | {reason} | {action} |
|
|
143
|
-
```
|
|
92
|
+
If nothing is found: `## Security Review — Phase {N}` + `No security findings in this diff.` + the Scope line.
|
|
144
93
|
|
|
145
|
-
|
|
94
|
+
Severity guide: **critical** = remotely exploitable with material impact, fix before merge; **high** = exploitable under realistic conditions; **medium** = weakens a control or needs specific preconditions; **low** = hardening/hygiene.
|
|
95
|
+
</output_format>
|
|
146
96
|
|
|
147
97
|
<success_criteria>
|
|
148
|
-
- [ ]
|
|
149
|
-
- [ ]
|
|
150
|
-
- [ ]
|
|
151
|
-
- [ ] Threat flags from SUMMARY.md `## Threat Flags` incorporated
|
|
98
|
+
- [ ] Review confined to the provided diff scope
|
|
99
|
+
- [ ] Every finding names file:line, category, severity, and a concrete fix
|
|
100
|
+
- [ ] Reachability judged, not pattern-matched; uncertainty stated when present
|
|
152
101
|
- [ ] Implementation files never modified
|
|
153
|
-
- [ ] SECURITY.md
|
|
154
|
-
- [ ] Structured return: SECURED / OPEN_THREATS / ESCALATE
|
|
102
|
+
- [ ] Findings returned in the structured format (no SECURITY.md side effects)
|
|
155
103
|
</success_criteria>
|
package/agents/gsd-verifier.md
CHANGED
|
@@ -70,9 +70,6 @@ Then verify each level against the actual codebase.
|
|
|
70
70
|
|
|
71
71
|
<verification_process>
|
|
72
72
|
|
|
73
|
-
At verification decision points, apply structured reasoning:
|
|
74
|
-
@~/.claude/get-shit-done/references/thinking-models-verification.md
|
|
75
|
-
|
|
76
73
|
At verification decision points, reference calibration examples:
|
|
77
74
|
@~/.claude/get-shit-done/references/few-shot-examples/verifier.md
|
|
78
75
|
|
package/bin/install.js
CHANGED
|
@@ -4295,7 +4295,7 @@ function copyWithPathReplacement(srcDir, destDir, pathPrefix, runtime, isCommand
|
|
|
4295
4295
|
}
|
|
4296
4296
|
}
|
|
4297
4297
|
|
|
4298
|
-
function copySdkBundleToRuntime(srcRoot, gsdRuntimeDir) {
|
|
4298
|
+
function copySdkBundleToRuntime(srcRoot, gsdRuntimeDir, runtime, pathPrefix, isGlobal) {
|
|
4299
4299
|
const sdkSrc = path.join(srcRoot, 'sdk');
|
|
4300
4300
|
const sdkDest = path.join(gsdRuntimeDir, 'sdk');
|
|
4301
4301
|
const sdkEntries = ['src', 'prompts', 'package.json', 'package-lock.json', 'tsconfig.json'];
|
|
@@ -4313,7 +4313,15 @@ function copySdkBundleToRuntime(srcRoot, gsdRuntimeDir) {
|
|
|
4313
4313
|
for (const entry of sdkEntries) {
|
|
4314
4314
|
const source = path.join(sdkSrc, entry);
|
|
4315
4315
|
if (!fs.existsSync(source)) continue;
|
|
4316
|
-
|
|
4316
|
+
// The prompts/ mirror is markdown that must have Claude references (CLAUDE.md,
|
|
4317
|
+
// .claude/) rewritten for non-Claude runtimes (#2112). Route it through the same
|
|
4318
|
+
// transform used for the rest of the get-shit-done tree. SDK source and manifests
|
|
4319
|
+
// are copied verbatim so the bundled repair source stays a faithful rebuild input.
|
|
4320
|
+
if (entry === 'prompts' && runtime && runtime !== 'claude') {
|
|
4321
|
+
copyWithPathReplacement(source, path.join(sdkDest, entry), pathPrefix, runtime, false, isGlobal);
|
|
4322
|
+
} else {
|
|
4323
|
+
fs.cpSync(source, path.join(sdkDest, entry), { recursive: true });
|
|
4324
|
+
}
|
|
4317
4325
|
}
|
|
4318
4326
|
|
|
4319
4327
|
return true;
|
|
@@ -4801,7 +4809,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
4801
4809
|
// 4. Remove GSD hooks
|
|
4802
4810
|
const hooksDir = path.join(targetDir, 'hooks');
|
|
4803
4811
|
if (fs.existsSync(hooksDir)) {
|
|
4804
|
-
const gsdHooks = ['gsd-statusline.js', 'gsd-
|
|
4812
|
+
const gsdHooks = ['gsd-statusline.js', 'gsd-context-monitor.js', 'gsd-prompt-guard.js', 'gsd-read-guard.js', 'gsd-read-injection-scanner.js', 'gsd-workflow-guard.js', 'gsd-session-state.sh', 'gsd-validate-commit.sh', 'gsd-phase-boundary.sh'];
|
|
4805
4813
|
let hookCount = 0;
|
|
4806
4814
|
for (const hook of gsdHooks) {
|
|
4807
4815
|
const hookPath = path.join(hooksDir, hook);
|
|
@@ -4853,7 +4861,7 @@ function uninstall(isGlobal, runtime = 'claude') {
|
|
|
4853
4861
|
// Remove GSD hooks from settings — per-hook granularity to preserve
|
|
4854
4862
|
// user hooks that share an entry with a GSD hook (#1755 followup)
|
|
4855
4863
|
const isGsdHookCommand = (cmd) =>
|
|
4856
|
-
cmd && (cmd.includes('gsd-
|
|
4864
|
+
cmd && (cmd.includes('gsd-statusline') ||
|
|
4857
4865
|
cmd.includes('gsd-session-state') || cmd.includes('gsd-context-monitor') ||
|
|
4858
4866
|
cmd.includes('gsd-phase-boundary') || cmd.includes('gsd-prompt-guard') ||
|
|
4859
4867
|
cmd.includes('gsd-read-guard') || cmd.includes('gsd-read-injection-scanner') ||
|
|
@@ -5363,9 +5371,9 @@ function writeManifest(configDir, runtime = 'claude') {
|
|
|
5363
5371
|
|
|
5364
5372
|
/**
|
|
5365
5373
|
* Detect user-modified GSD files by comparing against install manifest.
|
|
5366
|
-
* Backs up modified files to gsd-local-patches/ for
|
|
5374
|
+
* Backs up modified files to gsd-local-patches/ for manual re-merge after reinstall.
|
|
5367
5375
|
* Also saves pristine copies (from manifest) to gsd-pristine/ to enable
|
|
5368
|
-
* three-way merge
|
|
5376
|
+
* a three-way merge (pristine vs user vs new) when re-merging by hand.
|
|
5369
5377
|
*/
|
|
5370
5378
|
function saveLocalPatches(configDir) {
|
|
5371
5379
|
const manifestPath = path.join(configDir, MANIFEST_NAME);
|
|
@@ -5393,7 +5401,7 @@ function saveLocalPatches(configDir) {
|
|
|
5393
5401
|
|
|
5394
5402
|
// Save pristine copies of modified files from the CURRENT install (before wipe)
|
|
5395
5403
|
// These represent the original GSD distribution files that the user then modified.
|
|
5396
|
-
//
|
|
5404
|
+
// These enable a manual three-way merge after reinstall:
|
|
5397
5405
|
// pristine (original) → user's version (what they changed) → new version (after update)
|
|
5398
5406
|
if (modified.length > 0) {
|
|
5399
5407
|
// We need the pristine originals, but the current files on disk are user-modified.
|
|
@@ -5434,13 +5442,6 @@ function reportLocalPatches(configDir, runtime = 'claude') {
|
|
|
5434
5442
|
try { meta = JSON.parse(fs.readFileSync(metaPath, 'utf8')); } catch { return []; }
|
|
5435
5443
|
|
|
5436
5444
|
if (meta.files && meta.files.length > 0) {
|
|
5437
|
-
const reapplyCommand = (runtime === 'opencode' || runtime === 'kilo' || runtime === 'copilot')
|
|
5438
|
-
? '/gsd-reapply-patches'
|
|
5439
|
-
: runtime === 'codex'
|
|
5440
|
-
? '$gsd-reapply-patches'
|
|
5441
|
-
: runtime === 'cursor'
|
|
5442
|
-
? 'gsd-reapply-patches (mention the skill name)'
|
|
5443
|
-
: '/gsd-reapply-patches';
|
|
5444
5445
|
console.log('');
|
|
5445
5446
|
console.log(' ' + yellow + 'Local patches detected' + reset + ' (from v' + meta.from_version + '):');
|
|
5446
5447
|
for (const f of meta.files) {
|
|
@@ -5448,8 +5449,7 @@ function reportLocalPatches(configDir, runtime = 'claude') {
|
|
|
5448
5449
|
}
|
|
5449
5450
|
console.log('');
|
|
5450
5451
|
console.log(' Your modifications are saved in ' + cyan + PATCHES_DIR_NAME + '/' + reset);
|
|
5451
|
-
console.log('
|
|
5452
|
-
console.log(' Or manually compare and merge the files.');
|
|
5452
|
+
console.log(' Manually compare and merge the files into the new version.');
|
|
5453
5453
|
console.log('');
|
|
5454
5454
|
}
|
|
5455
5455
|
return meta.files || [];
|
|
@@ -5729,7 +5729,7 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
5729
5729
|
const skillDest = path.join(targetDir, 'get-shit-done');
|
|
5730
5730
|
const savedGsdArtifacts = preserveUserArtifacts(skillDest, ['USER-PROFILE.md']);
|
|
5731
5731
|
copyWithPathReplacement(skillSrc, skillDest, pathPrefix, runtime, false, isGlobal);
|
|
5732
|
-
const copiedSdkBundle = copySdkBundleToRuntime(src, skillDest);
|
|
5732
|
+
const copiedSdkBundle = copySdkBundleToRuntime(src, skillDest, runtime, pathPrefix, isGlobal);
|
|
5733
5733
|
restoreUserArtifacts(skillDest, savedGsdArtifacts);
|
|
5734
5734
|
if (verifyInstalled(skillDest, 'get-shit-done')) {
|
|
5735
5735
|
console.log(` ${green}✓${reset} Installed get-shit-done`);
|
|
@@ -5896,8 +5896,8 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
5896
5896
|
// Ensure hook files are executable (fixes #1162 — missing +x permission)
|
|
5897
5897
|
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows doesn't support chmod */ }
|
|
5898
5898
|
} else {
|
|
5899
|
-
// .sh hooks carry a gsd-hook-version header
|
|
5900
|
-
//
|
|
5899
|
+
// .sh hooks carry a gsd-hook-version header stamped with the install
|
|
5900
|
+
// version — stamp the version just like .js hooks.
|
|
5901
5901
|
if (entry.endsWith('.sh')) {
|
|
5902
5902
|
let content = fs.readFileSync(srcFile, 'utf8');
|
|
5903
5903
|
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
|
|
@@ -5924,11 +5924,6 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
5924
5924
|
}
|
|
5925
5925
|
}
|
|
5926
5926
|
|
|
5927
|
-
// Clear stale update cache so next session re-evaluates hook versions
|
|
5928
|
-
// Cache lives at ~/.cache/gsd/ (see hooks/gsd-check-update.js line 35-36)
|
|
5929
|
-
const updateCacheFile = path.join(os.homedir(), '.cache', 'gsd', 'gsd-update-check.json');
|
|
5930
|
-
try { fs.unlinkSync(updateCacheFile); } catch (e) { /* cache may not exist yet */ }
|
|
5931
|
-
|
|
5932
5927
|
if (failures.length > 0) {
|
|
5933
5928
|
console.error(`\n ${yellow}Installation incomplete!${reset} Failed: ${failures.join(', ')}`);
|
|
5934
5929
|
process.exit(1);
|
|
@@ -5996,73 +5991,6 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
5996
5991
|
console.log(` ${green}✓${reset} Generated config.toml with ${agentCount} agent roles`);
|
|
5997
5992
|
console.log(` ${green}✓${reset} Generated ${agentCount} agent .toml config files`);
|
|
5998
5993
|
|
|
5999
|
-
// Copy hook files that are referenced in config.toml (#2153)
|
|
6000
|
-
// The main hook-copy block is gated to non-Codex runtimes, but Codex registers
|
|
6001
|
-
// gsd-check-update.js in config.toml — the file must physically exist.
|
|
6002
|
-
const codexHooksSrc = path.join(src, 'hooks', 'dist');
|
|
6003
|
-
if (fs.existsSync(codexHooksSrc)) {
|
|
6004
|
-
const codexHooksDest = path.join(targetDir, 'hooks');
|
|
6005
|
-
fs.mkdirSync(codexHooksDest, { recursive: true });
|
|
6006
|
-
const configDirReplacement = getConfigDirFromHome(runtime, isGlobal);
|
|
6007
|
-
for (const entry of fs.readdirSync(codexHooksSrc)) {
|
|
6008
|
-
const srcFile = path.join(codexHooksSrc, entry);
|
|
6009
|
-
if (!fs.statSync(srcFile).isFile()) continue;
|
|
6010
|
-
const destFile = path.join(codexHooksDest, entry);
|
|
6011
|
-
if (entry.endsWith('.js')) {
|
|
6012
|
-
let content = fs.readFileSync(srcFile, 'utf8');
|
|
6013
|
-
content = content.replace(/'\.claude'/g, configDirReplacement);
|
|
6014
|
-
content = content.replace(/\/\.claude\//g, `/${getDirName(runtime)}/`);
|
|
6015
|
-
content = content.replace(/\.claude\//g, `${getDirName(runtime)}/`);
|
|
6016
|
-
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
|
|
6017
|
-
fs.writeFileSync(destFile, content);
|
|
6018
|
-
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
|
|
6019
|
-
} else {
|
|
6020
|
-
if (entry.endsWith('.sh')) {
|
|
6021
|
-
let content = fs.readFileSync(srcFile, 'utf8');
|
|
6022
|
-
content = content.replace(/\{\{GSD_VERSION\}\}/g, pkg.version);
|
|
6023
|
-
fs.writeFileSync(destFile, content);
|
|
6024
|
-
try { fs.chmodSync(destFile, 0o755); } catch (e) { /* Windows */ }
|
|
6025
|
-
} else {
|
|
6026
|
-
fs.copyFileSync(srcFile, destFile);
|
|
6027
|
-
}
|
|
6028
|
-
}
|
|
6029
|
-
}
|
|
6030
|
-
console.log(` ${green}✓${reset} Installed hooks`);
|
|
6031
|
-
}
|
|
6032
|
-
|
|
6033
|
-
// Add Codex hooks (SessionStart for update checking) — requires codex_hooks feature flag
|
|
6034
|
-
const configPath = path.join(targetDir, 'config.toml');
|
|
6035
|
-
try {
|
|
6036
|
-
let configContent = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf-8') : '';
|
|
6037
|
-
const eol = detectLineEnding(configContent);
|
|
6038
|
-
const codexHooksFeature = ensureCodexHooksFeature(configContent);
|
|
6039
|
-
configContent = setManagedCodexHooksOwnership(codexHooksFeature.content, codexHooksFeature.ownership);
|
|
6040
|
-
|
|
6041
|
-
// Add SessionStart hook for update checking
|
|
6042
|
-
const updateCheckScript = path.resolve(targetDir, 'hooks', 'gsd-check-update.js').replace(/\\/g, '/');
|
|
6043
|
-
const hookBlock =
|
|
6044
|
-
`${eol}# GSD Hooks${eol}` +
|
|
6045
|
-
`[[hooks]]${eol}` +
|
|
6046
|
-
`event = "SessionStart"${eol}` +
|
|
6047
|
-
`command = "node ${updateCheckScript}"${eol}`;
|
|
6048
|
-
|
|
6049
|
-
// Migrate legacy gsd-update-check entries from prior installs (#1755 followup)
|
|
6050
|
-
// Remove stale hook blocks that used the inverted filename or wrong path
|
|
6051
|
-
if (configContent.includes('gsd-update-check')) {
|
|
6052
|
-
configContent = configContent.replace(/\n# GSD Hooks\n\[\[hooks\]\]\nevent = "SessionStart"\ncommand = "node [^\n]*gsd-update-check\.js"\n/g, '\n');
|
|
6053
|
-
configContent = configContent.replace(/\r\n# GSD Hooks\r\n\[\[hooks\]\]\r\nevent = "SessionStart"\r\ncommand = "node [^\r\n]*gsd-update-check\.js"\r\n/g, '\r\n');
|
|
6054
|
-
}
|
|
6055
|
-
|
|
6056
|
-
if (hasEnabledCodexHooksFeature(configContent) && !configContent.includes('gsd-check-update')) {
|
|
6057
|
-
configContent += hookBlock;
|
|
6058
|
-
}
|
|
6059
|
-
|
|
6060
|
-
fs.writeFileSync(configPath, configContent, 'utf-8');
|
|
6061
|
-
console.log(` ${green}✓${reset} Configured Codex hooks (SessionStart)`);
|
|
6062
|
-
} catch (e) {
|
|
6063
|
-
console.warn(` ${yellow}⚠${reset} Could not configure Codex hooks: ${e.message}`);
|
|
6064
|
-
}
|
|
6065
|
-
|
|
6066
5994
|
return { settingsPath: null, settings: null, statuslineCommand: null, runtime, configDir: targetDir };
|
|
6067
5995
|
}
|
|
6068
5996
|
|
|
@@ -6131,9 +6059,6 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
6131
6059
|
const statuslineCommand = isGlobal
|
|
6132
6060
|
? buildHookCommand(targetDir, 'gsd-statusline.js', hookOpts)
|
|
6133
6061
|
: 'node ' + localPrefix + '/hooks/gsd-statusline.js';
|
|
6134
|
-
const updateCheckCommand = isGlobal
|
|
6135
|
-
? buildHookCommand(targetDir, 'gsd-check-update.js', hookOpts)
|
|
6136
|
-
: 'node ' + localPrefix + '/hooks/gsd-check-update.js';
|
|
6137
6062
|
const contextMonitorCommand = isGlobal
|
|
6138
6063
|
? buildHookCommand(targetDir, 'gsd-context-monitor.js', hookOpts)
|
|
6139
6064
|
: 'node ' + localPrefix + '/hooks/gsd-context-monitor.js';
|
|
@@ -6158,7 +6083,7 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
6158
6083
|
}
|
|
6159
6084
|
}
|
|
6160
6085
|
|
|
6161
|
-
// Configure
|
|
6086
|
+
// Configure GSD hooks (skip for opencode)
|
|
6162
6087
|
if (!isOpencode && !isKilo) {
|
|
6163
6088
|
if (!settings.hooks) {
|
|
6164
6089
|
settings.hooks = {};
|
|
@@ -6167,29 +6092,6 @@ function install(isGlobal, runtime = 'claude') {
|
|
|
6167
6092
|
settings.hooks.SessionStart = [];
|
|
6168
6093
|
}
|
|
6169
6094
|
|
|
6170
|
-
const hasGsdUpdateHook = settings.hooks.SessionStart.some(entry =>
|
|
6171
|
-
entry.hooks && entry.hooks.some(h => h.command && h.command.includes('gsd-check-update'))
|
|
6172
|
-
);
|
|
6173
|
-
|
|
6174
|
-
// Guard: only register if the hook file was actually installed (#1754).
|
|
6175
|
-
// When hooks/dist/ is missing from the npm package (as in v1.32.0), the
|
|
6176
|
-
// copy step produces no files but the registration step ran unconditionally,
|
|
6177
|
-
// causing "hook error" on every tool invocation.
|
|
6178
|
-
const checkUpdateFile = path.join(targetDir, 'hooks', 'gsd-check-update.js');
|
|
6179
|
-
if (!hasGsdUpdateHook && fs.existsSync(checkUpdateFile)) {
|
|
6180
|
-
settings.hooks.SessionStart.push({
|
|
6181
|
-
hooks: [
|
|
6182
|
-
{
|
|
6183
|
-
type: 'command',
|
|
6184
|
-
command: updateCheckCommand
|
|
6185
|
-
}
|
|
6186
|
-
]
|
|
6187
|
-
});
|
|
6188
|
-
console.log(` ${green}✓${reset} Configured update check hook`);
|
|
6189
|
-
} else if (!hasGsdUpdateHook && !fs.existsSync(checkUpdateFile)) {
|
|
6190
|
-
console.warn(` ${yellow}⚠${reset} Skipped update check hook — gsd-check-update.js not found at target`);
|
|
6191
|
-
}
|
|
6192
|
-
|
|
6193
6095
|
// Configure post-tool hook for context window monitoring
|
|
6194
6096
|
if (!settings.hooks[postToolEvent]) {
|
|
6195
6097
|
settings.hooks[postToolEvent] = [];
|