gsd-antigravity-kit 2.0.0 → 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 +4 -2
- package/.agent/skills/release-manager/SKILL.md +0 -162
- package/.agent/skills/release-manager/bin/LICENSE +0 -21
- package/.agent/skills/release-manager/bin/gh.exe +0 -0
- package/.agent/skills/release-manager/references/update_kb_from_fixes.md +0 -29
- package/.agent/skills/release-manager/scripts/release.ps1 +0 -222
- package/.agent/skills/selectpaste-update/SKILL.md +0 -46
- package/.agent/skills/selectpaste-update/scripts/sync-commands.py +0 -317
|
@@ -44,6 +44,22 @@ function withProjectRoot(cwd, result) {
|
|
|
44
44
|
if (config.response_language) {
|
|
45
45
|
result.response_language = config.response_language;
|
|
46
46
|
}
|
|
47
|
+
// Inject project identity into all init outputs so handoff blocks
|
|
48
|
+
// can include project context for cross-session continuity.
|
|
49
|
+
if (config.project_code) {
|
|
50
|
+
result.project_code = config.project_code;
|
|
51
|
+
}
|
|
52
|
+
// Extract project title from PROJECT.md first H1 heading.
|
|
53
|
+
const projectMdPath = path.join(planningDir(cwd), 'PROJECT.md');
|
|
54
|
+
try {
|
|
55
|
+
if (fs.existsSync(projectMdPath)) {
|
|
56
|
+
const content = fs.readFileSync(projectMdPath, 'utf8');
|
|
57
|
+
const h1Match = content.match(/^#\s+(.+)$/m);
|
|
58
|
+
if (h1Match) {
|
|
59
|
+
result.project_title = h1Match[1].trim();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch { /* intentionally empty */ }
|
|
47
63
|
return result;
|
|
48
64
|
}
|
|
49
65
|
|
|
@@ -58,6 +74,16 @@ function cmdInitExecutePhase(cwd, phase, includes, raw, options = {}) {
|
|
|
58
74
|
|
|
59
75
|
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
60
76
|
|
|
77
|
+
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
|
78
|
+
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
|
79
|
+
// match — we are initializing a new phase in the current milestone that
|
|
80
|
+
// happens to share a number with an archived one. Without this, phase_dir,
|
|
81
|
+
// phase_slug and related fields would point at artifacts from a previous
|
|
82
|
+
// milestone.
|
|
83
|
+
if (phaseInfo?.archived && roadmapPhase?.found) {
|
|
84
|
+
phaseInfo = null;
|
|
85
|
+
}
|
|
86
|
+
|
|
61
87
|
// Fallback to ROADMAP.md if no phase directory exists yet
|
|
62
88
|
if (!phaseInfo && roadmapPhase?.found) {
|
|
63
89
|
const phaseName = roadmapPhase.phase_name;
|
|
@@ -88,6 +114,7 @@ function cmdInitExecutePhase(cwd, phase, includes, raw, options = {}) {
|
|
|
88
114
|
verifier_model: resolveModelInternal(cwd, 'gsd-verifier'),
|
|
89
115
|
|
|
90
116
|
// Config flags
|
|
117
|
+
tdd_mode: options.tdd || config.tdd_mode || false,
|
|
91
118
|
commit_docs: config.commit_docs,
|
|
92
119
|
sub_repos: config.sub_repos,
|
|
93
120
|
parallelization: config.parallelization,
|
|
@@ -175,6 +202,16 @@ function cmdInitPlanPhase(cwd, phase, includes, raw, options = {}) {
|
|
|
175
202
|
|
|
176
203
|
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
177
204
|
|
|
205
|
+
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
|
206
|
+
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
|
207
|
+
// match — we are planning a new phase in the current milestone that happens
|
|
208
|
+
// to share a number with an archived one. Without this, phase_dir,
|
|
209
|
+
// phase_slug, has_context and has_research would point at artifacts from a
|
|
210
|
+
// previous milestone.
|
|
211
|
+
if (phaseInfo?.archived && roadmapPhase?.found) {
|
|
212
|
+
phaseInfo = null;
|
|
213
|
+
}
|
|
214
|
+
|
|
178
215
|
// Fallback to ROADMAP.md if no phase directory exists yet
|
|
179
216
|
if (!phaseInfo && roadmapPhase?.found) {
|
|
180
217
|
const phaseName = roadmapPhase.phase_name;
|
|
@@ -206,11 +243,18 @@ function cmdInitPlanPhase(cwd, phase, includes, raw, options = {}) {
|
|
|
206
243
|
checker_model: resolveModelInternal(cwd, 'gsd-plan-checker'),
|
|
207
244
|
|
|
208
245
|
// Workflow flags
|
|
246
|
+
tdd_mode: options.tdd || config.tdd_mode || false,
|
|
209
247
|
research_enabled: config.research,
|
|
210
248
|
plan_checker_enabled: config.plan_checker,
|
|
211
249
|
nyquist_validation_enabled: config.nyquist_validation,
|
|
212
250
|
commit_docs: config.commit_docs,
|
|
213
251
|
text_mode: config.text_mode,
|
|
252
|
+
// Auto-advance config — included so workflows don't need separate config-get
|
|
253
|
+
// calls for these values, which causes infinite config-read loops on some models
|
|
254
|
+
// (e.g. Kimi K2.5). See #2192.
|
|
255
|
+
auto_advance: !!(config.auto_advance),
|
|
256
|
+
auto_chain_active: !!(config._auto_chain_active),
|
|
257
|
+
mode: config.mode || 'interactive',
|
|
214
258
|
|
|
215
259
|
...buildPhaseBase(phaseInfo),
|
|
216
260
|
padded_phase: phaseInfo?.phase_number ? normalizePhaseName(phaseInfo.phase_number) : null,
|
|
@@ -231,6 +275,9 @@ function cmdInitPlanPhase(cwd, phase, includes, raw, options = {}) {
|
|
|
231
275
|
state_path: toPosixPath(path.relative(cwd, path.join(planningDir(cwd), 'STATE.md'))),
|
|
232
276
|
roadmap_path: toPosixPath(path.relative(cwd, path.join(planningDir(cwd), 'ROADMAP.md'))),
|
|
233
277
|
requirements_path: toPosixPath(path.relative(cwd, path.join(planningDir(cwd), 'REQUIREMENTS.md'))),
|
|
278
|
+
|
|
279
|
+
// Pattern mapper output (null until PATTERNS.md exists in phase dir)
|
|
280
|
+
patterns_path: null,
|
|
234
281
|
};
|
|
235
282
|
|
|
236
283
|
if (phaseInfo?.directory) {
|
|
@@ -258,6 +305,10 @@ function cmdInitPlanPhase(cwd, phase, includes, raw, options = {}) {
|
|
|
258
305
|
if (reviewsFile) {
|
|
259
306
|
result.reviews_path = toPosixPath(path.join(phaseInfo.directory, reviewsFile));
|
|
260
307
|
}
|
|
308
|
+
const patternsFile = files.find(f => f.endsWith('-PATTERNS.md') || f === 'PATTERNS.md');
|
|
309
|
+
if (patternsFile) {
|
|
310
|
+
result.patterns_path = toPosixPath(path.join(phaseInfo.directory, patternsFile));
|
|
311
|
+
}
|
|
261
312
|
} catch { /* intentionally empty */ }
|
|
262
313
|
}
|
|
263
314
|
|
|
@@ -533,6 +584,16 @@ function cmdInitVerifyWork(cwd, phase, includes, raw) {
|
|
|
533
584
|
const config = loadConfig(cwd);
|
|
534
585
|
let phaseInfo = findPhaseInternal(cwd, phase);
|
|
535
586
|
|
|
587
|
+
// If findPhaseInternal matched an archived phase from a prior milestone, but
|
|
588
|
+
// the phase exists in the current milestone's ROADMAP.md, ignore the archive
|
|
589
|
+
// match — same pattern as cmdInitPhaseOp.
|
|
590
|
+
if (phaseInfo?.archived) {
|
|
591
|
+
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
592
|
+
if (roadmapPhase?.found) {
|
|
593
|
+
phaseInfo = null;
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
|
|
536
597
|
// Fallback to ROADMAP.md if no phase directory exists yet
|
|
537
598
|
if (!phaseInfo) {
|
|
538
599
|
const roadmapPhase = getRoadmapPhaseInternal(cwd, phase);
|
|
@@ -803,6 +864,7 @@ function cmdInitMilestoneOp(cwd, includes, raw) {
|
|
|
803
864
|
|
|
804
865
|
function cmdInitMapCodebase(cwd, includes, raw) {
|
|
805
866
|
const config = loadConfig(cwd);
|
|
867
|
+
const now = new Date();
|
|
806
868
|
|
|
807
869
|
// Check for existing codebase maps
|
|
808
870
|
const codebaseDir = path.join(planningRoot(cwd), 'codebase');
|
|
@@ -821,6 +883,10 @@ function cmdInitMapCodebase(cwd, includes, raw) {
|
|
|
821
883
|
parallelization: config.parallelization,
|
|
822
884
|
subagent_timeout: config.subagent_timeout,
|
|
823
885
|
|
|
886
|
+
// Timestamps
|
|
887
|
+
date: now.toISOString().split('T')[0],
|
|
888
|
+
timestamp: now.toISOString(),
|
|
889
|
+
|
|
824
890
|
// Paths
|
|
825
891
|
codebase_dir: '.planning/codebase',
|
|
826
892
|
|
|
@@ -855,6 +921,23 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
855
921
|
const phasesDir = paths.phases;
|
|
856
922
|
const isDirInMilestone = getMilestonePhaseFilter(cwd);
|
|
857
923
|
|
|
924
|
+
// Pre-compute directory listing once (avoids O(N) readdirSync per phase)
|
|
925
|
+
const _phaseDirEntries = (() => {
|
|
926
|
+
try {
|
|
927
|
+
return fs.readdirSync(phasesDir, { withFileTypes: true })
|
|
928
|
+
.filter(e => e.isDirectory())
|
|
929
|
+
.map(e => e.name);
|
|
930
|
+
} catch { return []; }
|
|
931
|
+
})();
|
|
932
|
+
|
|
933
|
+
// Pre-extract all checkbox states in a single pass (avoids O(N) regex per phase)
|
|
934
|
+
const _checkboxStates = new Map();
|
|
935
|
+
const _cbPattern = /-\s*\[(x| )\]\s*.*Phase\s+(\d+[A-Z]?(?:\.\d+)*)[:\s]/gi;
|
|
936
|
+
let _cbMatch;
|
|
937
|
+
while ((_cbMatch = _cbPattern.exec(content)) !== null) {
|
|
938
|
+
_checkboxStates.set(_cbMatch[2], _cbMatch[1].toLowerCase() === 'x');
|
|
939
|
+
}
|
|
940
|
+
|
|
858
941
|
const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:\s*([^\n]+)/gi;
|
|
859
942
|
const phases = [];
|
|
860
943
|
let match;
|
|
@@ -885,8 +968,7 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
885
968
|
let isActive = false;
|
|
886
969
|
|
|
887
970
|
try {
|
|
888
|
-
const
|
|
889
|
-
const dirs = entries.filter(e => e.isDirectory()).map(e => e.name).filter(isDirInMilestone);
|
|
971
|
+
const dirs = _phaseDirEntries.filter(isDirInMilestone);
|
|
890
972
|
const dirMatch = dirs.find(d => phaseTokenMatches(d, normalized));
|
|
891
973
|
|
|
892
974
|
if (dirMatch) {
|
|
@@ -920,10 +1002,8 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
920
1002
|
}
|
|
921
1003
|
} catch { /* intentionally empty */ }
|
|
922
1004
|
|
|
923
|
-
// Check ROADMAP checkbox status
|
|
924
|
-
const
|
|
925
|
-
const checkboxMatch = content.match(checkboxPattern);
|
|
926
|
-
const roadmapComplete = checkboxMatch ? checkboxMatch[1] === 'x' : false;
|
|
1005
|
+
// Check ROADMAP checkbox status (pre-extracted above the loop)
|
|
1006
|
+
const roadmapComplete = _checkboxStates.get(phaseNum) || false;
|
|
927
1007
|
if (roadmapComplete && diskStatus !== 'complete') {
|
|
928
1008
|
diskStatus = 'complete';
|
|
929
1009
|
}
|
|
@@ -956,6 +1036,17 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
956
1036
|
|
|
957
1037
|
// Dependency satisfaction: check if all depends_on phases are complete
|
|
958
1038
|
const completedNums = new Set(phases.filter(p => p.disk_status === 'complete').map(p => p.number));
|
|
1039
|
+
|
|
1040
|
+
// Also include phases from previously shipped milestones — they are all
|
|
1041
|
+
// complete by definition (a milestone only ships when all phases are done).
|
|
1042
|
+
// rawContent is the full ROADMAP.md (including <details>-wrapped shipped
|
|
1043
|
+
// milestone sections that extractCurrentMilestone strips out).
|
|
1044
|
+
const _allCompletedPattern = /-\s*\[x\]\s*.*Phase\s+(\d+[A-Z]?(?:\.\d+)*)[:\s]/gi;
|
|
1045
|
+
let _allMatch;
|
|
1046
|
+
while ((_allMatch = _allCompletedPattern.exec(rawContent)) !== null) {
|
|
1047
|
+
completedNums.add(_allMatch[1]);
|
|
1048
|
+
}
|
|
1049
|
+
|
|
959
1050
|
for (const phase of phases) {
|
|
960
1051
|
if (!phase.depends_on || /^none$/i.test(phase.depends_on.trim())) {
|
|
961
1052
|
phase.deps_satisfied = true;
|
|
@@ -974,15 +1065,10 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
974
1065
|
: '—';
|
|
975
1066
|
}
|
|
976
1067
|
|
|
977
|
-
// Sliding window: discuss is sequential — only the first undiscussed phase is available
|
|
978
|
-
let foundNextToDiscuss = false;
|
|
979
1068
|
for (const phase of phases) {
|
|
980
|
-
|
|
981
|
-
phase.
|
|
982
|
-
|
|
983
|
-
} else {
|
|
984
|
-
phase.is_next_to_discuss = false;
|
|
985
|
-
}
|
|
1069
|
+
phase.is_next_to_discuss =
|
|
1070
|
+
(phase.disk_status === 'empty' || phase.disk_status === 'no_directory') &&
|
|
1071
|
+
phase.deps_satisfied;
|
|
986
1072
|
}
|
|
987
1073
|
|
|
988
1074
|
// Check for WAITING.json signal
|
|
@@ -1066,7 +1152,9 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
1066
1152
|
return true;
|
|
1067
1153
|
});
|
|
1068
1154
|
|
|
1069
|
-
|
|
1155
|
+
// Exclude backlog phases (999.x) from completion accounting (#2129)
|
|
1156
|
+
const nonBacklogPhases = phases.filter(p => !/^999(?:\.|$)/.test(p.number));
|
|
1157
|
+
const completedCount = nonBacklogPhases.filter(p => p.disk_status === 'complete').length;
|
|
1070
1158
|
|
|
1071
1159
|
// Read manager flags from config (passthrough flags for each step)
|
|
1072
1160
|
// Validate: flags must be CLI-safe (only --flags, alphanumeric, hyphens, spaces)
|
|
@@ -1097,7 +1185,7 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
1097
1185
|
in_progress_count: phases.filter(p => ['partial', 'planned', 'discussed', 'researched'].includes(p.disk_status)).length,
|
|
1098
1186
|
recommended_actions: filteredActions,
|
|
1099
1187
|
waiting_signal: waitingSignal,
|
|
1100
|
-
all_complete: completedCount ===
|
|
1188
|
+
all_complete: completedCount === nonBacklogPhases.length && nonBacklogPhases.length > 0,
|
|
1101
1189
|
project_exists: pathExistsInternal(cwd, '.planning/PROJECT.md'),
|
|
1102
1190
|
roadmap_exists: true,
|
|
1103
1191
|
state_exists: true,
|
|
@@ -1108,6 +1196,10 @@ function cmdInitManager(cwd, includes, raw) {
|
|
|
1108
1196
|
}
|
|
1109
1197
|
|
|
1110
1198
|
function cmdInitProgress(cwd, includes, raw) {
|
|
1199
|
+
try {
|
|
1200
|
+
const { pruneOrphanedWorktrees } = require('./core.cjs');
|
|
1201
|
+
pruneOrphanedWorktrees(cwd);
|
|
1202
|
+
} catch (_) {}
|
|
1111
1203
|
const config = loadConfig(cwd);
|
|
1112
1204
|
const milestone = getMilestoneInfo(cwd);
|
|
1113
1205
|
|
|
@@ -1429,6 +1521,8 @@ function cmdInitRemoveWorkspace(cwd, name, includes, raw) {
|
|
|
1429
1521
|
*/
|
|
1430
1522
|
function buildAgentSkillsBlock(config, agentType, projectRoot) {
|
|
1431
1523
|
const { validatePath } = require('./security.cjs');
|
|
1524
|
+
const os = require('os');
|
|
1525
|
+
const globalSkillsBase = path.join(os.homedir(), '.antigravity', 'skills');
|
|
1432
1526
|
|
|
1433
1527
|
if (!config || !config.agent_skills || !agentType) return '';
|
|
1434
1528
|
|
|
@@ -1443,6 +1537,37 @@ function buildAgentSkillsBlock(config, agentType, projectRoot) {
|
|
|
1443
1537
|
for (const skillPath of skillPaths) {
|
|
1444
1538
|
if (typeof skillPath !== 'string') continue;
|
|
1445
1539
|
|
|
1540
|
+
// Support global: prefix for skills installed at ~/.antigravity/skills/ (#1992)
|
|
1541
|
+
if (skillPath.startsWith('global:')) {
|
|
1542
|
+
const skillName = skillPath.slice(7);
|
|
1543
|
+
// Explicit empty-name guard before regex for clearer error message
|
|
1544
|
+
if (!skillName) {
|
|
1545
|
+
process.stderr.write(`[agent-skills] WARNING: "global:" prefix with empty skill name — skipping\n`);
|
|
1546
|
+
continue;
|
|
1547
|
+
}
|
|
1548
|
+
// Sanitize: skill name must be alphanumeric, hyphens, or underscores only
|
|
1549
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(skillName)) {
|
|
1550
|
+
process.stderr.write(`[agent-skills] WARNING: Invalid global skill name "${skillName}" — skipping\n`);
|
|
1551
|
+
continue;
|
|
1552
|
+
}
|
|
1553
|
+
const globalSkillDir = path.join(globalSkillsBase, skillName);
|
|
1554
|
+
const globalSkillMd = path.join(globalSkillDir, 'SKILL.md');
|
|
1555
|
+
if (!fs.existsSync(globalSkillMd)) {
|
|
1556
|
+
process.stderr.write(`[agent-skills] WARNING: Global skill not found at "~/.antigravity/skills/${skillName}/SKILL.md" — skipping\n`);
|
|
1557
|
+
continue;
|
|
1558
|
+
}
|
|
1559
|
+
// Symlink escape guard: validatePath resolves symlinks and enforces
|
|
1560
|
+
// containment within globalSkillsBase. Prevents a skill directory
|
|
1561
|
+
// symlinked to an arbitrary location from being injected (#1992).
|
|
1562
|
+
const pathCheck = validatePath(globalSkillMd, globalSkillsBase, { allowAbsolute: true });
|
|
1563
|
+
if (!pathCheck.safe) {
|
|
1564
|
+
process.stderr.write(`[agent-skills] WARNING: Global skill "${skillName}" failed path check (symlink escape?) — skipping\n`);
|
|
1565
|
+
continue;
|
|
1566
|
+
}
|
|
1567
|
+
validPaths.push({ ref: `${globalSkillDir}/SKILL.md`, display: `~/.antigravity/skills/${skillName}` });
|
|
1568
|
+
continue;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1446
1571
|
// Validate path safety — must resolve within project root
|
|
1447
1572
|
const pathCheck = validatePath(skillPath, projectRoot);
|
|
1448
1573
|
if (!pathCheck.safe) {
|
|
@@ -1457,12 +1582,12 @@ function buildAgentSkillsBlock(config, agentType, projectRoot) {
|
|
|
1457
1582
|
continue;
|
|
1458
1583
|
}
|
|
1459
1584
|
|
|
1460
|
-
validPaths.push(skillPath);
|
|
1585
|
+
validPaths.push({ ref: `${skillPath}/SKILL.md`, display: skillPath });
|
|
1461
1586
|
}
|
|
1462
1587
|
|
|
1463
1588
|
if (validPaths.length === 0) return '';
|
|
1464
1589
|
|
|
1465
|
-
const lines = validPaths.map(p => `- @${p}
|
|
1590
|
+
const lines = validPaths.map(p => `- @${p.ref}`).join('\n');
|
|
1466
1591
|
return `<agent_skills>\nRead these user-configured skills:\n${lines}\n</agent_skills>`;
|
|
1467
1592
|
}
|
|
1468
1593
|
|
|
@@ -1486,6 +1611,232 @@ function cmdAgentSkills(cwd, agentType, raw) {
|
|
|
1486
1611
|
process.exit(0);
|
|
1487
1612
|
}
|
|
1488
1613
|
|
|
1614
|
+
/**
|
|
1615
|
+
* Generate a skill manifest from a skills directory.
|
|
1616
|
+
*
|
|
1617
|
+
* Scans the canonical skill discovery roots and returns a normalized
|
|
1618
|
+
* inventory object with discovered skills, root metadata, and installation
|
|
1619
|
+
* summary flags. A legacy `skillsDir` override is still accepted for focused
|
|
1620
|
+
* scans, but the default mode is multi-root discovery.
|
|
1621
|
+
*
|
|
1622
|
+
* @param {string} cwd - Project root directory
|
|
1623
|
+
* @param {string|null} [skillsDir] - Optional absolute path to a specific skills directory
|
|
1624
|
+
* @returns {{
|
|
1625
|
+
* skills: Array<{name: string, description: string, triggers: string[], path: string, file_path: string, root: string, scope: string, installed: boolean, deprecated: boolean}>,
|
|
1626
|
+
* roots: Array<{root: string, path: string, scope: string, present: boolean, skill_count?: number, command_count?: number, deprecated?: boolean}>,
|
|
1627
|
+
* installation: { gsd_skills_installed: boolean, legacy_antigravity_commands_installed: boolean },
|
|
1628
|
+
* counts: { skills: number, roots: number }
|
|
1629
|
+
* }}
|
|
1630
|
+
*/
|
|
1631
|
+
function buildSkillManifest(cwd, skillsDir = null) {
|
|
1632
|
+
const { extractFrontmatter } = require('./frontmatter.cjs');
|
|
1633
|
+
const os = require('os');
|
|
1634
|
+
|
|
1635
|
+
const canonicalRoots = skillsDir ? [{
|
|
1636
|
+
root: path.resolve(skillsDir),
|
|
1637
|
+
path: path.resolve(skillsDir),
|
|
1638
|
+
scope: 'custom',
|
|
1639
|
+
present: fs.existsSync(skillsDir),
|
|
1640
|
+
kind: 'skills',
|
|
1641
|
+
}] : [
|
|
1642
|
+
{
|
|
1643
|
+
root: '.antigravity/skills',
|
|
1644
|
+
path: path.join(cwd, '.antigravity', 'skills'),
|
|
1645
|
+
scope: 'project',
|
|
1646
|
+
kind: 'skills',
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
root: '.agents/skills',
|
|
1650
|
+
path: path.join(cwd, '.agents', 'skills'),
|
|
1651
|
+
scope: 'project',
|
|
1652
|
+
kind: 'skills',
|
|
1653
|
+
},
|
|
1654
|
+
{
|
|
1655
|
+
root: '.cursor/skills',
|
|
1656
|
+
path: path.join(cwd, '.cursor', 'skills'),
|
|
1657
|
+
scope: 'project',
|
|
1658
|
+
kind: 'skills',
|
|
1659
|
+
},
|
|
1660
|
+
{
|
|
1661
|
+
root: '.github/skills',
|
|
1662
|
+
path: path.join(cwd, '.github', 'skills'),
|
|
1663
|
+
scope: 'project',
|
|
1664
|
+
kind: 'skills',
|
|
1665
|
+
},
|
|
1666
|
+
{
|
|
1667
|
+
root: '.codex/skills',
|
|
1668
|
+
path: path.join(cwd, '.codex', 'skills'),
|
|
1669
|
+
scope: 'project',
|
|
1670
|
+
kind: 'skills',
|
|
1671
|
+
},
|
|
1672
|
+
{
|
|
1673
|
+
root: '~/.antigravity/skills',
|
|
1674
|
+
path: path.join(os.homedir(), '.antigravity', 'skills'),
|
|
1675
|
+
scope: 'global',
|
|
1676
|
+
kind: 'skills',
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
root: '~/.codex/skills',
|
|
1680
|
+
path: path.join(os.homedir(), '.codex', 'skills'),
|
|
1681
|
+
scope: 'global',
|
|
1682
|
+
kind: 'skills',
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
root: '.antigravity/get-shit-done/skills',
|
|
1686
|
+
path: path.join(os.homedir(), '.antigravity', 'get-shit-done', 'skills'),
|
|
1687
|
+
scope: 'import-only',
|
|
1688
|
+
kind: 'skills',
|
|
1689
|
+
deprecated: true,
|
|
1690
|
+
},
|
|
1691
|
+
{
|
|
1692
|
+
root: '.antigravity/commands/gsd',
|
|
1693
|
+
path: path.join(os.homedir(), '.antigravity', 'commands', 'gsd'),
|
|
1694
|
+
scope: 'legacy-commands',
|
|
1695
|
+
kind: 'commands',
|
|
1696
|
+
deprecated: true,
|
|
1697
|
+
},
|
|
1698
|
+
];
|
|
1699
|
+
|
|
1700
|
+
const skills = [];
|
|
1701
|
+
const roots = [];
|
|
1702
|
+
let legacyAntigravityCommandsInstalled = false;
|
|
1703
|
+
for (const rootInfo of canonicalRoots) {
|
|
1704
|
+
const rootPath = rootInfo.path;
|
|
1705
|
+
const rootSummary = {
|
|
1706
|
+
root: rootInfo.root,
|
|
1707
|
+
path: rootPath,
|
|
1708
|
+
scope: rootInfo.scope,
|
|
1709
|
+
present: fs.existsSync(rootPath),
|
|
1710
|
+
deprecated: !!rootInfo.deprecated,
|
|
1711
|
+
};
|
|
1712
|
+
|
|
1713
|
+
if (!rootSummary.present) {
|
|
1714
|
+
roots.push(rootSummary);
|
|
1715
|
+
continue;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
if (rootInfo.kind === 'commands') {
|
|
1719
|
+
let entries = [];
|
|
1720
|
+
try {
|
|
1721
|
+
entries = fs.readdirSync(rootPath, { withFileTypes: true });
|
|
1722
|
+
} catch {
|
|
1723
|
+
roots.push(rootSummary);
|
|
1724
|
+
continue;
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
const commandFiles = entries.filter(entry => entry.isFile() && entry.name.endsWith('.md'));
|
|
1728
|
+
rootSummary.command_count = commandFiles.length;
|
|
1729
|
+
if (rootSummary.command_count > 0) legacyAntigravityCommandsInstalled = true;
|
|
1730
|
+
roots.push(rootSummary);
|
|
1731
|
+
continue;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1734
|
+
let entries;
|
|
1735
|
+
try {
|
|
1736
|
+
entries = fs.readdirSync(rootPath, { withFileTypes: true });
|
|
1737
|
+
} catch {
|
|
1738
|
+
roots.push(rootSummary);
|
|
1739
|
+
continue;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
let skillCount = 0;
|
|
1743
|
+
for (const entry of entries) {
|
|
1744
|
+
if (!entry.isDirectory()) continue;
|
|
1745
|
+
|
|
1746
|
+
const skillMdPath = path.join(rootPath, entry.name, 'SKILL.md');
|
|
1747
|
+
if (!fs.existsSync(skillMdPath)) continue;
|
|
1748
|
+
|
|
1749
|
+
let content;
|
|
1750
|
+
try {
|
|
1751
|
+
content = fs.readFileSync(skillMdPath, 'utf-8');
|
|
1752
|
+
} catch {
|
|
1753
|
+
continue;
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
const frontmatter = extractFrontmatter(content);
|
|
1757
|
+
const name = frontmatter.name || entry.name;
|
|
1758
|
+
const description = frontmatter.description || '';
|
|
1759
|
+
|
|
1760
|
+
// Extract trigger lines from body text (after frontmatter)
|
|
1761
|
+
const triggers = [];
|
|
1762
|
+
const bodyMatch = content.match(/^---[\s\S]*?---\s*\n([\s\S]*)$/);
|
|
1763
|
+
if (bodyMatch) {
|
|
1764
|
+
const body = bodyMatch[1];
|
|
1765
|
+
const triggerLines = body.match(/^TRIGGER\s+when:\s*(.+)$/gmi);
|
|
1766
|
+
if (triggerLines) {
|
|
1767
|
+
for (const line of triggerLines) {
|
|
1768
|
+
const m = line.match(/^TRIGGER\s+when:\s*(.+)$/i);
|
|
1769
|
+
if (m) triggers.push(m[1].trim());
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
skills.push({
|
|
1775
|
+
name,
|
|
1776
|
+
description,
|
|
1777
|
+
triggers,
|
|
1778
|
+
path: entry.name,
|
|
1779
|
+
file_path: `${entry.name}/SKILL.md`,
|
|
1780
|
+
root: rootInfo.root,
|
|
1781
|
+
scope: rootInfo.scope,
|
|
1782
|
+
installed: rootInfo.scope !== 'import-only',
|
|
1783
|
+
deprecated: !!rootInfo.deprecated,
|
|
1784
|
+
});
|
|
1785
|
+
skillCount++;
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
rootSummary.skill_count = skillCount;
|
|
1789
|
+
roots.push(rootSummary);
|
|
1790
|
+
}
|
|
1791
|
+
|
|
1792
|
+
skills.sort((a, b) => {
|
|
1793
|
+
const rootCmp = a.root.localeCompare(b.root);
|
|
1794
|
+
return rootCmp !== 0 ? rootCmp : a.name.localeCompare(b.name);
|
|
1795
|
+
});
|
|
1796
|
+
|
|
1797
|
+
const gsdSkillsInstalled = skills.some(skill => skill.name.startsWith('gsd-'));
|
|
1798
|
+
|
|
1799
|
+
return {
|
|
1800
|
+
skills,
|
|
1801
|
+
roots,
|
|
1802
|
+
installation: {
|
|
1803
|
+
gsd_skills_installed: gsdSkillsInstalled,
|
|
1804
|
+
legacy_antigravity_commands_installed: legacyAntigravityCommandsInstalled,
|
|
1805
|
+
},
|
|
1806
|
+
counts: {
|
|
1807
|
+
skills: skills.length,
|
|
1808
|
+
roots: roots.length,
|
|
1809
|
+
},
|
|
1810
|
+
};
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
/**
|
|
1814
|
+
* Command: generate skill manifest JSON.
|
|
1815
|
+
*
|
|
1816
|
+
* Options:
|
|
1817
|
+
* --skills-dir <path> Optional absolute path to a single skills directory
|
|
1818
|
+
* --write Also write to .planning/skill-manifest.json
|
|
1819
|
+
*/
|
|
1820
|
+
function cmdSkillManifest(cwd, args, raw) {
|
|
1821
|
+
const skillsDirIdx = args.indexOf('--skills-dir');
|
|
1822
|
+
const skillsDir = skillsDirIdx >= 0 && args[skillsDirIdx + 1]
|
|
1823
|
+
? args[skillsDirIdx + 1]
|
|
1824
|
+
: null;
|
|
1825
|
+
|
|
1826
|
+
const manifest = buildSkillManifest(cwd, skillsDir);
|
|
1827
|
+
|
|
1828
|
+
// Optionally write to .planning/skill-manifest.json
|
|
1829
|
+
if (args.includes('--write')) {
|
|
1830
|
+
const planningDir = path.join(cwd, '.planning');
|
|
1831
|
+
if (fs.existsSync(planningDir)) {
|
|
1832
|
+
const manifestPath = path.join(planningDir, 'skill-manifest.json');
|
|
1833
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1837
|
+
output(manifest, raw);
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1489
1840
|
module.exports = {
|
|
1490
1841
|
cmdInitExecutePhase,
|
|
1491
1842
|
cmdInitPlanPhase,
|
|
@@ -1506,4 +1857,6 @@ module.exports = {
|
|
|
1506
1857
|
detectChildRepos,
|
|
1507
1858
|
buildAgentSkillsBlock,
|
|
1508
1859
|
cmdAgentSkills,
|
|
1860
|
+
buildSkillManifest,
|
|
1861
|
+
cmdSkillManifest,
|
|
1509
1862
|
};
|
|
@@ -19,10 +19,10 @@ const crypto = require('crypto');
|
|
|
19
19
|
const INTEL_DIR = '.planning/intel';
|
|
20
20
|
|
|
21
21
|
const INTEL_FILES = {
|
|
22
|
-
files: '
|
|
23
|
-
apis: '
|
|
24
|
-
deps: '
|
|
25
|
-
arch: 'arch.
|
|
22
|
+
files: 'file-roles.json',
|
|
23
|
+
apis: 'api-map.json',
|
|
24
|
+
deps: 'dependency-graph.json',
|
|
25
|
+
arch: 'arch-decisions.json',
|
|
26
26
|
stack: 'stack.json'
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -204,10 +204,8 @@ function intelQuery(term, planningDir) {
|
|
|
204
204
|
const matches = [];
|
|
205
205
|
let total = 0;
|
|
206
206
|
|
|
207
|
-
// Search JSON intel files
|
|
207
|
+
// Search all JSON intel files
|
|
208
208
|
for (const [_key, filename] of Object.entries(INTEL_FILES)) {
|
|
209
|
-
if (filename.endsWith('.md')) continue; // Skip arch.md here
|
|
210
|
-
|
|
211
209
|
const filePath = intelFilePath(planningDir, filename);
|
|
212
210
|
const data = safeReadJson(filePath);
|
|
213
211
|
if (!data) continue;
|
|
@@ -219,14 +217,6 @@ function intelQuery(term, planningDir) {
|
|
|
219
217
|
}
|
|
220
218
|
}
|
|
221
219
|
|
|
222
|
-
// Search arch.md
|
|
223
|
-
const archPath = intelFilePath(planningDir, INTEL_FILES.arch);
|
|
224
|
-
const archMatches = searchArchMd(archPath, term);
|
|
225
|
-
if (archMatches.length > 0) {
|
|
226
|
-
matches.push({ source: INTEL_FILES.arch, entries: archMatches });
|
|
227
|
-
total += archMatches.length;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
220
|
return { matches, term, total };
|
|
231
221
|
}
|
|
232
222
|
|
|
@@ -257,20 +247,10 @@ function intelStatus(planningDir) {
|
|
|
257
247
|
|
|
258
248
|
let updatedAt = null;
|
|
259
249
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const stat = fs.statSync(filePath);
|
|
264
|
-
updatedAt = stat.mtime.toISOString();
|
|
265
|
-
} catch (_e) {
|
|
266
|
-
// intentionally silent: fall through on error
|
|
267
|
-
}
|
|
268
|
-
} else {
|
|
269
|
-
// For JSON files, read _meta.updated_at
|
|
270
|
-
const data = safeReadJson(filePath);
|
|
271
|
-
if (data && data._meta && data._meta.updated_at) {
|
|
250
|
+
// All intel files are JSON — read _meta.updated_at
|
|
251
|
+
const data = safeReadJson(filePath);
|
|
252
|
+
if (data && data._meta && data._meta.updated_at) {
|
|
272
253
|
updatedAt = data._meta.updated_at;
|
|
273
|
-
}
|
|
274
254
|
}
|
|
275
255
|
|
|
276
256
|
let stale = true;
|
|
@@ -409,8 +389,7 @@ function intelValidate(planningDir) {
|
|
|
409
389
|
continue;
|
|
410
390
|
}
|
|
411
391
|
|
|
412
|
-
//
|
|
413
|
-
if (filename.endsWith('.md')) continue;
|
|
392
|
+
// All intel files are JSON — validate _meta and entries structure
|
|
414
393
|
|
|
415
394
|
// Parse JSON
|
|
416
395
|
let data;
|