@skillcap/gdh 0.18.2 → 0.19.1

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 (82) hide show
  1. package/INSTALL-BUNDLE.json +1 -1
  2. package/README.md +4 -4
  3. package/RELEASE-SPAN-UPDATE-CONTRACTS.json +145 -8
  4. package/node_modules/@gdh/adapters/dist/authoring-hook-render.d.ts +10 -0
  5. package/node_modules/@gdh/adapters/dist/authoring-hook-render.d.ts.map +1 -0
  6. package/node_modules/@gdh/adapters/dist/authoring-hook-render.js +150 -0
  7. package/node_modules/@gdh/adapters/dist/authoring-hook-render.js.map +1 -0
  8. package/node_modules/@gdh/adapters/dist/claude-settings-patch.d.ts +16 -13
  9. package/node_modules/@gdh/adapters/dist/claude-settings-patch.d.ts.map +1 -1
  10. package/node_modules/@gdh/adapters/dist/claude-settings-patch.js +92 -40
  11. package/node_modules/@gdh/adapters/dist/claude-settings-patch.js.map +1 -1
  12. package/node_modules/@gdh/adapters/dist/claude-statusline-render.d.ts +12 -13
  13. package/node_modules/@gdh/adapters/dist/claude-statusline-render.d.ts.map +1 -1
  14. package/node_modules/@gdh/adapters/dist/claude-statusline-render.js +12 -13
  15. package/node_modules/@gdh/adapters/dist/claude-statusline-render.js.map +1 -1
  16. package/node_modules/@gdh/adapters/dist/index.d.ts +18 -30
  17. package/node_modules/@gdh/adapters/dist/index.d.ts.map +1 -1
  18. package/node_modules/@gdh/adapters/dist/index.js +375 -1137
  19. package/node_modules/@gdh/adapters/dist/index.js.map +1 -1
  20. package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts +45 -0
  21. package/node_modules/@gdh/adapters/dist/skill-rendering.d.ts.map +1 -0
  22. package/node_modules/@gdh/adapters/dist/skill-rendering.js +431 -0
  23. package/node_modules/@gdh/adapters/dist/skill-rendering.js.map +1 -0
  24. package/node_modules/@gdh/adapters/package.json +8 -8
  25. package/node_modules/@gdh/authoring/dist/diagnostics-summary.d.ts +8 -0
  26. package/node_modules/@gdh/authoring/dist/diagnostics-summary.d.ts.map +1 -0
  27. package/node_modules/@gdh/authoring/dist/diagnostics-summary.js +22 -0
  28. package/node_modules/@gdh/authoring/dist/diagnostics-summary.js.map +1 -0
  29. package/node_modules/@gdh/authoring/dist/index.d.ts +4 -1
  30. package/node_modules/@gdh/authoring/dist/index.d.ts.map +1 -1
  31. package/node_modules/@gdh/authoring/dist/index.js +17 -2
  32. package/node_modules/@gdh/authoring/dist/index.js.map +1 -1
  33. package/node_modules/@gdh/authoring/dist/lsp.d.ts +5 -1
  34. package/node_modules/@gdh/authoring/dist/lsp.d.ts.map +1 -1
  35. package/node_modules/@gdh/authoring/dist/lsp.js +95 -1
  36. package/node_modules/@gdh/authoring/dist/lsp.js.map +1 -1
  37. package/node_modules/@gdh/authoring/dist/project.d.ts.map +1 -1
  38. package/node_modules/@gdh/authoring/dist/project.js +1 -0
  39. package/node_modules/@gdh/authoring/dist/project.js.map +1 -1
  40. package/node_modules/@gdh/authoring/dist/scene-resource.d.ts +2 -0
  41. package/node_modules/@gdh/authoring/dist/scene-resource.d.ts.map +1 -1
  42. package/node_modules/@gdh/authoring/dist/scene-resource.js +15 -1
  43. package/node_modules/@gdh/authoring/dist/scene-resource.js.map +1 -1
  44. package/node_modules/@gdh/authoring/package.json +2 -2
  45. package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
  46. package/node_modules/@gdh/cli/dist/index.js +206 -280
  47. package/node_modules/@gdh/cli/dist/index.js.map +1 -1
  48. package/node_modules/@gdh/cli/package.json +10 -10
  49. package/node_modules/@gdh/core/dist/index.d.ts +78 -83
  50. package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
  51. package/node_modules/@gdh/core/dist/index.js +4 -4
  52. package/node_modules/@gdh/core/dist/index.js.map +1 -1
  53. package/node_modules/@gdh/core/package.json +1 -1
  54. package/node_modules/@gdh/docs/dist/agent-contract.js +1 -1
  55. package/node_modules/@gdh/docs/dist/agent-contract.js.map +1 -1
  56. package/node_modules/@gdh/docs/dist/guidance.d.ts.map +1 -1
  57. package/node_modules/@gdh/docs/dist/guidance.js +84 -15
  58. package/node_modules/@gdh/docs/dist/guidance.js.map +1 -1
  59. package/node_modules/@gdh/docs/dist/rules.js +3 -3
  60. package/node_modules/@gdh/docs/dist/rules.js.map +1 -1
  61. package/node_modules/@gdh/docs/package.json +2 -2
  62. package/node_modules/@gdh/mcp/package.json +8 -8
  63. package/node_modules/@gdh/observability/dist/guidance-audit.d.ts.map +1 -1
  64. package/node_modules/@gdh/observability/dist/guidance-audit.js +1 -50
  65. package/node_modules/@gdh/observability/dist/guidance-audit.js.map +1 -1
  66. package/node_modules/@gdh/observability/package.json +2 -2
  67. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.d.ts +23 -0
  68. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.d.ts.map +1 -0
  69. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.js +120 -0
  70. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.js.map +1 -0
  71. package/node_modules/@gdh/runtime/dist/index.d.ts +2 -1
  72. package/node_modules/@gdh/runtime/dist/index.d.ts.map +1 -1
  73. package/node_modules/@gdh/runtime/dist/index.js +28 -62
  74. package/node_modules/@gdh/runtime/dist/index.js.map +1 -1
  75. package/node_modules/@gdh/runtime/package.json +2 -2
  76. package/node_modules/@gdh/scan/package.json +3 -3
  77. package/node_modules/@gdh/verify/dist/index.d.ts +0 -1
  78. package/node_modules/@gdh/verify/dist/index.d.ts.map +1 -1
  79. package/node_modules/@gdh/verify/dist/index.js +1 -2
  80. package/node_modules/@gdh/verify/dist/index.js.map +1 -1
  81. package/node_modules/@gdh/verify/package.json +7 -7
  82. package/package.json +11 -11
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "product": "GDH",
3
- "version": "0.18.2",
3
+ "version": "0.19.1",
4
4
  "installMode": "packaged_install"
5
5
  }
package/README.md CHANGED
@@ -19,7 +19,7 @@ Then open your agent in that project and run:
19
19
  /gdh-onboard
20
20
  ```
21
21
 
22
- GDH writes the project guidance, command surfaces, MCP config, and local state that supported agents use for future work. Setup records the resolved GDH version in the target project so later updates can migrate that project deliberately.
22
+ GDH writes the project guidance, agent skill surfaces, MCP config, and local state that supported agents use for future work. Setup records the resolved GDH version in the target project so later updates can migrate that project deliberately.
23
23
 
24
24
  ## Requirements
25
25
 
@@ -32,7 +32,7 @@ GDH writes the project guidance, command surfaces, MCP config, and local state t
32
32
  ## What It Does
33
33
 
34
34
  - Finds Godot project roots and writes `.gdh/project.yaml` plus `.gdh-state/` derived state.
35
- - Installs agent commands and skills such as `/gdh-status`, `/gdh-prepare`, `/gdh-check`, `/gdh-verify`, `/gdh-migrate`, and `/gdh-update`.
35
+ - Installs agent commands and skills such as `/gdh-status`, `/gdh-prepare`, `/gdh-check`, `/gdh-migrate`, and `/gdh-update`.
36
36
  - Exposes MCP tools for project status, authoring checks, docs lookup, runtime bridge operations, and verification.
37
37
  - Keeps generated target-project files inside the managed project, not in GDH's own implementation repo.
38
38
 
@@ -42,8 +42,8 @@ GDH writes the project guidance, command surfaces, MCP config, and local state t
42
42
  npx -y @skillcap/gdh@latest setup
43
43
  gdh status
44
44
  gdh target prepare --dry-run
45
- gdh authoring check
46
- gdh verify recommend --since main
45
+ gdh authoring check --mode final
46
+ gdh authoring check --mode post-edit --changed res://scripts/player.gd --format compact
47
47
  gdh self-update --dry-run --target .
48
48
  ```
49
49
 
@@ -218,8 +218,8 @@
218
218
  "releaseHighlights": {
219
219
  "summary": "`v0.3.0` reshapes GDH's agent integration surface. MCP is now strictly for Godot engine interaction (11 tools). Project management workflows move to 5 new agent skills generated during `gdh setup` for Claude, Codex, and Cursor.",
220
220
  "operatorChanges": [
221
- "**5 new agent skills:** `/gdh-status`, `/gdh-migrate`, `/gdh-check`, `/gdh-prepare`, `/gdh-verify` generated for all three supported agents during `gdh setup`.",
222
- "**MCP scope reduction:** Removed 6 non-engine MCP tools (`status.get`, `guidance.resolve`, `verify.recommend`, `verify.done`, `verify.inspect`, `verify.readiness`). These workflows are now handled by agent skills + CLI.",
221
+ "**Agent workflow skills:** `/gdh-status`, `/gdh-migrate`, `/gdh-check`, and `/gdh-prepare` generated for all three supported agents during `gdh setup`.",
222
+ "**MCP scope reduction:** Removed non-engine MCP tools for status, guidance, and verification administration. These workflows are now handled by agent skills + CLI.",
223
223
  "**MCP retains 11 engine tools:** `docs.*`, `target.prepare`, `authoring.check`, `run-config.*`, `bridge.*`, `verify.run`.",
224
224
  "Existing targets need `gdh setup --yes` re-run to pick up the new skills."
225
225
  ]
@@ -1274,7 +1274,7 @@
1274
1274
  "version": "0.17.0",
1275
1275
  "releaseTag": "v0.17.0",
1276
1276
  "migrationStatus": "required",
1277
- "summary": "v0.17.0 completes real Godot authoring validation policy and guidance. The release changes GDH_GUIDANCE_UNIT_VERSION (6 -> 7) and GDH_RULES_SCHEMA_VERSION (1 -> 2), so managed targets need `gdh migrate --apply` to refresh generated guidance with the managed LSP lifecycle, validator-family split, and done-policy evidence rules, plus manual review for project-owned stale rules files.",
1277
+ "summary": "v0.17.0 completes real Godot authoring validation guidance. The release changes GDH_GUIDANCE_UNIT_VERSION (6 -> 7) and GDH_RULES_SCHEMA_VERSION (1 -> 2), so managed targets need `gdh migrate --apply` to refresh generated guidance with the managed LSP lifecycle and validator-family split, plus manual review for project-owned stale rules files.",
1278
1278
  "releaseHighlights": {
1279
1279
  "summary": "v0.17.0 makes authoring validation real instead of lifecycle-shaped. GDH now manages a Godot LSP protocol client, separates LSP process health from diagnostic evidence, collects GDScript diagnostics, validates `.tscn` and `.tres` resources through Godot, and teaches agents that required authoring checks stay blocked when evidence is unavailable or degraded.",
1280
1280
  "operatorChanges": [
@@ -1282,7 +1282,7 @@
1282
1282
  "**LSP state is worktree-safe.** Managed LSP identity includes worktree, project, launcher, editor binary, and editor version data; GDH mutates registry state through a lock and exposes bounded `gdh lsp prune` / `gdh lsp stop` cleanup commands.",
1283
1283
  "**GDScript diagnostics are collected through the LSP.** `gdh authoring check` can surface real `.gd` diagnostics with source, severity, range, and provenance instead of a placeholder readiness result.",
1284
1284
  "**Scene and resource files have their own validator.** `.tscn` and `.tres` files route through the `godot_scene_resource` validator, while unsupported authoring files remain manual-validation work.",
1285
- "**Done policy is validator-aware.** `gdh verify recommend` and `gdh verify done` distinguish `gdscript_lsp`, `godot_scene_resource`, and unsupported authoring surfaces so agents do not claim completion from incomplete evidence.",
1285
+ "**Authoring checks are validator-aware.** `gdh authoring check` distinguishes `gdscript_lsp`, `godot_scene_resource`, and unsupported authoring surfaces so agents do not claim code validity from incomplete evidence.",
1286
1286
  "**Generated guidance rejects fake readiness.** Managed guidance and adapter skills now tell agents to use `gdh authoring check` for evidence and treat lifecycle-only LSP status as operational visibility."
1287
1287
  ]
1288
1288
  },
@@ -1343,15 +1343,14 @@
1343
1343
  "id": "validate_authoring_evidence",
1344
1344
  "kind": "mechanical",
1345
1345
  "summary": "Collect real authoring validator evidence.",
1346
- "detail": "Run `gdh authoring check`, then use `gdh verify recommend` and `gdh verify done` for changed files. Required authoring checks remain blocked when validator evidence is unavailable, degraded, or missing.",
1346
+ "detail": "Run `gdh authoring check` for changed files. Required authoring checks remain blocked when validator evidence is unavailable, degraded, or missing.",
1347
1347
  "commands": [
1348
1348
  "gdh authoring check",
1349
- "gdh verify recommend",
1350
- "gdh verify done"
1349
+ "gdh authoring check"
1351
1350
  ],
1352
1351
  "validationCommands": [
1353
1352
  "gdh authoring check",
1354
- "gdh verify done"
1353
+ "gdh authoring check"
1355
1354
  ]
1356
1355
  }
1357
1356
  ]
@@ -1694,6 +1693,144 @@
1694
1693
  }
1695
1694
  ]
1696
1695
  }
1696
+ },
1697
+ {
1698
+ "version": "0.19.0",
1699
+ "releaseTag": "v0.19.0",
1700
+ "migrationStatus": "required",
1701
+ "summary": "v0.19.0 ships the bridge broker contract, authoring validator hooks and guidance, shared Markdown skill rendering, Claude project skills under `.claude/skills/gdh-*/SKILL.md`, and removal of the retired `/gdh-verify` policy surface. Managed targets need `gdh migrate --apply` because GDH_RULES_SCHEMA_VERSION moves 2 -> 3, GDH_AGENT_CONTRACT_VERSION moves 2 -> 3, GDH_GUIDANCE_INDEX_VERSION moves 2 -> 3, and GDH_GUIDANCE_UNIT_VERSION moves 9 -> 11.",
1702
+ "releaseHighlights": {
1703
+ "summary": "v0.19.0 ships the next authoring and agent-adapter hardening slice: the runtime package now has a target-local bridge broker contract, GDH authoring validation is wired into agent hooks and clearer skill guidance, shipped skills are generated from one shared Markdown definition set across Claude, Codex, and Cursor, and the retired `/gdh-verify` policy surface is removed. Managed targets need `gdh migrate --apply` after update because rules, guidance, and agent-contract surface versions moved.",
1704
+ "operatorChanges": [
1705
+ "**Runtime bridge broker contract added.** GDH now defines the target-local bridge broker identity, lifecycle, state, and ownership contract that later reconnectable CLI/MCP bridge clients build on. This release establishes the contract; later phases implement the full broker lifecycle and reconnecting clients.",
1706
+ "**Authoring hooks route agents through GDH validation.** Generated Codex and Claude hook surfaces now run fast post-edit checks and final authoring checks using GDH authoring diagnostics, with skill guidance updated to distinguish validation evidence from LSP lifecycle visibility.",
1707
+ "**Shipped skill rendering is shared and Markdown-native.** Claude, Codex, and Cursor skills now render from one `GDH_SKILL_DEFINITIONS` map. Current skill bodies use Markdown headings plus a neutral `GDH_MANAGED_AGENT_SKILL` marker instead of GDH-specific XML wrapper tags.",
1708
+ "**Claude canonical skill path changed.** GDH now writes Claude project skills to `.claude/skills/gdh-*/SKILL.md`. Old GDH-managed `.claude/commands/gdh/*.md` command files are removed only when GDH can prove ownership; user-authored command files are preserved.",
1709
+ "**Rules and migrate guidance tightened.** The default rules schema moves to version 3 to reflect the updated authoring-validation wording. Default prior-version rules are auto-refreshable; customized prior-version rules stay on manual review.",
1710
+ "**`/gdh-verify` is retired.** Agents should use `/gdh-check` and the authoring-check path for code-validity evidence."
1711
+ ]
1712
+ },
1713
+ "updateContract": {
1714
+ "summary": "Managed targets need release-specific migration for v0.19.0 because rules, guidance, and agent contract surfaces changed. After self-update, run `gdh migrate --apply` to refresh generated guidance, agent instruction blocks, adapter skills, hooks, and default rules where safe. Customized prior-version rules require manual review.",
1715
+ "steps": [
1716
+ {
1717
+ "id": "verify_post_update_status",
1718
+ "kind": "mechanical",
1719
+ "summary": "Run the standard post-update lifecycle check.",
1720
+ "detail": "Start with `gdh status` so GDH can report whether the target needs rules, guidance, agent-contract, or adapter migration for v0.19.0.",
1721
+ "commands": [
1722
+ "gdh status"
1723
+ ],
1724
+ "validationCommands": [
1725
+ "gdh status"
1726
+ ]
1727
+ },
1728
+ {
1729
+ "id": "apply_managed_surface_migration",
1730
+ "kind": "mechanical",
1731
+ "summary": "Refresh managed guidance, agent contract, adapter skills, hooks, and default rules.",
1732
+ "detail": "Run `gdh migrate --apply` when status or migrate preview reports outdated guidance, agent contract, adapter skills, hooks, or default rules. This re-bakes Claude, Codex, and Cursor skills at the current pin and moves Claude GDH-owned skills to `.claude/skills/gdh-*/SKILL.md`.",
1733
+ "commands": [
1734
+ "gdh migrate --apply"
1735
+ ],
1736
+ "validationCommands": [
1737
+ "gdh guidance status",
1738
+ "gdh status",
1739
+ "gdh verify drift"
1740
+ ]
1741
+ },
1742
+ {
1743
+ "id": "review_custom_rules_schema_v3",
1744
+ "kind": "manual_review",
1745
+ "summary": "Review customized prior-version rules before adopting schema version 3.",
1746
+ "detail": "If GDH reports `rules_version_unrecognized`, inspect `.gdh/rules.yaml`. Default boilerplate should be refreshed by `gdh migrate --apply`; customized project rules must be ported into a schema version 3 file or explicitly accepted by the project owner.",
1747
+ "commands": [
1748
+ "gdh migrate"
1749
+ ],
1750
+ "validationCommands": [
1751
+ "gdh status"
1752
+ ]
1753
+ },
1754
+ {
1755
+ "id": "use_authoring_check_for_validation_evidence",
1756
+ "kind": "agent_reasoning",
1757
+ "summary": "Use authoring-check diagnostics instead of readiness guesses.",
1758
+ "detail": "After migration, agents should use `/gdh-check` or `gdh authoring check` for Godot code-validity evidence. LSP lifecycle commands explain availability and cleanup only; they are not proof that code is valid.",
1759
+ "commands": [
1760
+ "gdh authoring check --mode final"
1761
+ ],
1762
+ "validationCommands": [
1763
+ "gdh authoring check --mode final"
1764
+ ]
1765
+ },
1766
+ {
1767
+ "id": "confirm_broker_contract_scope",
1768
+ "kind": "agent_reasoning",
1769
+ "summary": "Treat the bridge broker as a contract foundation, not a full reconnecting runtime yet.",
1770
+ "detail": "v0.19.0 defines the target-local broker contract in GDH runtime code. Do not assume full broker lifecycle ownership or reconnectable bridge clients are available until later v1.16 phases ship them.",
1771
+ "commands": [
1772
+ "gdh status"
1773
+ ],
1774
+ "validationCommands": [
1775
+ "gdh status"
1776
+ ]
1777
+ }
1778
+ ]
1779
+ }
1780
+ },
1781
+ {
1782
+ "version": "0.19.1",
1783
+ "releaseTag": "v0.19.1",
1784
+ "migrationStatus": "no_op",
1785
+ "summary": "v0.19.1 hardens supported-agent adapter behavior without changing managed schema or lifecycle surface versions. Claude adapter install no longer auto-registers GDH in Claude Code's single project `statusLine` slot, removes only the exact old GDH-managed statusLine entry during repair/update, and preserves custom statuslines. Generated gdh-update, gdh-status, and gdh-onboard skill guidance is clearer, but no release-scoped schema migration is required.",
1786
+ "releaseHighlights": {
1787
+ "summary": "v0.19.1 hardens supported-agent adapter behavior from dogfooding feedback. Claude project installs no longer auto-own Claude Code's single `statusLine` slot, so existing user or global statuslines stay visible. The release also tightens generated `/gdh-update`, `/gdh-status`, and `/gdh-onboard` skill guidance so agents have clearer operational context during update, status, and onboarding flows.",
1788
+ "operatorChanges": [
1789
+ "**Claude statusline ownership is non-destructive.** GDH still bakes `.claude/hooks/gdh-statusline.js` as an optional script, but adapter install no longer writes a project-level `statusLine` entry when one is absent. This prevents GDH from shadowing user/global Claude statuslines.",
1790
+ "**Old GDH-managed statusline entries are cleaned up safely.** Adapter repair/update removes only the exact prior GDH-managed `statusLine` entry. Custom, user-owned, or tool-owned statuslines are preserved.",
1791
+ "**Shipped skill guidance is clearer.** `/gdh-update` now emphasizes terminal-state follow-through, drift verification, explicit target handling, and stale MCP cleanup boundaries. `/gdh-status` and `/gdh-onboard` define the operational terms agents need instead of assuming project-specific vocabulary is already known."
1792
+ ]
1793
+ },
1794
+ "updateContract": {
1795
+ "summary": "No release-scoped managed schema migration is required for v0.19.1. After self-update, the adapter re-bake path applies the Claude statusline cleanup automatically: exact old GDH-managed statusLine ownership is removed, custom statuslines are preserved, and the optional GDH statusline script remains available for projects that explicitly opt into it.",
1796
+ "steps": [
1797
+ {
1798
+ "id": "rebake_agent_adapters",
1799
+ "kind": "mechanical",
1800
+ "summary": "Re-bake supported-agent surfaces at the new GDH pin.",
1801
+ "detail": "`gdh self-update` re-runs the adapter install path. If an agent needs to repair surfaces manually, run `gdh adapters install <target>` for repo-local agent surfaces.",
1802
+ "commands": [
1803
+ "gdh adapters install <target>"
1804
+ ],
1805
+ "validationCommands": [
1806
+ "gdh adapters status <target>",
1807
+ "gdh verify drift <target>"
1808
+ ]
1809
+ },
1810
+ {
1811
+ "id": "preserve_claude_statusline",
1812
+ "kind": "agent_reasoning",
1813
+ "summary": "Do not replace project or user Claude statuslines with GDH's optional statusline script.",
1814
+ "detail": "Claude Code exposes one statusLine command slot. GDH no longer auto-registers its optional statusline script because a project-level entry can shadow a user's global/custom statusline. If a project deliberately wants the GDH hint, it can configure `.claude/hooks/gdh-statusline.js` itself.",
1815
+ "commands": [],
1816
+ "validationCommands": [
1817
+ "gdh adapters status <target>"
1818
+ ]
1819
+ },
1820
+ {
1821
+ "id": "verify_custom_statusline_survived",
1822
+ "kind": "mechanical",
1823
+ "summary": "When a project had a custom Claude statusLine, confirm it remains configured.",
1824
+ "detail": "Inspect `.claude/settings.json` only when statusline behavior is relevant. Custom statusLine entries should remain unchanged; only the exact prior GDH-managed command is removed.",
1825
+ "commands": [
1826
+ "gdh adapters status <target>"
1827
+ ],
1828
+ "validationCommands": [
1829
+ "gdh adapters status <target>"
1830
+ ]
1831
+ }
1832
+ ]
1833
+ }
1697
1834
  }
1698
1835
  ]
1699
1836
  }
@@ -0,0 +1,10 @@
1
+ export declare const CLAUDE_AUTHORING_HOOK_RELATIVE_PATH = ".claude/hooks/gdh-authoring-guard.js";
2
+ export declare const CODEX_AUTHORING_HOOK_RELATIVE_PATH = ".codex/hooks/gdh-authoring-guard.js";
3
+ export declare const CLAUDE_AUTHORING_HOOK_COMMAND = "node -e \"const fs=require('fs'),path=require('path');let d=process.cwd();for(;;){const f=path.join(d,'.claude/hooks/gdh-authoring-guard.js');if(fs.existsSync(f)){require(f);break}const p=path.dirname(d);if(p===d)throw new Error('GDH Claude authoring hook not found');d=p}\"";
4
+ export declare const CODEX_AUTHORING_HOOK_COMMAND = "node -e \"const fs=require('fs'),path=require('path');let d=process.cwd();for(;;){const f=path.join(d,'.codex/hooks/gdh-authoring-guard.js');if(fs.existsSync(f)){require(f);break}const p=path.dirname(d);if(p===d)throw new Error('GDH Codex authoring hook not found');d=p}\"";
5
+ export declare function renderGdhAuthoringHook(input: {
6
+ readonly pinnedVersion: string;
7
+ readonly targetRelativePath: string;
8
+ readonly agent: "codex" | "claude";
9
+ }): string;
10
+ //# sourceMappingURL=authoring-hook-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-hook-render.d.ts","sourceRoot":"","sources":["../src/authoring-hook-render.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,mCAAmC,yCAAyC,CAAC;AAC1F,eAAO,MAAM,kCAAkC,wCAAwC,CAAC;AACxF,eAAO,MAAM,6BAA6B,uRAC4O,CAAC;AACvR,eAAO,MAAM,4BAA4B,qRAC2O,CAAC;AAErR,wBAAgB,sBAAsB,CAAC,KAAK,EAAE;IAC5C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ,CAAC;CACpC,GAAG,MAAM,CA+IT"}
@@ -0,0 +1,150 @@
1
+ import { GDH_UPDATE_HOOK_VERSION } from "@gdh/core";
2
+ export const CLAUDE_AUTHORING_HOOK_RELATIVE_PATH = ".claude/hooks/gdh-authoring-guard.js";
3
+ export const CODEX_AUTHORING_HOOK_RELATIVE_PATH = ".codex/hooks/gdh-authoring-guard.js";
4
+ export const CLAUDE_AUTHORING_HOOK_COMMAND = "node -e \"const fs=require('fs'),path=require('path');let d=process.cwd();for(;;){const f=path.join(d,'.claude/hooks/gdh-authoring-guard.js');if(fs.existsSync(f)){require(f);break}const p=path.dirname(d);if(p===d)throw new Error('GDH Claude authoring hook not found');d=p}\"";
5
+ export const CODEX_AUTHORING_HOOK_COMMAND = "node -e \"const fs=require('fs'),path=require('path');let d=process.cwd();for(;;){const f=path.join(d,'.codex/hooks/gdh-authoring-guard.js');if(fs.existsSync(f)){require(f);break}const p=path.dirname(d);if(p===d)throw new Error('GDH Codex authoring hook not found');d=p}\"";
6
+ export function renderGdhAuthoringHook(input) {
7
+ return [
8
+ "#!/usr/bin/env node",
9
+ `// gdh-hook-version: ${GDH_UPDATE_HOOK_VERSION}`,
10
+ "// GDH authoring validation hook. Dependency-free by design.",
11
+ `const PINNED_VERSION = ${JSON.stringify(input.pinnedVersion)};`,
12
+ `const TARGET_RELATIVE_PATH = ${JSON.stringify(input.targetRelativePath)};`,
13
+ `const AGENT = ${JSON.stringify(input.agent)};`,
14
+ "",
15
+ "const fs = require('fs');",
16
+ "const path = require('path');",
17
+ "const crypto = require('crypto');",
18
+ "const { spawnSync } = require('child_process');",
19
+ "",
20
+ "const AUTHORING_EXTENSIONS = new Set(['.gd', '.tscn', '.tres']);",
21
+ "let CURRENT_EVENT = '';",
22
+ "",
23
+ "main();",
24
+ "",
25
+ "function main() {",
26
+ " const input = readHookInput();",
27
+ " const targetRoot = resolveTargetRoot(input);",
28
+ " const hookEvent = String(input.hook_event_name || '');",
29
+ " CURRENT_EVENT = hookEvent;",
30
+ " if (!targetRoot) return allow();",
31
+ " if (hookEvent === 'PostToolUse' || hookEvent === 'FileChanged') return handlePostEdit(input, targetRoot);",
32
+ " if (hookEvent === 'Stop') return handleStop(input, targetRoot);",
33
+ " return allow();",
34
+ "}",
35
+ "",
36
+ "function handlePostEdit(input, targetRoot) {",
37
+ " const changed = collectChangedFiles(input, targetRoot);",
38
+ " const authoring = changed.filter(isAuthoringPath);",
39
+ " if (authoring.length === 0) return allow();",
40
+ " const state = readDirtyState(targetRoot);",
41
+ " const dirtyFiles = unique([...(state.dirtyFiles || []), ...authoring]);",
42
+ " writeDirtyState(targetRoot, { dirtyFiles, updatedAt: new Date().toISOString(), lastBlockedHash: state.lastBlockedHash || null });",
43
+ " const scoped = authoring.filter((file) => AUTHORING_EXTENSIONS.has(path.extname(file).toLowerCase()));",
44
+ " if (scoped.length === 0) return allow();",
45
+ " const result = runGdh(targetRoot, ['authoring', 'check', '--target', targetRoot, '--mode', 'post-edit', '--format', 'compact', ...scoped.flatMap((file) => ['--changed', file])]);",
46
+ " if (!result.ok || !/Completion allowed\\./.test(result.output)) {",
47
+ " return block(`GDH post-edit authoring check needs attention.\\n${result.output || result.error || 'No check output.'}`);",
48
+ " }",
49
+ " return allow();",
50
+ "}",
51
+ "",
52
+ "function handleStop(input, targetRoot) {",
53
+ " const state = readDirtyState(targetRoot);",
54
+ " const dirtyFiles = unique(state.dirtyFiles || []);",
55
+ " if (dirtyFiles.length === 0) return allow();",
56
+ " const result = runGdh(targetRoot, ['authoring', 'check', '--target', targetRoot, '--mode', 'final', '--format', 'compact']);",
57
+ " if (result.ok && /Completion allowed\\./.test(result.output)) {",
58
+ " clearDirtyState(targetRoot);",
59
+ " return allow();",
60
+ " }",
61
+ " const dirtyHash = hash(JSON.stringify(dirtyFiles));",
62
+ " if (input.stop_hook_active === true && state.lastBlockedHash === dirtyHash) return allow();",
63
+ " writeDirtyState(targetRoot, { dirtyFiles, updatedAt: new Date().toISOString(), lastBlockedHash: dirtyHash });",
64
+ " return block(`GDH final authoring check is not clean for changed authoring files. Continue fixing before stopping.\\n${result.output || result.error || 'No check output.'}`);",
65
+ "}",
66
+ "",
67
+ "function runGdh(targetRoot, args) {",
68
+ " const result = spawnSync('npx', ['-y', `@skillcap/gdh@${PINNED_VERSION}`, ...args], {",
69
+ " cwd: targetRoot,",
70
+ " encoding: 'utf8',",
71
+ " windowsHide: true,",
72
+ " timeout: 120000,",
73
+ " });",
74
+ " const output = `${result.stdout || ''}${result.stderr || ''}`.trim();",
75
+ " return { ok: result.status === 0, output, error: result.error ? String(result.error.message || result.error) : '' };",
76
+ "}",
77
+ "",
78
+ "function collectChangedFiles(input, targetRoot) {",
79
+ " const files = [];",
80
+ " addFile(files, input.file_path, targetRoot);",
81
+ " addFromToolPayload(files, input.tool_input, targetRoot);",
82
+ " addFromToolPayload(files, input.tool_response, targetRoot);",
83
+ " const command = input && input.tool_input && typeof input.tool_input.command === 'string' ? input.tool_input.command : '';",
84
+ " for (const file of parsePatchFileNames(command)) addFile(files, file, targetRoot);",
85
+ " return unique(files);",
86
+ "}",
87
+ "",
88
+ "function addFromToolPayload(files, payload, targetRoot) {",
89
+ " if (!payload || typeof payload !== 'object') return;",
90
+ " addFile(files, payload.file_path, targetRoot);",
91
+ " addFile(files, payload.filePath, targetRoot);",
92
+ " addFile(files, payload.path, targetRoot);",
93
+ " if (Array.isArray(payload.file_paths)) for (const file of payload.file_paths) addFile(files, file, targetRoot);",
94
+ " if (Array.isArray(payload.files)) for (const file of payload.files) addFile(files, file, targetRoot);",
95
+ "}",
96
+ "",
97
+ "function parsePatchFileNames(command) {",
98
+ " const files = [];",
99
+ " const pattern = /^\\*\\*\\* (?:Add|Update|Delete) File: (.+)$/gm;",
100
+ " let match;",
101
+ " while ((match = pattern.exec(command)) !== null) files.push(match[1].trim());",
102
+ " return files;",
103
+ "}",
104
+ "",
105
+ "function addFile(files, value, targetRoot) {",
106
+ " if (typeof value !== 'string' || value.trim() === '') return;",
107
+ " const normalized = normalizeToTargetRelative(value.trim(), targetRoot);",
108
+ " if (normalized) files.push(normalized);",
109
+ "}",
110
+ "",
111
+ "function normalizeToTargetRelative(value, targetRoot) {",
112
+ " if (value.startsWith('res://')) return value.slice('res://'.length);",
113
+ " const absolute = path.isAbsolute(value) ? path.resolve(value) : path.resolve(targetRoot, value);",
114
+ " const relative = path.relative(targetRoot, absolute);",
115
+ " if (relative.startsWith('..') || path.isAbsolute(relative)) return null;",
116
+ " return relative.split(path.sep).join('/');",
117
+ "}",
118
+ "",
119
+ "function isAuthoringPath(file) {",
120
+ " if (file === 'project.godot' || file.endsWith('/project.godot')) return true;",
121
+ " return AUTHORING_EXTENSIONS.has(path.extname(file).toLowerCase());",
122
+ "}",
123
+ "",
124
+ "function resolveTargetRoot(input) {",
125
+ " const base = path.resolve(__dirname, '..', '..');",
126
+ " const fromScript = path.resolve(base, TARGET_RELATIVE_PATH || '.');",
127
+ " if (fs.existsSync(fromScript)) return fromScript;",
128
+ " if (input && typeof input.cwd === 'string') return input.cwd;",
129
+ " return process.cwd();",
130
+ "}",
131
+ "",
132
+ "function dirtyStatePath(targetRoot) { return path.join(targetRoot, '.gdh-state', 'agent-hooks', 'authoring-dirty.json'); }",
133
+ "function readDirtyState(targetRoot) { try { return JSON.parse(fs.readFileSync(dirtyStatePath(targetRoot), 'utf8')); } catch { return { dirtyFiles: [], lastBlockedHash: null }; } }",
134
+ "function writeDirtyState(targetRoot, state) { const file = dirtyStatePath(targetRoot); fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, `${JSON.stringify(state, null, 2)}\\n`, 'utf8'); }",
135
+ "function clearDirtyState(targetRoot) { try { fs.rmSync(dirtyStatePath(targetRoot), { force: true }); } catch {} }",
136
+ "function unique(values) { return [...new Set(values.filter(Boolean))].sort(); }",
137
+ "function hash(value) { return crypto.createHash('sha256').update(value).digest('hex'); }",
138
+ "function readHookInput() { try { return JSON.parse(fs.readFileSync(0, 'utf8') || '{}'); } catch { return {}; } }",
139
+ "",
140
+ "function allow() { process.exit(0); }",
141
+ "function block(reason) {",
142
+ " const payload = { decision: 'block', reason };",
143
+ " if (AGENT === 'codex') payload.hookSpecificOutput = { hookEventName: CURRENT_EVENT, additionalContext: reason };",
144
+ " process.stdout.write(`${JSON.stringify(payload)}\\n`);",
145
+ " process.exit(0);",
146
+ "}",
147
+ "",
148
+ ].join("\n");
149
+ }
150
+ //# sourceMappingURL=authoring-hook-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authoring-hook-render.js","sourceRoot":"","sources":["../src/authoring-hook-render.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,7 @@ export declare const CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
12
12
  * command string.
13
13
  */
14
14
  export declare const GDH_SESSION_START_HOOK_COMMAND = "node .claude/hooks/gdh-check-update.js";
15
+ export declare const GDH_AUTHORING_HOOK_COMMAND = "node -e \"const fs=require('fs'),path=require('path');let d=process.cwd();for(;;){const f=path.join(d,'.claude/hooks/gdh-authoring-guard.js');if(fs.existsSync(f)){require(f);break}const p=path.dirname(d);if(p===d)throw new Error('GDH Claude authoring hook not found');d=p}\"";
15
16
  /**
16
17
  * Patch-merge .claude/settings.json so the GDH SessionStart hook is
17
18
  * registered idempotently without clobbering sibling content.
@@ -38,21 +39,22 @@ export declare const GDH_SESSION_START_HOOK_COMMAND = "node .claude/hooks/gdh-ch
38
39
  */
39
40
  export declare function patchClaudeSettingsForGdhSessionStart(existingContent: string): string;
40
41
  /**
41
- * Patch-merge .claude/settings.json so the GDH statusline is registered ONLY
42
- * when no existing `statusLine` entry is configured (write-if-absent).
42
+ * Patch-merge .claude/settings.json so GDH does not own Claude's single
43
+ * statusLine slot automatically.
43
44
  *
44
- * Planner-lock #2 resolution (Plan 03) per D-18:
45
- * - If `settings.statusLine` is present as ANY truthy value, leave it
46
- * untouched. GDH does not clobber a user-configured statusline; other
47
- * tools (e.g. GSD) can own the slot, and UPD-02 silently no-ops for
48
- * that target. The universal cross-adapter detection surface is MCP
49
- * `_meta` (UPD-03), so a no-op here is acceptable degradation.
50
- * - If `settings.statusLine` is `undefined` or `null`, register GDH's
51
- * `{ type: "command", command: "node .claude/hooks/gdh-statusline.js" }`.
52
- * - Preserves every sibling top-level key verbatim (hooks, env,
45
+ * Claude Code exposes one project `statusLine` command. Project settings can
46
+ * shadow user/global statusline configuration, so GDH must not create a
47
+ * project-level statusLine entry just to show update hints. The SessionStart
48
+ * hook, MCP `_meta`, and CLI banner are the non-destructive update surfaces.
49
+ *
50
+ * Migration behavior:
51
+ * - If `settings.statusLine` is the exact old GDH-managed entry, remove it.
52
+ * This lets existing targets fall back to user/global statusline behavior.
53
+ * - If `settings.statusLine` is absent, null, or anything else, leave it
54
+ * untouched. GDH does not compose or guess at other tools' commands.
55
+ * - Preserve every sibling top-level key verbatim (hooks, env,
53
56
  * permissions, etc.). Composes cleanly with
54
- * `patchClaudeSettingsForGdhSessionStart` (idempotent + commutative,
55
- * proven by the Task 1 Test J suite).
57
+ * `patchClaudeSettingsForGdhSessionStart` and authoring hook patches.
56
58
  *
57
59
  * Input handling:
58
60
  * - Empty string / whitespace-only → fresh `{}` base (GDH-only output).
@@ -71,4 +73,5 @@ export declare function patchClaudeSettingsForGdhSessionStart(existingContent: s
71
73
  * that both sides import from.
72
74
  */
73
75
  export declare function patchClaudeSettingsForGdhStatusline(existingContent: string): string;
76
+ export declare function patchClaudeSettingsForGdhAuthoringHooks(existingContent: string): string;
74
77
  //# sourceMappingURL=claude-settings-patch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claude-settings-patch.d.ts","sourceRoot":"","sources":["../src/claude-settings-patch.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,eAAO,MAAM,6BAA6B,0BAA0B,CAAC;AAErE;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,2CACD,CAAC;AA6C3C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,MAAM,GACtB,MAAM,CA4CR;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mCAAmC,CACjD,eAAe,EAAE,MAAM,GACtB,MAAM,CA6BR"}
1
+ {"version":3,"file":"claude-settings-patch.d.ts","sourceRoot":"","sources":["../src/claude-settings-patch.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,eAAO,MAAM,6BAA6B,0BAA0B,CAAC;AAErE;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,2CAA2C,CAAC;AACvF,eAAO,MAAM,0BAA0B,uRAAgC,CAAC;AA8DxE;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,qCAAqC,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAuCrF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,mCAAmC,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAQnF;AAeD,wBAAgB,uCAAuC,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CA2CvF"}