godot-cli 0.17.3 → 0.19.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.
package/README.md CHANGED
@@ -59,6 +59,9 @@ npm install -g godot-cli
59
59
  # Install the godot_mcp addon into a project
60
60
  godot-cli install-plugin ./MyGodotProject
61
61
 
62
+ # Sign in to the ai-game.dev cloud (OAuth 2.1 device login — once per machine)
63
+ godot-cli login
64
+
62
65
  # Open the project (builds C# first, then launches the editor with MCP connection)
63
66
  godot-cli open ./MyGodotProject
64
67
 
@@ -86,7 +89,8 @@ npx godot-cli install-plugin /path/to/godot/project
86
89
  | `run-system-tool <tool> [path]` | POST to `<url>/api/system-tools/<tool>` (tools not exposed to MCP clients). |
87
90
  | `status [path]` | Detect a running Godot editor for the project and probe MCP-server health. |
88
91
  | `wait-for-ready [path]` | Poll the MCP server until it answers `ping`. |
89
- | `setup-mcp <agent> [path]` | Write the agent's MCP-client config pointing at the Godot server's `<host>/mcp` URL. |
92
+ | `login [path]` | Authenticate with the ai-game.dev cloud via the OAuth 2.1 device-authorization flow (RFC 8628) — opens a browser, then saves a cloud credential to the shared machine store (`~/.ai-game-dev/credentials.json`) the editor plugin auto-adopts. See the `login` section below for its `--project` / `--base-url` / `--force` flags. |
93
+ | `setup-mcp <agent> [path]` | Write the agent's MCP-client config pointing at the project-pinned `<host>/mcp/p/<pin>` URL (so the agent routes to *this* project's editor). Add `--no-pin` for the bare `<host>/mcp` URL. |
90
94
  | `setup-skills <agent> [path]` | Generate Godot-MCP skill files (a `SKILL.md`-per-tool-family) under the agent's skills path. `--list` shows each agent's skills support. |
91
95
  | `configure [path]` | List / enable / disable tools, prompts, and resources in the project-local `.godot-mcp/features.json`. |
92
96
  | `close [path]` | Gracefully stop the Godot editor running for a project (`--force` to hard-kill). |
@@ -149,6 +153,28 @@ Pass `--url http://localhost:<port>` to target a local/self-hosted server.
149
153
 
150
154
  ![divider](https://github.com/IvanMurzak/Unity-MCP/blob/main/docs/img/promo/hazzard-divider.svg?raw=true)
151
155
 
156
+ ## `login`
157
+
158
+ `godot-cli login` authenticates the editor plugin's **cloud** connection to
159
+ [ai-game.dev](https://ai-game.dev) using the **OAuth 2.1 device-authorization flow** (RFC 8628) — it prints
160
+ a short user code + verification URL, opens your browser, and polls until you approve:
161
+
162
+ ```bash
163
+ godot-cli login # sign in once per machine (default)
164
+ godot-cli login --project ./MyGame # keep a per-project credential instead
165
+ godot-cli login --base-url <url> # authenticate against a non-default server
166
+ godot-cli login --force # re-authenticate over an existing credential
167
+ ```
168
+
169
+ - By default the credential is saved to the shared **machine store** `~/.ai-game-dev/credentials.json`
170
+ (`0600` on POSIX / DPAPI on Windows) — sign in **once per machine** and the Godot editor plugin
171
+ auto-adopts it, so `godot-cli open --mode Cloud` connects with **no `--token`**.
172
+ - `--project <path>` (or the positional `[path]`) keeps a per-project credential
173
+ (`<path>/.godot-mcp/credentials.json`, gitignored) for per-project accounts.
174
+ - The flow persists the **full** credential set (access token + rotating refresh token + expiry) — **no
175
+ personal access token (PAT) is ever minted**. On any failure nothing is written, so an existing
176
+ credential survives a denied / expired / network error intact.
177
+
152
178
  ## `setup-skills`
153
179
 
154
180
  `godot-cli setup-skills <agent> [path]` generates AI-agent **skill files** for a Godot project under the
@@ -278,9 +304,15 @@ generate its skill files). Use `--list` on either command to see every supported
278
304
 
279
305
  ```bash
280
306
  godot-cli setup-mcp --list # list every supported agent id
281
- godot-cli setup-mcp claude-code ./MyGame # write the agent's MCP client config
307
+ godot-cli setup-mcp claude-code ./MyGame # write the agent's MCP client config (pinned to this project)
308
+ godot-cli setup-mcp claude-code ./MyGame --no-pin # write the bare, unpinned <host>/mcp URL instead
282
309
  ```
283
310
 
311
+ OAuth-capable agents (Claude Code, Cursor, Codex, Copilot, …) authenticate to the cloud with their **own**
312
+ OAuth handshake, so `setup-mcp` writes them a credential-free, URL-only config — no bearer token is stored
313
+ in the agent file. A static `Authorization` header is written only for a client that cannot OAuth, or when
314
+ you pass an explicit `--token` (a deliberate personal-token opt-in for a self-hosted, required-auth server).
315
+
284
316
  > For the full Godot-MCP project documentation, see the
285
317
  > [main README](https://github.com/IvanMurzak/Godot-MCP/blob/main/README.md). Backed by
286
318
  > **[ai-game.dev](https://ai-game.dev)**.
@@ -12,6 +12,7 @@ export const setupMcpCommand = new Command('setup-mcp')
12
12
  .argument('[path]', 'Godot project path (defaults to cwd)')
13
13
  .option('--url <url>', 'MCP server host override (the <host>/mcp client URL is derived from it)')
14
14
  .option('--token <token>', 'Auth token override (defaults to GODOT_MCP_TOKEN)')
15
+ .option('--no-pin', 'Write an unpinned <host>/mcp URL (default pins /p/<pin> to route to this project)')
15
16
  .option('--list', 'List all available agent IDs')
16
17
  .action(async (agentId, positionalPath, options) => {
17
18
  if (options.list) {
@@ -35,6 +36,7 @@ export const setupMcpCommand = new Command('setup-mcp')
35
36
  godotProjectPath: positionalPath,
36
37
  url: options.url,
37
38
  token: options.token,
39
+ noPin: options.pin === false,
38
40
  });
39
41
  if (result.kind === 'failure') {
40
42
  spinner.error('Failed to write config');
@@ -50,6 +52,7 @@ export const setupMcpCommand = new Command('setup-mcp')
50
52
  ui.label('Config file', result.configPath);
51
53
  ui.label('Server URL', result.serverUrl);
52
54
  ui.label('Server name', MCP_SERVER_NAME);
55
+ ui.label('Routing', result.pinned ? 'pinned to this project (/p/<pin>)' : 'unpinned (--no-pin)');
53
56
  for (const warning of result.warnings) {
54
57
  console.log('');
55
58
  ui.warn(warning);
@@ -1 +1 @@
1
- {"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/commands/setup-mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/commands/setup-mcp.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ import * as path from 'path';
3
3
  import { DEFAULT_CLOUD_BASE_URL } from '../utils/connection.js';
4
4
  import { redeemEnrollment } from '../utils/enroll.js';
5
5
  import { writeMachineCredentials, readMachineCredentials, getMachineCredentialsPath, } from '../utils/machine-credentials.js';
6
- import { derivePin, derivePort } from '../utils/project-identity.js';
6
+ import { deriveProjectIdentityV2 } from '../utils/project-identity.js';
7
7
  import { writeProjectMarker, getProjectMarkerPath, isLocalhostUrl, upsertPinIntoAgentConfigs, } from '../utils/project-marker.js';
8
8
  import { emitProgress } from './progress.js';
9
9
  /**
@@ -63,10 +63,14 @@ export async function enrollPlugin(opts) {
63
63
  }, opts.storeBaseDir);
64
64
  const credentialsPath = getMachineCredentialsPath(opts.storeBaseDir);
65
65
  emitProgress(opts.onProgress, { phase: 'enroll-redeemed', message: 'Credential planted', serverTarget });
66
- // 3. Project marker: server target + pin (+ derived port for a localhost target).
67
- const pin = derivePin(projectPath);
66
+ // 3. Project marker: server target + pin (+ derived port for a localhost target). The pin/port
67
+ // are derived with the cli-core **v2** algorithm (`\`→`/` normalization — defect B5): on a
68
+ // Windows `path.resolve` backslash root the pin now matches the forward-slash hash the plugin
69
+ // sends, so routing works. v1 hashed the backslash form to a DIFFERENT pin (the B5 break).
70
+ // Derive pin + port from ONE v2 hash of the project root (deriveProjectIdentityV2 hashes once).
71
+ const { pin, port: derivedPort } = deriveProjectIdentityV2(projectPath);
68
72
  const localhost = isLocalhostUrl(serverTarget);
69
- const port = localhost ? derivePort(projectPath) : undefined;
73
+ const port = localhost ? derivedPort : undefined;
70
74
  writeProjectMarker(projectPath, {
71
75
  serverTarget,
72
76
  pin,
@@ -1 +1 @@
1
- {"version":3,"file":"enroll.js","sourceRoot":"","sources":["../../src/lib/enroll.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"enroll.js","sourceRoot":"","sources":["../../src/lib/enroll.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,8 @@
1
1
  import * as path from 'path';
2
+ import { pinUrl } from '@baizor/gamedev-cli-core';
2
3
  import { CLOUD_MCP_URL, DEFAULT_CUSTOM_HOST, ENV_HOST, ENV_TOKEN, MCP_HUB_PATH, } from '../utils/connection.js';
3
4
  import { getAgentById, getAgentIds, writeJsonAgentConfig, writeTomlAgentConfig, MCP_SERVER_NAME, } from '../utils/agents.js';
5
+ import { derivePinV2 } from '../utils/project-identity.js';
4
6
  import { emitProgress } from './progress.js';
5
7
  import { requireExistingPath } from './validation.js';
6
8
  /**
@@ -114,7 +116,17 @@ export async function setupMcp(opts) {
114
116
  phase: 'start',
115
117
  message: `Configuring ${agent.name} for ${projectPath}`,
116
118
  });
117
- const serverUrl = resolveMcpClientUrl(opts.url);
119
+ // Pin the URL to THIS project's routing segment by DEFAULT (design 02 §T4 / defect B4): the
120
+ // written config points at `<base>/mcp/p/<pin-v2>`, so an agent session launched in this project
121
+ // folder routes strictly to this project's engine instance even when the account has several
122
+ // editors connected. `--no-pin` (opts.noPin) is the escape hatch → the bare `<base>/mcp` URL.
123
+ // The pin is the shared cli-core **v2** pin (`\`→`/` normalization), byte-identical to what the
124
+ // Godot editor's Configure writes — so a CLI-written and an editor-written config route the same
125
+ // (parity with the C# AgentConfigurator; the pin is a ROUTING segment, never the OAuth resource
126
+ // — decision M8).
127
+ const baseClientUrl = resolveMcpClientUrl(opts.url);
128
+ const pinned = opts.noPin !== true;
129
+ const serverUrl = pinned ? pinUrl(baseClientUrl, derivePinV2(projectPath)) : baseClientUrl;
118
130
  // A token supplied EXPLICITLY by the caller (`--token` / the library `token`
119
131
  // arg) is a deliberate Flow C PAT opt-in; a token that is only present in the
120
132
  // ambient `GODOT_MCP_TOKEN` env (e.g. one a prior `login` set) is NOT.
@@ -162,6 +174,7 @@ export async function setupMcp(opts) {
162
174
  agentId: agent.id,
163
175
  configPath,
164
176
  serverUrl,
177
+ pinned,
165
178
  warnings,
166
179
  };
167
180
  }
@@ -1 +1 @@
1
- {"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/lib/setup-mcp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup-mcp.js","sourceRoot":"","sources":["../../src/lib/setup-mcp.ts"],"names":[],"mappings":"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"}
@@ -100,6 +100,12 @@ export interface SetupMcpOptions {
100
100
  url?: string;
101
101
  /** Auth token override. */
102
102
  token?: string;
103
+ /**
104
+ * The `--no-pin` escape hatch (design 02 §T4 / defect B4). By default the written URL is PINNED to
105
+ * this project's routing segment (`<base>/mcp/p/<pin-v2>`) so an agent session routes strictly to
106
+ * this project's engine instance. Set `true` to write the unpinned `<base>/mcp` URL instead.
107
+ */
108
+ noPin?: boolean;
103
109
  onProgress?: ProgressCallback;
104
110
  }
105
111
  export interface SetupMcpSuccess {
@@ -107,7 +113,10 @@ export interface SetupMcpSuccess {
107
113
  success: true;
108
114
  agentId: string;
109
115
  configPath: string;
116
+ /** The MCP-client URL written to the config — pinned (`…/mcp/p/<pin-v2>`) unless `noPin`. */
110
117
  serverUrl: string;
118
+ /** True when the URL carries the `/p/<pin-v2>` routing segment (the default; false with `--no-pin`). */
119
+ pinned: boolean;
111
120
  warnings: string[];
112
121
  }
113
122
  export interface SetupMcpFailure {
@@ -20,7 +20,7 @@
20
20
  */
21
21
  export const ADDON_PACKAGE_REFERENCES = [
22
22
  { id: 'com.IvanMurzak.ReflectorNet', version: '5.3.2' },
23
- { id: 'com.IvanMurzak.McpPlugin', version: '7.1.1' },
23
+ { id: 'com.IvanMurzak.McpPlugin', version: '7.3.0' },
24
24
  ];
25
25
  /**
26
26
  * The exact `<EmbeddedResource>`s the consumer's project `.csproj` needs, single-sourced
@@ -1,4 +1,4 @@
1
- import { type DeviceAuthDeps } from './auth.js';
1
+ import { type DeviceAuthTransport } from '@baizor/gamedev-cli-core';
2
2
  /**
3
3
  * Where a successful `login` persists the credential.
4
4
  *
@@ -18,19 +18,34 @@ export type CredentialSink = {
18
18
  export interface CloudLoginOptions {
19
19
  /** Cloud base URL to authenticate against (default https://ai-game.dev). */
20
20
  baseUrl?: string;
21
- /** Client label sent to the authorize endpoint. */
22
- clientLabel?: string;
23
21
  /** Browser opener (injectable for tests; defaults to the real opener). */
24
22
  openBrowserImpl?: (url: string) => void;
25
- /** Device-flow dependency injection (fetch/sleep/clock) for tests. */
26
- authDeps?: DeviceAuthDeps;
27
23
  /** Where to persist the credential. Defaults to the shared machine store. */
28
24
  sink?: CredentialSink;
25
+ /**
26
+ * Injectable device-authorization transport (tests). Defaults to the real fetch-backed
27
+ * {@link HttpDeviceAuthTransport} which POSTs to `{base}/oauth/device_authorization` +
28
+ * `{base}/oauth/token` (the OAuth 2.1 device grant — NOT the retired legacy JSON device flow).
29
+ */
30
+ transport?: DeviceAuthTransport;
31
+ /** Injectable fetch for the default transport (tests). */
32
+ fetchImpl?: typeof fetch;
33
+ /** Injectable poll delay (tests) — bypass the real RFC 8628 polling wait. */
34
+ delay?: (ms: number, signal?: AbortSignal) => Promise<void>;
35
+ /** Injectable clock in ms (tests) — for deadline control. */
36
+ now?: () => number;
29
37
  }
30
38
  /**
31
- * Run the cloud device-auth flow: initiate, display the user code, open the browser, poll to
32
- * completion, and persist the token to the resolved {@link CredentialSink} (the shared machine store
33
- * by default; the project-local override when `--project` is used).
39
+ * Run the OAuth 2.1 device-authorization login (RFC 8628) via `@baizor/gamedev-cli-core`
40
+ * {@link deviceLogin}: request a device+user code, display the user code + verification URL, open the
41
+ * browser, poll `/oauth/token` to completion, and persist the **full** {@link MachineCredentials}
42
+ * (access + rotating refresh + expiry + subject) to the resolved {@link CredentialSink}.
43
+ *
44
+ * This REPLACES the retired legacy JSON device flow (which minted a non-expiring PAT and
45
+ * dropped the refresh/expiry — defects B2/B3). The client id is the product id `godot-cli`
46
+ * ({@link godotAdapter.clientId}) with scope `mcp:plugin`, and **no PAT is ever minted**. On any
47
+ * failure NOTHING is written (design 03 F4) — the store survives a denied/expired/network error
48
+ * intact.
34
49
  *
35
50
  * Returns the access token on success, or null on failure (errors are printed).
36
51
  */
@@ -2,39 +2,59 @@ import * as ui from './ui.js';
2
2
  import { DEFAULT_CLOUD_BASE_URL } from './connection.js';
3
3
  import { readCredentials, writeCredentials } from './credentials.js';
4
4
  import { readMachineCredentials, writeMachineCredentials } from './machine-credentials.js';
5
- import { deviceAuthFlow } from './auth.js';
6
5
  import { openBrowser } from './browser.js';
6
+ import { deviceLogin, HttpDeviceAuthTransport, godotAdapter, DEFAULT_PLUGIN_SCOPE, } from '@baizor/gamedev-cli-core';
7
7
  /**
8
- * Run the cloud device-auth flow: initiate, display the user code, open the browser, poll to
9
- * completion, and persist the token to the resolved {@link CredentialSink} (the shared machine store
10
- * by default; the project-local override when `--project` is used).
8
+ * Run the OAuth 2.1 device-authorization login (RFC 8628) via `@baizor/gamedev-cli-core`
9
+ * {@link deviceLogin}: request a device+user code, display the user code + verification URL, open the
10
+ * browser, poll `/oauth/token` to completion, and persist the **full** {@link MachineCredentials}
11
+ * (access + rotating refresh + expiry + subject) to the resolved {@link CredentialSink}.
12
+ *
13
+ * This REPLACES the retired legacy JSON device flow (which minted a non-expiring PAT and
14
+ * dropped the refresh/expiry — defects B2/B3). The client id is the product id `godot-cli`
15
+ * ({@link godotAdapter.clientId}) with scope `mcp:plugin`, and **no PAT is ever minted**. On any
16
+ * failure NOTHING is written (design 03 F4) — the store survives a denied/expired/network error
17
+ * intact.
11
18
  *
12
19
  * Returns the access token on success, or null on failure (errors are printed).
13
20
  */
14
21
  export async function runCloudLogin(options = {}) {
15
22
  const baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\/$/, '');
16
- const clientLabel = options.clientLabel ?? 'Godot-MCP CLI';
17
23
  const openBrowserImpl = options.openBrowserImpl ?? openBrowser;
18
24
  const sink = options.sink ?? { kind: 'machine' };
19
25
  let spinner;
26
+ const transport = options.transport ??
27
+ new HttpDeviceAuthTransport({
28
+ serverBaseUrl: baseUrl,
29
+ clientId: godotAdapter.clientId, // 'godot-cli'
30
+ scope: DEFAULT_PLUGIN_SCOPE, // 'mcp:plugin'
31
+ fetchImpl: options.fetchImpl,
32
+ });
20
33
  try {
21
- const result = await deviceAuthFlow(baseUrl, clientLabel, {
22
- onUserCode: (userCode, verificationUrl) => {
34
+ const result = await deviceLogin({
35
+ serverBaseUrl: baseUrl,
36
+ clientId: godotAdapter.clientId,
37
+ scope: DEFAULT_PLUGIN_SCOPE,
38
+ serverTarget: baseUrl,
39
+ transport,
40
+ delay: options.delay,
41
+ now: options.now,
42
+ onUserCode: (userCode, verificationUri) => {
23
43
  ui.info('Open this URL to authorize:');
24
44
  console.log();
25
- console.log(` ${verificationUrl}`);
45
+ console.log(` ${verificationUri}`);
26
46
  console.log();
27
47
  ui.label('Code', userCode);
28
- openBrowserImpl(verificationUrl);
29
48
  },
30
49
  onPolling: () => {
31
50
  spinner = ui.startSpinner('Waiting for authorization...');
32
51
  },
33
- }, options.authDeps);
34
- if (result.success) {
52
+ openBrowser: openBrowserImpl,
53
+ });
54
+ if (result.ok) {
35
55
  spinner?.success('Authorized');
36
- persistCredential(sink, result.accessToken, baseUrl);
37
- return result.accessToken;
56
+ persistCredential(sink, result.credentials, baseUrl);
57
+ return result.credentials.accessToken ?? null;
38
58
  }
39
59
  spinner?.stop();
40
60
  ui.error(result.message);
@@ -52,9 +72,11 @@ export async function runCloudLogin(options = {}) {
52
72
  return null;
53
73
  }
54
74
  }
55
- function persistCredential(sink, accessToken, baseUrl) {
75
+ function persistCredential(sink, credentials, baseUrl) {
56
76
  if (sink.kind === 'project') {
57
- // A corrupt existing credentials file must not block a fresh login.
77
+ // Legacy per-project override: keep the project store's `cloudToken`/`cloudBaseUrl` shape a
78
+ // `--project` login and `open --mode Cloud` read back (credentials.ts). A corrupt existing
79
+ // credentials file must not block a fresh login.
58
80
  let existing = {};
59
81
  try {
60
82
  existing = readCredentials(sink.projectPath) ?? {};
@@ -64,13 +86,14 @@ function persistCredential(sink, accessToken, baseUrl) {
64
86
  }
65
87
  writeCredentials(sink.projectPath, {
66
88
  ...existing,
67
- cloudToken: accessToken,
89
+ cloudToken: credentials.accessToken,
68
90
  cloudBaseUrl: baseUrl,
69
91
  });
70
92
  return;
71
93
  }
72
- // Machine store: preserve any stored identity/refresh fields, replacing the token material and
73
- // recording the server target the credential was issued for.
94
+ // Machine store: persist the FULL credential set (access + refresh + expiry + subject the B3
95
+ // fix), preserving any prior identity / forward-compat fields, and recording the server target
96
+ // the credential was issued for.
74
97
  let existing = {};
75
98
  try {
76
99
  existing = readMachineCredentials(sink.storeBaseDir) ?? {};
@@ -80,8 +103,8 @@ function persistCredential(sink, accessToken, baseUrl) {
80
103
  }
81
104
  writeMachineCredentials({
82
105
  ...existing,
106
+ ...credentials,
83
107
  version: 1,
84
- accessToken,
85
108
  serverTarget: baseUrl,
86
109
  }, sink.storeBaseDir);
87
110
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-login.js","sourceRoot":"","sources":["../../src/utils/cloud-login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-login.js","sourceRoot":"","sources":["../../src/utils/cloud-login.ts"],"names":[],"mappings":"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"}
@@ -1,76 +1,22 @@
1
1
  /**
2
- * The single canonical derivation of a project's **routing pin** and its
3
- * **deterministic local port** from the project root path the TypeScript port of the
4
- * shared 7.0 library `com.IvanMurzak.McpPlugin.AgentConfig.ProjectIdentity`
5
- * (`MCP-Plugin-dotnet/McpPlugin/src/AgentConfig/ProjectIdentity.cs`), which the Godot addon
6
- * consumes via `GodotProjectIdentity`. Every runtime (Unity/Godot/Unreal plugins, the .NET
7
- * sidecar, and the engine CLIs) derives identical values with no shared state and no probing,
8
- * so an agent session launched in a project folder routes strictly to that project's engine
9
- * instance (design `06-engine-plugins.md` § D14/D15).
2
+ * The single canonical derivation of a project's **routing pin** and its **deterministic local
3
+ * port** now a THIN RE-EXPORT of the shared `@baizor/gamedev-cli-core` `project-identity` module
4
+ * (auth-fixes design 02 §T3 / T7, defect B5). cli-core is the ONE TypeScript source of truth, gated
5
+ * byte-for-byte against the same golden vectors as the C# reference
6
+ * `com.IvanMurzak.McpPlugin.AgentConfig.ProjectIdentity` so the Godot CLI, the Godot addon, and the
7
+ * other two engine CLIs all derive identical pins/ports.
10
8
  *
11
- * Algorithm (kept verbatim from the shipped Unity `GeneratePortFromDirectory` / the C# reference):
12
- * 1. Trim trailing directory separators (`/` and `\`) so `/a/b` and `/a/b/` are the same project.
13
- * Separators are NOT converted `C:\a` and `C:/a` hash differently (do NOT `path.normalize`).
14
- * 2. Lowercase with an invariant fold (`ToLowerInvariant`-equivalent see {@link toLowerInvariant}).
15
- * 3. UTF-8 encode, then SHA-256 hash.
16
- * 4. pin = the first 4 bytes of the hash as 8 lowercase hex chars.
17
- * 5. port = 20000 + (littleEndianUInt32(first 4 bytes) % 10000). Range 20000-29999.
9
+ * Two normalizations ship side by side:
10
+ * - **v1** (`derivePin` / `derivePort` / `normalize` / …) the legacy algorithm, kept verbatim so
11
+ * old `.mcp.json` pins keep matching during the dual-hash transition (decision M1). Separators
12
+ * are NOT converted: `C:\a` and `C:/a` hash differently.
13
+ * - **v2** (`derivePinV2` / `derivePortV2` / `normalizeV2` / …) — adds ONE step (convert `\`→`/`)
14
+ * so a Windows root reported with backslashes and the same root with forward slashes hash
15
+ * IDENTICALLY. This is the **B5 fix**: the pin `enroll` / `setup-mcp` write now matches the
16
+ * forward-slash hash the plugin sends, even from a Windows `path.resolve` backslash root.
18
17
  *
19
- * Cross-language parity (C# vs TS) is pinned by the committed golden-vector file
20
- * (`ProjectIdentity.GoldenVectors.json`) and reproduced byte-for-byte by
21
- * `tests/project-identity.test.ts`.
18
+ * The local reimplementation this file used to carry was removed in the cli-core migration (task
19
+ * i1-godot-cli-migration) so the two can never silently diverge.
22
20
  */
23
- /** Inclusive lower bound of the deterministic local-port range. */
24
- export declare const MIN_PORT = 20000;
25
- /** Inclusive upper bound of the deterministic local-port range. */
26
- export declare const MAX_PORT = 29999;
27
- /** Number of ports in the deterministic range (10000). */
28
- export declare const PORT_RANGE: number;
29
- /** Number of hex characters in the routing pin (first 4 bytes of the hash). */
30
- export declare const PIN_LENGTH = 8;
31
- /** The resolved identity for a project root. */
32
- export interface ProjectIdentity {
33
- /** The routing pin: first 8 lowercase hex chars of the SHA-256 of the normalized project root. */
34
- pin: string;
35
- /** The resolved local port — the hash-derived port unless an explicit override was supplied. */
36
- port: number;
37
- /** True when {@link port} came from an explicit user override rather than the hash. */
38
- portIsOverridden: boolean;
39
- }
40
- /**
41
- * Invariant lowercasing that matches C# `string.ToLowerInvariant()`.
42
- *
43
- * JS `String.prototype.toLowerCase()` and C# `ToLowerInvariant()` disagree on some Unicode
44
- * characters. The one that matters for real project paths — and the one the golden-vector file
45
- * explicitly pins (`unicodeDivergence`) — is **U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE**:
46
- * C# `ToLowerInvariant` leaves it unchanged, whereas a naive JS `toLowerCase()` folds it to
47
- * `i` + U+0307 (COMBINING DOT ABOVE), producing a DIFFERENT hash. Preserve U+0130 so the TS
48
- * derivation reproduces the canonical C# value byte-for-byte; every other character lowercases
49
- * identically under both implementations.
50
- */
51
- export declare function toLowerInvariant(value: string): string;
52
- /**
53
- * The exact string that is UTF-8/SHA-256 hashed: the project root with trailing directory
54
- * separators trimmed, then invariant-lowercased. Exposed so callers/tests can reproduce the
55
- * pre-hash string.
56
- */
57
- export declare function normalize(projectRoot: string): string;
58
- /** The routing pin only (first 8 lowercase hex chars of the hash). Never affected by overrides. */
59
- export declare function derivePin(projectRoot: string): string;
60
- /**
61
- * The pure hash-derived port (ignores any override). Byte-for-byte equivalent of the shipped
62
- * Unity `GeneratePortFromDirectory` when given the same directory string.
63
- */
64
- export declare function derivePort(projectRoot: string): number;
65
- /**
66
- * The FULL project-path hash: the complete 64-char lowercase hex SHA-256 of the normalized
67
- * project root — the `projectPathHash` an engine plugin sends in its hub instance-metadata
68
- * handshake. The routing pin is a case-insensitive prefix of this value by construction.
69
- */
70
- export declare function deriveProjectPathHash(projectRoot: string): string;
71
- /**
72
- * Derive the identity for `projectRoot`. When `portOverride` is non-null (the user's explicit
73
- * override from the project marker) it always wins for {@link ProjectIdentity.port}; the
74
- * {@link ProjectIdentity.pin} is always hash-derived.
75
- */
76
- export declare function deriveProjectIdentity(projectRoot: string, portOverride?: number | null): ProjectIdentity;
21
+ export { MIN_PORT, MAX_PORT, PORT_RANGE, PIN_LENGTH, toLowerInvariant, normalize, derivePin, derivePort, deriveProjectPathHash, deriveProjectIdentity, normalizeV2, derivePinV2, derivePortV2, deriveProjectPathHashV2, deriveProjectIdentityV2, } from '@baizor/gamedev-cli-core';
22
+ export type { ProjectIdentity } from '@baizor/gamedev-cli-core';
@@ -1,111 +1,26 @@
1
- import { createHash } from 'crypto';
2
1
  /**
3
- * The single canonical derivation of a project's **routing pin** and its
4
- * **deterministic local port** from the project root path the TypeScript port of the
5
- * shared 7.0 library `com.IvanMurzak.McpPlugin.AgentConfig.ProjectIdentity`
6
- * (`MCP-Plugin-dotnet/McpPlugin/src/AgentConfig/ProjectIdentity.cs`), which the Godot addon
7
- * consumes via `GodotProjectIdentity`. Every runtime (Unity/Godot/Unreal plugins, the .NET
8
- * sidecar, and the engine CLIs) derives identical values with no shared state and no probing,
9
- * so an agent session launched in a project folder routes strictly to that project's engine
10
- * instance (design `06-engine-plugins.md` § D14/D15).
2
+ * The single canonical derivation of a project's **routing pin** and its **deterministic local
3
+ * port** now a THIN RE-EXPORT of the shared `@baizor/gamedev-cli-core` `project-identity` module
4
+ * (auth-fixes design 02 §T3 / T7, defect B5). cli-core is the ONE TypeScript source of truth, gated
5
+ * byte-for-byte against the same golden vectors as the C# reference
6
+ * `com.IvanMurzak.McpPlugin.AgentConfig.ProjectIdentity` so the Godot CLI, the Godot addon, and the
7
+ * other two engine CLIs all derive identical pins/ports.
11
8
  *
12
- * Algorithm (kept verbatim from the shipped Unity `GeneratePortFromDirectory` / the C# reference):
13
- * 1. Trim trailing directory separators (`/` and `\`) so `/a/b` and `/a/b/` are the same project.
14
- * Separators are NOT converted `C:\a` and `C:/a` hash differently (do NOT `path.normalize`).
15
- * 2. Lowercase with an invariant fold (`ToLowerInvariant`-equivalent see {@link toLowerInvariant}).
16
- * 3. UTF-8 encode, then SHA-256 hash.
17
- * 4. pin = the first 4 bytes of the hash as 8 lowercase hex chars.
18
- * 5. port = 20000 + (littleEndianUInt32(first 4 bytes) % 10000). Range 20000-29999.
9
+ * Two normalizations ship side by side:
10
+ * - **v1** (`derivePin` / `derivePort` / `normalize` / …) the legacy algorithm, kept verbatim so
11
+ * old `.mcp.json` pins keep matching during the dual-hash transition (decision M1). Separators
12
+ * are NOT converted: `C:\a` and `C:/a` hash differently.
13
+ * - **v2** (`derivePinV2` / `derivePortV2` / `normalizeV2` / …) — adds ONE step (convert `\`→`/`)
14
+ * so a Windows root reported with backslashes and the same root with forward slashes hash
15
+ * IDENTICALLY. This is the **B5 fix**: the pin `enroll` / `setup-mcp` write now matches the
16
+ * forward-slash hash the plugin sends, even from a Windows `path.resolve` backslash root.
19
17
  *
20
- * Cross-language parity (C# vs TS) is pinned by the committed golden-vector file
21
- * (`ProjectIdentity.GoldenVectors.json`) and reproduced byte-for-byte by
22
- * `tests/project-identity.test.ts`.
18
+ * The local reimplementation this file used to carry was removed in the cli-core migration (task
19
+ * i1-godot-cli-migration) so the two can never silently diverge.
23
20
  */
24
- /** Inclusive lower bound of the deterministic local-port range. */
25
- export const MIN_PORT = 20000;
26
- /** Inclusive upper bound of the deterministic local-port range. */
27
- export const MAX_PORT = 29999;
28
- /** Number of ports in the deterministic range (10000). */
29
- export const PORT_RANGE = MAX_PORT - MIN_PORT + 1;
30
- /** Number of hex characters in the routing pin (first 4 bytes of the hash). */
31
- export const PIN_LENGTH = 8;
32
- const SEPARATOR_FORWARD = '/';
33
- const SEPARATOR_BACK = String.fromCharCode(92); // backslash
34
- /**
35
- * Invariant lowercasing that matches C# `string.ToLowerInvariant()`.
36
- *
37
- * JS `String.prototype.toLowerCase()` and C# `ToLowerInvariant()` disagree on some Unicode
38
- * characters. The one that matters for real project paths — and the one the golden-vector file
39
- * explicitly pins (`unicodeDivergence`) — is **U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE**:
40
- * C# `ToLowerInvariant` leaves it unchanged, whereas a naive JS `toLowerCase()` folds it to
41
- * `i` + U+0307 (COMBINING DOT ABOVE), producing a DIFFERENT hash. Preserve U+0130 so the TS
42
- * derivation reproduces the canonical C# value byte-for-byte; every other character lowercases
43
- * identically under both implementations.
44
- */
45
- export function toLowerInvariant(value) {
46
- let result = '';
47
- for (const ch of value) {
48
- result += ch === 'İ' ? ch : ch.toLowerCase();
49
- }
50
- return result;
51
- }
52
- /**
53
- * The exact string that is UTF-8/SHA-256 hashed: the project root with trailing directory
54
- * separators trimmed, then invariant-lowercased. Exposed so callers/tests can reproduce the
55
- * pre-hash string.
56
- */
57
- export function normalize(projectRoot) {
58
- return toLowerInvariant(trimTrailingSeparators(projectRoot));
59
- }
60
- /** The routing pin only (first 8 lowercase hex chars of the hash). Never affected by overrides. */
61
- export function derivePin(projectRoot) {
62
- return hashOf(projectRoot).subarray(0, PIN_LENGTH / 2).toString('hex');
63
- }
64
- /**
65
- * The pure hash-derived port (ignores any override). Byte-for-byte equivalent of the shipped
66
- * Unity `GeneratePortFromDirectory` when given the same directory string.
67
- */
68
- export function derivePort(projectRoot) {
69
- return portFromHash(hashOf(projectRoot));
70
- }
71
- /**
72
- * The FULL project-path hash: the complete 64-char lowercase hex SHA-256 of the normalized
73
- * project root — the `projectPathHash` an engine plugin sends in its hub instance-metadata
74
- * handshake. The routing pin is a case-insensitive prefix of this value by construction.
75
- */
76
- export function deriveProjectPathHash(projectRoot) {
77
- return hashOf(projectRoot).toString('hex');
78
- }
79
- /**
80
- * Derive the identity for `projectRoot`. When `portOverride` is non-null (the user's explicit
81
- * override from the project marker) it always wins for {@link ProjectIdentity.port}; the
82
- * {@link ProjectIdentity.pin} is always hash-derived.
83
- */
84
- export function deriveProjectIdentity(projectRoot, portOverride) {
85
- const hash = hashOf(projectRoot);
86
- const pin = hash.subarray(0, PIN_LENGTH / 2).toString('hex');
87
- if (portOverride !== undefined && portOverride !== null) {
88
- return { pin, port: portOverride, portIsOverridden: true };
89
- }
90
- return { pin, port: portFromHash(hash), portIsOverridden: false };
91
- }
92
- function hashOf(projectRoot) {
93
- if (projectRoot === null || projectRoot === undefined) {
94
- throw new TypeError('projectRoot must be a string');
95
- }
96
- return createHash('sha256').update(Buffer.from(normalize(projectRoot), 'utf8')).digest();
97
- }
98
- function portFromHash(hash) {
99
- // First 4 bytes as an explicit little-endian uint32 — matches the C# byte-shift
100
- // (`hash[0] | hash[1]<<8 | hash[2]<<16 | hash[3]<<24`) and is CPU-endianness independent.
101
- const value = hash.readUInt32LE(0);
102
- return MIN_PORT + (value % PORT_RANGE);
103
- }
104
- function trimTrailingSeparators(path) {
105
- let end = path.length;
106
- while (end > 1 && (path[end - 1] === SEPARATOR_FORWARD || path[end - 1] === SEPARATOR_BACK)) {
107
- end--;
108
- }
109
- return end === path.length ? path : path.slice(0, end);
110
- }
21
+ export { MIN_PORT, MAX_PORT, PORT_RANGE, PIN_LENGTH, toLowerInvariant,
22
+ // v1 (legacy, separator-sensitive)
23
+ normalize, derivePin, derivePort, deriveProjectPathHash, deriveProjectIdentity,
24
+ // v2 (B5 fix — `\`→`/` normalization; what configurators now emit)
25
+ normalizeV2, derivePinV2, derivePortV2, deriveProjectPathHashV2, deriveProjectIdentityV2, } from '@baizor/gamedev-cli-core';
111
26
  //# sourceMappingURL=project-identity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"project-identity.js","sourceRoot":"","sources":["../../src/utils/project-identity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-identity.js","sourceRoot":"","sources":["../../src/utils/project-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EACL,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,UAAU,EACV,gBAAgB;AAChB,mCAAmC;AACnC,SAAS,EACT,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,qBAAqB;AACrB,mEAAmE;AACnE,WAAW,EACX,WAAW,EACX,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,0BAA0B,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * download entirely (offline / CI). Bumping the addon's server pin requires
6
6
  * bumping this in the same PR or the parity test goes red.
7
7
  */
8
- export declare const DEFAULT_SERVER_VERSION = "9.1.0";
8
+ export declare const DEFAULT_SERVER_VERSION = "9.2.0";
9
9
  /** GitHub-release host the server zip + manifest are downloaded from. NOTHING else is trusted. */
10
10
  export declare const TRUSTED_DOWNLOAD_HOST = "github.com";
11
11
  /** The `owner/repo` the shared server releases live under. */
@@ -18,7 +18,7 @@ import { createHash } from 'crypto';
18
18
  * download entirely (offline / CI). Bumping the addon's server pin requires
19
19
  * bumping this in the same PR or the parity test goes red.
20
20
  */
21
- export const DEFAULT_SERVER_VERSION = '9.1.0';
21
+ export const DEFAULT_SERVER_VERSION = '9.2.0';
22
22
  /** GitHub-release host the server zip + manifest are downloaded from. NOTHING else is trusted. */
23
23
  export const TRUSTED_DOWNLOAD_HOST = 'github.com';
24
24
  /** The `owner/repo` the shared server releases live under. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "godot-cli",
3
- "version": "0.17.3",
3
+ "version": "0.19.0",
4
4
  "description": "Cross-platform CLI tool for Godot-MCP (Skills & MCP). Resolves and launches the Godot editor with MCP connection env vars, runs MCP/system tools over HTTP, probes server health, configures AI agents (Claude Code, Cursor, VS Code, …), and enables/disables the godot_mcp addon. Works with Claude Code, Cursor, Copilot, and any MCP client.",
5
5
  "type": "module",
6
6
  "main": "dist/lib.js",
@@ -62,6 +62,7 @@
62
62
  "node": "^20.19.0 || >=22.12.0"
63
63
  },
64
64
  "dependencies": {
65
+ "@baizor/gamedev-cli-core": "^0.1.0",
65
66
  "chalk": "^5.6.2",
66
67
  "commander": "^13.1.0",
67
68
  "yocto-spinner": "^1.1.0"
@@ -1,42 +0,0 @@
1
- export interface DeviceAuthorizeResponse {
2
- device_code: string;
3
- user_code: string;
4
- verification_uri: string;
5
- verification_uri_complete: string;
6
- expires_in: number;
7
- interval: number;
8
- }
9
- export type DeviceAuthResult = {
10
- success: true;
11
- accessToken: string;
12
- } | {
13
- success: false;
14
- reason: 'expired' | 'denied' | 'error';
15
- message: string;
16
- };
17
- export interface DeviceAuthCallbacks {
18
- /** Invoked once the device+user codes are issued so the caller can display them / open a browser. */
19
- onUserCode: (userCode: string, verificationUrl: string) => void;
20
- /** Invoked once, right before polling begins (e.g. to start a spinner). */
21
- onPolling?: () => void;
22
- }
23
- /** Injectable dependencies — all default to the real implementations. */
24
- export interface DeviceAuthDeps {
25
- /** HTTP client (defaults to global `fetch`). */
26
- fetchImpl?: typeof fetch;
27
- /** Delay primitive (defaults to a real `setTimeout` sleep). */
28
- sleepImpl?: (ms: number) => Promise<void>;
29
- /** Monotonic clock in ms (defaults to `Date.now`). */
30
- nowImpl?: () => number;
31
- /** Floor for the poll interval in ms (defaults to 5000). */
32
- minIntervalMs?: number;
33
- }
34
- /**
35
- * Run the RFC 8628 Device Authorization Grant flow against `baseUrl`.
36
- *
37
- * 1. POST `/api/auth/device/authorize` → device_code + user_code.
38
- * 2. Invoke `onUserCode` so the caller can display instructions / open a browser.
39
- * 3. Poll `/api/auth/device/token` until success, denial, or expiry, honoring
40
- * `authorization_pending` / `slow_down` / `access_denied` / `expired_token`.
41
- */
42
- export declare function deviceAuthFlow(baseUrl: string, clientLabel: string, callbacks: DeviceAuthCallbacks, deps?: DeviceAuthDeps): Promise<DeviceAuthResult>;
@@ -1,113 +0,0 @@
1
- import { verbose } from './ui.js';
2
- // ─── Flow ────────────────────────────────────────────────────────────────────
3
- /**
4
- * Run the RFC 8628 Device Authorization Grant flow against `baseUrl`.
5
- *
6
- * 1. POST `/api/auth/device/authorize` → device_code + user_code.
7
- * 2. Invoke `onUserCode` so the caller can display instructions / open a browser.
8
- * 3. Poll `/api/auth/device/token` until success, denial, or expiry, honoring
9
- * `authorization_pending` / `slow_down` / `access_denied` / `expired_token`.
10
- */
11
- export async function deviceAuthFlow(baseUrl, clientLabel, callbacks, deps = {}) {
12
- const doFetch = deps.fetchImpl ?? fetch;
13
- const sleep = deps.sleepImpl ?? defaultSleep;
14
- const now = deps.nowImpl ?? (() => Date.now());
15
- const minIntervalMs = deps.minIntervalMs ?? 5000;
16
- const authorizeUrl = `${baseUrl}/api/auth/device/authorize`;
17
- verbose(`POST ${authorizeUrl}`);
18
- const initResponse = await fetchWithTimeout(doFetch, authorizeUrl, {
19
- method: 'POST',
20
- headers: { 'Content-Type': 'application/json' },
21
- body: JSON.stringify({ client_label: clientLabel }),
22
- }, 30000);
23
- if (!initResponse.ok) {
24
- const text = await initResponse.text();
25
- return {
26
- success: false,
27
- reason: 'error',
28
- message: `Failed to initiate device auth (HTTP ${initResponse.status}): ${text}`,
29
- };
30
- }
31
- const auth = (await initResponse.json());
32
- verbose(`Device code received, user code: ${auth.user_code}, expires in ${auth.expires_in}s`);
33
- callbacks.onUserCode(auth.user_code, auth.verification_uri_complete);
34
- callbacks.onPolling?.();
35
- const tokenUrl = `${baseUrl}/api/auth/device/token`;
36
- const deadline = now() + auth.expires_in * 1000;
37
- let interval = Math.max(auth.interval * 1000, minIntervalMs);
38
- while (now() < deadline) {
39
- await sleep(interval);
40
- if (now() >= deadline)
41
- break;
42
- verbose(`Polling ${tokenUrl} (interval=${interval / 1000}s)`);
43
- const pollResponse = await fetchWithTimeout(doFetch, tokenUrl, {
44
- method: 'POST',
45
- headers: { 'Content-Type': 'application/json' },
46
- body: JSON.stringify({
47
- device_code: auth.device_code,
48
- grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
49
- }),
50
- }, 15000);
51
- if (pollResponse.ok) {
52
- const data = (await pollResponse.json());
53
- return { success: true, accessToken: data.access_token };
54
- }
55
- let errorData;
56
- try {
57
- errorData = (await pollResponse.json());
58
- }
59
- catch {
60
- return {
61
- success: false,
62
- reason: 'error',
63
- message: `Unexpected response from token endpoint (HTTP ${pollResponse.status})`,
64
- };
65
- }
66
- verbose(`Poll response: ${errorData.error} — ${errorData.error_description ?? ''}`);
67
- switch (errorData.error) {
68
- case 'authorization_pending':
69
- break;
70
- case 'slow_down':
71
- interval = Math.min(interval + 5000, 30000);
72
- verbose(`Slowing down, new interval: ${interval / 1000}s`);
73
- break;
74
- case 'expired_token':
75
- return {
76
- success: false,
77
- reason: 'expired',
78
- message: errorData.error_description ?? 'Device code expired. Please try again.',
79
- };
80
- case 'access_denied':
81
- return {
82
- success: false,
83
- reason: 'denied',
84
- message: errorData.error_description ?? 'Authorization was denied.',
85
- };
86
- default:
87
- return {
88
- success: false,
89
- reason: 'error',
90
- message: errorData.error_description ?? `Unexpected error: ${errorData.error}`,
91
- };
92
- }
93
- }
94
- return {
95
- success: false,
96
- reason: 'expired',
97
- message: 'Device code expired. Please try again.',
98
- };
99
- }
100
- function defaultSleep(ms) {
101
- return new Promise((resolve) => setTimeout(resolve, ms));
102
- }
103
- async function fetchWithTimeout(doFetch, url, options, timeoutMs) {
104
- const controller = new AbortController();
105
- const timer = setTimeout(() => controller.abort(), timeoutMs);
106
- try {
107
- return await doFetch(url, { ...options, signal: controller.signal });
108
- }
109
- finally {
110
- clearTimeout(timer);
111
- }
112
- }
113
- //# sourceMappingURL=auth.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/utils/auth.ts"],"names":[],"mappings":"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"}