gsd-pi 2.19.0 → 2.20.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 +5 -1
- package/dist/cli.js +3 -3
- package/dist/onboarding.d.ts +3 -1
- package/dist/onboarding.js +77 -3
- package/dist/remote-questions-config.d.ts +1 -1
- package/dist/resources/extensions/google-search/index.ts +164 -47
- package/dist/resources/extensions/gsd/auto-prompts.ts +103 -24
- package/dist/resources/extensions/gsd/auto-worktree.ts +93 -9
- package/dist/resources/extensions/gsd/auto.ts +424 -30
- package/dist/resources/extensions/gsd/commands.ts +518 -36
- package/dist/resources/extensions/gsd/context-budget.ts +243 -0
- package/dist/resources/extensions/gsd/context-store.ts +195 -0
- package/dist/resources/extensions/gsd/dashboard-overlay.ts +41 -3
- package/dist/resources/extensions/gsd/db-writer.ts +341 -0
- package/dist/resources/extensions/gsd/debug-logger.ts +178 -0
- package/dist/resources/extensions/gsd/dispatch-guard.ts +0 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +54 -0
- package/dist/resources/extensions/gsd/doctor-proactive.ts +286 -0
- package/dist/resources/extensions/gsd/doctor.ts +283 -2
- package/dist/resources/extensions/gsd/export.ts +81 -2
- package/dist/resources/extensions/gsd/files.ts +39 -9
- package/dist/resources/extensions/gsd/git-service.ts +6 -0
- package/dist/resources/extensions/gsd/gsd-db.ts +752 -0
- package/dist/resources/extensions/gsd/guided-flow.ts +26 -1
- package/dist/resources/extensions/gsd/history.ts +0 -1
- package/dist/resources/extensions/gsd/index.ts +277 -1
- package/dist/resources/extensions/gsd/md-importer.ts +526 -0
- package/dist/resources/extensions/gsd/metrics.ts +39 -3
- package/dist/resources/extensions/gsd/notifications.ts +0 -1
- package/dist/resources/extensions/gsd/post-unit-hooks.ts +70 -1
- package/dist/resources/extensions/gsd/preferences.ts +125 -150
- package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -5
- package/dist/resources/extensions/gsd/prompts/heal-skill.md +45 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +5 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +48 -0
- package/dist/resources/extensions/gsd/prompts/system.md +2 -1
- package/dist/resources/extensions/gsd/quick.ts +156 -0
- package/dist/resources/extensions/gsd/skill-discovery.ts +5 -3
- package/dist/resources/extensions/gsd/skill-health.ts +417 -0
- package/dist/resources/extensions/gsd/skill-telemetry.ts +127 -0
- package/dist/resources/extensions/gsd/state.ts +30 -0
- package/dist/resources/extensions/gsd/templates/preferences.md +1 -0
- package/dist/resources/extensions/gsd/tests/context-budget.test.ts +283 -0
- package/dist/resources/extensions/gsd/tests/context-compression.test.ts +1 -1
- package/dist/resources/extensions/gsd/tests/context-store.test.ts +462 -0
- package/dist/resources/extensions/gsd/tests/continue-here.test.ts +204 -0
- package/dist/resources/extensions/gsd/tests/dashboard-budget.test.ts +346 -0
- package/dist/resources/extensions/gsd/tests/db-writer.test.ts +602 -0
- package/dist/resources/extensions/gsd/tests/debug-logger.test.ts +185 -0
- package/dist/resources/extensions/gsd/tests/derive-state-db.test.ts +406 -0
- package/dist/resources/extensions/gsd/tests/dispatch-guard.test.ts +0 -1
- package/dist/resources/extensions/gsd/tests/dist-redirect.mjs +22 -0
- package/dist/resources/extensions/gsd/tests/doctor-proactive.test.ts +244 -0
- package/dist/resources/extensions/gsd/tests/doctor-runtime.test.ts +303 -0
- package/dist/resources/extensions/gsd/tests/gsd-db.test.ts +353 -0
- package/dist/resources/extensions/gsd/tests/gsd-inspect.test.ts +125 -0
- package/dist/resources/extensions/gsd/tests/gsd-tools.test.ts +326 -0
- package/dist/resources/extensions/gsd/tests/integration-edge.test.ts +228 -0
- package/dist/resources/extensions/gsd/tests/integration-lifecycle.test.ts +277 -0
- package/dist/resources/extensions/gsd/tests/md-importer.test.ts +411 -0
- package/dist/resources/extensions/gsd/tests/metrics.test.ts +197 -0
- package/dist/resources/extensions/gsd/tests/model-isolation.test.ts +99 -0
- package/dist/resources/extensions/gsd/tests/parsers.test.ts +40 -0
- package/dist/resources/extensions/gsd/tests/post-unit-hooks.test.ts +41 -1
- package/dist/resources/extensions/gsd/tests/preferences-git.test.ts +0 -1
- package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +0 -1
- package/dist/resources/extensions/gsd/tests/preferences-mode.test.ts +110 -0
- package/dist/resources/extensions/gsd/tests/preferences-models.test.ts +0 -1
- package/dist/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +464 -0
- package/dist/resources/extensions/gsd/tests/prompt-db.test.ts +385 -0
- package/dist/resources/extensions/gsd/tests/remote-questions.test.ts +262 -1
- package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +17 -29
- package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +2 -8
- package/dist/resources/extensions/gsd/tests/skill-lifecycle.test.ts +126 -0
- package/dist/resources/extensions/gsd/tests/stop-auto-remote.test.ts +31 -8
- package/dist/resources/extensions/gsd/tests/token-savings.test.ts +366 -0
- package/dist/resources/extensions/gsd/tests/unit-runtime.test.ts +25 -1
- package/dist/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +145 -0
- package/dist/resources/extensions/gsd/tests/visualizer-data.test.ts +92 -0
- package/dist/resources/extensions/gsd/tests/visualizer-overlay.test.ts +120 -0
- package/dist/resources/extensions/gsd/tests/visualizer-views.test.ts +228 -5
- package/dist/resources/extensions/gsd/tests/worktree-db-integration.test.ts +205 -0
- package/dist/resources/extensions/gsd/tests/worktree-db.test.ts +442 -0
- package/dist/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +165 -0
- package/dist/resources/extensions/gsd/types.ts +29 -0
- package/dist/resources/extensions/gsd/undo.ts +0 -1
- package/dist/resources/extensions/gsd/unit-runtime.ts +5 -1
- package/dist/resources/extensions/gsd/visualizer-data.ts +352 -1
- package/dist/resources/extensions/gsd/visualizer-overlay.ts +166 -22
- package/dist/resources/extensions/gsd/visualizer-views.ts +464 -2
- package/dist/resources/extensions/gsd/worktree-command.ts +18 -0
- package/dist/resources/extensions/gsd/worktree-manager.ts +11 -4
- package/dist/resources/extensions/remote-questions/config.ts +4 -2
- package/dist/resources/extensions/remote-questions/discord-adapter.ts +2 -4
- package/dist/resources/extensions/remote-questions/format.ts +154 -8
- package/dist/resources/extensions/remote-questions/manager.ts +9 -7
- package/dist/resources/extensions/remote-questions/remote-command.ts +100 -4
- package/dist/resources/extensions/remote-questions/slack-adapter.ts +58 -2
- package/dist/resources/extensions/remote-questions/telegram-adapter.ts +161 -0
- package/dist/resources/extensions/remote-questions/types.ts +2 -1
- package/dist/resources/extensions/ttsr/ttsr-manager.ts +26 -0
- package/dist/resources/extensions/voice/index.ts +4 -3
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +12 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +5 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +25 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/lsp/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/index.js +106 -3
- package/packages/pi-coding-agent/dist/core/lsp/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp.md +6 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts +35 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/types.js +6 -0
- package/packages/pi-coding-agent/dist/core/lsp/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts +3 -1
- package/packages/pi-coding-agent/dist/core/lsp/utils.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/utils.js +45 -0
- package/packages/pi-coding-agent/dist/core/lsp/utils.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +6 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +43 -11
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +7 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -0
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +5 -0
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +13 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +6 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +26 -0
- package/packages/pi-coding-agent/src/core/lsp/index.ts +157 -2
- package/packages/pi-coding-agent/src/core/lsp/lsp.md +6 -0
- package/packages/pi-coding-agent/src/core/lsp/types.ts +53 -0
- package/packages/pi-coding-agent/src/core/lsp/utils.ts +56 -0
- package/packages/pi-coding-agent/src/core/settings-manager.ts +41 -11
- package/packages/pi-coding-agent/src/core/system-prompt.ts +7 -1
- package/packages/pi-coding-agent/src/core/tools/edit.ts +3 -0
- package/packages/pi-coding-agent/src/core/tools/write.ts +3 -0
- package/src/resources/extensions/google-search/index.ts +164 -47
- package/src/resources/extensions/gsd/auto-prompts.ts +103 -24
- package/src/resources/extensions/gsd/auto-worktree.ts +93 -9
- package/src/resources/extensions/gsd/auto.ts +424 -30
- package/src/resources/extensions/gsd/commands.ts +518 -36
- package/src/resources/extensions/gsd/context-budget.ts +243 -0
- package/src/resources/extensions/gsd/context-store.ts +195 -0
- package/src/resources/extensions/gsd/dashboard-overlay.ts +41 -3
- package/src/resources/extensions/gsd/db-writer.ts +341 -0
- package/src/resources/extensions/gsd/debug-logger.ts +178 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +0 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +54 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +286 -0
- package/src/resources/extensions/gsd/doctor.ts +283 -2
- package/src/resources/extensions/gsd/export.ts +81 -2
- package/src/resources/extensions/gsd/files.ts +39 -9
- package/src/resources/extensions/gsd/git-service.ts +6 -0
- package/src/resources/extensions/gsd/gsd-db.ts +752 -0
- package/src/resources/extensions/gsd/guided-flow.ts +26 -1
- package/src/resources/extensions/gsd/history.ts +0 -1
- package/src/resources/extensions/gsd/index.ts +277 -1
- package/src/resources/extensions/gsd/md-importer.ts +526 -0
- package/src/resources/extensions/gsd/metrics.ts +39 -3
- package/src/resources/extensions/gsd/notifications.ts +0 -1
- package/src/resources/extensions/gsd/post-unit-hooks.ts +70 -1
- package/src/resources/extensions/gsd/preferences.ts +125 -150
- package/src/resources/extensions/gsd/prompts/execute-task.md +3 -5
- package/src/resources/extensions/gsd/prompts/heal-skill.md +45 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +5 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +48 -0
- package/src/resources/extensions/gsd/prompts/system.md +2 -1
- package/src/resources/extensions/gsd/quick.ts +156 -0
- package/src/resources/extensions/gsd/skill-discovery.ts +5 -3
- package/src/resources/extensions/gsd/skill-health.ts +417 -0
- package/src/resources/extensions/gsd/skill-telemetry.ts +127 -0
- package/src/resources/extensions/gsd/state.ts +30 -0
- package/src/resources/extensions/gsd/templates/preferences.md +1 -0
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +283 -0
- package/src/resources/extensions/gsd/tests/context-compression.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +462 -0
- package/src/resources/extensions/gsd/tests/continue-here.test.ts +204 -0
- package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +346 -0
- package/src/resources/extensions/gsd/tests/db-writer.test.ts +602 -0
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +185 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +406 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +22 -0
- package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +244 -0
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +303 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +353 -0
- package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +125 -0
- package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +326 -0
- package/src/resources/extensions/gsd/tests/integration-edge.test.ts +228 -0
- package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +277 -0
- package/src/resources/extensions/gsd/tests/md-importer.test.ts +411 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +197 -0
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/parsers.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +41 -1
- package/src/resources/extensions/gsd/tests/preferences-git.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/preferences-mode.test.ts +110 -0
- package/src/resources/extensions/gsd/tests/preferences-models.test.ts +0 -1
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +464 -0
- package/src/resources/extensions/gsd/tests/prompt-db.test.ts +385 -0
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +262 -1
- package/src/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +17 -29
- package/src/resources/extensions/gsd/tests/resolve-ts.mjs +2 -8
- package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +126 -0
- package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +31 -8
- package/src/resources/extensions/gsd/tests/token-savings.test.ts +366 -0
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +145 -0
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +228 -5
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +442 -0
- package/src/resources/extensions/gsd/tests/worktree-post-create-hook.test.ts +165 -0
- package/src/resources/extensions/gsd/types.ts +29 -0
- package/src/resources/extensions/gsd/undo.ts +0 -1
- package/src/resources/extensions/gsd/unit-runtime.ts +5 -1
- package/src/resources/extensions/gsd/visualizer-data.ts +352 -1
- package/src/resources/extensions/gsd/visualizer-overlay.ts +166 -22
- package/src/resources/extensions/gsd/visualizer-views.ts +464 -2
- package/src/resources/extensions/gsd/worktree-command.ts +18 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +11 -4
- package/src/resources/extensions/remote-questions/config.ts +4 -2
- package/src/resources/extensions/remote-questions/discord-adapter.ts +2 -4
- package/src/resources/extensions/remote-questions/format.ts +154 -8
- package/src/resources/extensions/remote-questions/manager.ts +9 -7
- package/src/resources/extensions/remote-questions/remote-command.ts +100 -4
- package/src/resources/extensions/remote-questions/slack-adapter.ts +58 -2
- package/src/resources/extensions/remote-questions/telegram-adapter.ts +161 -0
- package/src/resources/extensions/remote-questions/types.ts +2 -1
- package/src/resources/extensions/ttsr/ttsr-manager.ts +26 -0
- package/src/resources/extensions/voice/index.ts +4 -3
|
@@ -55,7 +55,7 @@ export async function inlineFileOptional(
|
|
|
55
55
|
* Load and inline dependency slice summaries (full content, not just paths).
|
|
56
56
|
*/
|
|
57
57
|
export async function inlineDependencySummaries(
|
|
58
|
-
mid: string, sid: string, base: string,
|
|
58
|
+
mid: string, sid: string, base: string, budgetChars?: number,
|
|
59
59
|
): Promise<string> {
|
|
60
60
|
const roadmapFile = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
61
61
|
const roadmapContent = roadmapFile ? await loadFile(roadmapFile) : null;
|
|
@@ -79,7 +79,14 @@ export async function inlineDependencySummaries(
|
|
|
79
79
|
sections.push(`- \`${relPath}\` _(not found)_`);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
|
|
83
|
+
const result = sections.join("\n\n");
|
|
84
|
+
// When a budget is provided, truncate at section boundaries to fit
|
|
85
|
+
if (budgetChars !== undefined && result.length > budgetChars) {
|
|
86
|
+
const { truncateAtSectionBoundary } = await import("./context-budget.js");
|
|
87
|
+
return truncateAtSectionBoundary(result, budgetChars).content;
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
/**
|
|
@@ -95,6 +102,76 @@ export async function inlineGsdRootFile(
|
|
|
95
102
|
return inlineFileOptional(absPath, relGsdRootFile(key), label);
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
// ─── DB-Aware Inline Helpers ──────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Inline decisions with optional milestone scoping from the DB.
|
|
109
|
+
* Falls back to filesystem via inlineGsdRootFile when DB unavailable or empty.
|
|
110
|
+
*/
|
|
111
|
+
export async function inlineDecisionsFromDb(
|
|
112
|
+
base: string, milestoneId?: string, scope?: string,
|
|
113
|
+
): Promise<string | null> {
|
|
114
|
+
try {
|
|
115
|
+
const { isDbAvailable } = await import("./gsd-db.js");
|
|
116
|
+
if (isDbAvailable()) {
|
|
117
|
+
const { queryDecisions, formatDecisionsForPrompt } = await import("./context-store.js");
|
|
118
|
+
const decisions = queryDecisions({ milestoneId, scope });
|
|
119
|
+
if (decisions.length > 0) {
|
|
120
|
+
const formatted = formatDecisionsForPrompt(decisions);
|
|
121
|
+
return `### Decisions\nSource: \`.gsd/DECISIONS.md\`\n\n${formatted}`;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
} catch {
|
|
125
|
+
// DB not available — fall through to filesystem
|
|
126
|
+
}
|
|
127
|
+
return inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Inline requirements with optional slice scoping from the DB.
|
|
132
|
+
* Falls back to filesystem via inlineGsdRootFile when DB unavailable or empty.
|
|
133
|
+
*/
|
|
134
|
+
export async function inlineRequirementsFromDb(
|
|
135
|
+
base: string, sliceId?: string,
|
|
136
|
+
): Promise<string | null> {
|
|
137
|
+
try {
|
|
138
|
+
const { isDbAvailable } = await import("./gsd-db.js");
|
|
139
|
+
if (isDbAvailable()) {
|
|
140
|
+
const { queryRequirements, formatRequirementsForPrompt } = await import("./context-store.js");
|
|
141
|
+
const requirements = queryRequirements({ sliceId });
|
|
142
|
+
if (requirements.length > 0) {
|
|
143
|
+
const formatted = formatRequirementsForPrompt(requirements);
|
|
144
|
+
return `### Requirements\nSource: \`.gsd/REQUIREMENTS.md\`\n\n${formatted}`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
} catch {
|
|
148
|
+
// DB not available — fall through to filesystem
|
|
149
|
+
}
|
|
150
|
+
return inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Inline project context from the DB.
|
|
155
|
+
* Falls back to filesystem via inlineGsdRootFile when DB unavailable or empty.
|
|
156
|
+
*/
|
|
157
|
+
export async function inlineProjectFromDb(
|
|
158
|
+
base: string,
|
|
159
|
+
): Promise<string | null> {
|
|
160
|
+
try {
|
|
161
|
+
const { isDbAvailable } = await import("./gsd-db.js");
|
|
162
|
+
if (isDbAvailable()) {
|
|
163
|
+
const { queryProject } = await import("./context-store.js");
|
|
164
|
+
const content = queryProject();
|
|
165
|
+
if (content) {
|
|
166
|
+
return `### Project\nSource: \`.gsd/PROJECT.md\`\n\n${content}`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
} catch {
|
|
170
|
+
// DB not available — fall through to filesystem
|
|
171
|
+
}
|
|
172
|
+
return inlineGsdRootFile(base, "project.md", "Project");
|
|
173
|
+
}
|
|
174
|
+
|
|
98
175
|
// ─── Skill Discovery ──────────────────────────────────────────────────────
|
|
99
176
|
|
|
100
177
|
/**
|
|
@@ -371,11 +448,11 @@ export async function buildResearchMilestonePrompt(mid: string, midTitle: string
|
|
|
371
448
|
|
|
372
449
|
const inlined: string[] = [];
|
|
373
450
|
inlined.push(await inlineFile(contextPath, contextRel, "Milestone Context"));
|
|
374
|
-
const projectInline = await
|
|
451
|
+
const projectInline = await inlineProjectFromDb(base);
|
|
375
452
|
if (projectInline) inlined.push(projectInline);
|
|
376
|
-
const requirementsInline = await
|
|
453
|
+
const requirementsInline = await inlineRequirementsFromDb(base);
|
|
377
454
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
378
|
-
const decisionsInline = await
|
|
455
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
379
456
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
380
457
|
const knowledgeInlineRM = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
381
458
|
if (knowledgeInlineRM) inlined.push(knowledgeInlineRM);
|
|
@@ -409,12 +486,14 @@ export async function buildPlanMilestonePrompt(mid: string, midTitle: string, ba
|
|
|
409
486
|
const { inlinePriorMilestoneSummary } = await import("./files.js");
|
|
410
487
|
const priorSummaryInline = await inlinePriorMilestoneSummary(mid, base);
|
|
411
488
|
if (priorSummaryInline) inlined.push(priorSummaryInline);
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
489
|
+
if (inlineLevel !== "minimal") {
|
|
490
|
+
const projectInline = await inlineProjectFromDb(base);
|
|
491
|
+
if (projectInline) inlined.push(projectInline);
|
|
492
|
+
const requirementsInline = await inlineRequirementsFromDb(base);
|
|
493
|
+
if (requirementsInline) inlined.push(requirementsInline);
|
|
494
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
495
|
+
if (decisionsInline) inlined.push(decisionsInline);
|
|
496
|
+
}
|
|
418
497
|
const knowledgeInlinePM = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
419
498
|
if (knowledgeInlinePM) inlined.push(knowledgeInlinePM);
|
|
420
499
|
inlined.push(inlineTemplate("roadmap", "Roadmap"));
|
|
@@ -461,9 +540,9 @@ export async function buildResearchSlicePrompt(
|
|
|
461
540
|
if (contextInline) inlined.push(contextInline);
|
|
462
541
|
const researchInline = await inlineFileOptional(milestoneResearchPath, milestoneResearchRel, "Milestone Research");
|
|
463
542
|
if (researchInline) inlined.push(researchInline);
|
|
464
|
-
const decisionsInline = await
|
|
543
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
465
544
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
466
|
-
const requirementsInline = await
|
|
545
|
+
const requirementsInline = await inlineRequirementsFromDb(base, sid);
|
|
467
546
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
468
547
|
const knowledgeInlineRS = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
469
548
|
if (knowledgeInlineRS) inlined.push(knowledgeInlineRS);
|
|
@@ -505,9 +584,9 @@ export async function buildPlanSlicePrompt(
|
|
|
505
584
|
const researchInline = await inlineFileOptional(researchPath, researchRel, "Slice Research");
|
|
506
585
|
if (researchInline) inlined.push(researchInline);
|
|
507
586
|
if (inlineLevel !== "minimal") {
|
|
508
|
-
const decisionsInline = await
|
|
587
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
509
588
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
510
|
-
const requirementsInline = await
|
|
589
|
+
const requirementsInline = await inlineRequirementsFromDb(base, sid);
|
|
511
590
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
512
591
|
}
|
|
513
592
|
const knowledgeInlinePS = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
@@ -634,7 +713,7 @@ export async function buildCompleteSlicePrompt(
|
|
|
634
713
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Milestone Roadmap"));
|
|
635
714
|
inlined.push(await inlineFile(slicePlanPath, slicePlanRel, "Slice Plan"));
|
|
636
715
|
if (inlineLevel !== "minimal") {
|
|
637
|
-
const requirementsInline = await
|
|
716
|
+
const requirementsInline = await inlineRequirementsFromDb(base, sid);
|
|
638
717
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
639
718
|
}
|
|
640
719
|
const knowledgeInlineCS = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
@@ -705,11 +784,11 @@ export async function buildCompleteMilestonePrompt(
|
|
|
705
784
|
|
|
706
785
|
// Inline root GSD files (skip for minimal — completion can read these if needed)
|
|
707
786
|
if (inlineLevel !== "minimal") {
|
|
708
|
-
const requirementsInline = await
|
|
787
|
+
const requirementsInline = await inlineRequirementsFromDb(base);
|
|
709
788
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
710
|
-
const decisionsInline = await
|
|
789
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
711
790
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
712
|
-
const projectInline = await
|
|
791
|
+
const projectInline = await inlineProjectFromDb(base);
|
|
713
792
|
if (projectInline) inlined.push(projectInline);
|
|
714
793
|
}
|
|
715
794
|
const knowledgeInlineCM = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
@@ -767,7 +846,7 @@ export async function buildReplanSlicePrompt(
|
|
|
767
846
|
}
|
|
768
847
|
|
|
769
848
|
// Inline decisions
|
|
770
|
-
const decisionsInline = await
|
|
849
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
771
850
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
772
851
|
const replanActiveOverrides = await loadActiveOverrides(base);
|
|
773
852
|
const replanOverridesInline = formatOverridesSection(replanActiveOverrides);
|
|
@@ -818,7 +897,7 @@ export async function buildRunUatPrompt(
|
|
|
818
897
|
if (summaryInline) inlined.push(summaryInline);
|
|
819
898
|
}
|
|
820
899
|
|
|
821
|
-
const projectInline = await
|
|
900
|
+
const projectInline = await inlineProjectFromDb(base);
|
|
822
901
|
if (projectInline) inlined.push(projectInline);
|
|
823
902
|
|
|
824
903
|
const inlinedContext = `## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`;
|
|
@@ -850,11 +929,11 @@ export async function buildReassessRoadmapPrompt(
|
|
|
850
929
|
inlined.push(await inlineFile(roadmapPath, roadmapRel, "Current Roadmap"));
|
|
851
930
|
inlined.push(await inlineFile(summaryPath, summaryRel, `${completedSliceId} Summary`));
|
|
852
931
|
if (inlineLevel !== "minimal") {
|
|
853
|
-
const projectInline = await
|
|
932
|
+
const projectInline = await inlineProjectFromDb(base);
|
|
854
933
|
if (projectInline) inlined.push(projectInline);
|
|
855
|
-
const requirementsInline = await
|
|
934
|
+
const requirementsInline = await inlineRequirementsFromDb(base);
|
|
856
935
|
if (requirementsInline) inlined.push(requirementsInline);
|
|
857
|
-
const decisionsInline = await
|
|
936
|
+
const decisionsInline = await inlineDecisionsFromDb(base, mid);
|
|
858
937
|
if (decisionsInline) inlined.push(decisionsInline);
|
|
859
938
|
}
|
|
860
939
|
const knowledgeInlineRA = await inlineGsdRootFile(base, "knowledge.md", "Project Knowledge");
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { existsSync, cpSync, readFileSync, realpathSync, utimesSync } from "node:fs";
|
|
10
|
-
import { join, resolve } from "node:path";
|
|
11
|
-
import {
|
|
10
|
+
import { isAbsolute, join, resolve } from "node:path";
|
|
11
|
+
import { copyWorktreeDb, reconcileWorktreeDb, isDbAvailable } from "./gsd-db.js";
|
|
12
|
+
import { execSync, execFileSync } from "node:child_process";
|
|
12
13
|
import {
|
|
13
14
|
createWorktree,
|
|
14
15
|
removeWorktree,
|
|
@@ -33,6 +34,7 @@ import {
|
|
|
33
34
|
nativeAddPaths,
|
|
34
35
|
nativeRmForce,
|
|
35
36
|
nativeBranchDelete,
|
|
37
|
+
nativeBranchExists,
|
|
36
38
|
} from "./native-git-bridge.js";
|
|
37
39
|
|
|
38
40
|
// ─── Module State ──────────────────────────────────────────────────────────
|
|
@@ -75,6 +77,48 @@ function nudgeGitBranchCache(previousCwd: string): void {
|
|
|
75
77
|
}
|
|
76
78
|
}
|
|
77
79
|
|
|
80
|
+
// ─── Worktree Post-Create Hook (#597) ────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Run the user-configured post-create hook script after worktree creation.
|
|
84
|
+
* The script receives SOURCE_DIR and WORKTREE_DIR as environment variables.
|
|
85
|
+
* Failure is non-fatal — returns the error message or null on success.
|
|
86
|
+
*
|
|
87
|
+
* Reads the hook path from git.worktree_post_create in preferences.
|
|
88
|
+
* Pass hookPath directly to bypass preference loading (useful for testing).
|
|
89
|
+
*/
|
|
90
|
+
export function runWorktreePostCreateHook(sourceDir: string, worktreeDir: string, hookPath?: string): string | null {
|
|
91
|
+
if (hookPath === undefined) {
|
|
92
|
+
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
93
|
+
hookPath = prefs?.worktree_post_create;
|
|
94
|
+
}
|
|
95
|
+
if (!hookPath) return null;
|
|
96
|
+
|
|
97
|
+
// Resolve relative paths against the source project root
|
|
98
|
+
const resolved = isAbsolute(hookPath) ? hookPath : join(sourceDir, hookPath);
|
|
99
|
+
if (!existsSync(resolved)) {
|
|
100
|
+
return `Worktree post-create hook not found: ${resolved}`;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
execSync(resolved, {
|
|
105
|
+
cwd: worktreeDir,
|
|
106
|
+
env: {
|
|
107
|
+
...process.env,
|
|
108
|
+
SOURCE_DIR: sourceDir,
|
|
109
|
+
WORKTREE_DIR: worktreeDir,
|
|
110
|
+
},
|
|
111
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
112
|
+
encoding: "utf-8",
|
|
113
|
+
timeout: 30_000, // 30 second timeout
|
|
114
|
+
});
|
|
115
|
+
return null;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
118
|
+
return `Worktree post-create hook failed: ${msg}`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
78
122
|
// ─── Auto-Worktree Branch Naming ───────────────────────────────────────────
|
|
79
123
|
|
|
80
124
|
export function autoWorktreeBranch(milestoneId: string): string {
|
|
@@ -93,11 +137,21 @@ export function autoWorktreeBranch(milestoneId: string): string {
|
|
|
93
137
|
export function createAutoWorktree(basePath: string, milestoneId: string): string {
|
|
94
138
|
const branch = autoWorktreeBranch(milestoneId);
|
|
95
139
|
|
|
96
|
-
//
|
|
97
|
-
//
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
const
|
|
140
|
+
// Check if the milestone branch already exists — it survives auto-mode
|
|
141
|
+
// stop/pause and contains committed work from prior sessions. If it exists,
|
|
142
|
+
// re-attach the worktree to it WITHOUT resetting. Only create a fresh branch
|
|
143
|
+
// from the integration branch when no prior work exists.
|
|
144
|
+
const branchExists = nativeBranchExists(basePath, branch);
|
|
145
|
+
|
|
146
|
+
let info: { name: string; path: string; branch: string; exists: boolean };
|
|
147
|
+
if (branchExists) {
|
|
148
|
+
// Re-attach worktree to the existing milestone branch (preserving commits)
|
|
149
|
+
info = createWorktree(basePath, milestoneId, { branch, reuseExistingBranch: true });
|
|
150
|
+
} else {
|
|
151
|
+
// Fresh start — create branch from integration branch
|
|
152
|
+
const integrationBranch = readIntegrationBranch(basePath, milestoneId) ?? undefined;
|
|
153
|
+
info = createWorktree(basePath, milestoneId, { branch, startPoint: integrationBranch });
|
|
154
|
+
}
|
|
101
155
|
|
|
102
156
|
// Copy .gsd/ planning artifacts from the source repo into the new worktree.
|
|
103
157
|
// Worktrees are fresh git checkouts — untracked files don't carry over.
|
|
@@ -106,6 +160,13 @@ export function createAutoWorktree(basePath: string, milestoneId: string): strin
|
|
|
106
160
|
// on plan-slice because the plan file doesn't exist in the worktree.
|
|
107
161
|
copyPlanningArtifacts(basePath, info.path);
|
|
108
162
|
|
|
163
|
+
// Run user-configured post-create hook (#597) — e.g. copy .env, symlink assets
|
|
164
|
+
const hookError = runWorktreePostCreateHook(basePath, info.path);
|
|
165
|
+
if (hookError) {
|
|
166
|
+
// Non-fatal — log but don't prevent worktree usage
|
|
167
|
+
console.error(`[GSD] ${hookError}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
109
170
|
const previousCwd = process.cwd();
|
|
110
171
|
|
|
111
172
|
try {
|
|
@@ -151,14 +212,28 @@ function copyPlanningArtifacts(srcBase: string, wtPath: string): void {
|
|
|
151
212
|
} catch { /* non-fatal */ }
|
|
152
213
|
}
|
|
153
214
|
}
|
|
215
|
+
|
|
216
|
+
// Copy gsd.db if present in source
|
|
217
|
+
const srcDb = join(srcGsd, "gsd.db");
|
|
218
|
+
const destDb = join(dstGsd, "gsd.db");
|
|
219
|
+
if (existsSync(srcDb)) {
|
|
220
|
+
try {
|
|
221
|
+
copyWorktreeDb(srcDb, destDb);
|
|
222
|
+
} catch { /* non-fatal */ }
|
|
223
|
+
}
|
|
154
224
|
}
|
|
155
225
|
|
|
156
226
|
/**
|
|
157
227
|
* Teardown an auto-worktree: chdir back to original base, then remove
|
|
158
228
|
* the worktree and its branch.
|
|
159
229
|
*/
|
|
160
|
-
export function teardownAutoWorktree(
|
|
230
|
+
export function teardownAutoWorktree(
|
|
231
|
+
originalBasePath: string,
|
|
232
|
+
milestoneId: string,
|
|
233
|
+
opts: { preserveBranch?: boolean } = {},
|
|
234
|
+
): void {
|
|
161
235
|
const branch = autoWorktreeBranch(milestoneId);
|
|
236
|
+
const { preserveBranch = false } = opts;
|
|
162
237
|
const previousCwd = process.cwd();
|
|
163
238
|
|
|
164
239
|
try {
|
|
@@ -171,7 +246,7 @@ export function teardownAutoWorktree(originalBasePath: string, milestoneId: stri
|
|
|
171
246
|
}
|
|
172
247
|
|
|
173
248
|
nudgeGitBranchCache(previousCwd);
|
|
174
|
-
removeWorktree(originalBasePath, milestoneId, { branch });
|
|
249
|
+
removeWorktree(originalBasePath, milestoneId, { branch, deleteBranch: !preserveBranch });
|
|
175
250
|
}
|
|
176
251
|
|
|
177
252
|
/**
|
|
@@ -299,6 +374,15 @@ export function mergeMilestoneToMain(
|
|
|
299
374
|
// 1. Auto-commit dirty state in worktree before leaving
|
|
300
375
|
autoCommitDirtyState(worktreeCwd);
|
|
301
376
|
|
|
377
|
+
// Reconcile worktree DB into main DB before leaving worktree context
|
|
378
|
+
if (isDbAvailable()) {
|
|
379
|
+
try {
|
|
380
|
+
const worktreeDbPath = join(worktreeCwd, ".gsd", "gsd.db");
|
|
381
|
+
const mainDbPath = join(originalBasePath_, ".gsd", "gsd.db");
|
|
382
|
+
reconcileWorktreeDb(mainDbPath, worktreeDbPath);
|
|
383
|
+
} catch { /* non-fatal */ }
|
|
384
|
+
}
|
|
385
|
+
|
|
302
386
|
// 2. Parse roadmap for slice listing
|
|
303
387
|
const roadmap = parseRoadmap(roadmapContent);
|
|
304
388
|
const completedSlices = roadmap.slices.filter(s => s.done);
|