@skillcap/gdh 0.19.0 → 0.19.2

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 (56) hide show
  1. package/INSTALL-BUNDLE.json +1 -1
  2. package/README.md +1 -1
  3. package/RELEASE-SPAN-UPDATE-CONTRACTS.json +138 -0
  4. package/node_modules/@gdh/adapters/dist/authoring-hook-render.d.ts.map +1 -1
  5. package/node_modules/@gdh/adapters/dist/authoring-hook-render.js +26 -16
  6. package/node_modules/@gdh/adapters/dist/authoring-hook-render.js.map +1 -1
  7. package/node_modules/@gdh/adapters/dist/claude-settings-patch.d.ts +14 -13
  8. package/node_modules/@gdh/adapters/dist/claude-settings-patch.d.ts.map +1 -1
  9. package/node_modules/@gdh/adapters/dist/claude-settings-patch.js +27 -40
  10. package/node_modules/@gdh/adapters/dist/claude-settings-patch.js.map +1 -1
  11. package/node_modules/@gdh/adapters/dist/claude-statusline-render.d.ts +12 -13
  12. package/node_modules/@gdh/adapters/dist/claude-statusline-render.d.ts.map +1 -1
  13. package/node_modules/@gdh/adapters/dist/claude-statusline-render.js +12 -13
  14. package/node_modules/@gdh/adapters/dist/claude-statusline-render.js.map +1 -1
  15. package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
  16. package/node_modules/@gdh/adapters/dist/index.js +122 -18
  17. package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
  18. package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts.map +1 -1
  19. package/node_modules/@gdh/adapters/dist/skill-rendering.js +22 -7
  20. package/node_modules/@gdh/adapters/dist/skill-rendering.js.map +1 -1
  21. package/node_modules/@gdh/adapters/package.json +8 -8
  22. package/node_modules/@gdh/authoring/package.json +2 -2
  23. package/node_modules/@gdh/cli/dist/migrate.d.ts.map +1 -1
  24. package/node_modules/@gdh/cli/dist/migrate.js +12 -2
  25. package/node_modules/@gdh/cli/dist/migrate.js.map +1 -1
  26. package/node_modules/@gdh/cli/dist/setup.d.ts.map +1 -1
  27. package/node_modules/@gdh/cli/dist/setup.js +11 -4
  28. package/node_modules/@gdh/cli/dist/setup.js.map +1 -1
  29. package/node_modules/@gdh/cli/package.json +10 -10
  30. package/node_modules/@gdh/core/dist/index.d.ts +11 -6
  31. package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
  32. package/node_modules/@gdh/core/dist/index.js +6 -6
  33. package/node_modules/@gdh/core/dist/index.js.map +1 -1
  34. package/node_modules/@gdh/core/package.json +1 -1
  35. package/node_modules/@gdh/docs/dist/agent-contract.d.ts +8 -3
  36. package/node_modules/@gdh/docs/dist/agent-contract.d.ts.map +1 -1
  37. package/node_modules/@gdh/docs/dist/agent-contract.js +53 -6
  38. package/node_modules/@gdh/docs/dist/agent-contract.js.map +1 -1
  39. package/node_modules/@gdh/docs/dist/guidance.d.ts.map +1 -1
  40. package/node_modules/@gdh/docs/dist/guidance.js +5 -4
  41. package/node_modules/@gdh/docs/dist/guidance.js.map +1 -1
  42. package/node_modules/@gdh/docs/dist/query.d.ts.map +1 -1
  43. package/node_modules/@gdh/docs/dist/query.js +94 -22
  44. package/node_modules/@gdh/docs/dist/query.js.map +1 -1
  45. package/node_modules/@gdh/docs/package.json +2 -2
  46. package/node_modules/@gdh/mcp/package.json +8 -8
  47. package/node_modules/@gdh/observability/package.json +2 -2
  48. package/node_modules/@gdh/runtime/dist/bridge-surface.js +5 -3
  49. package/node_modules/@gdh/runtime/dist/bridge-surface.js.map +1 -1
  50. package/node_modules/@gdh/runtime/package.json +2 -2
  51. package/node_modules/@gdh/scan/dist/onboard.d.ts.map +1 -1
  52. package/node_modules/@gdh/scan/dist/onboard.js +11 -2
  53. package/node_modules/@gdh/scan/dist/onboard.js.map +1 -1
  54. package/node_modules/@gdh/scan/package.json +3 -3
  55. package/node_modules/@gdh/verify/package.json +7 -7
  56. package/package.json +11 -11
@@ -317,8 +317,9 @@ export function renderCursorRule() {
317
317
  `<!-- GDH CURSOR RULE VERSION: ${GDH_CURSOR_RULE_VERSION} -->`,
318
318
  "# GDH Cursor Rule",
319
319
  "",
320
- "This repository uses GDH.",
321
- "Follow the canonical repo-local entrypoint in [AGENTS.md](../../AGENTS.md), then load the canonical guidance index at [docs/agent/README.md](../../docs/agent/README.md) before substantive work.",
320
+ "This GDH-managed Godot target uses GDH.",
321
+ "Apply this rule only for files inside this Godot target or when the user explicitly asks for GDH work on this target.",
322
+ "Follow the canonical target-local entrypoint in [AGENTS.md](../../AGENTS.md), then load the canonical guidance index at [docs/agent/README.md](../../docs/agent/README.md) before substantive Godot work.",
322
323
  "For runtime bridge usage, load [docs/agent/authoring-and-validation.md](../../docs/agent/authoring-and-validation.md) and follow its runtime bridge section.",
323
324
  "Do not duplicate or override the canonical GDH guidance chain here.",
324
325
  "",
@@ -1126,7 +1127,7 @@ async function planInstallActions(targetPath, adapters, requestedAgents, options
1126
1127
  continue;
1127
1128
  }
1128
1129
  if (adapter.agent === "claude") {
1129
- actions.push(...planClaudeInstallActions(targetPath, adapter, options.pinnedVersion));
1130
+ actions.push(...planClaudeInstallActions(targetPath, adapter, options.pinnedVersion, options.integrationRootPath));
1130
1131
  continue;
1131
1132
  }
1132
1133
  if (adapter.agent === "cursor") {
@@ -1471,7 +1472,7 @@ function planCodexUserInstallActions(targetPath, projectMcp, integrationRootPath
1471
1472
  }));
1472
1473
  return actions;
1473
1474
  }
1474
- function planClaudeInstallActions(targetPath, adapter, pinnedVersion) {
1475
+ function planClaudeInstallActions(targetPath, adapter, pinnedVersion, integrationRootPath) {
1475
1476
  const actions = [];
1476
1477
  const claudeSurface = adapter.surfaces.find((surface) => surface.relativePath === CLAUDE_SHIM_RELATIVE_PATH);
1477
1478
  if (!claudeSurface || claudeSurface.state === "ready") {
@@ -1505,22 +1506,48 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion) {
1505
1506
  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_CHECK_COMMAND_RELATIVE_PATH, renderClaudeCheckCommand, "gdh-check", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_PREPARE_COMMAND_RELATIVE_PATH, renderClaudePrepareCommand, "gdh-prepare", pinnedVersion), planSkillInstallAction("claude", targetPath, adapter, CLAUDE_SCAN_COMMAND_RELATIVE_PATH, renderClaudeScanCommand, "gdh-scan", pinnedVersion),
1506
1507
  // UPD-01 managed hook surfaces baked at the pinned version.
1507
1508
  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),
1508
- // UPD-02 managed statusline surface baked at the pinned version. The .js
1509
- // file is ALWAYS baked, even when settings.json statusLine is not owned
1510
- // by GDH (write-if-absent below) users can manually point their config
1511
- // at gdh-statusline.js later; the baked file is a no-op until wired.
1509
+ // Optional statusline script baked at the pinned version. The .js file is
1510
+ // ALWAYS baked, but GDH no longer registers Claude's single project
1511
+ // statusLine slot automatically because that would shadow user/global
1512
+ // statusline content. Users can manually point their config at
1513
+ // gdh-statusline.js later; the baked file is a no-op until wired.
1512
1514
  planHookInstallAction("claude", targetPath, adapter, CLAUDE_STATUSLINE_RELATIVE_PATH, renderClaudeUpdateStatusline, "gdh-statusline", pinnedVersion), planHookInstallAction("claude", targetPath, adapter, CLAUDE_AUTHORING_HOOK_RELATIVE_PATH, (version) => renderGdhAuthoringHook({
1513
1515
  pinnedVersion: version,
1514
1516
  targetRelativePath: ".",
1515
1517
  agent: "claude",
1516
1518
  }), "authoring guard", pinnedVersion));
1517
- // UPD-01 + UPD-02 .claude/settings.json composite patch action.
1519
+ if (path.resolve(integrationRootPath) !== path.resolve(targetPath)) {
1520
+ const rootTargetRelativePath = path.relative(integrationRootPath, targetPath) || ".";
1521
+ actions.push(planDirectSymlinkAction({
1522
+ agent: "claude",
1523
+ targetPath: integrationRootPath,
1524
+ relativePath: CLAUDE_SHIM_RELATIVE_PATH,
1525
+ expectedTarget: "AGENTS.md",
1526
+ readySummary: "Root CLAUDE.md already points to the thin root AGENTS.md router.",
1527
+ createSummary: "Create root CLAUDE.md as a symlink to the thin root AGENTS.md router.",
1528
+ replaceSummary: "Replace root CLAUDE.md with a symlink to the thin root AGENTS.md router.",
1529
+ }), planDirectWriteFileAction({
1530
+ agent: "claude",
1531
+ targetPath: integrationRootPath,
1532
+ relativePath: CLAUDE_AUTHORING_HOOK_RELATIVE_PATH,
1533
+ content: renderGdhAuthoringHook({
1534
+ pinnedVersion,
1535
+ targetRelativePath: rootTargetRelativePath,
1536
+ agent: "claude",
1537
+ }),
1538
+ readySummary: "Root-launched Claude authoring hook already matches the managed target-scoped hook.",
1539
+ createSummary: "Create the root-launched Claude authoring hook with target-scoped filtering.",
1540
+ replaceSummary: "Replace the root-launched Claude authoring hook with the target-scoped managed hook.",
1541
+ }), planRootClaudeAuthoringSettingsAction(integrationRootPath));
1542
+ }
1543
+ // .claude/settings.json composite patch action.
1518
1544
  // - Plan 02 (Strategy A, planner-lock #1): patch-merge the SessionStart
1519
1545
  // hook entry by exact command-literal match, preserving siblings.
1520
- // - Plan 03 (write-if-absent, planner-lock #2 / D-18): add the statusLine
1521
- // entry ONLY when no existing statusLine is configured (e.g. GSD-owned
1522
- // or user-owned). Silent no-op for UPD-02 on targets where another
1523
- // tool already owns the slot; the universal surface is MCP _meta.
1546
+ // - Claude statusline migration: remove only the exact old GDH-managed
1547
+ // statusLine entry and never create a new one. Claude supports one
1548
+ // statusLine command; project-level GDH ownership can shadow a user's
1549
+ // global statusline. SessionStart, MCP _meta, and CLI banner remain the
1550
+ // non-destructive update surfaces.
1524
1551
  //
1525
1552
  // Synchronous read via fsSync is intentional: planClaudeInstallActions is
1526
1553
  // called without `await`, and making it async would ripple to every sibling
@@ -1528,7 +1555,7 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion) {
1528
1555
  // commutative (proven in Task 1 Test J) so application order is irrelevant.
1529
1556
  let existingSettingsContent = "";
1530
1557
  try {
1531
- existingSettingsContent = fsSync.readFileSync(path.join(targetPath, CLAUDE_SETTINGS_RELATIVE_PATH), "utf8");
1558
+ existingSettingsContent = fsSync.readFileSync(path.resolve(targetPath, CLAUDE_SETTINGS_RELATIVE_PATH), "utf8");
1532
1559
  }
1533
1560
  catch {
1534
1561
  existingSettingsContent = "";
@@ -1545,15 +1572,92 @@ function planClaudeInstallActions(targetPath, adapter, pinnedVersion) {
1545
1572
  state: settingsIsUnchanged ? "unchanged" : "planned",
1546
1573
  mode: settingsIsUnchanged ? "unchanged" : settingsExistedOnDisk ? "replace" : "create",
1547
1574
  summary: settingsIsUnchanged
1548
- ? "GDH SessionStart hook, authoring guard hooks, and statusline already registered in .claude/settings.json."
1575
+ ? "GDH SessionStart hook and authoring guard hooks already registered in .claude/settings.json; statusline ownership preserved."
1549
1576
  : settingsExistedOnDisk
1550
- ? "Register the GDH SessionStart hook, authoring guard hooks, and statusline (write-if-absent) in .claude/settings.json while preserving sibling content (patch-merge)."
1551
- : "Create .claude/settings.json with the GDH SessionStart hook, authoring guard hooks, and statusline registration.",
1577
+ ? "Register the GDH SessionStart hook and authoring guard hooks in .claude/settings.json while preserving sibling content and removing any exact old GDH-managed statusline."
1578
+ : "Create .claude/settings.json with the GDH SessionStart hook and authoring guard hooks.",
1552
1579
  content: patchedSettings,
1553
1580
  }));
1554
1581
  actions.push(...planLegacyClaudeCommandCleanupActions(targetPath));
1555
1582
  return actions;
1556
1583
  }
1584
+ function planDirectSymlinkAction(input) {
1585
+ const absolutePath = path.resolve(input.targetPath, input.relativePath);
1586
+ let present = false;
1587
+ let ready = false;
1588
+ try {
1589
+ const stat = fsSync.lstatSync(absolutePath);
1590
+ present = true;
1591
+ ready = stat.isSymbolicLink() && fsSync.readlinkSync(absolutePath) === input.expectedTarget;
1592
+ }
1593
+ catch {
1594
+ present = false;
1595
+ }
1596
+ return createInstallAction({
1597
+ agent: input.agent,
1598
+ kind: "ensure_symlink",
1599
+ scope: "repo",
1600
+ targetPath: input.targetPath,
1601
+ relativePath: input.relativePath,
1602
+ state: ready ? "unchanged" : "planned",
1603
+ mode: ready ? "unchanged" : present ? "replace" : "create",
1604
+ summary: ready ? input.readySummary : present ? input.replaceSummary : input.createSummary,
1605
+ expectedTarget: input.expectedTarget,
1606
+ });
1607
+ }
1608
+ function planDirectWriteFileAction(input) {
1609
+ const absolutePath = path.resolve(input.targetPath, input.relativePath);
1610
+ let existingContent = null;
1611
+ try {
1612
+ existingContent = fsSync.readFileSync(absolutePath, "utf8");
1613
+ }
1614
+ catch {
1615
+ existingContent = null;
1616
+ }
1617
+ const ready = existingContent === input.content;
1618
+ return createInstallAction({
1619
+ agent: input.agent,
1620
+ kind: "write_file",
1621
+ scope: "repo",
1622
+ targetPath: input.targetPath,
1623
+ relativePath: input.relativePath,
1624
+ state: ready ? "unchanged" : "planned",
1625
+ mode: ready ? "unchanged" : existingContent === null ? "create" : "replace",
1626
+ summary: ready
1627
+ ? input.readySummary
1628
+ : existingContent === null
1629
+ ? input.createSummary
1630
+ : input.replaceSummary,
1631
+ content: input.content,
1632
+ });
1633
+ }
1634
+ function planRootClaudeAuthoringSettingsAction(integrationRootPath) {
1635
+ const absolutePath = path.join(integrationRootPath, CLAUDE_SETTINGS_RELATIVE_PATH);
1636
+ let existingSettingsContent = "";
1637
+ try {
1638
+ existingSettingsContent = fsSync.readFileSync(absolutePath, "utf8");
1639
+ }
1640
+ catch {
1641
+ existingSettingsContent = "";
1642
+ }
1643
+ const patchedSettings = patchClaudeSettingsForGdhAuthoringHooks(existingSettingsContent);
1644
+ const ready = existingSettingsContent === patchedSettings;
1645
+ return createInstallAction({
1646
+ agent: "claude",
1647
+ kind: "write_file",
1648
+ scope: "repo",
1649
+ targetPath: integrationRootPath,
1650
+ relativePath: CLAUDE_SETTINGS_RELATIVE_PATH,
1651
+ state: ready ? "unchanged" : "planned",
1652
+ mode: ready ? "unchanged" : existingSettingsContent.length > 0 ? "replace" : "create",
1653
+ summary: ready
1654
+ ? "Root-launched Claude authoring hooks are already registered with target-scoped filtering."
1655
+ : existingSettingsContent.length > 0
1656
+ ? "Register root-launched Claude authoring hooks while preserving sibling settings."
1657
+ : "Create root .claude/settings.json with target-scoped authoring hooks.",
1658
+ content: patchedSettings,
1659
+ });
1660
+ }
1557
1661
  function planCursorInstallActions(targetPath, adapter, pinnedVersion) {
1558
1662
  const actions = [];
1559
1663
  const cursorRuleSurface = adapter.surfaces.find((surface) => surface.relativePath === CURSOR_RULE_RELATIVE_PATH);
@@ -2216,7 +2320,7 @@ function inspectAgentContractLifecycleSurface(targetPath, guidanceStatus) {
2216
2320
  const status = guidanceStatus.agentContract;
2217
2321
  const probes = [
2218
2322
  createVersionProbe({
2219
- targetPath,
2323
+ targetPath: path.dirname(status.absolutePath),
2220
2324
  relativePath: status.relativePath,
2221
2325
  present: status.present,
2222
2326
  expectedVersion: GDH_AGENT_CONTRACT_VERSION,