* fix(#1521): resolve own runtime + worktrees-off for all non-Claude installs Generalizes the Codex-only #1515/#1519 fix to every non-Claude runtime, and wires it into the real install path (where it was previously dead-on-arrival). Root causes: 1. The runtime-default stamping lived only in `_applyRuntimeRewrites`, but the installer emits `gsd-core/workflows/*.md` via `copyWithPathReplacement`, which never calls it — so a real `--codex`/`--cursor`/etc. install emitted `--default claude` and worktrees-on. RUNTIME mis-resolved to claude and the workflow ran executors unisolated against the main checkout. (#1515/#1519 were also dead-on-arrival in real installs; this repairs them.) 2. Only `case 'codex'` was stamped; every other non-Claude runtime kept the Claude default. Fix: - New `_stampNonClaudeRuntimeDefaults(content, runtime)` (single shared helper) stamps `--default <runtime>` + `use_worktrees=false` for every `runtime != claude`; called from both `_applyRuntimeRewrites` and, crucially, `copyWithPathReplacement` in bin/install.js (the real workflow emit path). - Generalize the fail-closed worktree guard `= codex` -> `!= claude` in execute-phase/quick/diagnose-issues (worktree isolation is Claude-Code-only). - Flip manager/autonomous inline-vs-background gating to `codex -> background, everything-else -> inline` (research: only Codex can background-nest the pipeline's subagents; all others run inline, which they support). Worktree-capability determination is research-backed (official docs for all 14 non-Claude runtimes: none honor GSD's isolation="worktree" mechanism, only Codex background-nests). New end-to-end real-install test asserts the EMITTED workflow is stamped — the regression guard that would have caught the dead-on-arrival bug. Closes #1521 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013vX5eUtWa2wsZEyeMf5i3r * chore(#1521): backfill changeset PR number (#1537) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013vX5eUtWa2wsZEyeMf5i3r --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2119,6 +2119,40 @@ function computePathPrefix({ isGlobal, isOpencode, isWindowsHost: _isWindowsHost
|
||||
return `${resolvedTarget}/`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Canonical list of every non-Claude runtime that gsd-core emits artifacts for.
|
||||
* Exported so test files can import this single source of truth rather than
|
||||
* maintaining divergent hand-rolled arrays (#1521).
|
||||
*
|
||||
* Keep in sync with the runtime flags in bin/install.js and getDirName().
|
||||
*/
|
||||
const NON_CLAUDE_RUNTIMES: string[] = [
|
||||
'codex', 'opencode', 'kilo', 'gemini', 'copilot', 'antigravity',
|
||||
'cursor', 'windsurf', 'augment', 'trae', 'qwen', 'hermes', 'kimi',
|
||||
'codebuddy', 'cline',
|
||||
];
|
||||
|
||||
/**
|
||||
* #1521: Every non-Claude runtime resolves its own runtime identity from a
|
||||
* runtime-neutral config, and defaults workflow.use_worktrees to false —
|
||||
* GSD's worktree isolation uses Claude Code's isolation="worktree" spawn
|
||||
* parameter, which no other runtime honors. Stamped into the emitted
|
||||
* workflow runtime-resolution blocks. (Generalizes the Codex-only #1515 fix.)
|
||||
*
|
||||
* @private — exported as `_stampNonClaudeRuntimeDefaults` for tests.
|
||||
*/
|
||||
function _stampNonClaudeRuntimeDefaults(content: string, runtime: string): string {
|
||||
content = content.replace(
|
||||
/config-get workflow\.use_worktrees --raw 2>\/dev\/null \|\| echo "true"/g,
|
||||
'config-get workflow.use_worktrees --default false --raw 2>/dev/null || echo "false"',
|
||||
);
|
||||
content = content.replace(
|
||||
/config-get runtime --default claude --raw 2>\/dev\/null \|\| echo "claude"/g,
|
||||
`config-get runtime --default ${runtime} --raw 2>/dev/null || echo "${runtime}"`,
|
||||
);
|
||||
return content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the per-runtime rewrite table to a single content string.
|
||||
* Relocated from bin/install.js `_applyRuntimeRewrites`.
|
||||
@@ -2133,26 +2167,20 @@ function _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal = false, a
|
||||
const dirName = getDirName(runtime);
|
||||
const normalizedPathPrefix = pathPrefix.replace(/\/$/, '');
|
||||
|
||||
// #1521: stamp runtime identity + use_worktrees=false for every non-Claude runtime
|
||||
// before brand-specific path rewrites, so the replace operates on the pristine
|
||||
// source line and is idempotent regardless of subsequent path substitutions.
|
||||
if (runtime !== 'claude') {
|
||||
content = _stampNonClaudeRuntimeDefaults(content, runtime);
|
||||
}
|
||||
|
||||
switch (runtime) {
|
||||
case 'codex':
|
||||
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
||||
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
||||
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
||||
content = content.replace(/~\/\.codex\//g, pathPrefix);
|
||||
// #1515: stamp Codex's own runtime identity + safe worktree default into
|
||||
// emitted workflow runtime-resolution blocks. A Codex install with a
|
||||
// runtime-neutral .planning/config.json must resolve RUNTIME=codex (Codex
|
||||
// cannot honor Claude's isolation="worktree"), and default
|
||||
// workflow.use_worktrees to false so the fail-closed guard lets execution
|
||||
// proceed without worktrees instead of falling back to Claude semantics.
|
||||
content = content.replace(
|
||||
/config-get runtime --default claude --raw 2>\/dev\/null \|\| echo "claude"/g,
|
||||
'config-get runtime --default codex --raw 2>/dev/null || echo "codex"',
|
||||
);
|
||||
content = content.replace(
|
||||
/config-get workflow\.use_worktrees --raw 2>\/dev\/null \|\| echo "true"/g,
|
||||
'config-get workflow.use_worktrees --default false --raw 2>/dev/null || echo "false"',
|
||||
);
|
||||
// #1515 stamp moved to _stampNonClaudeRuntimeDefaults (#1521 generalisation).
|
||||
content = processAttribution(content, attribution);
|
||||
break;
|
||||
|
||||
@@ -2531,4 +2559,7 @@ export = {
|
||||
rewriteStagedCommandBodies,
|
||||
_computePathPrefix: computePathPrefix,
|
||||
_applyRuntimeRewrites,
|
||||
_stampNonClaudeRuntimeDefaults,
|
||||
// #1521: canonical non-Claude runtime list for test files and tooling
|
||||
NON_CLAUDE_RUNTIMES,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user