@skillcap/gdh 0.16.0 → 0.17.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.
Files changed (53) hide show
  1. package/INSTALL-BUNDLE.json +1 -1
  2. package/RELEASE-SPAN-UPDATE-CONTRACTS.json +87 -0
  3. package/node_modules/@gdh/adapters/dist/index.d.ts +2 -2
  4. package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
  5. package/node_modules/@gdh/adapters/dist/index.js +143 -110
  6. package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
  7. package/node_modules/@gdh/adapters/package.json +8 -8
  8. package/node_modules/@gdh/authoring/dist/index.d.ts +4 -3
  9. package/node_modules/@gdh/authoring/dist/index.d.ts.map +1 -1
  10. package/node_modules/@gdh/authoring/dist/index.js +80 -9
  11. package/node_modules/@gdh/authoring/dist/index.js.map +1 -1
  12. package/node_modules/@gdh/authoring/dist/lsp-client.d.ts +47 -0
  13. package/node_modules/@gdh/authoring/dist/lsp-client.d.ts.map +1 -0
  14. package/node_modules/@gdh/authoring/dist/lsp-client.js +371 -0
  15. package/node_modules/@gdh/authoring/dist/lsp-client.js.map +1 -0
  16. package/node_modules/@gdh/authoring/dist/lsp-test-server.test-utils.d.ts +35 -0
  17. package/node_modules/@gdh/authoring/dist/lsp-test-server.test-utils.d.ts.map +1 -0
  18. package/node_modules/@gdh/authoring/dist/lsp-test-server.test-utils.js +194 -0
  19. package/node_modules/@gdh/authoring/dist/lsp-test-server.test-utils.js.map +1 -0
  20. package/node_modules/@gdh/authoring/dist/lsp.d.ts +62 -1
  21. package/node_modules/@gdh/authoring/dist/lsp.d.ts.map +1 -1
  22. package/node_modules/@gdh/authoring/dist/lsp.js +1207 -109
  23. package/node_modules/@gdh/authoring/dist/lsp.js.map +1 -1
  24. package/node_modules/@gdh/authoring/dist/scene-resource.d.ts +39 -0
  25. package/node_modules/@gdh/authoring/dist/scene-resource.d.ts.map +1 -0
  26. package/node_modules/@gdh/authoring/dist/scene-resource.js +544 -0
  27. package/node_modules/@gdh/authoring/dist/scene-resource.js.map +1 -0
  28. package/node_modules/@gdh/authoring/package.json +2 -2
  29. package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
  30. package/node_modules/@gdh/cli/dist/index.js +116 -18
  31. package/node_modules/@gdh/cli/dist/index.js.map +1 -1
  32. package/node_modules/@gdh/cli/package.json +10 -10
  33. package/node_modules/@gdh/core/dist/index.d.ts +48 -13
  34. package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
  35. package/node_modules/@gdh/core/dist/index.js +14 -17
  36. package/node_modules/@gdh/core/dist/index.js.map +1 -1
  37. package/node_modules/@gdh/core/package.json +1 -1
  38. package/node_modules/@gdh/docs/dist/guidance.d.ts.map +1 -1
  39. package/node_modules/@gdh/docs/dist/guidance.js +12 -2
  40. package/node_modules/@gdh/docs/dist/guidance.js.map +1 -1
  41. package/node_modules/@gdh/docs/dist/rules.d.ts.map +1 -1
  42. package/node_modules/@gdh/docs/dist/rules.js +2 -2
  43. package/node_modules/@gdh/docs/dist/rules.js.map +1 -1
  44. package/node_modules/@gdh/docs/package.json +2 -2
  45. package/node_modules/@gdh/mcp/package.json +8 -8
  46. package/node_modules/@gdh/observability/package.json +2 -2
  47. package/node_modules/@gdh/runtime/package.json +2 -2
  48. package/node_modules/@gdh/scan/package.json +3 -3
  49. package/node_modules/@gdh/verify/dist/policy.d.ts.map +1 -1
  50. package/node_modules/@gdh/verify/dist/policy.js +157 -29
  51. package/node_modules/@gdh/verify/dist/policy.js.map +1 -1
  52. package/node_modules/@gdh/verify/package.json +7 -7
  53. package/package.json +11 -11
@@ -4,17 +4,17 @@ import fs from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { promisify } from "node:util";
7
- import { readProjectConfig, resolvePinnedVersion, resolvePinnedVersionOrNull, resolveProjectRoot, readWorktreeState, resolveAuthoringStatus, } from "@gdh/authoring";
8
- import { CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH, renderClaudeCheckUpdateHook, } from "./claude-update-hook-render.js";
9
- import { renderClaudeCheckUpdateWorker } from "./claude-update-worker-render.js";
10
- import { CLAUDE_STATUSLINE_RELATIVE_PATH, renderClaudeUpdateStatusline, } from "./claude-statusline-render.js";
11
- import { CLAUDE_SETTINGS_RELATIVE_PATH, patchClaudeSettingsForGdhSessionStart, patchClaudeSettingsForGdhStatusline, } from "./claude-settings-patch.js";
12
- import { GDH_AGENT_CONTRACT_VERSION, GDH_CURSOR_RULE_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, assertProjectLifecycleCompatibilityInvariant, definePackageBoundary, resolveCurrentGdhInstall, resolveConfiguredGodotEditorBin, resolveGdhProductMetadata, } from "@gdh/core";
7
+ import { readProjectConfig, readWorktreeState, resolveAuthoringStatus, resolvePinnedVersion, resolvePinnedVersionOrNull, resolveProjectRoot, } from "@gdh/authoring";
8
+ import { assertProjectLifecycleCompatibilityInvariant, definePackageBoundary, GDH_AGENT_CONTRACT_VERSION, GDH_CURSOR_RULE_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";
13
9
  import { createDefaultGuidanceUnits, getGuidanceStatus, resolveGuidanceQuery, resolveRecoveryHints, } from "@gdh/docs";
14
10
  import { inspectGuidanceAudit } from "@gdh/observability";
15
- import { inspectRuntimeBridgeSurface, inspectRuntimeKnowledgeSurface, } from "@gdh/runtime";
11
+ import { inspectRuntimeBridgeSurface, inspectRuntimeKnowledgeSurface } from "@gdh/runtime";
16
12
  import { readInventoryCacheOrScan } from "@gdh/scan";
17
13
  import { evaluateDonePolicy, recommendValidationForChange } from "@gdh/verify";
14
+ import { CLAUDE_SETTINGS_RELATIVE_PATH, patchClaudeSettingsForGdhSessionStart, patchClaudeSettingsForGdhStatusline, } from "./claude-settings-patch.js";
15
+ import { CLAUDE_STATUSLINE_RELATIVE_PATH, renderClaudeUpdateStatusline, } from "./claude-statusline-render.js";
16
+ import { CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH, renderClaudeCheckUpdateHook, } from "./claude-update-hook-render.js";
17
+ import { renderClaudeCheckUpdateWorker } from "./claude-update-worker-render.js";
18
18
  export const adaptersPackage = definePackageBoundary({
19
19
  name: "@gdh/adapters",
20
20
  layer: "integration",
@@ -29,7 +29,11 @@ export const adaptersPackage = definePackageBoundary({
29
29
  "@gdh/verify",
30
30
  ],
31
31
  });
32
- export const SUPPORTED_AGENTS = ["codex", "claude", "cursor"];
32
+ export const SUPPORTED_AGENTS = [
33
+ "codex",
34
+ "claude",
35
+ "cursor",
36
+ ];
33
37
  export const CLAUDE_SHIM_RELATIVE_PATH = "CLAUDE.md";
34
38
  export const CLAUDE_ONBOARD_COMMAND_RELATIVE_PATH = ".claude/commands/gdh/onboard.md";
35
39
  export const PROJECT_MCP_RELATIVE_PATH = ".mcp.json";
@@ -199,9 +203,7 @@ export async function inspectProjectLifecycleCompatibility(targetPath) {
199
203
  autoApplicable: false,
200
204
  },
201
205
  });
202
- return summarizeProjectLifecycleCompatibility(resolvedTargetPath, [
203
- blockedSurface,
204
- ]);
206
+ return summarizeProjectLifecycleCompatibility(resolvedTargetPath, [blockedSurface]);
205
207
  }
206
208
  const guidanceStatus = await getGuidanceStatus(resolvedTargetPath);
207
209
  const bridgeStatus = await inspectRuntimeBridgeSurface({
@@ -721,7 +723,7 @@ export function renderClaudeMigrateCommand(pinnedVersion) {
721
723
  "",
722
724
  `1. Run \`npx -y @skillcap/gdh@${pinnedVersion} migrate\` to preview pending migrations (this is a dry-run; the JSON \`mode\` field will be \`"preview"\`).`,
723
725
  "2. Inspect `compatibility.blockingReasons` vs `compatibility.coupledReasons` — if `blockingReasons` is non-empty, STOP: `migrate --apply` cannot fix them (recommend `/gdh-update` or manual intervention per each reason's recovery hint). If only `coupledReasons` is non-empty, proceed.",
724
- "3. Explain what each migration step will change and why (use \"would\" verb forms — \"would delete\", \"would create\", \"would refresh\").",
726
+ '3. Explain what each migration step will change and why (use "would" verb forms — "would delete", "would create", "would refresh").',
725
727
  `4. Offer to run \`npx -y @skillcap/gdh@${pinnedVersion} migrate --apply\` if the user approves — after apply, the JSON \`mode\` field becomes \`"applied"\` and verbs switch to past tense ("deleted", "created", "refreshed").`,
726
728
  "5. After apply, read `terminal.state` in the stdout JSON.",
727
729
  "6. If `terminal.state` is `healthy`, confirm no further migration action is required and stop.",
@@ -766,7 +768,7 @@ export function renderCodexMigrateSkill(pinnedVersion) {
766
768
  "",
767
769
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} migrate\` to preview pending migrations (this is a dry-run; the JSON \`mode\` field will be \`"preview"\`)`,
768
770
  "- inspect `compatibility.blockingReasons` vs `compatibility.coupledReasons` — if `blockingReasons` is non-empty, STOP: `migrate --apply` cannot fix them (recommend `/gdh-update` or manual intervention per each reason's recovery hint); if only `coupledReasons` is non-empty, proceed",
769
- "- explain what each migration step will change and why (use \"would\" verb forms — \"would delete\", \"would create\", \"would refresh\")",
771
+ '- explain what each migration step will change and why (use "would" verb forms — "would delete", "would create", "would refresh")',
770
772
  `- offer to run \`npx -y @skillcap/gdh@${pinnedVersion} migrate --apply\` if the user approves — after apply, the JSON \`mode\` field becomes \`"applied"\` and verbs switch to past tense ("deleted", "created", "refreshed")`,
771
773
  "- after apply, read `terminal.state` in the stdout JSON",
772
774
  "- if `terminal.state` is `healthy`, confirm no further migration action is required and stop",
@@ -809,7 +811,7 @@ export function renderCursorMigrateSkill(pinnedVersion) {
809
811
  "",
810
812
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} migrate\` to preview pending migrations (this is a dry-run; the JSON \`mode\` field will be \`"preview"\`)`,
811
813
  "- inspect `compatibility.blockingReasons` vs `compatibility.coupledReasons` — if `blockingReasons` is non-empty, STOP: `migrate --apply` cannot fix them (recommend `/gdh-update` or manual intervention per each reason's recovery hint); if only `coupledReasons` is non-empty, proceed",
812
- "- explain what each migration step will change and why (use \"would\" verb forms — \"would delete\", \"would create\", \"would refresh\")",
814
+ '- explain what each migration step will change and why (use "would" verb forms — "would delete", "would create", "would refresh")',
813
815
  `- offer to run \`npx -y @skillcap/gdh@${pinnedVersion} migrate --apply\` if the user approves — after apply, the JSON \`mode\` field becomes \`"applied"\` and verbs switch to past tense ("deleted", "created", "refreshed")`,
814
816
  "- after apply, read `terminal.state` in the stdout JSON",
815
817
  "- if `terminal.state` is `healthy`, confirm no further migration action is required and stop",
@@ -1004,15 +1006,20 @@ export function renderClaudeCheckCommand(pinnedVersion) {
1004
1006
  "<process>",
1005
1007
  "Follow this order:",
1006
1008
  "",
1007
- `1. Run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\`.`,
1008
- "2. Explain each diagnostic finding with severity and provenance.",
1009
- "3. Surface any import-state caveats or editor-side warnings.",
1010
- "4. If issues found, suggest concrete remediation steps.",
1009
+ `1. Run \`npx -y @skillcap/gdh@${pinnedVersion} lsp status\` only for lifecycle visibility; do not treat lifecycle readiness as diagnostic evidence.`,
1010
+ `2. Run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\` to collect validator evidence.`,
1011
+ "3. Explain each diagnostic finding with severity, provenance, and validator family (`gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`).",
1012
+ "4. Surface any import-state caveats or editor-side warnings.",
1013
+ `5. If stale managed LSP state is suspected, use bounded GDH cleanup such as \`npx -y @skillcap/gdh@${pinnedVersion} lsp prune\` or \`npx -y @skillcap/gdh@${pinnedVersion} lsp stop\`; do not hand-manage Godot LSP processes.`,
1014
+ "6. If issues found, suggest concrete remediation steps.",
1011
1015
  "</process>",
1012
1016
  "",
1013
1017
  "<rules>",
1014
1018
  "- Do not fix issues automatically unless asked.",
1019
+ "- Do not hand-manage Godot LSP processes; use GDH lifecycle commands.",
1020
+ "- The gdh lsp lifecycle commands are status, prune, and stop.",
1015
1021
  "- Explain diagnostics in human-readable terms.",
1022
+ "- A ready `authoring.lsp` lifecycle is not proof that the authoring check collected diagnostics.",
1016
1023
  "- Report both hard failures and informational caveats.",
1017
1024
  "</rules>",
1018
1025
  "",
@@ -1044,15 +1051,20 @@ export function renderCodexCheckSkill(pinnedVersion) {
1044
1051
  "<process>",
1045
1052
  "Follow this order:",
1046
1053
  "",
1047
- `- run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\``,
1048
- "- explain each diagnostic finding with severity and provenance",
1054
+ `- run \`npx -y @skillcap/gdh@${pinnedVersion} lsp status\` only for lifecycle visibility; do not treat lifecycle readiness as diagnostic evidence`,
1055
+ `- run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\` to collect validator evidence`,
1056
+ "- explain each diagnostic finding with severity, provenance, and validator family (`gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`)",
1049
1057
  "- surface any import-state caveats or editor-side warnings",
1058
+ `- if stale managed LSP state is suspected, use bounded GDH cleanup such as \`npx -y @skillcap/gdh@${pinnedVersion} lsp prune\` or \`npx -y @skillcap/gdh@${pinnedVersion} lsp stop\`; do not hand-manage Godot LSP processes`,
1050
1059
  "- if issues found, suggest concrete remediation steps",
1051
1060
  "</process>",
1052
1061
  "",
1053
1062
  "<rules>",
1054
1063
  "- Do not fix issues automatically unless asked.",
1064
+ "- Do not hand-manage Godot LSP processes; use GDH lifecycle commands.",
1065
+ "- The gdh lsp lifecycle commands are status, prune, and stop.",
1055
1066
  "- Explain diagnostics in human-readable terms.",
1067
+ "- A ready `authoring.lsp` lifecycle is not proof that the authoring check collected diagnostics.",
1056
1068
  "- Report both hard failures and informational caveats.",
1057
1069
  "</rules>",
1058
1070
  "",
@@ -1082,15 +1094,20 @@ export function renderCursorCheckSkill(pinnedVersion) {
1082
1094
  "<process>",
1083
1095
  "Follow this order:",
1084
1096
  "",
1085
- `- run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\``,
1086
- "- explain each diagnostic finding with severity and provenance",
1097
+ `- run \`npx -y @skillcap/gdh@${pinnedVersion} lsp status\` only for lifecycle visibility; do not treat lifecycle readiness as diagnostic evidence`,
1098
+ `- run \`npx -y @skillcap/gdh@${pinnedVersion} authoring check\` to collect validator evidence`,
1099
+ "- explain each diagnostic finding with severity, provenance, and validator family (`gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`)",
1087
1100
  "- surface any import-state caveats or editor-side warnings",
1101
+ `- if stale managed LSP state is suspected, use bounded GDH cleanup such as \`npx -y @skillcap/gdh@${pinnedVersion} lsp prune\` or \`npx -y @skillcap/gdh@${pinnedVersion} lsp stop\`; do not hand-manage Godot LSP processes`,
1088
1102
  "- if issues found, suggest concrete remediation steps",
1089
1103
  "</process>",
1090
1104
  "",
1091
1105
  "<rules>",
1092
1106
  "- Do not fix issues automatically unless asked.",
1107
+ "- Do not hand-manage Godot LSP processes; use GDH lifecycle commands.",
1108
+ "- The gdh lsp lifecycle commands are status, prune, and stop.",
1093
1109
  "- Explain diagnostics in human-readable terms.",
1110
+ "- A ready `authoring.lsp` lifecycle is not proof that the authoring check collected diagnostics.",
1094
1111
  "- Report both hard failures and informational caveats.",
1095
1112
  "</rules>",
1096
1113
  "",
@@ -1233,8 +1250,9 @@ export function renderClaudeVerifyCommand(pinnedVersion) {
1233
1250
  "1. Identify changed files from git diff or user input.",
1234
1251
  `2. Run \`npx -y @skillcap/gdh@${pinnedVersion} verify recommend\` with those files to get recommended validation kinds.`,
1235
1252
  `3. Run \`npx -y @skillcap/gdh@${pinnedVersion} verify done\` with performed validations to check done eligibility.`,
1236
- "4. Summarize gaps between recommended and performed validation.",
1237
- "5. Suggest specific next verification steps.",
1253
+ "4. For authoring checks, explain validator-family expectations: `gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`, and manual validation for unsupported authoring files.",
1254
+ "5. Summarize gaps between recommended and performed validation, including unavailable/degraded authoring evidence.",
1255
+ "6. Suggest specific next verification steps.",
1238
1256
  "</process>",
1239
1257
  "",
1240
1258
  "<rules>",
@@ -1274,7 +1292,8 @@ export function renderCodexVerifySkill(pinnedVersion) {
1274
1292
  "- identify changed files from git diff or user input",
1275
1293
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} verify recommend\` with those files to get recommended validation kinds`,
1276
1294
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} verify done\` with performed validations to check done eligibility`,
1277
- "- summarize gaps between recommended and performed validation",
1295
+ "- for authoring checks, explain validator-family expectations: `gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`, and manual validation for unsupported authoring files",
1296
+ "- summarize gaps between recommended and performed validation, including unavailable/degraded authoring evidence",
1278
1297
  "- suggest specific next verification steps",
1279
1298
  "</process>",
1280
1299
  "",
@@ -1313,7 +1332,8 @@ export function renderCursorVerifySkill(pinnedVersion) {
1313
1332
  "- identify changed files from git diff or user input",
1314
1333
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} verify recommend\` with those files to get recommended validation kinds`,
1315
1334
  `- run \`npx -y @skillcap/gdh@${pinnedVersion} verify done\` with performed validations to check done eligibility`,
1316
- "- summarize gaps between recommended and performed validation",
1335
+ "- for authoring checks, explain validator-family expectations: `gdscript_lsp` for `.gd`, `godot_scene_resource` for `.tscn`/`.tres`, and manual validation for unsupported authoring files",
1336
+ "- summarize gaps between recommended and performed validation, including unavailable/degraded authoring evidence",
1317
1337
  "- suggest specific next verification steps",
1318
1338
  "</process>",
1319
1339
  "",
@@ -1334,7 +1354,9 @@ async function inspectProjectMcpSupport(targetPath, options) {
1334
1354
  const [projectFile, cursorFile, codexProjectContent, localPathHints] = await Promise.all([
1335
1355
  inspectJsonFile(path.join(options.integrationRootPath, PROJECT_MCP_RELATIVE_PATH)),
1336
1356
  inspectJsonFile(path.join(options.integrationRootPath, CURSOR_MCP_RELATIVE_PATH)),
1337
- fs.readFile(path.join(options.integrationRootPath, CODEX_PROJECT_CONFIG_RELATIVE_PATH), "utf8").catch(() => null),
1357
+ fs
1358
+ .readFile(path.join(options.integrationRootPath, CODEX_PROJECT_CONFIG_RELATIVE_PATH), "utf8")
1359
+ .catch(() => null),
1338
1360
  readLocalPathHints(options.integrationRootPath),
1339
1361
  ]);
1340
1362
  const codexConfigPath = path.join(os.homedir(), ".codex/config.toml");
@@ -1539,11 +1561,7 @@ function inspectCodexSkillSurface(targetPath, relativePath, content, expectedCon
1539
1561
  targetPath,
1540
1562
  relativePath,
1541
1563
  present: content !== null,
1542
- state: content === null
1543
- ? "missing"
1544
- : content === expectedContent
1545
- ? "ready"
1546
- : "misconfigured",
1564
+ state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
1547
1565
  summary: content === null
1548
1566
  ? `Codex \`/${skillName}\` skill is missing and should install under .codex/skills/.`
1549
1567
  : content === expectedContent
@@ -1575,11 +1593,7 @@ function inspectClaudeCommandSurface(targetPath, relativePath, content, expected
1575
1593
  targetPath,
1576
1594
  relativePath,
1577
1595
  present: content !== null,
1578
- state: content === null
1579
- ? "missing"
1580
- : content === expectedContent
1581
- ? "ready"
1582
- : "misconfigured",
1596
+ state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
1583
1597
  summary: content === null
1584
1598
  ? `Claude \`/${commandName}\` command is missing and should install under .claude/commands/gdh/.`
1585
1599
  : content === expectedContent
@@ -1611,11 +1625,7 @@ function inspectCursorSkillSurface(targetPath, relativePath, content, expectedCo
1611
1625
  targetPath,
1612
1626
  relativePath,
1613
1627
  present: content !== null,
1614
- state: content === null
1615
- ? "missing"
1616
- : content === expectedContent
1617
- ? "ready"
1618
- : "misconfigured",
1628
+ state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
1619
1629
  summary: content === null
1620
1630
  ? `Cursor \`/${skillName}\` skill is missing and should install under .cursor/skills/.`
1621
1631
  : content === expectedContent
@@ -1628,17 +1638,31 @@ function inspectCursorSkillSurface(targetPath, relativePath, content, expectedCo
1628
1638
  async function inspectCodexAdapter(targetPath, guidance, projectMcp, pinnedVersion, options) {
1629
1639
  const codexSkillPath = path.join(targetPath, CODEX_ONBOARD_SKILL_RELATIVE_PATH);
1630
1640
  const codexSkillContent = await fs.readFile(codexSkillPath, "utf8").catch(() => null);
1631
- const codexStatusContent = await fs.readFile(path.join(targetPath, CODEX_STATUS_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1632
- const codexMigrateContent = await fs.readFile(path.join(targetPath, CODEX_MIGRATE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1641
+ const codexStatusContent = await fs
1642
+ .readFile(path.join(targetPath, CODEX_STATUS_SKILL_RELATIVE_PATH), "utf8")
1643
+ .catch(() => null);
1644
+ const codexMigrateContent = await fs
1645
+ .readFile(path.join(targetPath, CODEX_MIGRATE_SKILL_RELATIVE_PATH), "utf8")
1646
+ .catch(() => null);
1633
1647
  // Phase 13 Plan 13-03 deliverable — /gdh-update skill for Codex. Inspection
1634
1648
  // wiring is required so planSkillInstallAction can see the surface state;
1635
1649
  // otherwise the planner returns `unchanged` for a missing file and install
1636
1650
  // becomes a no-op (Plan 13-05 integration-test Rule 2 fix).
1637
- const codexUpdateContent = await fs.readFile(path.join(targetPath, CODEX_UPDATE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1638
- const codexCheckContent = await fs.readFile(path.join(targetPath, CODEX_CHECK_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1639
- const codexPrepareContent = await fs.readFile(path.join(targetPath, CODEX_PREPARE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1640
- const codexVerifyContent = await fs.readFile(path.join(targetPath, CODEX_VERIFY_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1641
- const codexScanContent = await fs.readFile(path.join(targetPath, CODEX_SCAN_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1651
+ const codexUpdateContent = await fs
1652
+ .readFile(path.join(targetPath, CODEX_UPDATE_SKILL_RELATIVE_PATH), "utf8")
1653
+ .catch(() => null);
1654
+ const codexCheckContent = await fs
1655
+ .readFile(path.join(targetPath, CODEX_CHECK_SKILL_RELATIVE_PATH), "utf8")
1656
+ .catch(() => null);
1657
+ const codexPrepareContent = await fs
1658
+ .readFile(path.join(targetPath, CODEX_PREPARE_SKILL_RELATIVE_PATH), "utf8")
1659
+ .catch(() => null);
1660
+ const codexVerifyContent = await fs
1661
+ .readFile(path.join(targetPath, CODEX_VERIFY_SKILL_RELATIVE_PATH), "utf8")
1662
+ .catch(() => null);
1663
+ const codexScanContent = await fs
1664
+ .readFile(path.join(targetPath, CODEX_SCAN_SKILL_RELATIVE_PATH), "utf8")
1665
+ .catch(() => null);
1642
1666
  const expectedCodexOnboardSkill = pinnedVersion === null ? null : renderCodexOnboardSkill(pinnedVersion);
1643
1667
  const expectedCodexStatusSkill = pinnedVersion === null ? null : renderCodexStatusSkill(pinnedVersion);
1644
1668
  const expectedCodexMigrateSkill = pinnedVersion === null ? null : renderCodexMigrateSkill(pinnedVersion);
@@ -1728,20 +1752,40 @@ async function inspectClaudeAdapter(targetPath, guidance, projectMcp, pinnedVers
1728
1752
  const onboardCommandPath = path.join(targetPath, CLAUDE_ONBOARD_COMMAND_RELATIVE_PATH);
1729
1753
  const lstat = await fs.lstat(absolutePath).catch(() => null);
1730
1754
  const onboardCommandContent = await fs.readFile(onboardCommandPath, "utf8").catch(() => null);
1731
- const claudeStatusContent = await fs.readFile(path.join(targetPath, CLAUDE_STATUS_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1732
- const claudeMigrateContent = await fs.readFile(path.join(targetPath, CLAUDE_MIGRATE_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1755
+ const claudeStatusContent = await fs
1756
+ .readFile(path.join(targetPath, CLAUDE_STATUS_COMMAND_RELATIVE_PATH), "utf8")
1757
+ .catch(() => null);
1758
+ const claudeMigrateContent = await fs
1759
+ .readFile(path.join(targetPath, CLAUDE_MIGRATE_COMMAND_RELATIVE_PATH), "utf8")
1760
+ .catch(() => null);
1733
1761
  // Phase 13 Plan 13-03 deliverable — /gdh-update slash command for Claude.
1734
1762
  // Inspection wiring is required so planSkillInstallAction can see the surface
1735
1763
  // state; otherwise the planner returns `unchanged` for a missing file and
1736
1764
  // install becomes a no-op (Plan 13-05 integration-test Rule 2 fix).
1737
- const claudeUpdateContent = await fs.readFile(path.join(targetPath, CLAUDE_UPDATE_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1738
- const claudeCheckContent = await fs.readFile(path.join(targetPath, CLAUDE_CHECK_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1739
- const claudePrepareContent = await fs.readFile(path.join(targetPath, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1740
- const claudeVerifyContent = await fs.readFile(path.join(targetPath, CLAUDE_VERIFY_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1741
- const claudeScanContent = await fs.readFile(path.join(targetPath, CLAUDE_SCAN_COMMAND_RELATIVE_PATH), "utf8").catch(() => null);
1742
- const claudeCheckUpdateHookContent = await fs.readFile(path.join(targetPath, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH), "utf8").catch(() => null);
1743
- const claudeCheckUpdateWorkerContent = await fs.readFile(path.join(targetPath, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH), "utf8").catch(() => null);
1744
- const claudeStatuslineContent = await fs.readFile(path.join(targetPath, CLAUDE_STATUSLINE_RELATIVE_PATH), "utf8").catch(() => null);
1765
+ const claudeUpdateContent = await fs
1766
+ .readFile(path.join(targetPath, CLAUDE_UPDATE_COMMAND_RELATIVE_PATH), "utf8")
1767
+ .catch(() => null);
1768
+ const claudeCheckContent = await fs
1769
+ .readFile(path.join(targetPath, CLAUDE_CHECK_COMMAND_RELATIVE_PATH), "utf8")
1770
+ .catch(() => null);
1771
+ const claudePrepareContent = await fs
1772
+ .readFile(path.join(targetPath, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH), "utf8")
1773
+ .catch(() => null);
1774
+ const claudeVerifyContent = await fs
1775
+ .readFile(path.join(targetPath, CLAUDE_VERIFY_COMMAND_RELATIVE_PATH), "utf8")
1776
+ .catch(() => null);
1777
+ const claudeScanContent = await fs
1778
+ .readFile(path.join(targetPath, CLAUDE_SCAN_COMMAND_RELATIVE_PATH), "utf8")
1779
+ .catch(() => null);
1780
+ const claudeCheckUpdateHookContent = await fs
1781
+ .readFile(path.join(targetPath, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH), "utf8")
1782
+ .catch(() => null);
1783
+ const claudeCheckUpdateWorkerContent = await fs
1784
+ .readFile(path.join(targetPath, CLAUDE_CHECK_UPDATE_WORKER_RELATIVE_PATH), "utf8")
1785
+ .catch(() => null);
1786
+ const claudeStatuslineContent = await fs
1787
+ .readFile(path.join(targetPath, CLAUDE_STATUSLINE_RELATIVE_PATH), "utf8")
1788
+ .catch(() => null);
1745
1789
  let detectedTarget = null;
1746
1790
  if (lstat?.isSymbolicLink()) {
1747
1791
  detectedTarget = await fs.readlink(absolutePath).catch(() => null);
@@ -1832,17 +1876,31 @@ async function inspectCursorAdapter(targetPath, guidance, projectMcp, pinnedVers
1832
1876
  const onboardSkillPath = path.join(targetPath, CURSOR_ONBOARD_SKILL_RELATIVE_PATH);
1833
1877
  const content = await fs.readFile(absolutePath, "utf8").catch(() => null);
1834
1878
  const onboardSkillContent = await fs.readFile(onboardSkillPath, "utf8").catch(() => null);
1835
- const cursorStatusContent = await fs.readFile(path.join(targetPath, CURSOR_STATUS_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1836
- const cursorMigrateContent = await fs.readFile(path.join(targetPath, CURSOR_MIGRATE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1879
+ const cursorStatusContent = await fs
1880
+ .readFile(path.join(targetPath, CURSOR_STATUS_SKILL_RELATIVE_PATH), "utf8")
1881
+ .catch(() => null);
1882
+ const cursorMigrateContent = await fs
1883
+ .readFile(path.join(targetPath, CURSOR_MIGRATE_SKILL_RELATIVE_PATH), "utf8")
1884
+ .catch(() => null);
1837
1885
  // Phase 13 Plan 13-03 deliverable — /gdh-update skill for Cursor. Inspection
1838
1886
  // wiring required so planSkillInstallAction sees the surface state; otherwise
1839
1887
  // the planner returns `unchanged` for a missing file and install becomes a
1840
1888
  // no-op (Plan 13-05 integration-test Rule 2 fix).
1841
- const cursorUpdateContent = await fs.readFile(path.join(targetPath, CURSOR_UPDATE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1842
- const cursorCheckContent = await fs.readFile(path.join(targetPath, CURSOR_CHECK_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1843
- const cursorPrepareContent = await fs.readFile(path.join(targetPath, CURSOR_PREPARE_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1844
- const cursorVerifyContent = await fs.readFile(path.join(targetPath, CURSOR_VERIFY_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1845
- const cursorScanContent = await fs.readFile(path.join(targetPath, CURSOR_SCAN_SKILL_RELATIVE_PATH), "utf8").catch(() => null);
1889
+ const cursorUpdateContent = await fs
1890
+ .readFile(path.join(targetPath, CURSOR_UPDATE_SKILL_RELATIVE_PATH), "utf8")
1891
+ .catch(() => null);
1892
+ const cursorCheckContent = await fs
1893
+ .readFile(path.join(targetPath, CURSOR_CHECK_SKILL_RELATIVE_PATH), "utf8")
1894
+ .catch(() => null);
1895
+ const cursorPrepareContent = await fs
1896
+ .readFile(path.join(targetPath, CURSOR_PREPARE_SKILL_RELATIVE_PATH), "utf8")
1897
+ .catch(() => null);
1898
+ const cursorVerifyContent = await fs
1899
+ .readFile(path.join(targetPath, CURSOR_VERIFY_SKILL_RELATIVE_PATH), "utf8")
1900
+ .catch(() => null);
1901
+ const cursorScanContent = await fs
1902
+ .readFile(path.join(targetPath, CURSOR_SCAN_SKILL_RELATIVE_PATH), "utf8")
1903
+ .catch(() => null);
1846
1904
  const expectedContent = renderCursorRule();
1847
1905
  const version = readCursorRuleVersion(content);
1848
1906
  const expectedCursorOnboardSkill = pinnedVersion === null ? null : renderCursorOnboardSkill(pinnedVersion);
@@ -1860,11 +1918,7 @@ async function inspectCursorAdapter(targetPath, guidance, projectMcp, pinnedVers
1860
1918
  targetPath,
1861
1919
  relativePath: CURSOR_RULE_RELATIVE_PATH,
1862
1920
  present: content !== null,
1863
- state: content === null
1864
- ? "missing"
1865
- : content === expectedContent
1866
- ? "ready"
1867
- : "misconfigured",
1921
+ state: content === null ? "missing" : content === expectedContent ? "ready" : "misconfigured",
1868
1922
  summary: content === null
1869
1923
  ? "Cursor reinforcement is missing and should point back to AGENTS.md."
1870
1924
  : content === expectedContent
@@ -2150,12 +2204,7 @@ function planCodexUserInstallActions(targetPath, projectMcp, integrationRootPath
2150
2204
  }
2151
2205
  const resolvedTargetPath = path.resolve(targetPath);
2152
2206
  const resolvedIntegrationRootPath = path.resolve(integrationRootPath);
2153
- const codexCommandArgs = [
2154
- "-y",
2155
- `@skillcap/gdh@${pinnedVersion}`,
2156
- "mcp",
2157
- "serve",
2158
- ];
2207
+ const codexCommandArgs = ["-y", `@skillcap/gdh@${pinnedVersion}`, "mcp", "serve"];
2159
2208
  if (resolvedTargetPath !== resolvedIntegrationRootPath) {
2160
2209
  codexCommandArgs.push("--target", resolvedTargetPath);
2161
2210
  }
@@ -2264,11 +2313,7 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion) {
2264
2313
  targetPath,
2265
2314
  relativePath: CLAUDE_SETTINGS_RELATIVE_PATH,
2266
2315
  state: settingsIsUnchanged ? "unchanged" : "planned",
2267
- mode: settingsIsUnchanged
2268
- ? "unchanged"
2269
- : settingsExistedOnDisk
2270
- ? "replace"
2271
- : "create",
2316
+ mode: settingsIsUnchanged ? "unchanged" : settingsExistedOnDisk ? "replace" : "create",
2272
2317
  summary: settingsIsUnchanged
2273
2318
  ? "GDH SessionStart hook + statusline already registered in .claude/settings.json."
2274
2319
  : settingsExistedOnDisk
@@ -2428,8 +2473,7 @@ function isMatchingManagedMcpServerEntry(entry, expectedEntry) {
2428
2473
  if (entry === null) {
2429
2474
  return false;
2430
2475
  }
2431
- return (JSON.stringify(normalizeJson(entry)) ===
2432
- JSON.stringify(normalizeJson(expectedEntry)));
2476
+ return JSON.stringify(normalizeJson(entry)) === JSON.stringify(normalizeJson(expectedEntry));
2433
2477
  }
2434
2478
  function renderManagedMcpConfig(absolutePath, managedEntry) {
2435
2479
  const existing = readExistingMcpConfig(absolutePath);
@@ -2507,10 +2551,7 @@ function extractManagedCodexSection(content) {
2507
2551
  break;
2508
2552
  }
2509
2553
  }
2510
- return lines
2511
- .slice(start, end)
2512
- .join("\n")
2513
- .replace(/\s+$/, "");
2554
+ return lines.slice(start, end).join("\n").replace(/\s+$/, "");
2514
2555
  }
2515
2556
  function normalizeJson(value) {
2516
2557
  if (Array.isArray(value)) {
@@ -2653,12 +2694,7 @@ async function listCodexMcpServers() {
2653
2694
  function isMatchingCodexRegistration(registration, input) {
2654
2695
  const resolvedTargetPath = path.resolve(input.targetPath);
2655
2696
  const resolvedIntegrationRootPath = path.resolve(input.integrationRootPath);
2656
- const expectedArgs = [
2657
- "-y",
2658
- `@skillcap/gdh@${input.pinnedVersion}`,
2659
- "mcp",
2660
- "serve",
2661
- ];
2697
+ const expectedArgs = ["-y", `@skillcap/gdh@${input.pinnedVersion}`, "mcp", "serve"];
2662
2698
  if (resolvedTargetPath !== resolvedIntegrationRootPath) {
2663
2699
  expectedArgs.push("--target", resolvedTargetPath);
2664
2700
  }
@@ -2668,9 +2704,7 @@ function isMatchingCodexRegistration(registration, input) {
2668
2704
  }
2669
2705
  async function inspectProjectConfigLifecycleSurface(targetPath) {
2670
2706
  const relativePath = ".gdh/project.yaml";
2671
- const content = await fs
2672
- .readFile(path.join(targetPath, relativePath), "utf8")
2673
- .catch(() => null);
2707
+ const content = await fs.readFile(path.join(targetPath, relativePath), "utf8").catch(() => null);
2674
2708
  const detectedVersion = readYamlVersionHeader(content);
2675
2709
  const probes = [
2676
2710
  createVersionProbe({
@@ -2773,9 +2807,7 @@ async function inspectVerificationScenarioLifecycleSurface(targetPath) {
2773
2807
  }
2774
2808
  async function inspectRulesLifecycleSurface(targetPath) {
2775
2809
  const relativePath = ".gdh/rules.yaml";
2776
- const content = await fs
2777
- .readFile(path.join(targetPath, relativePath), "utf8")
2778
- .catch(() => null);
2810
+ const content = await fs.readFile(path.join(targetPath, relativePath), "utf8").catch(() => null);
2779
2811
  const detectedVersion = readYamlVersionHeader(content);
2780
2812
  const probes = [
2781
2813
  createVersionProbe({
@@ -2874,9 +2906,7 @@ function inspectAgentContractLifecycleSurface(targetPath, guidanceStatus) {
2874
2906
  }
2875
2907
  async function inspectGuidanceIndexLifecycleSurface(targetPath) {
2876
2908
  const relativePath = "docs/agent/README.md";
2877
- const content = await fs
2878
- .readFile(path.join(targetPath, relativePath), "utf8")
2879
- .catch(() => null);
2909
+ const content = await fs.readFile(path.join(targetPath, relativePath), "utf8").catch(() => null);
2880
2910
  const detectedVersion = readTaggedVersion(content, /<!-- GDH GUIDANCE INDEX VERSION: (\d+) -->/);
2881
2911
  const probes = [
2882
2912
  createVersionProbe({
@@ -3084,9 +3114,7 @@ function inspectCursorRuleLifecycleSurface(targetPath, adapterStatus) {
3084
3114
  management: "managed",
3085
3115
  state: surface?.present ? "migration_available" : "migration_needed",
3086
3116
  summary: "Cursor rule file needs to be created or refreshed through the adapter install flow.",
3087
- reasons: surface?.present
3088
- ? ["cursor_rule_misconfigured"]
3089
- : ["cursor_rule_missing"],
3117
+ reasons: surface?.present ? ["cursor_rule_misconfigured"] : ["cursor_rule_missing"],
3090
3118
  probes,
3091
3119
  action: {
3092
3120
  kind: "run_repair",
@@ -3533,8 +3561,7 @@ function readTaggedVersion(content, pattern) {
3533
3561
  function findAdapterSurface(adapterStatus, agent, kind) {
3534
3562
  return (adapterStatus.adapters
3535
3563
  .find((entry) => entry.agent === agent)
3536
- ?.surfaces.find((surface) => surface.kind === kind && surface.scope === "repo") ??
3537
- null);
3564
+ ?.surfaces.find((surface) => surface.kind === kind && surface.scope === "repo") ?? null);
3538
3565
  }
3539
3566
  async function pathExists(targetPath) {
3540
3567
  try {
@@ -3580,6 +3607,9 @@ async function addOperationalCapabilityStatus(capabilities, targetPath) {
3580
3607
  operationalAvailability: "available",
3581
3608
  operationalReason: null,
3582
3609
  operationalSummary: "Machine-local Godot editor path is configured, so managed authoring.lsp can launch or reuse an instance.",
3610
+ diagnosticAvailability: "available",
3611
+ diagnosticReason: null,
3612
+ diagnosticSummary: "Machine-local Godot editor path is configured. `gdh authoring check` can launch the GDScript LSP and scene/resource validators, but capability status alone is not diagnostic evidence.",
3583
3613
  };
3584
3614
  }
3585
3615
  return {
@@ -3587,6 +3617,9 @@ async function addOperationalCapabilityStatus(capabilities, targetPath) {
3587
3617
  operationalAvailability: "unavailable",
3588
3618
  operationalReason: "godot_editor_not_configured",
3589
3619
  operationalSummary: "Managed authoring.lsp is enabled for this target, but no machine-local Godot editor path is configured yet.",
3620
+ diagnosticAvailability: "unavailable",
3621
+ diagnosticReason: "godot_editor_not_configured",
3622
+ diagnosticSummary: "Authoring diagnostics require `gdh authoring check` plus a machine-local Godot editor path; declared `authoring.lsp` capability is not diagnostic evidence.",
3590
3623
  };
3591
3624
  });
3592
3625
  }
@@ -3615,9 +3648,9 @@ function deriveRepoState(context) {
3615
3648
  function normalizeChangedFiles(files) {
3616
3649
  return [...new Set(files.map((file) => file.trim()).filter((file) => file.length > 0))];
3617
3650
  }
3618
- export { bumpAndRebakePin, } from "./self-update-mechanics.js";
3619
- export { CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH } from "./claude-update-hook-render.js";
3620
3651
  export { CLAUDE_STATUSLINE_RELATIVE_PATH } from "./claude-statusline-render.js";
3652
+ export { CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH } from "./claude-update-hook-render.js";
3653
+ export { bumpAndRebakePin, } from "./self-update-mechanics.js";
3621
3654
  // Internal aggregator exposed for Wave 0 unit tests
3622
3655
  // (packages/adapters/src/lifecycle-compatibility.test.ts). Callers outside this
3623
3656
  // package should continue to use inspectProjectLifecycleCompatibility, which