feat(#2097): migrate Augment onto EoS declarative adapter + settings.json MCP companion (ADR-1239)
Fold augment's runtime-literal conversion branches onto descriptor-driven
hostBehaviors and delete dead code:
- Site A (_applyRuntimeRewrites case 'augment'): the 4 ~/.augment dot-dir
regexes now derive from getDirName('augment') via escapeRegExp (byte-
identical; getDirName('augment')==='.augment') — no runtime literal.
- Site B (applyRuntimeContentRewritesForCommandsInPlace): the
`if (runtime==='augment')` markdown-converter branch now reads
runtime.hostBehaviors.commandBodyConverter and dispatches through a local
COMMAND_BODY_CONVERTERS map (degrade-closed on unknown/absent name).
- Deleted dead `claudeToAugmentTools` map (zero refs; orphaned by ADR-1508
single-sourcing) and the unreachable `else if (isAugment)` agent-conversion
branch (augment ∈ _DESCRIPTOR_AGENTS_RUNTIMES → gated out upstream).
- Incidental orphan cleanup (no-defer): removed the equally-unreachable
`else if (isTrae)` agent-conversion arm left behind by trae's already-merged
migration #2094 (trae ∈ _DESCRIPTOR_AGENTS_RUNTIMES, same upstream gate).
copilot/windsurf/codebuddy arms are removed by their own pending migrations.
UPGRADE 3 (transport:mcp): register the GSD companion MCP server in Augment's
settings.json under mcpServers.gsd (Augment hosts MCP in settings.json, not a
standalone file). mergeGsdMcpServerIntoSettings mutates the in-memory settings
object finishInstall already writes (gated on hostBehaviors.mcpCompanion===
'settings-json'); non-destructive + idempotent; symmetric uninstall removal.
settings.json is golden-excluded, so no golden change. UPGRADE 1 (named/
background dispatch) + UPGRADE 2 (settings-json hook bus, Claude dialect)
were already live in production — this adds tests exercising both.
Golden: byte-identical for all 16 runtimes (folds preserve regex behavior;
MCP lives in golden-excluded settings.json) — verified by a real double-install
tree diff. Tests: declarative-reference-augment (adapter/axes/fail-closed/
undocumented-sub-axes + source-grep guard scoped to conversion-logic branches)
+ augment-upgrades (dispatch negotiation, hook-bus live install, MCP add/
idempotent/preserve/uninstall). Matrix + connect-gsd-mcp-server + a stale
install-on-your-runtime hook-ownership claim corrected; changeset (Changed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1107,6 +1107,11 @@ function convertClaudeToAugmentMarkdown(content) {
|
||||
return converted;
|
||||
}
|
||||
|
||||
// #2097 (ADR-1239): command-body converters selected by descriptor
|
||||
// (runtime.hostBehaviors.commandBodyConverter) instead of a runtime-name
|
||||
// branch. Degrade-closed: unknown/absent name → no conversion.
|
||||
const COMMAND_BODY_CONVERTERS = { convertClaudeToAugmentMarkdown };
|
||||
|
||||
function getAugmentSkillAdapterHeader(skillName) {
|
||||
return `<augment_skill_adapter>
|
||||
## A. Skill Invocation
|
||||
@@ -2442,19 +2447,24 @@ function _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal = false, a
|
||||
break;
|
||||
}
|
||||
|
||||
case 'augment':
|
||||
case 'augment': {
|
||||
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
||||
content = content.replace(/\$HOME\/\.claude\//g, pathPrefix);
|
||||
content = content.replace(/\.\/\.claude\//g, `./${dirName}/`);
|
||||
content = content.replace(/~\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
||||
content = content.replace(/\$HOME\/\.claude(?![\w-])/g, normalizedPathPrefix);
|
||||
content = content.replace(/\.\/\.claude(?![\w-])/g, `./${dirName}`);
|
||||
content = content.replace(/~\/\.augment\//g, pathPrefix);
|
||||
content = content.replace(/\$HOME\/\.augment\//g, pathPrefix);
|
||||
content = content.replace(/~\/\.augment(?![\w-])/g, normalizedPathPrefix);
|
||||
content = content.replace(/\$HOME\/\.augment(?![\w-])/g, normalizedPathPrefix);
|
||||
// #2097: dot-dir self-references (~/.augment/…) → resolved prefix,
|
||||
// dirName-derived (no runtime literal). getDirName('augment') resolves
|
||||
// to '.augment', so this is byte-identical to the prior hardcoded regexes.
|
||||
const _dd = escapeRegExp(dirName);
|
||||
content = content.replace(new RegExp('~/' + _dd + '/', 'g'), pathPrefix);
|
||||
content = content.replace(new RegExp('\\$HOME/' + _dd + '/', 'g'), pathPrefix);
|
||||
content = content.replace(new RegExp('~/' + _dd + '(?![\\w-])', 'g'), normalizedPathPrefix);
|
||||
content = content.replace(new RegExp('\\$HOME/' + _dd + '(?![\\w-])', 'g'), normalizedPathPrefix);
|
||||
content = processAttribution(content, attribution);
|
||||
break;
|
||||
}
|
||||
|
||||
case 'trae':
|
||||
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
||||
@@ -2631,8 +2641,11 @@ function applyRuntimeContentRewritesForCommandsInPlace(stagedDir, runtime, pathP
|
||||
if (!entry.isFile() || !entry.name.endsWith('.md')) continue;
|
||||
let content = fs.readFileSync(path.join(stagedDir, entry.name), 'utf8');
|
||||
content = _applyRuntimeRewrites(content, runtime, pathPrefix, isGlobal, attribution);
|
||||
if (runtime === 'augment') {
|
||||
content = convertClaudeToAugmentMarkdown(content);
|
||||
// #2097 (ADR-1239): descriptor-driven — commandBodyConverter name comes
|
||||
// from runtime.hostBehaviors instead of a hardcoded runtime-name branch.
|
||||
const _cmdConv = _hostBehaviors(runtime).commandBodyConverter;
|
||||
if (_cmdConv && COMMAND_BODY_CONVERTERS[_cmdConv]) {
|
||||
content = COMMAND_BODY_CONVERTERS[_cmdConv](content);
|
||||
}
|
||||
fs.writeFileSync(path.join(tempDir, entry.name), content);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user