unity-open-mcp 0.9.0 → 1.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 (144) hide show
  1. package/dist/asmdef-discovery.d.ts +35 -0
  2. package/dist/asmdef-discovery.js +171 -0
  3. package/dist/asmdef-discovery.js.map +1 -0
  4. package/dist/batch-spawn.d.ts +27 -0
  5. package/dist/batch-spawn.js +218 -24
  6. package/dist/batch-spawn.js.map +1 -1
  7. package/dist/capabilities/build-capabilities.d.ts +10 -0
  8. package/dist/capabilities/build-capabilities.js +4 -0
  9. package/dist/capabilities/build-capabilities.js.map +1 -1
  10. package/dist/capabilities/capabilities-view.d.ts +48 -0
  11. package/dist/capabilities/capabilities-view.js +93 -0
  12. package/dist/capabilities/capabilities-view.js.map +1 -0
  13. package/dist/capabilities/intent-groups.js +42 -0
  14. package/dist/capabilities/intent-groups.js.map +1 -1
  15. package/dist/capabilities/rule-catalog.js +7 -1
  16. package/dist/capabilities/rule-catalog.js.map +1 -1
  17. package/dist/capabilities/tool-groups.js +37 -2
  18. package/dist/capabilities/tool-groups.js.map +1 -1
  19. package/dist/child-supervision.d.ts +34 -0
  20. package/dist/child-supervision.js +110 -0
  21. package/dist/child-supervision.js.map +1 -0
  22. package/dist/cli/cli.js +9 -0
  23. package/dist/cli/cli.js.map +1 -1
  24. package/dist/cli/commands.js +37 -4
  25. package/dist/cli/commands.js.map +1 -1
  26. package/dist/compressible-router.js +12 -1
  27. package/dist/compressible-router.js.map +1 -1
  28. package/dist/constants.d.ts +31 -1
  29. package/dist/constants.js +31 -1
  30. package/dist/constants.js.map +1 -1
  31. package/dist/dialog-dismiss.d.ts +11 -0
  32. package/dist/dialog-dismiss.js +59 -4
  33. package/dist/dialog-dismiss.js.map +1 -1
  34. package/dist/editor-wedge.d.ts +45 -0
  35. package/dist/editor-wedge.js +111 -0
  36. package/dist/editor-wedge.js.map +1 -0
  37. package/dist/event-stream.d.ts +19 -6
  38. package/dist/event-stream.js +139 -17
  39. package/dist/event-stream.js.map +1 -1
  40. package/dist/gate-error.d.ts +2 -0
  41. package/dist/gate-error.js +9 -0
  42. package/dist/gate-error.js.map +1 -1
  43. package/dist/instance-discovery.d.ts +23 -0
  44. package/dist/instance-discovery.js +47 -1
  45. package/dist/instance-discovery.js.map +1 -1
  46. package/dist/live-client.d.ts +40 -5
  47. package/dist/live-client.js +254 -36
  48. package/dist/live-client.js.map +1 -1
  49. package/dist/offline/api.js +82 -30
  50. package/dist/offline/api.js.map +1 -1
  51. package/dist/offline/index-builders.d.ts +9 -0
  52. package/dist/offline/index-builders.js +58 -8
  53. package/dist/offline/index-builders.js.map +1 -1
  54. package/dist/offline/parse.js +5 -1
  55. package/dist/offline/parse.js.map +1 -1
  56. package/dist/process-diagnostics.d.ts +101 -19
  57. package/dist/process-diagnostics.js +197 -59
  58. package/dist/process-diagnostics.js.map +1 -1
  59. package/dist/project-settings.d.ts +36 -0
  60. package/dist/project-settings.js +96 -0
  61. package/dist/project-settings.js.map +1 -0
  62. package/dist/results.d.ts +8 -0
  63. package/dist/results.js +4 -1
  64. package/dist/results.js.map +1 -1
  65. package/dist/routers.js +4 -1
  66. package/dist/routers.js.map +1 -1
  67. package/dist/running-unity.d.ts +23 -0
  68. package/dist/running-unity.js +60 -0
  69. package/dist/running-unity.js.map +1 -1
  70. package/dist/server.js +8 -2
  71. package/dist/server.js.map +1 -1
  72. package/dist/stale-assembly-cache.d.ts +40 -0
  73. package/dist/stale-assembly-cache.js +76 -0
  74. package/dist/stale-assembly-cache.js.map +1 -0
  75. package/dist/tool-hint.d.ts +36 -0
  76. package/dist/tool-hint.js +98 -0
  77. package/dist/tool-hint.js.map +1 -0
  78. package/dist/tool-router.d.ts +47 -2
  79. package/dist/tool-router.js +652 -71
  80. package/dist/tool-router.js.map +1 -1
  81. package/dist/tools/agent-capabilities.js +27 -1
  82. package/dist/tools/agent-capabilities.js.map +1 -1
  83. package/dist/tools/baseline-create.js +1 -1
  84. package/dist/tools/baseline-create.js.map +1 -1
  85. package/dist/tools/batch-execute.js +12 -1
  86. package/dist/tools/batch-execute.js.map +1 -1
  87. package/dist/tools/bridge-status.js +21 -1
  88. package/dist/tools/bridge-status.js.map +1 -1
  89. package/dist/tools/capture-inline.js +4 -3
  90. package/dist/tools/capture-inline.js.map +1 -1
  91. package/dist/tools/editor-status.js +7 -2
  92. package/dist/tools/editor-status.js.map +1 -1
  93. package/dist/tools/execute-csharp.js +36 -3
  94. package/dist/tools/execute-csharp.js.map +1 -1
  95. package/dist/tools/execute-menu.js +33 -2
  96. package/dist/tools/execute-menu.js.map +1 -1
  97. package/dist/tools/index.d.ts +1 -0
  98. package/dist/tools/index.js +44 -0
  99. package/dist/tools/index.js.map +1 -1
  100. package/dist/tools/inputsim-key.d.ts +40 -0
  101. package/dist/tools/inputsim-key.js +72 -0
  102. package/dist/tools/inputsim-key.js.map +1 -0
  103. package/dist/tools/inputsim-pointer.d.ts +40 -0
  104. package/dist/tools/inputsim-pointer.js +121 -0
  105. package/dist/tools/inputsim-pointer.js.map +1 -0
  106. package/dist/tools/inputsim-pointer3d.d.ts +40 -0
  107. package/dist/tools/inputsim-pointer3d.js +55 -0
  108. package/dist/tools/inputsim-pointer3d.js.map +1 -0
  109. package/dist/tools/inputsim-probe.d.ts +40 -0
  110. package/dist/tools/inputsim-probe.js +43 -0
  111. package/dist/tools/inputsim-probe.js.map +1 -0
  112. package/dist/tools/inputsim-step.d.ts +40 -0
  113. package/dist/tools/inputsim-step.js +50 -0
  114. package/dist/tools/inputsim-step.js.map +1 -0
  115. package/dist/tools/inputsim-touch.d.ts +40 -0
  116. package/dist/tools/inputsim-touch.js +83 -0
  117. package/dist/tools/inputsim-touch.js.map +1 -0
  118. package/dist/tools/invoke-method.js +15 -1
  119. package/dist/tools/invoke-method.js.map +1 -1
  120. package/dist/tools/memory-snapshot-capture.js +11 -5
  121. package/dist/tools/memory-snapshot-capture.js.map +1 -1
  122. package/dist/tools/pull-events.js +18 -10
  123. package/dist/tools/pull-events.js.map +1 -1
  124. package/dist/tools/read-compile-errors.js +36 -7
  125. package/dist/tools/read-compile-errors.js.map +1 -1
  126. package/dist/tools/regression-check.js +2 -1
  127. package/dist/tools/regression-check.js.map +1 -1
  128. package/dist/tools/resource-pressure.js +21 -10
  129. package/dist/tools/resource-pressure.js.map +1 -1
  130. package/dist/tools/run-tests.js +11 -2
  131. package/dist/tools/run-tests.js.map +1 -1
  132. package/dist/tools/scan-all.js +2 -2
  133. package/dist/tools/scan-all.js.map +1 -1
  134. package/dist/tools/screenshot-window.js +18 -12
  135. package/dist/tools/screenshot-window.js.map +1 -1
  136. package/dist/tools/screenshot.js +13 -6
  137. package/dist/tools/screenshot.js.map +1 -1
  138. package/dist/tools/visual-compare.d.ts +40 -0
  139. package/dist/tools/visual-compare.js +98 -0
  140. package/dist/tools/visual-compare.js.map +1 -0
  141. package/dist/unity-log.d.ts +67 -2
  142. package/dist/unity-log.js +206 -8
  143. package/dist/unity-log.js.map +1 -1
  144. package/package.json +1 -1
@@ -0,0 +1,98 @@
1
+ // Centralized "how to name a tool inside an agent-facing hint" helper.
2
+ //
3
+ // specs/feedback.md 2026-08-14 (hint regression) — a runtime hint that names a
4
+ // tool the caller cannot see is worse than no hint at all: the agent follows
5
+ // it, the tool is not in its surface (`ToolSearch` answers "no matching
6
+ // deferred tools found"), and it falls back to hand-rolling the behavior the
7
+ // tool exists to replace. This had already been fixed once by appending the
8
+ // `manage_tools` activation call at three hand-maintained call sites; the
9
+ // strings drifted apart again on the next release.
10
+ //
11
+ // The structural fix is this module: ONE helper that looks the tool's group up
12
+ // from the registry (`capabilities/tool-groups.ts`) and appends the activation
13
+ // call automatically when — and only when — that group is not enabled by
14
+ // default. No call site can forget it, and a future group move (or a group
15
+ // flipping to `defaultEnabled`) fixes every hint at once.
16
+ //
17
+ // `tool-hint.test.ts` pins the invariant at the string level: every emitted
18
+ // hint / tool description that names a non-default-group tool must also carry
19
+ // the `manage_tools` activation call.
20
+ import { DEFAULT_ENABLED_GROUPS, groupFor, } from "./capabilities/tool-groups.js";
21
+ // ---------------------------------------------------------------------------
22
+ // feedback 2026-08-17 — a hint must not name a tool that is not registered.
23
+ // The reported case: the remediation hint pointed at
24
+ // unity_open_mcp_recompile_scripts (in the typed-editor group), the agent
25
+ // activated the group, and the tool was still absent from its surface — the
26
+ // hint sent it down a dead end. `tools/index.ts` registers the full
27
+ // ALL_TOOLS name list here once at module init (a push, so this module never
28
+ // imports the tool graph and no import cycle exists). Until that
29
+ // registration has run — i.e. during module-eval-time calls from tool
30
+ // definition files — the registry is empty and the guard is a no-op; the
31
+ // static companion test in tool-hint.test.ts pins the invariant at source
32
+ // level instead.
33
+ // ---------------------------------------------------------------------------
34
+ /** Names of every registered MCP tool. Empty until tools/index.ts registers. */
35
+ const registeredTools = new Set();
36
+ /** Warn-once bookkeeping so an unregistered name logs a single line. */
37
+ const warnedUnregistered = new Set();
38
+ /**
39
+ * Register the reachable tool-name set. Called once from `tools/index.ts`
40
+ * after `ALL_TOOLS` is built. Not part of the public agent surface.
41
+ */
42
+ export function registerHintableToolNames(names) {
43
+ for (const name of names)
44
+ registeredTools.add(name);
45
+ }
46
+ /**
47
+ * Build the `manage_tools` activation call for a group id. Mirrors the exact
48
+ * invocation an agent must issue, so a hint can be followed verbatim.
49
+ */
50
+ export function activateInstruction(groupId) {
51
+ return `activate with manage_tools(action:"activate", group:"${groupId}")`;
52
+ }
53
+ /**
54
+ * True when `toolName` is reachable in a fresh session without a
55
+ * `manage_tools` activation — i.e. it has no group assignment (always-visible
56
+ * meta-tool) or its group is default-enabled.
57
+ */
58
+ export function isDefaultVisible(toolName) {
59
+ const group = groupFor(toolName);
60
+ if (group === null)
61
+ return true;
62
+ return DEFAULT_ENABLED_GROUPS.has(group);
63
+ }
64
+ /**
65
+ * Render a tool reference for use inside an agent-facing hint or tool
66
+ * description.
67
+ *
68
+ * Default-visible tools render as the bare name. A tool in a group that is NOT
69
+ * enabled by default renders as the name plus the group and the concrete
70
+ * activation call, e.g.
71
+ *
72
+ * unity_open_mcp_recompile_scripts (in the typed-editor group, not enabled
73
+ * by default — activate with manage_tools(action:"activate",
74
+ * group:"typed-editor"))
75
+ *
76
+ * Unknown tool names render bare: this helper never invents an activation call
77
+ * for a tool it cannot resolve. A name that is known to the group catalog but
78
+ * NOT registered (verified against the names registered by tools/index.ts,
79
+ * once available) also renders bare — a hint must not prescribe an activation
80
+ * call for a tool the server cannot actually serve — and logs one maintainer
81
+ * warning so the drift is visible.
82
+ */
83
+ export function toolHintReference(toolName) {
84
+ const group = groupFor(toolName);
85
+ const unregistered = registeredTools.size > 0 && !registeredTools.has(toolName);
86
+ if (unregistered && !warnedUnregistered.has(toolName)) {
87
+ warnedUnregistered.add(toolName);
88
+ console.error(`[unity-open-mcp] tool-hint drift: '${toolName}' is assigned to group ` +
89
+ `${group ?? "(none)"} but is not a registered tool — rendering the hint ` +
90
+ `without its activation call. Check tools/index.ts.`);
91
+ }
92
+ if (group === null || DEFAULT_ENABLED_GROUPS.has(group) || unregistered) {
93
+ return toolName;
94
+ }
95
+ return (`${toolName} (in the ${group} group, not enabled by default — ` +
96
+ `${activateInstruction(group)})`);
97
+ }
98
+ //# sourceMappingURL=tool-hint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-hint.js","sourceRoot":"","sources":["../src/tool-hint.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,wEAAwE;AACxE,6EAA6E;AAC7E,4EAA4E;AAC5E,0EAA0E;AAC1E,mDAAmD;AACnD,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,yEAAyE;AACzE,2EAA2E;AAC3E,0DAA0D;AAC1D,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,sCAAsC;AAEtC,OAAO,EACL,sBAAsB,EACtB,QAAQ,GACT,MAAM,+BAA+B,CAAC;AAEvC,8EAA8E;AAC9E,4EAA4E;AAC5E,qDAAqD;AACrD,0EAA0E;AAC1E,4EAA4E;AAC5E,oEAAoE;AACpE,6EAA6E;AAC7E,iEAAiE;AACjE,sEAAsE;AACtE,yEAAyE;AACzE,0EAA0E;AAC1E,iBAAiB;AACjB,8EAA8E;AAE9E,gFAAgF;AAChF,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;AAE1C,wEAAwE;AACxE,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAU,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CAAC,KAAwB;IAChE,KAAK,MAAM,IAAI,IAAI,KAAK;QAAE,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACtD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAe;IACjD,OAAO,wDAAwD,OAAO,IAAI,CAAC;AAC7E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,YAAY,GAChB,eAAe,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7D,IAAI,YAAY,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtD,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,OAAO,CAAC,KAAK,CACX,sCAAsC,QAAQ,yBAAyB;YACrE,GAAG,KAAK,IAAI,QAAQ,qDAAqD;YACzE,oDAAoD,CACvD,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,YAAY,EAAE,CAAC;QACxE,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,CACL,GAAG,QAAQ,YAAY,KAAK,mCAAmC;QAC/D,GAAG,mBAAmB,CAAC,KAAK,CAAC,GAAG,CACjC,CAAC;AACJ,CAAC"}
@@ -26,8 +26,24 @@ export interface HubControlBackend {
26
26
  import type { ToolSessionState } from "./tool-session-state.js";
27
27
  export type SourceTag = "live" | "offline" | "local";
28
28
  export interface RouteMeta {
29
- route: "live" | "batch";
29
+ /**
30
+ * Where the response came from: "live" (bridge), "batch" (headless spawn),
31
+ * "offline" (disk parser / offline-first attempt, no bridge contact), or
32
+ * "local" (caller-side validation / locally-computed result). The
33
+ * compressible branch derives this from the payload's `_source` tag —
34
+ * including error bodies — so the two tags never disagree about the origin.
35
+ */
36
+ route: "live" | "batch" | "offline" | "local";
30
37
  fallbackReason?: string;
38
+ /**
39
+ * feedback-fable-04-08 §7 — present only when a `live_unavailable` batch
40
+ * fallback landed on `editor_instance_locked` AND a live PID holds the
41
+ * project. The actionable truth for the agent is "the editor is busy
42
+ * (TestRunner run / long import); retry later", not a lock conflict, so
43
+ * `fallbackReason` is rewritten to `editor_busy` and the live PID is
44
+ * surfaced here so the agent can correlate.
45
+ */
46
+ editorPid?: number;
31
47
  }
32
48
  export declare class ToolRouter implements Router {
33
49
  private live;
@@ -37,6 +53,7 @@ export declare class ToolRouter implements Router {
37
53
  private sessionState;
38
54
  private onToolListChanged?;
39
55
  private hubBackend;
56
+ private globalLogPathOverride?;
40
57
  private readonly modelCache;
41
58
  /**
42
59
  * M28-refactoring Plan 3 (T3.2) — named-tool dispatch map. Replaces the
@@ -50,7 +67,7 @@ export declare class ToolRouter implements Router {
50
67
  */
51
68
  private routeHandlers?;
52
69
  private getRouteHandlers;
53
- constructor(live: LiveClient, batch: BatchSpawn, projectPath: string, eventStream: BridgeEventStream, sessionState: ToolSessionState, onToolListChanged?: (() => void | Promise<void>) | undefined, hubBackend?: HubControlBackend);
70
+ constructor(live: LiveClient, batch: BatchSpawn, projectPath: string, eventStream: BridgeEventStream, sessionState: ToolSessionState, onToolListChanged?: (() => void | Promise<void>) | undefined, hubBackend?: HubControlBackend, globalLogPathOverride?: string | undefined);
54
71
  route(toolName: string, args: Record<string, unknown>): Promise<CallToolResult>;
55
72
  /**
56
73
  * M23 Plan 3 — route with a per-call live-client override. Used when a
@@ -63,8 +80,26 @@ export declare class ToolRouter implements Router {
63
80
  routeOverride(toolName: string, args: Record<string, unknown>, overrideLive: LiveClient): Promise<CallToolResult>;
64
81
  private routeCore;
65
82
  private batchPingResult;
83
+ /**
84
+ * feedback-fable-04-08 §7 — when a `live_unavailable` batch fallback lands
85
+ * on `editor_instance_locked`, the message describes the BATCH SPAWNER's
86
+ * problem ("a live editor holds the project lock, so no headless spawn"),
87
+ * but the agent's actionable truth is "the editor is busy (TestRunner run /
88
+ * long import); retry later", not a lock conflict. Detect this case by
89
+ * inspecting the batch result for `error.code === "editor_instance_locked"`
90
+ * AND confirming a live PID still holds the project (a stale lock with no
91
+ * live PID is a genuine lock conflict — leave it as `live_unavailable`).
92
+ *
93
+ * Returns the rewritten meta (and the result unchanged — the lock error body
94
+ * is real and must stay intact) so the caller stamps it via injectRouteMeta.
95
+ * The live PID is surfaced as `editorPid` for agent correlation. Falls
96
+ * through unchanged when the code differs, no live PID exists, or the body
97
+ * is unparseable.
98
+ */
99
+ private rewriteEditorBusy;
66
100
  private routeReadCompileErrors;
67
101
  private resolveLiveEditorPid;
102
+ private resolveLiveUnityVersion;
68
103
  private routeListAssets;
69
104
  private routePullEvents;
70
105
  private routeCapabilities;
@@ -119,6 +154,16 @@ export declare class ToolRouter implements Router {
119
154
  private routeRestartEditor;
120
155
  /** Build the confirmed-kill response from a {@link KillResult}. */
121
156
  private restartEditorKillResponse;
157
+ /**
158
+ * Flatten a unity_senses_read_console result body into a single string the
159
+ * health-issue extractor can scan for the fd-exhaustion signature. The
160
+ * console result is a JSON object with an `entries[]` array of
161
+ * `{ message, stack, ... }`; we join message + stack so the Bee driver's
162
+ * `Could not register to wait for file descriptor N` frame (which lives in
163
+ * the stack trace) is reachable by {@link extractProjectHealthIssues}.
164
+ * Returns "" when the body has no entries.
165
+ */
166
+ private serializeConsoleEntries;
122
167
  /**
123
168
  * T31.4 — sample the live Unity process's file-descriptor usage and report
124
169
  * headroom against Mono's ~1024 fd ceiling (the real trip point for the Bee