fix: make worktree cleanup fail closed (#3385)

* fix: make worktree cleanup fail closed

* chore: add changeset for worktree cleanup safety

* fix: address worktree cleanup review findings

* docs: label remove-workspace failure block

* fix: initialize worktree manifest before dispatch
This commit is contained in:
Tom Boucher
2026-05-10 19:48:28 -04:00
committed by GitHub
parent a51fc86a18
commit 570dddd1cd
13 changed files with 750 additions and 73 deletions

View File

@@ -16,6 +16,7 @@ import { uatRenderCheckpoint, auditUat } from './uat.js';
import { intelStatus, intelDiff, intelSnapshot, intelValidate, intelQuery, intelExtractExports, intelPatchMeta, intelUpdate } from './intel.js';
import { writeProfile, generateClaudeProfile, generateDevPreferences, generateClaudeMd } from './profile-output.js';
import { phaseMvpMode, taskIsBehaviorAdding, userStoryValidate } from './mvp.js';
import { worktreeCleanupWave } from './worktree.js';
export const DOMAIN_STATIC_CATALOG: ReadonlyArray<readonly [string, QueryHandler]> = [
['agent-skills', agentSkills],
@@ -59,6 +60,8 @@ export const DOMAIN_STATIC_CATALOG: ReadonlyArray<readonly [string, QueryHandler
['workstream complete', workstreamComplete],
['workstream.progress', workstreamProgress],
['workstream progress', workstreamProgress],
['worktree.cleanup-wave', worktreeCleanupWave],
['worktree cleanup-wave', worktreeCleanupWave],
['docs-init', docsInit],
['websearch', websearch],
['learnings.copy', learningsCopy],

39
sdk/src/query/worktree.ts Normal file
View File

@@ -0,0 +1,39 @@
import { spawnSync } from 'node:child_process';
import { resolveGsdToolsPath } from '../sdk-package-compatibility.js';
import type { QueryHandler } from './utils.js';
export const worktreeCleanupWave: QueryHandler = async (args, projectDir) => {
const toolsPath = resolveGsdToolsPath(projectDir);
const result = spawnSync(process.execPath, [toolsPath, 'worktree', 'cleanup-wave', ...args], {
cwd: projectDir,
encoding: 'utf-8',
stdio: ['pipe', 'pipe', 'pipe'],
timeout: 30000,
maxBuffer: 1024 * 1024,
env: {
...process.env,
GIT_TERMINAL_PROMPT: '0',
GCM_INTERACTIVE: 'never',
},
});
if (result.error) {
return { data: { ok: false, reason: result.error.message || 'gsd-tools invocation failed' } };
}
const stdout = (result.stdout || '').trim();
if (stdout) {
try {
return { data: JSON.parse(stdout) };
} catch {
return { data: { ok: result.status === 0, reason: stdout } };
}
}
return {
data: {
ok: result.status === 0,
reason: result.stderr?.trim() || (result.status === 0 ? 'ok' : 'gsd-tools error'),
},
};
};