@skillcap/gdh 0.26.10 → 2.0.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/INSTALL-BUNDLE.json +1 -1
- package/README.md +1 -1
- package/RELEASE-SPAN-UPDATE-CONTRACTS.json +125 -0
- package/node_modules/@gdh/adapters/dist/codex-authoring-hook-block.d.ts +16 -0
- package/node_modules/@gdh/adapters/dist/codex-authoring-hook-block.d.ts.map +1 -0
- package/node_modules/@gdh/adapters/dist/codex-authoring-hook-block.js +40 -0
- package/node_modules/@gdh/adapters/dist/codex-authoring-hook-block.js.map +1 -0
- package/node_modules/@gdh/adapters/dist/index.d.ts +2 -30
- package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/index.js +99 -455
- package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.js +1 -1
- package/node_modules/@gdh/adapters/dist/self-update-mechanics.js.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts +4 -13
- package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts.map +1 -1
- package/node_modules/@gdh/adapters/dist/skill-rendering.js +36 -98
- package/node_modules/@gdh/adapters/dist/skill-rendering.js.map +1 -1
- package/node_modules/@gdh/adapters/package.json +8 -8
- package/node_modules/@gdh/authoring/package.json +2 -2
- package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/index.js +16 -23
- package/node_modules/@gdh/cli/dist/index.js.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/migrate.js +1 -4
- package/node_modules/@gdh/cli/dist/migrate.js.map +1 -1
- package/node_modules/@gdh/cli/dist/setup.d.ts.map +1 -1
- package/node_modules/@gdh/cli/dist/setup.js +6 -12
- package/node_modules/@gdh/cli/dist/setup.js.map +1 -1
- package/node_modules/@gdh/cli/package.json +10 -10
- package/node_modules/@gdh/core/dist/index.d.ts +18 -5
- package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/index.js +15 -6
- package/node_modules/@gdh/core/dist/index.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts +18 -54
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js +12 -67
- package/node_modules/@gdh/core/dist/migrations/managed-surface-classes.js.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.d.ts +11 -22
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.d.ts.map +1 -1
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.js +36 -38
- package/node_modules/@gdh/core/dist/migrations/managed-target-surface-inventory.js.map +1 -1
- package/node_modules/@gdh/core/package.json +1 -1
- package/node_modules/@gdh/docs/dist/recovery-hints.d.ts +18 -4
- package/node_modules/@gdh/docs/dist/recovery-hints.d.ts.map +1 -1
- package/node_modules/@gdh/docs/dist/recovery-hints.js +32 -34
- package/node_modules/@gdh/docs/dist/recovery-hints.js.map +1 -1
- package/node_modules/@gdh/docs/package.json +2 -2
- package/node_modules/@gdh/mcp/package.json +8 -8
- package/node_modules/@gdh/observability/package.json +2 -2
- package/node_modules/@gdh/runtime/package.json +2 -2
- package/node_modules/@gdh/scan/dist/onboard.js +2 -2
- package/node_modules/@gdh/scan/dist/onboard.js.map +1 -1
- package/node_modules/@gdh/scan/package.json +3 -3
- package/node_modules/@gdh/verify/package.json +7 -7
- package/package.json +11 -11
|
@@ -5,22 +5,22 @@ import os from "node:os";
|
|
|
5
5
|
import path from "node:path";
|
|
6
6
|
import { promisify } from "node:util";
|
|
7
7
|
import { readProjectConfig, readWorktreeState, resolveAuthoringStatus, resolveEffectiveTargetPath, resolvePinnedVersion, resolvePinnedVersionOrNull, resolveProjectRoot, } from "@gdh/authoring";
|
|
8
|
-
import { assertClassRegistered, assertProjectLifecycleCompatibilityInvariant, definePackageBoundary, GDH_AGENT_CONTRACT_VERSION,
|
|
8
|
+
import { assertClassRegistered, assertProjectLifecycleCompatibilityInvariant, definePackageBoundary, GDH_AGENT_CONTRACT_VERSION, GDH_GUIDANCE_INDEX_VERSION, GDH_GUIDANCE_UNIT_VERSION, GDH_PROJECT_CONFIG_VERSION, GDH_RECIPE_SCHEMA_VERSION, GDH_RULES_SCHEMA_VERSION, GDH_SCENARIO_SCHEMA_VERSION, resolveConfiguredGodotEditorBin, resolveCurrentGdhInstall, resolveGdhProductMetadata, } from "@gdh/core";
|
|
9
9
|
import { GDH_GUIDANCE_DIRECTORY_RELATIVE_PATH, GUIDANCE_INDEX_RELATIVE_PATH, createDefaultGuidanceUnits, createDefaultRulesDocument, getGuidanceStatus, readRulesDocument, renderRulesYaml, resolveGuidanceQuery, resolveRecoveryHints, } from "@gdh/docs";
|
|
10
10
|
import { inspectGuidanceAudit } from "@gdh/observability";
|
|
11
11
|
import { inspectRuntimeBridgeBroker, inspectRuntimeBridgeSurface, inspectRuntimeKnowledgeSurface, } from "@gdh/runtime";
|
|
12
12
|
import { readInventoryCacheOrScan } from "@gdh/scan";
|
|
13
13
|
import { CLAUDE_SETTINGS_RELATIVE_PATH, patchClaudeSettingsForGdhAuthoringHooks, patchClaudeSettingsForGdhSessionStart, patchClaudeSettingsForGdhStatusline, } from "./claude-settings-patch.js";
|
|
14
14
|
import { computeDeferredActionsAdvisory, } from "./deferred-actions-advisory.js";
|
|
15
|
-
import { CLAUDE_AUTHORING_HOOK_RELATIVE_PATH,
|
|
15
|
+
import { CLAUDE_AUTHORING_HOOK_RELATIVE_PATH, CODEX_AUTHORING_HOOK_RELATIVE_PATH, renderGdhAuthoringHook, } from "./authoring-hook-render.js";
|
|
16
16
|
import { computeStateRelativePathFromHook } from "./authoring-hook-state-path.js";
|
|
17
|
+
import { removeManagedCodexAuthoringHookBlock, renderManagedCodexAuthoringHookBlock, } from "./codex-authoring-hook-block.js";
|
|
17
18
|
import { CLAUDE_STATUSLINE_RELATIVE_PATH, renderClaudeUpdateStatusline, } from "./claude-statusline-render.js";
|
|
18
19
|
import { CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH, renderClaudeCheckUpdateHook, } from "./claude-update-hook-render.js";
|
|
19
20
|
import { renderClaudeCheckUpdateWorker } from "./claude-update-worker-render.js";
|
|
20
|
-
import { GDH_MANAGED_AGENT_SKILL_MARKER, renderClaudeMigrateSkill, renderClaudeOnboardSkill, renderClaudePrepareSkill, renderClaudeRunGameSkill,
|
|
21
|
-
export { GDH_MANAGED_AGENT_SKILL_MARKER, GDH_SKILL_DEFINITIONS, GDH_SKILL_IDS, renderGdhSkill, renderManagedSkillMarker, renderClaudeMigrateSkill, renderClaudeOnboardSkill, renderClaudePrepareSkill, renderClaudeRunGameSkill,
|
|
21
|
+
import { GDH_MANAGED_AGENT_SKILL_MARKER, renderClaudeMigrateSkill, renderClaudeOnboardSkill, renderClaudePrepareSkill, renderClaudeRunGameSkill, renderClaudeStatusSkill, renderClaudeUpdateSkill, renderCodexMigrateSkill, renderCodexOnboardSkill, renderCodexPrepareSkill, renderCodexRunGameSkill, renderCodexStatusSkill, renderCodexUpdateSkill, } from "./skill-rendering.js";
|
|
22
|
+
export { GDH_MANAGED_AGENT_SKILL_MARKER, GDH_SKILL_DEFINITIONS, GDH_SKILL_IDS, renderGdhSkill, renderManagedSkillMarker, renderClaudeMigrateSkill, renderClaudeOnboardSkill, renderClaudePrepareSkill, renderClaudeRunGameSkill, renderClaudeStatusSkill, renderClaudeUpdateSkill, renderCodexMigrateSkill, renderCodexOnboardSkill, renderCodexPrepareSkill, renderCodexRunGameSkill, renderCodexStatusSkill, renderCodexUpdateSkill, } from "./skill-rendering.js";
|
|
22
23
|
// Module-load drift guard. See packages/core/src/migrations/managed-surface-classes.ts.
|
|
23
|
-
assertClassRegistered("cursor_rule", "deterministic");
|
|
24
24
|
assertClassRegistered("claude_onboard_command", "deterministic");
|
|
25
25
|
assertClassRegistered("claude_status_command", "deterministic");
|
|
26
26
|
assertClassRegistered("claude_scan_command", "deterministic");
|
|
@@ -48,14 +48,10 @@ export const adaptersPackage = definePackageBoundary({
|
|
|
48
48
|
export const SUPPORTED_AGENTS = [
|
|
49
49
|
"codex",
|
|
50
50
|
"claude",
|
|
51
|
-
"cursor",
|
|
52
51
|
];
|
|
53
52
|
export const CLAUDE_SHIM_RELATIVE_PATH = "CLAUDE.md";
|
|
54
53
|
export const CLAUDE_ONBOARD_SKILL_RELATIVE_PATH = ".claude/skills/gdh-onboard/SKILL.md";
|
|
55
54
|
export const PROJECT_MCP_RELATIVE_PATH = ".mcp.json";
|
|
56
|
-
export const CURSOR_MCP_RELATIVE_PATH = ".cursor/mcp.json";
|
|
57
|
-
export const CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/gdh-agent.mdc";
|
|
58
|
-
export const CURSOR_ONBOARD_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-onboard.md";
|
|
59
55
|
export const CODEX_ONBOARD_SKILL_RELATIVE_PATH = ".agents/skills/gdh-onboard/SKILL.md";
|
|
60
56
|
export const CLAUDE_STATUS_SKILL_RELATIVE_PATH = ".claude/skills/gdh-status/SKILL.md";
|
|
61
57
|
export const CLAUDE_MIGRATE_SKILL_RELATIVE_PATH = ".claude/skills/gdh-migrate/SKILL.md";
|
|
@@ -67,10 +63,6 @@ export const CODEX_MIGRATE_SKILL_RELATIVE_PATH = ".agents/skills/gdh-migrate/SKI
|
|
|
67
63
|
export const CODEX_CHECK_SKILL_RELATIVE_PATH = ".agents/skills/gdh-check/SKILL.md";
|
|
68
64
|
export const CODEX_PREPARE_SKILL_RELATIVE_PATH = ".agents/skills/gdh-prepare/SKILL.md";
|
|
69
65
|
export const CODEX_RUN_GAME_SKILL_RELATIVE_PATH = ".agents/skills/gdh-run-game/SKILL.md";
|
|
70
|
-
export const CURSOR_STATUS_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-status.md";
|
|
71
|
-
export const CURSOR_MIGRATE_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-migrate.md";
|
|
72
|
-
export const CURSOR_PREPARE_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-prepare.md";
|
|
73
|
-
export const CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-run-game.md";
|
|
74
66
|
// Phase 13 SELF-01: /gdh-update skill surface path constants. The rendered
|
|
75
67
|
// bodies shell out to `npx -y @skillcap/gdh@latest self-update` (LITERAL
|
|
76
68
|
// @latest, not the pinned version — D-10) so the NEW CLI performs the update,
|
|
@@ -79,9 +71,6 @@ export const CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-run-g
|
|
|
79
71
|
// rendered bodies are version-agnostic by design.
|
|
80
72
|
export const CLAUDE_UPDATE_SKILL_RELATIVE_PATH = ".claude/skills/gdh-update/SKILL.md";
|
|
81
73
|
export const CODEX_UPDATE_SKILL_RELATIVE_PATH = ".agents/skills/gdh-update/SKILL.md";
|
|
82
|
-
export const CURSOR_UPDATE_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-update.md";
|
|
83
|
-
export const CLAUDE_SCAN_SKILL_RELATIVE_PATH = ".claude/skills/gdh-scan/SKILL.md";
|
|
84
|
-
export const CODEX_SCAN_SKILL_RELATIVE_PATH = ".agents/skills/gdh-scan/SKILL.md";
|
|
85
74
|
export const CLAUDE_ONBOARD_COMMAND_RELATIVE_PATH = CLAUDE_ONBOARD_SKILL_RELATIVE_PATH;
|
|
86
75
|
export const CLAUDE_STATUS_COMMAND_RELATIVE_PATH = CLAUDE_STATUS_SKILL_RELATIVE_PATH;
|
|
87
76
|
export const CLAUDE_MIGRATE_COMMAND_RELATIVE_PATH = CLAUDE_MIGRATE_SKILL_RELATIVE_PATH;
|
|
@@ -89,7 +78,6 @@ export const CLAUDE_CHECK_COMMAND_RELATIVE_PATH = CLAUDE_CHECK_SKILL_RELATIVE_PA
|
|
|
89
78
|
export const CLAUDE_PREPARE_COMMAND_RELATIVE_PATH = CLAUDE_PREPARE_SKILL_RELATIVE_PATH;
|
|
90
79
|
export const CLAUDE_RUN_GAME_COMMAND_RELATIVE_PATH = CLAUDE_RUN_GAME_SKILL_RELATIVE_PATH;
|
|
91
80
|
export const CLAUDE_UPDATE_COMMAND_RELATIVE_PATH = CLAUDE_UPDATE_SKILL_RELATIVE_PATH;
|
|
92
|
-
export const CLAUDE_SCAN_COMMAND_RELATIVE_PATH = CLAUDE_SCAN_SKILL_RELATIVE_PATH;
|
|
93
81
|
const LEGACY_CLAUDE_SKILL_COMMAND_RELATIVE_PATHS = [
|
|
94
82
|
[".claude/commands/gdh/onboard.md", "gdh-onboard"],
|
|
95
83
|
[".claude/commands/gdh/status.md", "gdh-status"],
|
|
@@ -111,18 +99,6 @@ const LEGACY_CODEX_SKILL_RELATIVE_PATHS = [
|
|
|
111
99
|
[".codex/skills/gdh-verify/SKILL.md", "gdh-verify"],
|
|
112
100
|
[".codex/skills/gdh-scan/SKILL.md", "gdh-scan"],
|
|
113
101
|
];
|
|
114
|
-
const LEGACY_CURSOR_SKILL_RELATIVE_PATHS = [
|
|
115
|
-
[".cursor/skills/gdh-onboard/SKILL.md", "gdh-onboard"],
|
|
116
|
-
[".cursor/skills/gdh-status/SKILL.md", "gdh-status"],
|
|
117
|
-
[".cursor/skills/gdh-migrate/SKILL.md", "gdh-migrate"],
|
|
118
|
-
[".cursor/skills/gdh-update/SKILL.md", "gdh-update"],
|
|
119
|
-
[".cursor/skills/gdh-check/SKILL.md", "gdh-check"],
|
|
120
|
-
[".cursor/skills/gdh-prepare/SKILL.md", "gdh-prepare"],
|
|
121
|
-
[".cursor/skills/gdh-run-game/SKILL.md", "gdh-run-game"],
|
|
122
|
-
[".cursor/skills/gdh-verify/SKILL.md", "gdh-verify"],
|
|
123
|
-
[".cursor/skills/gdh-scan/SKILL.md", "gdh-scan"],
|
|
124
|
-
];
|
|
125
|
-
export const CURSOR_SCAN_COMMAND_RELATIVE_PATH = ".cursor/commands/gdh-scan.md";
|
|
126
102
|
const CODEX_SKILL_RELATIVE_PATHS = [
|
|
127
103
|
path.dirname(CODEX_ONBOARD_SKILL_RELATIVE_PATH),
|
|
128
104
|
path.dirname(CODEX_STATUS_SKILL_RELATIVE_PATH),
|
|
@@ -130,7 +106,6 @@ const CODEX_SKILL_RELATIVE_PATHS = [
|
|
|
130
106
|
path.dirname(CODEX_UPDATE_SKILL_RELATIVE_PATH),
|
|
131
107
|
path.dirname(CODEX_PREPARE_SKILL_RELATIVE_PATH),
|
|
132
108
|
path.dirname(CODEX_RUN_GAME_SKILL_RELATIVE_PATH),
|
|
133
|
-
path.dirname(CODEX_SCAN_SKILL_RELATIVE_PATH),
|
|
134
109
|
];
|
|
135
110
|
const CLAUDE_SKILL_RELATIVE_PATHS = [
|
|
136
111
|
path.dirname(CLAUDE_ONBOARD_SKILL_RELATIVE_PATH),
|
|
@@ -139,16 +114,6 @@ const CLAUDE_SKILL_RELATIVE_PATHS = [
|
|
|
139
114
|
path.dirname(CLAUDE_UPDATE_SKILL_RELATIVE_PATH),
|
|
140
115
|
path.dirname(CLAUDE_PREPARE_SKILL_RELATIVE_PATH),
|
|
141
116
|
path.dirname(CLAUDE_RUN_GAME_SKILL_RELATIVE_PATH),
|
|
142
|
-
path.dirname(CLAUDE_SCAN_SKILL_RELATIVE_PATH),
|
|
143
|
-
];
|
|
144
|
-
const CURSOR_COMMAND_RELATIVE_PATHS = [
|
|
145
|
-
CURSOR_ONBOARD_COMMAND_RELATIVE_PATH,
|
|
146
|
-
CURSOR_STATUS_COMMAND_RELATIVE_PATH,
|
|
147
|
-
CURSOR_MIGRATE_COMMAND_RELATIVE_PATH,
|
|
148
|
-
CURSOR_UPDATE_COMMAND_RELATIVE_PATH,
|
|
149
|
-
CURSOR_PREPARE_COMMAND_RELATIVE_PATH,
|
|
150
|
-
CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH,
|
|
151
|
-
CURSOR_SCAN_COMMAND_RELATIVE_PATH,
|
|
152
117
|
];
|
|
153
118
|
export const LOCAL_PATH_HINTS_RELATIVE_PATH = ".gdh-state/local-paths.json";
|
|
154
119
|
export const CODEX_PROJECT_CONFIG_RELATIVE_PATH = ".codex/config.toml";
|
|
@@ -168,17 +133,16 @@ export async function getSupportedAgentAdaptersStatus(targetPath, options = {})
|
|
|
168
133
|
integrationRootPath: context.integrationRootPath,
|
|
169
134
|
pinnedVersion,
|
|
170
135
|
});
|
|
171
|
-
const [codex, claude
|
|
136
|
+
const [codex, claude] = await Promise.all([
|
|
172
137
|
inspectCodexAdapter(context.targetPath, guidance, projectMcp, pinnedVersion, {
|
|
173
138
|
includeUserLocal,
|
|
174
139
|
}),
|
|
175
140
|
inspectClaudeAdapter(context.targetPath, guidance, projectMcp, pinnedVersion),
|
|
176
|
-
inspectCursorAdapter(context.targetPath, guidance, projectMcp, pinnedVersion),
|
|
177
141
|
]);
|
|
178
142
|
return {
|
|
179
143
|
targetPath: context.targetPath,
|
|
180
144
|
guidance,
|
|
181
|
-
adapters: [codex, claude
|
|
145
|
+
adapters: [codex, claude],
|
|
182
146
|
};
|
|
183
147
|
}
|
|
184
148
|
export async function installSupportedAgentAdapters(targetPath, options = {}) {
|
|
@@ -306,7 +270,6 @@ export async function inspectProjectLifecycleCompatibility(targetPath) {
|
|
|
306
270
|
await inspectGuidanceIndexLifecycleSurface(guidanceStatus.guidanceRootPath, resolvedTargetPath),
|
|
307
271
|
await inspectGuidanceUnitLifecycleSurface(guidanceStatus.guidanceRootPath, projectConfig, resolvedTargetPath),
|
|
308
272
|
inspectMcpManifestLifecycleSurface(resolvedTargetPath, projectConfig.mcp.enabled, adapterStatus),
|
|
309
|
-
inspectCursorRuleLifecycleSurface(resolvedTargetPath, adapterStatus),
|
|
310
273
|
inspectRuntimeBridgeLifecycleSurface(resolvedTargetPath, bridgeStatus),
|
|
311
274
|
]);
|
|
312
275
|
}
|
|
@@ -417,35 +380,12 @@ function normalizePortableRelativePath(relativePath) {
|
|
|
417
380
|
const normalized = relativePath.split(path.sep).join("/");
|
|
418
381
|
return normalized === "" ? "." : normalized.replace(/\/+$/, "");
|
|
419
382
|
}
|
|
420
|
-
export function renderCursorRule(input) {
|
|
421
|
-
const targetPrefix = input?.targetRelativePath
|
|
422
|
-
? normalizePortableRelativePath(input.targetRelativePath)
|
|
423
|
-
: ".";
|
|
424
|
-
const prefixed = (relativePath) => targetPrefix === "." ? relativePath : `${targetPrefix}/${relativePath}`;
|
|
425
|
-
return [
|
|
426
|
-
"---",
|
|
427
|
-
"description: GDH visibility reinforcement",
|
|
428
|
-
"alwaysApply: true",
|
|
429
|
-
"---",
|
|
430
|
-
`<!-- GDH CURSOR RULE VERSION: ${GDH_CURSOR_RULE_VERSION} -->`,
|
|
431
|
-
"# GDH Cursor Rule",
|
|
432
|
-
"",
|
|
433
|
-
"This GDH-managed Godot target uses GDH.",
|
|
434
|
-
"Apply this rule only for files inside this Godot target or when the user explicitly asks for GDH work on this target.",
|
|
435
|
-
`Follow the canonical target-local entrypoint in [AGENTS.md](../../${prefixed("AGENTS.md")}), then load the canonical guidance index at [.gdh/guidance/README.md](../../${prefixed(".gdh/guidance/README.md")}) before substantive Godot work.`,
|
|
436
|
-
"Do not duplicate or override the canonical GDH guidance chain here.",
|
|
437
|
-
"",
|
|
438
|
-
].join("\n");
|
|
439
|
-
}
|
|
440
383
|
export function renderClaudeOnboardCommand(pinnedVersion) {
|
|
441
384
|
return renderClaudeOnboardSkill(pinnedVersion);
|
|
442
385
|
}
|
|
443
386
|
export function renderClaudeStatusCommand(pinnedVersion) {
|
|
444
387
|
return renderClaudeStatusSkill(pinnedVersion);
|
|
445
388
|
}
|
|
446
|
-
export function renderClaudeScanCommand(pinnedVersion) {
|
|
447
|
-
return renderClaudeScanSkill(pinnedVersion);
|
|
448
|
-
}
|
|
449
389
|
export function renderClaudeMigrateCommand(pinnedVersion) {
|
|
450
390
|
return renderClaudeMigrateSkill(pinnedVersion);
|
|
451
391
|
}
|
|
@@ -465,15 +405,11 @@ async function inspectProjectMcpSupport(targetPath, options) {
|
|
|
465
405
|
pinnedVersion: options.pinnedVersion ?? "latest",
|
|
466
406
|
});
|
|
467
407
|
const nestedTarget = path.resolve(targetPath) !== path.resolve(options.integrationRootPath);
|
|
468
|
-
const [projectFile,
|
|
408
|
+
const [projectFile, targetProjectFile, codexProjectContent, localPathHints,] = await Promise.all([
|
|
469
409
|
inspectJsonFile(path.join(options.integrationRootPath, PROJECT_MCP_RELATIVE_PATH)),
|
|
470
|
-
inspectJsonFile(path.join(options.integrationRootPath, CURSOR_MCP_RELATIVE_PATH)),
|
|
471
410
|
nestedTarget
|
|
472
411
|
? inspectJsonFile(path.join(targetPath, PROJECT_MCP_RELATIVE_PATH))
|
|
473
412
|
: inspectJsonFile(path.join(options.integrationRootPath, PROJECT_MCP_RELATIVE_PATH)),
|
|
474
|
-
nestedTarget
|
|
475
|
-
? inspectJsonFile(path.join(targetPath, CURSOR_MCP_RELATIVE_PATH))
|
|
476
|
-
: inspectJsonFile(path.join(options.integrationRootPath, CURSOR_MCP_RELATIVE_PATH)),
|
|
477
413
|
fs
|
|
478
414
|
.readFile(path.join(options.integrationRootPath, CODEX_PROJECT_CONFIG_RELATIVE_PATH), "utf8")
|
|
479
415
|
.catch(() => null),
|
|
@@ -486,9 +422,7 @@ async function inspectProjectMcpSupport(targetPath, options) {
|
|
|
486
422
|
integrationRootPath: options.integrationRootPath,
|
|
487
423
|
localPathHints,
|
|
488
424
|
projectFile: inspectManagedMcpFile(projectFile, enabled, PROJECT_MCP_RELATIVE_PATH, "Claude project MCP config", managedMcpEntry),
|
|
489
|
-
cursorFile: inspectManagedMcpFile(cursorFile, enabled, CURSOR_MCP_RELATIVE_PATH, "Cursor project MCP config", managedMcpEntry),
|
|
490
425
|
targetProjectFile: inspectManagedMcpFile(targetProjectFile, enabled, PROJECT_MCP_RELATIVE_PATH, "target-local Claude project MCP config", managedMcpEntry),
|
|
491
|
-
targetCursorFile: inspectManagedMcpFile(targetCursorFile, enabled, CURSOR_MCP_RELATIVE_PATH, "target-local Cursor project MCP config", managedMcpEntry),
|
|
492
426
|
codexProjectFile: inspectManagedCodexProjectFile(codexProjectContent, enabled, options.pinnedVersion),
|
|
493
427
|
codexRegistration: options.includeUserLocal
|
|
494
428
|
? await inspectCodexRegistration(targetPath, enabled, codexServerName, codexConfigPath, options.integrationRootPath, options.pinnedVersion)
|
|
@@ -785,38 +719,6 @@ function inspectClaudeSkillSurface(targetPath, relativePath, content, expectedCo
|
|
|
785
719
|
}),
|
|
786
720
|
];
|
|
787
721
|
}
|
|
788
|
-
function inspectCursorCommandSurface(targetPath, relativePath, content, expectedContent, commandName) {
|
|
789
|
-
if (expectedContent === null) {
|
|
790
|
-
return [
|
|
791
|
-
createSurfaceStatus({
|
|
792
|
-
kind: "command_file",
|
|
793
|
-
scope: "repo",
|
|
794
|
-
targetPath,
|
|
795
|
-
relativePath,
|
|
796
|
-
present: content !== null,
|
|
797
|
-
state: "missing",
|
|
798
|
-
summary: `Cursor ${commandName} command cannot be validated yet: no \`gdh_version\` is pinned (run \`gdh setup\` or \`gdh migrate --apply\`).`,
|
|
799
|
-
version: null,
|
|
800
|
-
}),
|
|
801
|
-
];
|
|
802
|
-
}
|
|
803
|
-
return [
|
|
804
|
-
createSurfaceStatus({
|
|
805
|
-
kind: "command_file",
|
|
806
|
-
scope: "repo",
|
|
807
|
-
targetPath,
|
|
808
|
-
relativePath,
|
|
809
|
-
present: content !== null,
|
|
810
|
-
state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
|
|
811
|
-
summary: content === null
|
|
812
|
-
? `Cursor \`/${commandName}\` command is missing and should install under .cursor/commands/.`
|
|
813
|
-
: content === expectedContent
|
|
814
|
-
? `Cursor can discover the managed \`/${commandName}\` command.`
|
|
815
|
-
: `Cursor \`/${commandName}\` command exists but no longer matches the expected managed GDH command.`,
|
|
816
|
-
version: null,
|
|
817
|
-
}),
|
|
818
|
-
];
|
|
819
|
-
}
|
|
820
722
|
async function inspectCodexAdapter(targetPath, guidance, projectMcp, pinnedVersion, options) {
|
|
821
723
|
const codexSkillPath = path.join(targetPath, CODEX_ONBOARD_SKILL_RELATIVE_PATH);
|
|
822
724
|
const codexSkillContent = await fs.readFile(codexSkillPath, "utf8").catch(() => null);
|
|
@@ -839,9 +741,6 @@ async function inspectCodexAdapter(targetPath, guidance, projectMcp, pinnedVersi
|
|
|
839
741
|
const codexRunGameContent = await fs
|
|
840
742
|
.readFile(path.resolve(targetPath, CODEX_RUN_GAME_SKILL_RELATIVE_PATH), "utf8")
|
|
841
743
|
.catch(() => null);
|
|
842
|
-
const codexScanContent = await fs
|
|
843
|
-
.readFile(path.join(targetPath, CODEX_SCAN_SKILL_RELATIVE_PATH), "utf8")
|
|
844
|
-
.catch(() => null);
|
|
845
744
|
const codexAuthoringHookContent = await fs
|
|
846
745
|
.readFile(path.join(projectMcp.integrationRootPath, CODEX_AUTHORING_HOOK_RELATIVE_PATH), "utf8")
|
|
847
746
|
.catch(() => null);
|
|
@@ -854,7 +753,6 @@ async function inspectCodexAdapter(targetPath, guidance, projectMcp, pinnedVersi
|
|
|
854
753
|
const expectedCodexUpdateSkill = pinnedVersion === null ? null : renderCodexUpdateSkill(pinnedVersion);
|
|
855
754
|
const expectedCodexPrepareSkill = pinnedVersion === null ? null : renderCodexPrepareSkill(pinnedVersion);
|
|
856
755
|
const expectedCodexRunGameSkill = pinnedVersion === null ? null : renderCodexRunGameSkill(pinnedVersion);
|
|
857
|
-
const expectedCodexScanSkill = pinnedVersion === null ? null : renderCodexScanSkill(pinnedVersion);
|
|
858
756
|
const expectedCodexAuthoringHook = pinnedVersion === null
|
|
859
757
|
? null
|
|
860
758
|
: renderGdhAuthoringHook({
|
|
@@ -909,7 +807,6 @@ async function inspectCodexAdapter(targetPath, guidance, projectMcp, pinnedVersi
|
|
|
909
807
|
...inspectCodexSkillSurface(targetPath, CODEX_UPDATE_SKILL_RELATIVE_PATH, codexUpdateContent, expectedCodexUpdateSkill, "gdh-update"),
|
|
910
808
|
...inspectCodexSkillSurface(targetPath, CODEX_PREPARE_SKILL_RELATIVE_PATH, codexPrepareContent, expectedCodexPrepareSkill, "gdh-prepare"),
|
|
911
809
|
...inspectCodexSkillSurface(targetPath, CODEX_RUN_GAME_SKILL_RELATIVE_PATH, codexRunGameContent, expectedCodexRunGameSkill, "gdh-run-game"),
|
|
912
|
-
...inspectCodexSkillSurface(targetPath, CODEX_SCAN_SKILL_RELATIVE_PATH, codexScanContent, expectedCodexScanSkill, "gdh-scan"),
|
|
913
810
|
inspectManagedHookSurface("codex", projectMcp.integrationRootPath, CODEX_AUTHORING_HOOK_RELATIVE_PATH, codexAuthoringHookContent, expectedCodexAuthoringHook, "authoring guard"),
|
|
914
811
|
inspectCodexAuthoringHookConfig(projectMcp.integrationRootPath, codexProjectConfigContent, projectMcp.enabled),
|
|
915
812
|
];
|
|
@@ -964,9 +861,6 @@ async function inspectClaudeAdapter(targetPath, guidance, projectMcp, pinnedVers
|
|
|
964
861
|
const claudeRunGameContent = await fs
|
|
965
862
|
.readFile(path.resolve(targetPath, CLAUDE_RUN_GAME_COMMAND_RELATIVE_PATH), "utf8")
|
|
966
863
|
.catch(() => null);
|
|
967
|
-
const claudeScanContent = await fs
|
|
968
|
-
.readFile(path.join(targetPath, CLAUDE_SCAN_COMMAND_RELATIVE_PATH), "utf8")
|
|
969
|
-
.catch(() => null);
|
|
970
864
|
const claudeCheckUpdateHookContent = await fs
|
|
971
865
|
.readFile(path.join(targetPath, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH), "utf8")
|
|
972
866
|
.catch(() => null);
|
|
@@ -1003,7 +897,6 @@ async function inspectClaudeAdapter(targetPath, guidance, projectMcp, pinnedVers
|
|
|
1003
897
|
const expectedClaudeUpdateCommand = pinnedVersion === null ? null : renderClaudeUpdateCommand(pinnedVersion);
|
|
1004
898
|
const expectedClaudePrepareCommand = pinnedVersion === null ? null : renderClaudePrepareCommand(pinnedVersion);
|
|
1005
899
|
const expectedClaudeRunGameCommand = pinnedVersion === null ? null : renderClaudeRunGameCommand(pinnedVersion);
|
|
1006
|
-
const expectedClaudeScanCommand = pinnedVersion === null ? null : renderClaudeScanCommand(pinnedVersion);
|
|
1007
900
|
const surfaces = [
|
|
1008
901
|
createSurfaceStatus({
|
|
1009
902
|
kind: "symlink",
|
|
@@ -1052,7 +945,6 @@ async function inspectClaudeAdapter(targetPath, guidance, projectMcp, pinnedVers
|
|
|
1052
945
|
...inspectClaudeSkillSurface(targetPath, CLAUDE_UPDATE_COMMAND_RELATIVE_PATH, claudeUpdateContent, expectedClaudeUpdateCommand, "gdh-update"),
|
|
1053
946
|
...inspectClaudeSkillSurface(targetPath, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH, claudePrepareContent, expectedClaudePrepareCommand, "gdh-prepare"),
|
|
1054
947
|
...inspectClaudeSkillSurface(targetPath, CLAUDE_RUN_GAME_COMMAND_RELATIVE_PATH, claudeRunGameContent, expectedClaudeRunGameCommand, "gdh-run-game"),
|
|
1055
|
-
...inspectClaudeSkillSurface(targetPath, CLAUDE_SCAN_COMMAND_RELATIVE_PATH, claudeScanContent, expectedClaudeScanCommand, "gdh-scan"),
|
|
1056
948
|
inspectManagedHookSurface("claude", targetPath, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, claudeCheckUpdateHookContent, expectedClaudeCheckUpdateHook, "gdh-check-update-hook"),
|
|
1057
949
|
inspectManagedHookSurface("claude", targetPath, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH, claudeCheckUpdateWorkerContent, expectedClaudeCheckUpdateWorker, "gdh-check-update-worker"),
|
|
1058
950
|
inspectManagedHookSurface("claude", targetPath, CLAUDE_STATUSLINE_RELATIVE_PATH, claudeStatuslineContent, expectedClaudeStatusline, "gdh-statusline"),
|
|
@@ -1124,112 +1016,6 @@ async function inspectRootSymlinkSurfaces(input) {
|
|
|
1124
1016
|
});
|
|
1125
1017
|
}));
|
|
1126
1018
|
}
|
|
1127
|
-
async function inspectCursorAdapter(targetPath, guidance, projectMcp, pinnedVersion) {
|
|
1128
|
-
const absolutePath = path.join(targetPath, CURSOR_RULE_RELATIVE_PATH);
|
|
1129
|
-
const onboardCommandPath = path.join(targetPath, CURSOR_ONBOARD_COMMAND_RELATIVE_PATH);
|
|
1130
|
-
const content = await fs.readFile(absolutePath, "utf8").catch(() => null);
|
|
1131
|
-
const onboardCommandContent = await fs.readFile(onboardCommandPath, "utf8").catch(() => null);
|
|
1132
|
-
const cursorStatusContent = await fs
|
|
1133
|
-
.readFile(path.join(targetPath, CURSOR_STATUS_COMMAND_RELATIVE_PATH), "utf8")
|
|
1134
|
-
.catch(() => null);
|
|
1135
|
-
const cursorMigrateContent = await fs
|
|
1136
|
-
.readFile(path.join(targetPath, CURSOR_MIGRATE_COMMAND_RELATIVE_PATH), "utf8")
|
|
1137
|
-
.catch(() => null);
|
|
1138
|
-
// Phase 13 Plan 13-03 deliverable — /gdh-update skill for Cursor. Inspection
|
|
1139
|
-
// wiring required so planSkillInstallAction sees the surface state; otherwise
|
|
1140
|
-
// the planner returns `unchanged` for a missing file and install becomes a
|
|
1141
|
-
// no-op (Plan 13-05 integration-test Rule 2 fix).
|
|
1142
|
-
const cursorUpdateContent = await fs
|
|
1143
|
-
.readFile(path.join(targetPath, CURSOR_UPDATE_COMMAND_RELATIVE_PATH), "utf8")
|
|
1144
|
-
.catch(() => null);
|
|
1145
|
-
const cursorPrepareContent = await fs
|
|
1146
|
-
.readFile(path.join(targetPath, CURSOR_PREPARE_COMMAND_RELATIVE_PATH), "utf8")
|
|
1147
|
-
.catch(() => null);
|
|
1148
|
-
const cursorRunGameContent = await fs
|
|
1149
|
-
.readFile(path.resolve(targetPath, CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH), "utf8")
|
|
1150
|
-
.catch(() => null);
|
|
1151
|
-
const cursorScanContent = await fs
|
|
1152
|
-
.readFile(path.join(targetPath, CURSOR_SCAN_COMMAND_RELATIVE_PATH), "utf8")
|
|
1153
|
-
.catch(() => null);
|
|
1154
|
-
const expectedContent = renderCursorRule();
|
|
1155
|
-
const version = readCursorRuleVersion(content);
|
|
1156
|
-
const expectedCursorOnboardSkill = pinnedVersion === null ? null : renderCursorOnboardSkill(pinnedVersion);
|
|
1157
|
-
const expectedCursorStatusSkill = pinnedVersion === null ? null : renderCursorStatusSkill(pinnedVersion);
|
|
1158
|
-
const expectedCursorMigrateSkill = pinnedVersion === null ? null : renderCursorMigrateSkill(pinnedVersion);
|
|
1159
|
-
const expectedCursorUpdateSkill = pinnedVersion === null ? null : renderCursorUpdateSkill(pinnedVersion);
|
|
1160
|
-
const expectedCursorPrepareSkill = pinnedVersion === null ? null : renderCursorPrepareSkill(pinnedVersion);
|
|
1161
|
-
const expectedCursorRunGameSkill = pinnedVersion === null ? null : renderCursorRunGameSkill(pinnedVersion);
|
|
1162
|
-
const expectedCursorScanSkill = pinnedVersion === null ? null : renderCursorScanSkill(pinnedVersion);
|
|
1163
|
-
const surfaces = [
|
|
1164
|
-
createSurfaceStatus({
|
|
1165
|
-
kind: "rule_file",
|
|
1166
|
-
scope: "repo",
|
|
1167
|
-
targetPath,
|
|
1168
|
-
relativePath: CURSOR_RULE_RELATIVE_PATH,
|
|
1169
|
-
present: content !== null,
|
|
1170
|
-
state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
|
|
1171
|
-
summary: content === null
|
|
1172
|
-
? "Cursor reinforcement is missing and should point back to AGENTS.md."
|
|
1173
|
-
: content === expectedContent
|
|
1174
|
-
? "Cursor has a thin always-on rule that points back to the canonical GDH guidance chain."
|
|
1175
|
-
: "Cursor reinforcement exists but no longer matches the expected managed GDH rule.",
|
|
1176
|
-
version,
|
|
1177
|
-
}),
|
|
1178
|
-
createSurfaceStatus({
|
|
1179
|
-
kind: "command_file",
|
|
1180
|
-
scope: "repo",
|
|
1181
|
-
targetPath,
|
|
1182
|
-
relativePath: CURSOR_ONBOARD_COMMAND_RELATIVE_PATH,
|
|
1183
|
-
present: onboardCommandContent !== null,
|
|
1184
|
-
state: onboardCommandContent === null
|
|
1185
|
-
? "missing"
|
|
1186
|
-
: expectedCursorOnboardSkill === null
|
|
1187
|
-
? "missing"
|
|
1188
|
-
: onboardCommandContent === expectedCursorOnboardSkill
|
|
1189
|
-
? "ready"
|
|
1190
|
-
: "misconfigured",
|
|
1191
|
-
summary: onboardCommandContent === null
|
|
1192
|
-
? "Cursor onboarding handoff is missing and should install `/gdh-onboard` under .cursor/commands/."
|
|
1193
|
-
: expectedCursorOnboardSkill === null
|
|
1194
|
-
? "Cursor onboarding handoff cannot be validated yet: no `gdh_version` is pinned (run `gdh setup` or `gdh migrate --apply`)."
|
|
1195
|
-
: onboardCommandContent === expectedCursorOnboardSkill
|
|
1196
|
-
? "Cursor can discover the managed `/gdh-onboard` handoff command."
|
|
1197
|
-
: "Cursor onboarding handoff exists but no longer matches the expected managed GDH command.",
|
|
1198
|
-
version: null,
|
|
1199
|
-
}),
|
|
1200
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_STATUS_COMMAND_RELATIVE_PATH, cursorStatusContent, expectedCursorStatusSkill, "gdh-status"),
|
|
1201
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_MIGRATE_COMMAND_RELATIVE_PATH, cursorMigrateContent, expectedCursorMigrateSkill, "gdh-migrate"),
|
|
1202
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_UPDATE_COMMAND_RELATIVE_PATH, cursorUpdateContent, expectedCursorUpdateSkill, "gdh-update"),
|
|
1203
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_PREPARE_COMMAND_RELATIVE_PATH, cursorPrepareContent, expectedCursorPrepareSkill, "gdh-prepare"),
|
|
1204
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH, cursorRunGameContent, expectedCursorRunGameSkill, "gdh-run-game"),
|
|
1205
|
-
...inspectCursorCommandSurface(targetPath, CURSOR_SCAN_COMMAND_RELATIVE_PATH, cursorScanContent, expectedCursorScanSkill, "gdh-scan"),
|
|
1206
|
-
];
|
|
1207
|
-
if (projectMcp.enabled) {
|
|
1208
|
-
surfaces.push(createSurfaceStatus({
|
|
1209
|
-
kind: "mcp_file",
|
|
1210
|
-
scope: "repo",
|
|
1211
|
-
targetPath: projectMcp.integrationRootPath,
|
|
1212
|
-
relativePath: CURSOR_MCP_RELATIVE_PATH,
|
|
1213
|
-
present: projectMcp.cursorFile.present,
|
|
1214
|
-
state: projectMcp.cursorFile.state,
|
|
1215
|
-
summary: projectMcp.cursorFile.summary,
|
|
1216
|
-
version: null,
|
|
1217
|
-
}));
|
|
1218
|
-
if (path.resolve(projectMcp.integrationRootPath) !== path.resolve(targetPath)) {
|
|
1219
|
-
surfaces.push(createSurfaceStatus({
|
|
1220
|
-
kind: "mcp_file",
|
|
1221
|
-
scope: "repo",
|
|
1222
|
-
targetPath,
|
|
1223
|
-
relativePath: CURSOR_MCP_RELATIVE_PATH,
|
|
1224
|
-
present: projectMcp.targetCursorFile.present,
|
|
1225
|
-
state: projectMcp.targetCursorFile.state,
|
|
1226
|
-
summary: projectMcp.targetCursorFile.summary,
|
|
1227
|
-
version: null,
|
|
1228
|
-
}));
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
return createAgentStatus("cursor", guidance, surfaces);
|
|
1232
|
-
}
|
|
1233
1019
|
function createAgentStatus(agent, guidance, surfaces) {
|
|
1234
1020
|
const state = !hasReadyVisibilityChain(guidance)
|
|
1235
1021
|
? "visibility_broken"
|
|
@@ -1341,17 +1127,12 @@ async function planInstallActions(targetPath, adapters, requestedAgents, options
|
|
|
1341
1127
|
}
|
|
1342
1128
|
if (adapter.agent === "claude") {
|
|
1343
1129
|
actions.push(...planClaudeInstallActions(targetPath, adapter, options.pinnedVersion, options.integrationRootPath));
|
|
1344
|
-
continue;
|
|
1345
|
-
}
|
|
1346
|
-
if (adapter.agent === "cursor") {
|
|
1347
|
-
actions.push(...planCursorInstallActions(targetPath, adapter, options.pinnedVersion, options.integrationRootPath));
|
|
1348
1130
|
}
|
|
1349
1131
|
}
|
|
1350
1132
|
actions.push(...planRetiredManagedSurfaceCleanupActions(targetPath));
|
|
1351
1133
|
if (path.resolve(options.integrationRootPath) !== path.resolve(targetPath)) {
|
|
1352
1134
|
actions.push(...planRetiredManagedSurfaceCleanupActions(options.integrationRootPath));
|
|
1353
1135
|
actions.push(...planLegacyCodexSkillCleanupActions(options.integrationRootPath, options.pinnedVersion));
|
|
1354
|
-
actions.push(...planLegacyCursorSkillCleanupActions(options.integrationRootPath));
|
|
1355
1136
|
}
|
|
1356
1137
|
return dedupeInstallActions(actions);
|
|
1357
1138
|
}
|
|
@@ -1377,21 +1158,6 @@ function planSharedRepoInstallActions(targetPath, projectMcp, agent, effectiveDe
|
|
|
1377
1158
|
content: renderManagedMcpConfig(path.join(integrationRootPath, PROJECT_MCP_RELATIVE_PATH), managedMcpEntry),
|
|
1378
1159
|
}));
|
|
1379
1160
|
}
|
|
1380
|
-
if (projectMcp.cursorFile.state !== "ready") {
|
|
1381
|
-
actions.push(createInstallAction({
|
|
1382
|
-
agent,
|
|
1383
|
-
kind: "write_file",
|
|
1384
|
-
scope: "repo",
|
|
1385
|
-
targetPath: integrationRootPath,
|
|
1386
|
-
relativePath: CURSOR_MCP_RELATIVE_PATH,
|
|
1387
|
-
state: "planned",
|
|
1388
|
-
mode: projectMcp.cursorFile.present ? "replace" : "create",
|
|
1389
|
-
summary: projectMcp.cursorFile.present
|
|
1390
|
-
? "Replace the managed `gdh` MCP entry in .cursor/mcp.json while preserving any non-GDH servers."
|
|
1391
|
-
: "Create .cursor/mcp.json with the managed `gdh` MCP entry.",
|
|
1392
|
-
content: renderManagedMcpConfig(path.join(integrationRootPath, CURSOR_MCP_RELATIVE_PATH), managedMcpEntry),
|
|
1393
|
-
}));
|
|
1394
|
-
}
|
|
1395
1161
|
if (nestedTarget && projectMcp.targetProjectFile.state !== "ready") {
|
|
1396
1162
|
actions.push(createInstallAction({
|
|
1397
1163
|
agent,
|
|
@@ -1407,21 +1173,6 @@ function planSharedRepoInstallActions(targetPath, projectMcp, agent, effectiveDe
|
|
|
1407
1173
|
content: renderManagedMcpConfig(path.join(targetPath, PROJECT_MCP_RELATIVE_PATH), managedMcpEntry),
|
|
1408
1174
|
}));
|
|
1409
1175
|
}
|
|
1410
|
-
if (nestedTarget && projectMcp.targetCursorFile.state !== "ready") {
|
|
1411
|
-
actions.push(createInstallAction({
|
|
1412
|
-
agent,
|
|
1413
|
-
kind: "write_file",
|
|
1414
|
-
scope: "repo",
|
|
1415
|
-
targetPath,
|
|
1416
|
-
relativePath: CURSOR_MCP_RELATIVE_PATH,
|
|
1417
|
-
state: "planned",
|
|
1418
|
-
mode: projectMcp.targetCursorFile.present ? "replace" : "create",
|
|
1419
|
-
summary: projectMcp.targetCursorFile.present
|
|
1420
|
-
? "Replace the managed `gdh` MCP entry in target-local .cursor/mcp.json while preserving any non-GDH servers."
|
|
1421
|
-
: "Create target-local .cursor/mcp.json so Cursor can discover GDH when opened at the Godot target.",
|
|
1422
|
-
content: renderManagedMcpConfig(path.join(targetPath, CURSOR_MCP_RELATIVE_PATH), managedMcpEntry),
|
|
1423
|
-
}));
|
|
1424
|
-
}
|
|
1425
1176
|
if (projectMcp.localPathHints.gdhDevRepoPath !== effectiveDevRepoPath) {
|
|
1426
1177
|
actions.push(createInstallAction({
|
|
1427
1178
|
agent,
|
|
@@ -1558,8 +1309,6 @@ function agentLabel(agent) {
|
|
|
1558
1309
|
return "Claude";
|
|
1559
1310
|
case "codex":
|
|
1560
1311
|
return "Codex";
|
|
1561
|
-
case "cursor":
|
|
1562
|
-
return "Cursor";
|
|
1563
1312
|
}
|
|
1564
1313
|
}
|
|
1565
1314
|
function planCodexRepoInstallActions(targetPath, adapter, pinnedVersion, projectMcp, integrationRootPath) {
|
|
@@ -1570,7 +1319,6 @@ function planCodexRepoInstallActions(targetPath, adapter, pinnedVersion, project
|
|
|
1570
1319
|
planSkillInstallAction("codex", targetPath, adapter, CODEX_UPDATE_SKILL_RELATIVE_PATH, renderCodexUpdateSkill, "gdh-update", pinnedVersion),
|
|
1571
1320
|
planSkillInstallAction("codex", targetPath, adapter, CODEX_PREPARE_SKILL_RELATIVE_PATH, renderCodexPrepareSkill, "gdh-prepare", pinnedVersion),
|
|
1572
1321
|
planSkillInstallAction("codex", targetPath, adapter, CODEX_RUN_GAME_SKILL_RELATIVE_PATH, renderCodexRunGameSkill, "gdh-run-game", pinnedVersion),
|
|
1573
|
-
planSkillInstallAction("codex", targetPath, adapter, CODEX_SCAN_SKILL_RELATIVE_PATH, renderCodexScanSkill, "gdh-scan", pinnedVersion),
|
|
1574
1322
|
planSkillInstallAction("codex", integrationRootPath, adapter, CODEX_AUTHORING_HOOK_RELATIVE_PATH, (version) => renderGdhAuthoringHook({
|
|
1575
1323
|
pinnedVersion: version,
|
|
1576
1324
|
targetRelativePath: path.relative(integrationRootPath, targetPath) || ".",
|
|
@@ -1616,20 +1364,14 @@ function planCodexRepoInstallActions(targetPath, adapter, pinnedVersion, project
|
|
|
1616
1364
|
// accepts both so old managed files can migrate without deleting user-authored
|
|
1617
1365
|
// files based only on path.
|
|
1618
1366
|
const LEGACY_CODEX_MANAGED_SKILL_MARKER = "<codex_skill_adapter>";
|
|
1619
|
-
const LEGACY_CURSOR_MANAGED_SKILL_MARKER = "<cursor_skill_adapter>";
|
|
1620
1367
|
function isManagedAgentSkillContent(content) {
|
|
1621
1368
|
return (content.includes(GDH_MANAGED_AGENT_SKILL_MARKER) ||
|
|
1622
|
-
content.includes(LEGACY_CODEX_MANAGED_SKILL_MARKER)
|
|
1623
|
-
content.includes(LEGACY_CURSOR_MANAGED_SKILL_MARKER));
|
|
1369
|
+
content.includes(LEGACY_CODEX_MANAGED_SKILL_MARKER));
|
|
1624
1370
|
}
|
|
1625
1371
|
function isManagedLegacyCodexSkillContent(content) {
|
|
1626
1372
|
return (content.includes(GDH_MANAGED_AGENT_SKILL_MARKER) ||
|
|
1627
1373
|
content.includes(LEGACY_CODEX_MANAGED_SKILL_MARKER));
|
|
1628
1374
|
}
|
|
1629
|
-
function isManagedLegacyCursorSkillContent(content) {
|
|
1630
|
-
return (content.includes(GDH_MANAGED_AGENT_SKILL_MARKER) ||
|
|
1631
|
-
content.includes(LEGACY_CURSOR_MANAGED_SKILL_MARKER));
|
|
1632
|
-
}
|
|
1633
1375
|
function isManagedLegacyClaudeCommandContent(content, skillName) {
|
|
1634
1376
|
const slashName = skillName.replace("gdh-", "gdh:");
|
|
1635
1377
|
return (content.includes(`name: ${slashName}`) &&
|
|
@@ -1656,13 +1398,6 @@ const RETIRED_MANAGED_SURFACE_RELATIVE_PATHS = [
|
|
|
1656
1398
|
isManaged: isManagedAgentSkillContent,
|
|
1657
1399
|
replacementSummary: "Agents should rely on GDH post-edit hooks, MCP/CLI status, and explicit `gdh authoring check --mode final` evidence instead.",
|
|
1658
1400
|
},
|
|
1659
|
-
{
|
|
1660
|
-
agent: "cursor",
|
|
1661
|
-
relativePath: ".cursor/skills/gdh-check/SKILL.md",
|
|
1662
|
-
skillName: "gdh-check",
|
|
1663
|
-
isManaged: isManagedAgentSkillContent,
|
|
1664
|
-
replacementSummary: "Agents should rely on MCP/CLI status and explicit `gdh authoring check --mode final` evidence instead.",
|
|
1665
|
-
},
|
|
1666
1401
|
{
|
|
1667
1402
|
agent: "claude",
|
|
1668
1403
|
relativePath: ".claude/skills/gdh-check/SKILL.md",
|
|
@@ -1677,13 +1412,6 @@ const RETIRED_MANAGED_SURFACE_RELATIVE_PATHS = [
|
|
|
1677
1412
|
isManaged: isManagedAgentSkillContent,
|
|
1678
1413
|
replacementSummary: "Agents should use `gdh authoring check --mode final` for code-validity evidence.",
|
|
1679
1414
|
},
|
|
1680
|
-
{
|
|
1681
|
-
agent: "cursor",
|
|
1682
|
-
relativePath: ".cursor/skills/gdh-verify/SKILL.md",
|
|
1683
|
-
skillName: "gdh-verify",
|
|
1684
|
-
isManaged: isManagedAgentSkillContent,
|
|
1685
|
-
replacementSummary: "Agents should use `gdh authoring check --mode final` for code-validity evidence.",
|
|
1686
|
-
},
|
|
1687
1415
|
{
|
|
1688
1416
|
agent: "claude",
|
|
1689
1417
|
relativePath: ".claude/commands/gdh/verify.md",
|
|
@@ -1692,6 +1420,87 @@ const RETIRED_MANAGED_SURFACE_RELATIVE_PATHS = [
|
|
|
1692
1420
|
(content.includes("@skillcap/gdh@") || content.includes("gdh verify recommend")),
|
|
1693
1421
|
replacementSummary: "Agents should use `gdh authoring check --mode final` for code-validity evidence.",
|
|
1694
1422
|
},
|
|
1423
|
+
// Retired generated discovery skill (v1.1.0). The `gdh scan` CLI verb
|
|
1424
|
+
// stays — only the agent-facing skill is dropped. Targets that ran a
|
|
1425
|
+
// pre-v1.1 GDH still carry GDH-rendered SKILL.md and command files at the
|
|
1426
|
+
// managed paths; the cleanup planner removes them content-checked so
|
|
1427
|
+
// user-authored content at the same paths is preserved verbatim. Agents
|
|
1428
|
+
// now invoke `gdh scan` directly from gdh-onboard or gdh-status when an
|
|
1429
|
+
// inventory probe is needed.
|
|
1430
|
+
{
|
|
1431
|
+
agent: "codex",
|
|
1432
|
+
relativePath: ".agents/skills/gdh-scan/SKILL.md",
|
|
1433
|
+
skillName: "gdh-scan",
|
|
1434
|
+
isManaged: isManagedAgentSkillContent,
|
|
1435
|
+
replacementSummary: "The gdh-scan skill is retired; the `gdh scan` CLI verb stays and agents invoke it directly from gdh-onboard or gdh-status when an inventory probe is needed.",
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
agent: "claude",
|
|
1439
|
+
relativePath: ".claude/skills/gdh-scan/SKILL.md",
|
|
1440
|
+
skillName: "gdh-scan",
|
|
1441
|
+
isManaged: isManagedAgentSkillContent,
|
|
1442
|
+
replacementSummary: "The gdh-scan skill is retired; the `gdh scan` CLI verb stays and agents invoke it directly from gdh-onboard or gdh-status when an inventory probe is needed.",
|
|
1443
|
+
},
|
|
1444
|
+
{
|
|
1445
|
+
agent: "claude",
|
|
1446
|
+
relativePath: ".claude/commands/gdh/scan.md",
|
|
1447
|
+
skillName: "gdh-scan",
|
|
1448
|
+
isManaged: isManagedAgentSkillContent,
|
|
1449
|
+
replacementSummary: "The gdh-scan command shim is retired; the `gdh scan` CLI verb stays and agents invoke it directly from gdh-onboard or gdh-status when an inventory probe is needed.",
|
|
1450
|
+
},
|
|
1451
|
+
// Retired cursor agent (commit 7f65b098, "feat(adapters)!: drop cursor
|
|
1452
|
+
// agent from source"). Cursor was a hard delete — no deprecation shim — so
|
|
1453
|
+
// legacy targets that ran a pre-removal GDH still carry GDH-rendered files
|
|
1454
|
+
// under .cursor/. The inventory sweep handles targets with a prior
|
|
1455
|
+
// render-inventory.json; these entries cover the legacy-target case where
|
|
1456
|
+
// no inventory exists yet (pre-Phase 70 onboarding). Content-checked so
|
|
1457
|
+
// user-authored .cursor/ files are never touched. The `agent` field is
|
|
1458
|
+
// attribution-only — cursor is no longer in GdhSupportedAgent — and is set
|
|
1459
|
+
// to "claude" because cursor commands/skills were Claude-style markdown
|
|
1460
|
+
// surfaces. .cursor/mcp.json is intentionally NOT enumerated here: it is a
|
|
1461
|
+
// JSON file that may carry non-GDH MCP servers; deleting it whole would
|
|
1462
|
+
// nuke user content. (The stale `gdh` entry inside it is harmless — the
|
|
1463
|
+
// command it points at is dead — and a JSON-aware partial delete is a
|
|
1464
|
+
// separate concern.)
|
|
1465
|
+
...([
|
|
1466
|
+
"gdh-onboard",
|
|
1467
|
+
"gdh-status",
|
|
1468
|
+
"gdh-migrate",
|
|
1469
|
+
"gdh-update",
|
|
1470
|
+
"gdh-prepare",
|
|
1471
|
+
"gdh-run-game",
|
|
1472
|
+
"gdh-scan",
|
|
1473
|
+
].map((skillName) => ({
|
|
1474
|
+
agent: "claude",
|
|
1475
|
+
relativePath: `.cursor/commands/${skillName}.md`,
|
|
1476
|
+
skillName,
|
|
1477
|
+
isManaged: isManagedAgentSkillContent,
|
|
1478
|
+
replacementSummary: "Cursor is no longer a supported GDH adapter target; this file was rendered by a pre-removal GDH version.",
|
|
1479
|
+
}))),
|
|
1480
|
+
...([
|
|
1481
|
+
"gdh-onboard",
|
|
1482
|
+
"gdh-status",
|
|
1483
|
+
"gdh-migrate",
|
|
1484
|
+
"gdh-update",
|
|
1485
|
+
"gdh-check",
|
|
1486
|
+
"gdh-prepare",
|
|
1487
|
+
"gdh-run-game",
|
|
1488
|
+
"gdh-verify",
|
|
1489
|
+
"gdh-scan",
|
|
1490
|
+
].map((skillName) => ({
|
|
1491
|
+
agent: "claude",
|
|
1492
|
+
relativePath: `.cursor/skills/${skillName}/SKILL.md`,
|
|
1493
|
+
skillName,
|
|
1494
|
+
isManaged: isManagedAgentSkillContent,
|
|
1495
|
+
replacementSummary: "Cursor is no longer a supported GDH adapter target; this file was rendered by a pre-removal GDH version.",
|
|
1496
|
+
}))),
|
|
1497
|
+
{
|
|
1498
|
+
agent: "claude",
|
|
1499
|
+
relativePath: ".cursor/rules/gdh-agent.mdc",
|
|
1500
|
+
skillName: "gdh-agent-rule",
|
|
1501
|
+
isManaged: (content) => content.includes("GDH CURSOR RULE VERSION:"),
|
|
1502
|
+
replacementSummary: "Cursor is no longer a supported GDH adapter target; this rule file was rendered by a pre-removal GDH version.",
|
|
1503
|
+
},
|
|
1695
1504
|
];
|
|
1696
1505
|
function planRetiredManagedSurfaceCleanupActions(targetPath) {
|
|
1697
1506
|
const actions = [];
|
|
@@ -1714,7 +1523,6 @@ function planRetiredManagedSurfaceCleanupActions(targetPath) {
|
|
|
1714
1523
|
summary: `Remove retired managed \`${entry.skillName}\` surface. ${entry.replacementSummary}`,
|
|
1715
1524
|
}));
|
|
1716
1525
|
}
|
|
1717
|
-
actions.push(...planLegacyCursorSkillCleanupActions(targetPath));
|
|
1718
1526
|
return actions;
|
|
1719
1527
|
}
|
|
1720
1528
|
function planLegacyCodexSkillCleanupActions(targetPath, _pinnedVersion) {
|
|
@@ -1746,29 +1554,6 @@ function planLegacyCodexSkillCleanupActions(targetPath, _pinnedVersion) {
|
|
|
1746
1554
|
}
|
|
1747
1555
|
return actions;
|
|
1748
1556
|
}
|
|
1749
|
-
function planLegacyCursorSkillCleanupActions(targetPath) {
|
|
1750
|
-
const actions = [];
|
|
1751
|
-
for (const [relativePath, skillName] of LEGACY_CURSOR_SKILL_RELATIVE_PATHS) {
|
|
1752
|
-
const absolutePath = path.join(targetPath, relativePath);
|
|
1753
|
-
const content = fsSync.existsSync(absolutePath)
|
|
1754
|
-
? fsSync.readFileSync(absolutePath, "utf8")
|
|
1755
|
-
: null;
|
|
1756
|
-
if (content === null || !isManagedLegacyCursorSkillContent(content)) {
|
|
1757
|
-
continue;
|
|
1758
|
-
}
|
|
1759
|
-
actions.push(createInstallAction({
|
|
1760
|
-
agent: "cursor",
|
|
1761
|
-
kind: "remove_file",
|
|
1762
|
-
scope: "repo",
|
|
1763
|
-
targetPath,
|
|
1764
|
-
relativePath,
|
|
1765
|
-
state: "planned",
|
|
1766
|
-
mode: "delete",
|
|
1767
|
-
summary: `Remove legacy managed Cursor \`/${skillName}\` skill from .cursor/skills after installing the documented .cursor/commands location.`,
|
|
1768
|
-
}));
|
|
1769
|
-
}
|
|
1770
|
-
return actions;
|
|
1771
|
-
}
|
|
1772
1557
|
function planLegacyClaudeCommandCleanupActions(targetPath) {
|
|
1773
1558
|
const actions = [];
|
|
1774
1559
|
for (const [relativePath, skillName] of LEGACY_CLAUDE_SKILL_COMMAND_RELATIVE_PATHS) {
|
|
@@ -1870,7 +1655,7 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion, integratio
|
|
|
1870
1655
|
expectedTarget: "AGENTS.md",
|
|
1871
1656
|
}));
|
|
1872
1657
|
}
|
|
1873
|
-
actions.push(planSkillInstallAction("claude", targetPath, adapter, CLAUDE_ONBOARD_COMMAND_RELATIVE_PATH, renderClaudeOnboardCommand, "gdh-onboard", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_STATUS_COMMAND_RELATIVE_PATH, renderClaudeStatusCommand, "gdh-status", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_MIGRATE_COMMAND_RELATIVE_PATH, renderClaudeMigrateCommand, "gdh-migrate", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_UPDATE_COMMAND_RELATIVE_PATH, renderClaudeUpdateCommand, "gdh-update", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH, renderClaudePrepareCommand, "gdh-prepare", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_RUN_GAME_COMMAND_RELATIVE_PATH, renderClaudeRunGameCommand, "gdh-run-game", pinnedVersion),
|
|
1658
|
+
actions.push(planSkillInstallAction("claude", targetPath, adapter, CLAUDE_ONBOARD_COMMAND_RELATIVE_PATH, renderClaudeOnboardCommand, "gdh-onboard", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_STATUS_COMMAND_RELATIVE_PATH, renderClaudeStatusCommand, "gdh-status", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_MIGRATE_COMMAND_RELATIVE_PATH, renderClaudeMigrateCommand, "gdh-migrate", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_UPDATE_COMMAND_RELATIVE_PATH, renderClaudeUpdateCommand, "gdh-update", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH, renderClaudePrepareCommand, "gdh-prepare", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_RUN_GAME_COMMAND_RELATIVE_PATH, renderClaudeRunGameCommand, "gdh-run-game", pinnedVersion),
|
|
1874
1659
|
// UPD-01 managed hook surfaces baked at the pinned version.
|
|
1875
1660
|
planHookInstallAction("claude", targetPath, adapter, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, renderClaudeCheckUpdateHook, "gdh-check-update-hook", pinnedVersion), planHookInstallAction("claude", targetPath, adapter, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH, renderClaudeCheckUpdateWorker, "gdh-check-update-worker", pinnedVersion),
|
|
1876
1661
|
// Optional statusline script baked at the pinned version. The .js file is
|
|
@@ -1936,7 +1721,7 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion, integratio
|
|
|
1936
1721
|
//
|
|
1937
1722
|
// Synchronous read via fsSync is intentional: planClaudeInstallActions is
|
|
1938
1723
|
// called without `await`, and making it async would ripple to every sibling
|
|
1939
|
-
// planner (Codex
|
|
1724
|
+
// planner (Codex). The composed patches are idempotent and
|
|
1940
1725
|
// commutative (proven in Task 1 Test J) so application order is irrelevant.
|
|
1941
1726
|
let existingSettingsContent = "";
|
|
1942
1727
|
try {
|
|
@@ -2059,60 +1844,6 @@ function planRootClaudeAuthoringSettingsAction(integrationRootPath) {
|
|
|
2059
1844
|
content: patchedSettings,
|
|
2060
1845
|
});
|
|
2061
1846
|
}
|
|
2062
|
-
function planCursorInstallActions(targetPath, adapter, pinnedVersion, integrationRootPath) {
|
|
2063
|
-
const actions = [];
|
|
2064
|
-
const cursorRuleSurface = adapter.surfaces.find((surface) => surface.relativePath === CURSOR_RULE_RELATIVE_PATH);
|
|
2065
|
-
const targetRelativePath = path.relative(integrationRootPath, targetPath) || ".";
|
|
2066
|
-
if (!cursorRuleSurface || cursorRuleSurface.state === "ready") {
|
|
2067
|
-
actions.push(createInstallAction({
|
|
2068
|
-
agent: "cursor",
|
|
2069
|
-
kind: "write_file",
|
|
2070
|
-
scope: "repo",
|
|
2071
|
-
targetPath,
|
|
2072
|
-
relativePath: CURSOR_RULE_RELATIVE_PATH,
|
|
2073
|
-
state: "unchanged",
|
|
2074
|
-
mode: "unchanged",
|
|
2075
|
-
summary: "The managed Cursor reinforcement rule already matches the expected GDH content.",
|
|
2076
|
-
version: GDH_CURSOR_RULE_VERSION,
|
|
2077
|
-
content: renderCursorRule(),
|
|
2078
|
-
}));
|
|
2079
|
-
}
|
|
2080
|
-
else {
|
|
2081
|
-
actions.push(createInstallAction({
|
|
2082
|
-
agent: "cursor",
|
|
2083
|
-
kind: "write_file",
|
|
2084
|
-
scope: "repo",
|
|
2085
|
-
targetPath,
|
|
2086
|
-
relativePath: CURSOR_RULE_RELATIVE_PATH,
|
|
2087
|
-
state: "planned",
|
|
2088
|
-
mode: cursorRuleSurface.present ? "replace" : "create",
|
|
2089
|
-
summary: cursorRuleSurface.present
|
|
2090
|
-
? "Replace the existing Cursor reinforcement rule with the managed GDH rule."
|
|
2091
|
-
: "Create the managed Cursor reinforcement rule that points back to AGENTS.md.",
|
|
2092
|
-
version: GDH_CURSOR_RULE_VERSION,
|
|
2093
|
-
content: renderCursorRule(),
|
|
2094
|
-
}));
|
|
2095
|
-
}
|
|
2096
|
-
actions.push(planCommandInstallAction("cursor", targetPath, adapter, CURSOR_ONBOARD_COMMAND_RELATIVE_PATH, renderCursorOnboardSkill, "gdh-onboard", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_STATUS_COMMAND_RELATIVE_PATH, renderCursorStatusSkill, "gdh-status", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_MIGRATE_COMMAND_RELATIVE_PATH, renderCursorMigrateSkill, "gdh-migrate", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_UPDATE_COMMAND_RELATIVE_PATH, renderCursorUpdateSkill, "gdh-update", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_PREPARE_COMMAND_RELATIVE_PATH, renderCursorPrepareSkill, "gdh-prepare", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_RUN_GAME_COMMAND_RELATIVE_PATH, renderCursorRunGameSkill, "gdh-run-game", pinnedVersion), planCommandInstallAction("cursor", targetPath, adapter, CURSOR_SCAN_COMMAND_RELATIVE_PATH, renderCursorScanSkill, "gdh-scan", pinnedVersion));
|
|
2097
|
-
if (path.resolve(integrationRootPath) !== path.resolve(targetPath)) {
|
|
2098
|
-
actions.push(planDirectWriteFileAction({
|
|
2099
|
-
agent: "cursor",
|
|
2100
|
-
targetPath: integrationRootPath,
|
|
2101
|
-
relativePath: CURSOR_RULE_RELATIVE_PATH,
|
|
2102
|
-
content: renderCursorRule({ targetRelativePath }),
|
|
2103
|
-
readySummary: "Root-launched Cursor rule already routes to the managed Godot target.",
|
|
2104
|
-
createSummary: "Create root-launched Cursor rule that routes to the managed Godot target.",
|
|
2105
|
-
replaceSummary: "Replace root-launched Cursor rule with target-aware links to the managed Godot target.",
|
|
2106
|
-
}), ...planRootSymlinkActions({
|
|
2107
|
-
agent: "cursor",
|
|
2108
|
-
integrationRootPath,
|
|
2109
|
-
targetPath,
|
|
2110
|
-
relativePaths: CURSOR_COMMAND_RELATIVE_PATHS,
|
|
2111
|
-
noun: "Cursor command",
|
|
2112
|
-
}));
|
|
2113
|
-
}
|
|
2114
|
-
return actions;
|
|
2115
|
-
}
|
|
2116
1847
|
function dedupeInstallActions(actions) {
|
|
2117
1848
|
const seen = new Set();
|
|
2118
1849
|
const deduped = [];
|
|
@@ -2164,8 +1895,11 @@ async function applyWriteFileAction(action) {
|
|
|
2164
1895
|
if (action.absolutePath === null) {
|
|
2165
1896
|
throw new Error("Write-file install action is missing an absolute path.");
|
|
2166
1897
|
}
|
|
1898
|
+
if (action.content === null) {
|
|
1899
|
+
throw new Error("Write-file install action is missing rendered content.");
|
|
1900
|
+
}
|
|
2167
1901
|
await fs.mkdir(path.dirname(action.absolutePath), { recursive: true });
|
|
2168
|
-
await fs.writeFile(action.absolutePath, action.content
|
|
1902
|
+
await fs.writeFile(action.absolutePath, action.content, "utf8");
|
|
2169
1903
|
}
|
|
2170
1904
|
async function applyRemoveFileAction(action) {
|
|
2171
1905
|
if (action.absolutePath === null) {
|
|
@@ -2196,16 +1930,6 @@ async function applyLocalHintsAction(action) {
|
|
|
2196
1930
|
gdhDevRepoPath: typeof parsed.gdhDevRepoPath === "string" ? parsed.gdhDevRepoPath : null,
|
|
2197
1931
|
});
|
|
2198
1932
|
}
|
|
2199
|
-
function readCursorRuleVersion(content) {
|
|
2200
|
-
if (content === null) {
|
|
2201
|
-
return null;
|
|
2202
|
-
}
|
|
2203
|
-
const match = content.match(/<!-- GDH CURSOR RULE VERSION: (\d+) -->/);
|
|
2204
|
-
if (!match?.[1]) {
|
|
2205
|
-
return null;
|
|
2206
|
-
}
|
|
2207
|
-
return Number.parseInt(match[1], 10);
|
|
2208
|
-
}
|
|
2209
1933
|
function resolveProjectMcpEnabled(projectConfig) {
|
|
2210
1934
|
if (projectConfig === null) {
|
|
2211
1935
|
return false;
|
|
@@ -2305,12 +2029,6 @@ function patchManagedCodexProjectSection(content, section) {
|
|
|
2305
2029
|
const afterJoin = afterNonEmpty.length > 0 ? `\n\n${afterNonEmpty}` : "\n";
|
|
2306
2030
|
return `${beforeJoin}${section}${afterJoin}`;
|
|
2307
2031
|
}
|
|
2308
|
-
function removeManagedCodexAuthoringHookBlock(content) {
|
|
2309
|
-
return content
|
|
2310
|
-
.replace(/(?:^|\n)# BEGIN GDH managed authoring hooks\n[\s\S]*?# END GDH managed authoring hooks\n?/, "\n")
|
|
2311
|
-
.replace(/\n{3,}/g, "\n\n")
|
|
2312
|
-
.trimEnd();
|
|
2313
|
-
}
|
|
2314
2032
|
function appendManagedCodexAuthoringHookBlock(content) {
|
|
2315
2033
|
const normalized = content.trimEnd();
|
|
2316
2034
|
const separator = normalized.length > 0 ? "\n\n" : "";
|
|
@@ -2340,30 +2058,6 @@ function ensureCodexHooksFeature(content) {
|
|
|
2340
2058
|
}
|
|
2341
2059
|
return [...lines.slice(0, featuresStart), ...featureLines, ...lines.slice(featuresEnd)].join("\n");
|
|
2342
2060
|
}
|
|
2343
|
-
function renderManagedCodexAuthoringHookBlock() {
|
|
2344
|
-
// Phase 82 / LSP-03. Render PostToolUse and Stop registrations inside one
|
|
2345
|
-
// BEGIN/END envelope, in that order. The empty line between the two blocks is
|
|
2346
|
-
// for human readability. removeManagedCodexAuthoringHookBlock strips the
|
|
2347
|
-
// entire envelope as a single unit, so re-render replaces both blocks
|
|
2348
|
-
// atomically (byte-identical idempotency).
|
|
2349
|
-
return [
|
|
2350
|
-
"# BEGIN GDH managed authoring hooks",
|
|
2351
|
-
"[[hooks.PostToolUse]]",
|
|
2352
|
-
'matcher = "^(apply_patch|Edit|Write)$"',
|
|
2353
|
-
"[[hooks.PostToolUse.hooks]]",
|
|
2354
|
-
'type = "command"',
|
|
2355
|
-
`command = ${JSON.stringify(CODEX_AUTHORING_HOOK_COMMAND)}`,
|
|
2356
|
-
"timeout = 30",
|
|
2357
|
-
"",
|
|
2358
|
-
"[[hooks.Stop]]",
|
|
2359
|
-
"[[hooks.Stop.hooks]]",
|
|
2360
|
-
'type = "command"',
|
|
2361
|
-
`command = ${JSON.stringify(CODEX_AUTHORING_HOOK_COMMAND)}`,
|
|
2362
|
-
"timeout = 60",
|
|
2363
|
-
"# END GDH managed authoring hooks",
|
|
2364
|
-
"",
|
|
2365
|
-
].join("\n");
|
|
2366
|
-
}
|
|
2367
2061
|
function extractManagedCodexSection(content) {
|
|
2368
2062
|
const lines = content.split("\n");
|
|
2369
2063
|
const start = lines.findIndex((line) => /^\[mcp_servers\.gdh\]\s*$/.test(line));
|
|
@@ -2995,9 +2689,8 @@ function inspectMcpManifestLifecycleSurface(targetPath, mcpEnabled, adapterStatu
|
|
|
2995
2689
|
});
|
|
2996
2690
|
}
|
|
2997
2691
|
const claudeMcp = findAdapterSurface(adapterStatus, "claude", "mcp_file");
|
|
2998
|
-
const cursorMcp = findAdapterSurface(adapterStatus, "cursor", "mcp_file");
|
|
2999
2692
|
const codexMcp = findAdapterSurface(adapterStatus, "codex", "mcp_file");
|
|
3000
|
-
const probes = [claudeMcp,
|
|
2693
|
+
const probes = [claudeMcp, codexMcp]
|
|
3001
2694
|
.filter((surface) => surface !== null)
|
|
3002
2695
|
.map((surface) => createVersionProbe({
|
|
3003
2696
|
targetPath,
|
|
@@ -3006,13 +2699,13 @@ function inspectMcpManifestLifecycleSurface(targetPath, mcpEnabled, adapterStatu
|
|
|
3006
2699
|
expectedVersion: null,
|
|
3007
2700
|
detectedVersion: surface.present ? surface.version : null,
|
|
3008
2701
|
}));
|
|
3009
|
-
const states = [claudeMcp?.state,
|
|
2702
|
+
const states = [claudeMcp?.state, codexMcp?.state].filter((state) => state !== undefined);
|
|
3010
2703
|
if (states.length > 0 && states.every((state) => state === "ready")) {
|
|
3011
2704
|
return createLifecycleSurfaceStatus({
|
|
3012
2705
|
surface: "mcp_manifest",
|
|
3013
2706
|
management: "managed",
|
|
3014
2707
|
state: "compatible",
|
|
3015
|
-
summary: "Project MCP config files are aligned for Codex
|
|
2708
|
+
summary: "Project MCP config files are aligned for Codex and Claude.",
|
|
3016
2709
|
reasons: [],
|
|
3017
2710
|
probes,
|
|
3018
2711
|
action: null,
|
|
@@ -3037,45 +2730,6 @@ function inspectMcpManifestLifecycleSurface(targetPath, mcpEnabled, adapterStatu
|
|
|
3037
2730
|
},
|
|
3038
2731
|
});
|
|
3039
2732
|
}
|
|
3040
|
-
function inspectCursorRuleLifecycleSurface(targetPath, adapterStatus) {
|
|
3041
|
-
const surface = findAdapterSurface(adapterStatus, "cursor", "rule_file");
|
|
3042
|
-
const probes = surface === null
|
|
3043
|
-
? []
|
|
3044
|
-
: [
|
|
3045
|
-
createVersionProbe({
|
|
3046
|
-
targetPath,
|
|
3047
|
-
relativePath: surface.relativePath ?? CURSOR_RULE_RELATIVE_PATH,
|
|
3048
|
-
present: surface.present,
|
|
3049
|
-
expectedVersion: GDH_CURSOR_RULE_VERSION,
|
|
3050
|
-
detectedVersion: surface.present ? surface.version : null,
|
|
3051
|
-
}),
|
|
3052
|
-
];
|
|
3053
|
-
if (surface?.state === "ready") {
|
|
3054
|
-
return createLifecycleSurfaceStatus({
|
|
3055
|
-
surface: "cursor_rule",
|
|
3056
|
-
management: "managed",
|
|
3057
|
-
state: "compatible",
|
|
3058
|
-
summary: "Cursor rule file matches the current GDH-managed surface.",
|
|
3059
|
-
reasons: [],
|
|
3060
|
-
probes,
|
|
3061
|
-
action: null,
|
|
3062
|
-
});
|
|
3063
|
-
}
|
|
3064
|
-
return createLifecycleSurfaceStatus({
|
|
3065
|
-
surface: "cursor_rule",
|
|
3066
|
-
management: "managed",
|
|
3067
|
-
state: surface?.present ? "migration_available" : "migration_needed",
|
|
3068
|
-
summary: "Cursor rule file needs to be created or refreshed through the adapter install flow.",
|
|
3069
|
-
reasons: surface?.present ? ["cursor_rule_misconfigured"] : ["cursor_rule_missing"],
|
|
3070
|
-
probes,
|
|
3071
|
-
action: {
|
|
3072
|
-
kind: "run_repair",
|
|
3073
|
-
summary: "Run GDH migrate or adapters install to refresh the managed Cursor rule file.",
|
|
3074
|
-
command: ["gdh", "adapters", "install", targetPath],
|
|
3075
|
-
autoApplicable: true,
|
|
3076
|
-
},
|
|
3077
|
-
});
|
|
3078
|
-
}
|
|
3079
2733
|
function inspectRuntimeBridgeLifecycleSurface(targetPath, bridgeStatus) {
|
|
3080
2734
|
const probes = bridgeStatus.managedArtifacts.map((artifact) => createVersionProbe({
|
|
3081
2735
|
targetPath,
|
|
@@ -3616,14 +3270,4 @@ export { DEFAULT_GRACEFUL_STOP_TIMEOUT_MS, STOP_AND_RESTART_ENV_SUBSET_KEYS, bui
|
|
|
3616
3270
|
// package should continue to use inspectProjectLifecycleCompatibility, which
|
|
3617
3271
|
// wraps this function with filesystem probing and surface discovery.
|
|
3618
3272
|
export { summarizeProjectLifecycleCompatibility };
|
|
3619
|
-
/**
|
|
3620
|
-
* Phase 82 / LSP-03. Test-only export of internals to support
|
|
3621
|
-
* codex-config-render.test.ts (Plan 82-02 Wave 0 RED test scaffold). Do NOT
|
|
3622
|
-
* consume this from production code paths; the public renderers/strippers go
|
|
3623
|
-
* through appendManagedCodexAuthoringHookBlock and the regular config patcher.
|
|
3624
|
-
*/
|
|
3625
|
-
export const __testing__ = {
|
|
3626
|
-
renderManagedCodexAuthoringHookBlock,
|
|
3627
|
-
removeManagedCodexAuthoringHookBlock,
|
|
3628
|
-
};
|
|
3629
3273
|
//# sourceMappingURL=index.js.map
|