@skillcap/gdh 3.0.2 → 3.1.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 (46) hide show
  1. package/INSTALL-BUNDLE.json +1 -1
  2. package/README.md +1 -0
  3. package/RELEASE-SPAN-UPDATE-CONTRACTS.json +83 -0
  4. package/node_modules/@gdh/adapters/package.json +8 -8
  5. package/node_modules/@gdh/authoring/package.json +2 -2
  6. package/node_modules/@gdh/cli/dist/index.d.ts.map +1 -1
  7. package/node_modules/@gdh/cli/dist/index.js +195 -4
  8. package/node_modules/@gdh/cli/dist/index.js.map +1 -1
  9. package/node_modules/@gdh/cli/package.json +11 -10
  10. package/node_modules/@gdh/core/dist/bridge-substrate.d.ts +20 -0
  11. package/node_modules/@gdh/core/dist/bridge-substrate.d.ts.map +1 -0
  12. package/node_modules/@gdh/core/dist/bridge-substrate.js +40 -0
  13. package/node_modules/@gdh/core/dist/bridge-substrate.js.map +1 -0
  14. package/node_modules/@gdh/core/dist/index.d.ts +24 -29
  15. package/node_modules/@gdh/core/dist/index.d.ts.map +1 -1
  16. package/node_modules/@gdh/core/dist/index.js +12 -11
  17. package/node_modules/@gdh/core/dist/index.js.map +1 -1
  18. package/node_modules/@gdh/core/package.json +1 -1
  19. package/node_modules/@gdh/docs/package.json +2 -2
  20. package/node_modules/@gdh/editor/dist/index.d.ts +205 -0
  21. package/node_modules/@gdh/editor/dist/index.d.ts.map +1 -0
  22. package/node_modules/@gdh/editor/dist/index.js +1064 -0
  23. package/node_modules/@gdh/editor/dist/index.js.map +1 -0
  24. package/node_modules/@gdh/editor/package.json +17 -0
  25. package/node_modules/@gdh/mcp/dist/index.d.ts +1 -1
  26. package/node_modules/@gdh/mcp/dist/index.d.ts.map +1 -1
  27. package/node_modules/@gdh/mcp/dist/index.js +104 -7
  28. package/node_modules/@gdh/mcp/dist/index.js.map +1 -1
  29. package/node_modules/@gdh/mcp/package.json +10 -8
  30. package/node_modules/@gdh/observability/package.json +2 -2
  31. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.d.ts +2 -2
  32. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.d.ts.map +1 -1
  33. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.js +2 -37
  34. package/node_modules/@gdh/runtime/dist/bridge-broker-contract.js.map +1 -1
  35. package/node_modules/@gdh/runtime/dist/bridge-surface.d.ts +1 -1
  36. package/node_modules/@gdh/runtime/dist/bridge-surface.d.ts.map +1 -1
  37. package/node_modules/@gdh/runtime/dist/bridge-surface.js +396 -73
  38. package/node_modules/@gdh/runtime/dist/bridge-surface.js.map +1 -1
  39. package/node_modules/@gdh/runtime/dist/index.d.ts +2 -3
  40. package/node_modules/@gdh/runtime/dist/index.d.ts.map +1 -1
  41. package/node_modules/@gdh/runtime/dist/index.js +2 -3
  42. package/node_modules/@gdh/runtime/dist/index.js.map +1 -1
  43. package/node_modules/@gdh/runtime/package.json +3 -2
  44. package/node_modules/@gdh/scan/package.json +3 -3
  45. package/node_modules/@gdh/verify/package.json +7 -7
  46. package/package.json +13 -11
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "product": "GDH",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "installMode": "packaged_install"
5
5
  }
package/README.md CHANGED
@@ -51,6 +51,7 @@ gdh self-update --dry-run --target .
51
51
 
52
52
  - [Install and update](./docs/development/install-and-update.md)
53
53
  - [Advanced CLI usage](./docs/development/advanced-cli-usage.md)
54
+ - [Editor Bridge](./docs/development/editor-bridge.md)
54
55
  - [Runtime support matrix](./docs/development/runtime-support-matrix.md)
55
56
  - [Runtime release readiness](./docs/development/runtime-release-readiness.md)
56
57
  - [All docs](./docs/README.md)
@@ -3896,6 +3896,89 @@
3896
3896
  }
3897
3897
  ]
3898
3898
  }
3899
+ },
3900
+ {
3901
+ "version": "3.1.0",
3902
+ "releaseTag": "v3.1.0",
3903
+ "migrationStatus": "required",
3904
+ "summary": "v3.1.0 adds the GDH editor bridge and exact-worktree editor session adoption. The managed Godot addon remains one addon under addons/gdh_bridge/, now with separate runtime and editor components composed by plugin.gd. GDH_RUNTIME_BRIDGE_SURFACE_VERSION moves 12 -> 14 so existing managed bridge targets re-bake or repair the bridge addon, generated bridge manifest, plugin.cfg/plugin.gd, autoload registration, and [editor_plugins] registration before editor operations are treated as healthy.",
3905
+ "releaseHighlights": {
3906
+ "summary": "v3.1.0 adds the editor bridge: a Godot-editor-backed authoring surface that lets agents inspect editor state and perform bounded scene/resource operations through Godot APIs instead of editing `.tscn` and `.tres` text directly. The release ships editor session adoption for already-open Godot editors that belong to the exact target/worktree, plus managed headless editor launch when no compatible editor is open. Editor-specific MCP tools lazily ensure this session; generic status and documentation tools do not launch the editor as a side effect. The managed Godot addon remains one addon under `addons/gdh_bridge/`. Runtime and editor bridge pieces are separated inside that addon, and the Godot-required `plugin.gd` composition root owns both pieces.",
3907
+ "operatorChanges": [
3908
+ "**Editor bridge MCP tools.** Agents can use `editor.session.status` and",
3909
+ "**CLI smoke-test commands.** Maintainers can run `gdh editor session status`",
3910
+ "**Exact-worktree editor adoption.** GDH adopts an already-open editor only",
3911
+ "**Managed headless fallback.** If no compatible editor is registered, GDH can",
3912
+ "**One managed addon.** Editor support ships inside the existing",
3913
+ "**Bounded v1 operation catalog.** The first catalog includes scene creation,"
3914
+ ]
3915
+ },
3916
+ "updateContract": {
3917
+ "summary": "Existing managed targets should self-update to v3.1.0, then let GDH migrate or repair the managed bridge addon when lifecycle or bridge status reports runtime bridge surface drift. Editor operations require the current single GDH addon, autoload registration, [editor_plugins] registration, and an exact-worktree adopted or managed headless editor session.",
3918
+ "steps": [
3919
+ {
3920
+ "id": "install_v3_1_0",
3921
+ "kind": "mechanical",
3922
+ "summary": "Install the v3.1.0 GDH package.",
3923
+ "detail": "Run the normal GDH update flow so the target uses the package that knows the editor bridge operation catalog and runtime bridge surface version 14.",
3924
+ "commands": [
3925
+ "gdh self-update --apply"
3926
+ ],
3927
+ "validationCommands": [
3928
+ "gdh status"
3929
+ ]
3930
+ },
3931
+ {
3932
+ "id": "apply_managed_surface_migration",
3933
+ "kind": "mechanical",
3934
+ "summary": "Apply pending managed-surface migration work.",
3935
+ "detail": "Run migrate when lifecycle status reports pending managed-surface work. This refreshes generated agent surfaces as needed and lets GDH plan or apply current managed bridge output for the configured target.",
3936
+ "commands": [
3937
+ "gdh migrate --apply"
3938
+ ],
3939
+ "validationCommands": [
3940
+ "gdh status",
3941
+ "gdh verify drift <target>"
3942
+ ]
3943
+ },
3944
+ {
3945
+ "id": "repair_bridge_addon_when_drifted",
3946
+ "kind": "mechanical",
3947
+ "summary": "Repair the managed bridge addon when bridge status reports runtime bridge drift.",
3948
+ "detail": "Run bridge repair only when GDH reports project-side runtime bridge surface drift. The repair path rewrites the single addons/gdh_bridge/ addon to the current runtime/editor composition, bridge manifest version 14, plugin.cfg/plugin.gd shape, GDHBridge autoload registration, and [editor_plugins] registration.",
3949
+ "commands": [
3950
+ "gdh bridge repair <target>"
3951
+ ],
3952
+ "validationCommands": [
3953
+ "gdh bridge status <target>",
3954
+ "gdh status"
3955
+ ]
3956
+ },
3957
+ {
3958
+ "id": "verify_editor_session_surface",
3959
+ "kind": "agent_reasoning",
3960
+ "summary": "Verify editor operations use the exact target/worktree editor session.",
3961
+ "detail": "For editor-specific work, inspect editor session status after opening the target in Godot or let the editor operation ensure a managed headless session. Adopted sessions are valid only when metadata points to the exact target/worktree; otherwise GDH should launch or report the managed session path for editor operations.",
3962
+ "commands": [
3963
+ "gdh editor session status [target]"
3964
+ ],
3965
+ "validationCommands": [
3966
+ "gdh editor session status [target]"
3967
+ ]
3968
+ },
3969
+ {
3970
+ "id": "manual_editor_plugin_enable_if_needed",
3971
+ "kind": "manual_review",
3972
+ "summary": "Enable the GDH bridge plugin in Godot if Godot has not loaded it yet.",
3973
+ "detail": "GDH writes the managed plugin registration, but Godot may still require the editor to reload or the operator to enable the GDH bridge plugin before adopted editor metadata and GDHBridge runtime registration are visible. Do this only when GDH status or bridge/editor session status reports the plugin is not active after repair.",
3974
+ "commands": [],
3975
+ "validationCommands": [
3976
+ "gdh bridge status <target>",
3977
+ "gdh editor session status [target]"
3978
+ ]
3979
+ }
3980
+ ]
3981
+ }
3899
3982
  }
3900
3983
  ]
3901
3984
  }
@@ -11,13 +11,13 @@
11
11
  }
12
12
  },
13
13
  "dependencies": {
14
- "@gdh/authoring": "3.0.2",
15
- "@gdh/core": "3.0.2",
16
- "@gdh/docs": "3.0.2",
17
- "@gdh/observability": "3.0.2",
18
- "@gdh/runtime": "3.0.2",
19
- "@gdh/scan": "3.0.2",
20
- "@gdh/verify": "3.0.2"
14
+ "@gdh/authoring": "3.1.0",
15
+ "@gdh/core": "3.1.0",
16
+ "@gdh/docs": "3.1.0",
17
+ "@gdh/observability": "3.1.0",
18
+ "@gdh/runtime": "3.1.0",
19
+ "@gdh/scan": "3.1.0",
20
+ "@gdh/verify": "3.1.0"
21
21
  },
22
- "version": "3.0.2"
22
+ "version": "3.1.0"
23
23
  }
@@ -14,7 +14,7 @@
14
14
  "test": "vitest run"
15
15
  },
16
16
  "dependencies": {
17
- "@gdh/core": "3.0.2"
17
+ "@gdh/core": "3.1.0"
18
18
  },
19
- "version": "3.0.2"
19
+ "version": "3.1.0"
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ import { buildGdhStatusResult, CLAUDE_CHECK_UPDATE_HOOK_RELATIVE_PATH, CLAUDE_MI
8
8
  import { checkManagedLsp, doctorAuthoringDiagnostics, doctorManagedLsp, getAuthoringDiagnosticsStatus, getCurrentAuthoringDiagnostics, getManagedLspStatus, hasCompleteOnboardingSurface, inspectCacheState, pruneAuthoringDiagnostics, pruneCacheState, pruneManagedLsp, readProjectConfig, readWorktreeState, refreshAuthoringDiagnostics, resolveAuthoringStatus, resolveEffectiveTargetPath, resolvePinnedVersion, resolveProjectRoot, resolveTargetGodotDocsVersion, restartManagedLsp, runAuthoringCheck, runImportRefresh, runTargetPrepare, runWarmup, stopManagedLsp, warmupManagedLsp, } from "@gdh/authoring";
9
9
  import { CODEX_RETRUST_REMINDER_TEXT, clearCodexRetrustReminder, definePackageBoundary, GDH_AUTHORING_DOGFOOD_VERSION, GDH_AUTHORING_SLICE_REPORT_VERSION, GDH_PRODUCT_NAME, readCodexRetrustReminder, resolveCurrentGdhInstall, resolveGdhProductMetadata, } from "@gdh/core";
10
10
  import { fetchOfficialGodotDoc, getGuidanceStatus, resolveGuidanceQuery, searchOfficialGodotDocs, } from "@gdh/docs";
11
+ import { inspectEditorBridgeSession, runEditorOperation, } from "@gdh/editor";
11
12
  import { createMcpManifest, invokeMcpTool, serveMcpOverStdio } from "@gdh/mcp";
12
13
  import { inspectAuthoringEffectiveness, inspectAuthoringSessions, inspectGuidanceAudit, recordAuthoringSessionEvent, } from "@gdh/observability";
13
14
  import { checkRuntimeRecipe, createRuntimeBridgeManager, inspectRuntimeBridgeSurface, installRuntimeBridgeSurface, listRuntimeRecipes, removeRuntimeBridgeSurface, repairRuntimeBridgeSurface, runRuntimeRecipe, serveRuntimeBridgeBroker, showRuntimeRecipe, } from "@gdh/runtime";
@@ -39,6 +40,7 @@ export const cliPackage = definePackageBoundary({
39
40
  "@gdh/core",
40
41
  "@gdh/authoring",
41
42
  "@gdh/docs",
43
+ "@gdh/editor",
42
44
  "@gdh/mcp",
43
45
  "@gdh/observability",
44
46
  "@gdh/runtime",
@@ -107,6 +109,9 @@ export async function runCli(args, io = { stdout: process.stdout, stderr: proces
107
109
  if (command === "bridge") {
108
110
  return runBridgeCommand(rest, io);
109
111
  }
112
+ if (command === "editor") {
113
+ return runEditorCommand(rest, io);
114
+ }
110
115
  if (command === "verification-scenario" || command === "scenario") {
111
116
  return runScenarioCommand(rest, io);
112
117
  }
@@ -1765,6 +1770,163 @@ async function runMcpCommand(args, io) {
1765
1770
  ].join("\n") + "\n");
1766
1771
  return 1;
1767
1772
  }
1773
+ async function runEditorCommand(args, io) {
1774
+ const [subcommand, ...rest] = args;
1775
+ if (!subcommand || subcommand === "--help" || subcommand === "help") {
1776
+ io.stdout.write([
1777
+ "Usage: gdh editor <command>",
1778
+ "",
1779
+ "Commands:",
1780
+ " session status [target] [--mode <mode>] [--godot-editor-bin <path>] Inspect Editor Bridge availability.",
1781
+ " operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>] Run one Godot-native editor operation.",
1782
+ ].join("\n") + "\n");
1783
+ return 0;
1784
+ }
1785
+ if (subcommand === "session") {
1786
+ return runEditorSessionCommand(rest, io);
1787
+ }
1788
+ if (subcommand === "operation") {
1789
+ return runEditorOperationCommand(rest, io);
1790
+ }
1791
+ io.stderr.write([
1792
+ `Unknown editor command: ${subcommand}`,
1793
+ "",
1794
+ "Usage: gdh editor session status [target] [--mode <mode>] [--godot-editor-bin <path>]",
1795
+ "Usage: gdh editor operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>]",
1796
+ ].join("\n") + "\n");
1797
+ return 1;
1798
+ }
1799
+ async function runEditorSessionCommand(args, io) {
1800
+ const [subcommand, ...rest] = args;
1801
+ if (!subcommand || subcommand === "--help" || subcommand === "help") {
1802
+ io.stdout.write([
1803
+ "Usage: gdh editor session status [target] [--mode <mode>] [--godot-editor-bin <path>]",
1804
+ "",
1805
+ "Inspect whether GDH can run editor operations for the exact target/worktree.",
1806
+ ].join("\n") + "\n");
1807
+ return 0;
1808
+ }
1809
+ if (subcommand !== "status") {
1810
+ io.stderr.write(`Unknown editor session command: ${subcommand}\nUsage: gdh editor session status [target] [--mode <mode>] [--godot-editor-bin <path>]\n`);
1811
+ return 1;
1812
+ }
1813
+ const unsupportedOptionsError = findUnsupportedOptionsError(rest, {
1814
+ usage: "Usage: gdh editor session status [target] [--mode <mode>] [--godot-editor-bin <path>]\n",
1815
+ optionsWithValues: ["--mode", "--godot-editor-bin"],
1816
+ });
1817
+ if (unsupportedOptionsError !== null) {
1818
+ io.stderr.write(unsupportedOptionsError);
1819
+ return 1;
1820
+ }
1821
+ const { targetPath, error } = parseOptionalPositionalTargetPath(rest, {
1822
+ usage: "Usage: gdh editor session status [target] [--mode <mode>] [--godot-editor-bin <path>]\n",
1823
+ additionalOptionsWithValues: new Set(["--mode", "--godot-editor-bin"]),
1824
+ });
1825
+ if (error !== null) {
1826
+ io.stderr.write(error);
1827
+ return 1;
1828
+ }
1829
+ const mode = parseEditorSessionMode(readSingleOptionValue(rest, "--mode"));
1830
+ if (mode === null) {
1831
+ io.stderr.write("Usage error: --mode must be one of auto, headless_only, headless-only, adopt_only, adopt-only, or disabled.\n");
1832
+ return 1;
1833
+ }
1834
+ try {
1835
+ const projectConfig = await readProjectConfig(targetPath);
1836
+ const result = await inspectEditorBridgeSession({
1837
+ targetPath,
1838
+ projectConfig,
1839
+ mode,
1840
+ godotEditorBin: readSingleOptionValue(rest, "--godot-editor-bin"),
1841
+ });
1842
+ writeJsonResult(io, result);
1843
+ return result.state === "blocked" ? 1 : 0;
1844
+ }
1845
+ catch (error) {
1846
+ io.stderr.write(`Failed to inspect Editor Bridge session: ${formatCliError(error)}\n`);
1847
+ return 1;
1848
+ }
1849
+ }
1850
+ async function runEditorOperationCommand(args, io) {
1851
+ const [subcommand, ...rest] = args;
1852
+ if (!subcommand || subcommand === "--help" || subcommand === "help") {
1853
+ io.stdout.write([
1854
+ "Usage: gdh editor operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>] [--timeout-ms <ms>] [--retain-artifacts <count>]",
1855
+ "",
1856
+ "Run one targeted Editor Bridge operation and print the action-oriented result as JSON.",
1857
+ ].join("\n") + "\n");
1858
+ return 0;
1859
+ }
1860
+ if (subcommand !== "run") {
1861
+ io.stderr.write(`Unknown editor operation command: ${subcommand}\nUsage: gdh editor operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>] [--timeout-ms <ms>] [--retain-artifacts <count>]\n`);
1862
+ return 1;
1863
+ }
1864
+ const unsupportedOptionsError = findUnsupportedOptionsError(rest, {
1865
+ usage: "Usage: gdh editor operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>] [--timeout-ms <ms>] [--retain-artifacts <count>]\n",
1866
+ optionsWithValues: [
1867
+ "--input-json",
1868
+ "--mode",
1869
+ "--godot-editor-bin",
1870
+ "--timeout-ms",
1871
+ "--retain-artifacts",
1872
+ ],
1873
+ });
1874
+ if (unsupportedOptionsError !== null) {
1875
+ io.stderr.write(unsupportedOptionsError);
1876
+ return 1;
1877
+ }
1878
+ if (readSingleOptionValue(rest, "--input-json") === null) {
1879
+ io.stderr.write("Usage error: gdh editor operation run requires --input-json <json>.\n");
1880
+ return 1;
1881
+ }
1882
+ const { targetPath, error } = parseOptionalPositionalTargetPath(rest, {
1883
+ usage: "Usage: gdh editor operation run [target] --input-json <json> [--mode <mode>] [--godot-editor-bin <path>] [--timeout-ms <ms>] [--retain-artifacts <count>]\n",
1884
+ additionalOptionsWithValues: new Set([
1885
+ "--input-json",
1886
+ "--mode",
1887
+ "--godot-editor-bin",
1888
+ "--timeout-ms",
1889
+ "--retain-artifacts",
1890
+ ]),
1891
+ });
1892
+ if (error !== null) {
1893
+ io.stderr.write(error);
1894
+ return 1;
1895
+ }
1896
+ const mode = parseEditorSessionMode(readSingleOptionValue(rest, "--mode"));
1897
+ if (mode === null) {
1898
+ io.stderr.write("Usage error: --mode must be one of auto, headless_only, headless-only, adopt_only, adopt-only, or disabled.\n");
1899
+ return 1;
1900
+ }
1901
+ const timeoutMs = parseOptionalPositiveIntegerOption(rest, "--timeout-ms");
1902
+ if (timeoutMs === null && rest.includes("--timeout-ms")) {
1903
+ io.stderr.write("Usage error: --timeout-ms must be a positive integer.\n");
1904
+ return 1;
1905
+ }
1906
+ const retainOperationArtifacts = parseOptionalPositiveIntegerOption(rest, "--retain-artifacts");
1907
+ if (retainOperationArtifacts === null && rest.includes("--retain-artifacts")) {
1908
+ io.stderr.write("Usage error: --retain-artifacts must be a positive integer.\n");
1909
+ return 1;
1910
+ }
1911
+ try {
1912
+ const projectConfig = await readProjectConfig(targetPath);
1913
+ const result = await runEditorOperation({
1914
+ targetPath,
1915
+ projectConfig,
1916
+ operation: parseEditorOperationJson(rest),
1917
+ mode,
1918
+ ...(typeof timeoutMs === "number" && { timeoutMs }),
1919
+ ...(typeof retainOperationArtifacts === "number" && { retainOperationArtifacts }),
1920
+ godotEditorBin: readSingleOptionValue(rest, "--godot-editor-bin"),
1921
+ });
1922
+ writeJsonResult(io, result);
1923
+ return result.state === "ok" ? 0 : 1;
1924
+ }
1925
+ catch (error) {
1926
+ io.stderr.write(`Failed to run Editor Bridge operation: ${formatCliError(error)}\n`);
1927
+ return 1;
1928
+ }
1929
+ }
1768
1930
  async function runAuthoringDogfoodCommand(args, io) {
1769
1931
  if (args.includes("--help")) {
1770
1932
  io.stdout.write([
@@ -3407,8 +3569,8 @@ async function runVerifyDriftCommand(args, io) {
3407
3569
  "the pinned value. Covers ROADMAP Success Criterion #3 (one source of truth).",
3408
3570
  "Also recognises the pre-v3.0.0 hook layout (RFC 0010 / CPATH-10): when",
3409
3571
  "`.claude/hooks/gdh-*.js` or `.codex/hooks/gdh-authoring-guard.js` is still on",
3410
- "disk, the result emits `legacyLayout.state: \"migration_pending\"` (legacy only)",
3411
- "or `\"partially_migrated\"` (legacy + canonical present) and points the",
3572
+ 'disk, the result emits `legacyLayout.state: "migration_pending"` (legacy only)',
3573
+ 'or `"partially_migrated"` (legacy + canonical present) and points the',
3412
3574
  "remediation action at `gdh self-update` rather than `gdh adapters install`.",
3413
3575
  "This command does NOT validate runtime bridge, project lifecycle, or authoring health.",
3414
3576
  "",
@@ -3484,8 +3646,7 @@ async function runVerifyDriftCommand(args, io) {
3484
3646
  // `gdh self-update` instead of `gdh adapters install`; the migration entry
3485
3647
  // owns the legacy-file cleanup that re-bake cannot perform.
3486
3648
  const legacyLayout = await inspectVerifyDriftLegacyLayout(targetPath);
3487
- const action = legacyLayout.state === "migration_pending" ||
3488
- legacyLayout.state === "partially_migrated"
3649
+ const action = legacyLayout.state === "migration_pending" || legacyLayout.state === "partially_migrated"
3489
3650
  ? {
3490
3651
  kind: "run_migration",
3491
3652
  summary: legacyLayout.state === "migration_pending"
@@ -4547,6 +4708,8 @@ function renderHelp() {
4547
4708
  " bridge install [target] [--dry-run] Install the GDH-managed runtime bridge surface.",
4548
4709
  " bridge repair [target] [--dry-run] Repair drifted GDH-managed bridge files and autoload state.",
4549
4710
  " bridge remove [target] [--dry-run] Remove the GDH-managed runtime bridge surface.",
4711
+ " editor session status [target] Inspect Editor Bridge availability for the exact target/worktree.",
4712
+ " editor operation run [target] --input-json <json> Run one Godot-native editor operation.",
4550
4713
  " verification-scenario list [target] List verification scenarios.",
4551
4714
  " verification-scenario show [target] <verification-scenario-id> Show one verification scenario.",
4552
4715
  " guidance status [target] Inspect durable guidance and audit availability.",
@@ -4796,6 +4959,34 @@ function parseMcpInputJson(args) {
4796
4959
  }
4797
4960
  return parsed;
4798
4961
  }
4962
+ function parseEditorOperationJson(args) {
4963
+ const parsed = parseMcpInputJson(args);
4964
+ const operation = parsed["operation"];
4965
+ if (operation !== null &&
4966
+ operation !== undefined &&
4967
+ !Array.isArray(operation) &&
4968
+ typeof operation === "object") {
4969
+ return operation;
4970
+ }
4971
+ return parsed;
4972
+ }
4973
+ function parseEditorSessionMode(value) {
4974
+ if (value === null || value === "auto")
4975
+ return "auto";
4976
+ if (value === "headless_only" || value === "headless-only")
4977
+ return "headless_only";
4978
+ if (value === "adopt_only" || value === "adopt-only")
4979
+ return "adopt_only";
4980
+ if (value === "disabled")
4981
+ return "disabled";
4982
+ return null;
4983
+ }
4984
+ function parseOptionalPositiveIntegerOption(args, optionName) {
4985
+ const value = readSingleOptionValue(args, optionName);
4986
+ if (value === null)
4987
+ return undefined;
4988
+ return parsePositiveIntegerOptionValue(value);
4989
+ }
4799
4990
  function collectAdapterNames(args) {
4800
4991
  const values = collectOptionValues(args, "--agent");
4801
4992
  if (values.length === 0) {