godot-cli 0.20.1 → 0.21.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/CHANGELOG.md +34 -0
- package/README.md +20 -4
- package/dist/commands/login.js +54 -24
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/open.js +2 -2
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/run-tool-builder.js +1 -1
- package/dist/commands/run-tool-builder.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/wait-for-ready.js +1 -1
- package/dist/commands/wait-for-ready.js.map +1 -1
- package/dist/lib/enroll.js +29 -19
- package/dist/lib/enroll.js.map +1 -1
- package/dist/utils/addon-deps.js +1 -1
- package/dist/utils/cloud-login.d.ts +80 -14
- package/dist/utils/cloud-login.js +204 -51
- package/dist/utils/cloud-login.js.map +1 -1
- package/dist/utils/connection.d.ts +13 -8
- package/dist/utils/connection.js +116 -15
- package/dist/utils/connection.js.map +1 -1
- package/dist/utils/credentials.d.ts +13 -19
- package/dist/utils/credentials.js +13 -59
- package/dist/utils/credentials.js.map +1 -1
- package/dist/utils/machine-store.d.ts +76 -0
- package/dist/utils/machine-store.js +129 -0
- package/dist/utils/machine-store.js.map +1 -0
- package/dist/utils/server-source.d.ts +1 -1
- package/dist/utils/server-source.js +1 -1
- package/dist/utils/ui.d.ts +5 -0
- package/dist/utils/ui.js +15 -0
- package/dist/utils/ui.js.map +1 -1
- package/package.json +2 -2
- package/dist/utils/machine-credentials.d.ts +0 -74
- package/dist/utils/machine-credentials.js +0 -182
- package/dist/utils/machine-credentials.js.map +0 -1
|
@@ -1,40 +1,48 @@
|
|
|
1
1
|
import * as ui from './ui.js';
|
|
2
2
|
import { DEFAULT_CLOUD_BASE_URL } from './connection.js';
|
|
3
|
-
import {
|
|
4
|
-
import { readMachineCredentials, writeMachineCredentials } from './machine-credentials.js';
|
|
3
|
+
import { openMachineStore, openProjectStore, ensureProjectStoreGitignored, createMachineCredentialProvider, hasPluginPlaneCredential, } from './machine-store.js';
|
|
5
4
|
import { openBrowser } from './browser.js';
|
|
6
|
-
import { deviceLogin, HttpDeviceAuthTransport, godotAdapter, DEFAULT_PLUGIN_SCOPE, } from '@baizor/gamedev-cli-core';
|
|
5
|
+
import { deviceLogin, HttpDeviceAuthTransport, HttpTokenExchangeClient, commitAgentLogin, commitToolsOnlyLogin, derivePluginFamily, effectiveFamilies, godotAdapter, DEFAULT_PLUGIN_SCOPE, MCP_AGENT_SCOPE, } from '@baizor/gamedev-cli-core';
|
|
7
6
|
/**
|
|
8
|
-
* Run the OAuth 2.1 device-authorization login (RFC 8628)
|
|
9
|
-
*
|
|
10
|
-
* browser, poll `/oauth/token` to completion, and persist the **full** {@link MachineCredentials}
|
|
11
|
-
* (access + rotating refresh + expiry + subject) to the resolved {@link CredentialSink}.
|
|
7
|
+
* Run the OAuth 2.1 device-authorization login (RFC 8628) and commit the mint through the shared
|
|
8
|
+
* cli-core login-commit machinery (unified-machine-auth 03 F1 / F10):
|
|
12
9
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
10
|
+
* - **Default (agent login, F1):** the device flow requests **`scope=mcp:agent`** with the
|
|
11
|
+
* product client id `godot-cli`; {@link commitAgentLogin} then writes the agent family under a
|
|
12
|
+
* FIRST lock hold, derives the plugin family via RFC 8693 token exchange with the lock
|
|
13
|
+
* released, and writes it (+ the v1 compat mirror) under a SECOND hold. A failed exchange
|
|
14
|
+
* leaves the agent family committed ("partially authorized") and the derivation is retried
|
|
15
|
+
* once here with backoff.
|
|
16
|
+
* - **`--tools-only` (O10/F10):** the device flow requests `scope=mcp:plugin` and
|
|
17
|
+
* {@link commitToolsOnlyLogin} writes a plugin family ONLY.
|
|
18
|
+
* - **Account-switch guard (D6/F7):** a subject mismatch against the stored credential requires
|
|
19
|
+
* confirmation (`--yes` / TTY prompt); a decline revokes the just-minted family (best effort,
|
|
20
|
+
* RFC 7009) and aborts with the store untouched.
|
|
18
21
|
*
|
|
19
|
-
*
|
|
22
|
+
* On any failure before the commit NOTHING is written (design 03 F4) — the store survives a
|
|
23
|
+
* denied/expired/network error intact. Nothing here logs token material.
|
|
24
|
+
*
|
|
25
|
+
* Returns the plugin-plane access token on success, or null on failure (errors are printed).
|
|
20
26
|
*/
|
|
21
27
|
export async function runCloudLogin(options = {}) {
|
|
22
28
|
const baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\/$/, '');
|
|
23
29
|
const openBrowserImpl = options.openBrowserImpl ?? openBrowser;
|
|
24
30
|
const sink = options.sink ?? { kind: 'machine' };
|
|
31
|
+
const clientId = godotAdapter.clientId; // 'godot-cli' (cli-core engine-adapter)
|
|
32
|
+
const scope = options.toolsOnly ? DEFAULT_PLUGIN_SCOPE : MCP_AGENT_SCOPE;
|
|
25
33
|
let spinner;
|
|
26
34
|
const transport = options.transport ??
|
|
27
35
|
new HttpDeviceAuthTransport({
|
|
28
36
|
serverBaseUrl: baseUrl,
|
|
29
|
-
clientId
|
|
30
|
-
scope
|
|
37
|
+
clientId,
|
|
38
|
+
scope,
|
|
31
39
|
fetchImpl: options.fetchImpl,
|
|
32
40
|
});
|
|
33
41
|
try {
|
|
34
42
|
const result = await deviceLogin({
|
|
35
43
|
serverBaseUrl: baseUrl,
|
|
36
|
-
clientId
|
|
37
|
-
scope
|
|
44
|
+
clientId,
|
|
45
|
+
scope,
|
|
38
46
|
serverTarget: baseUrl,
|
|
39
47
|
transport,
|
|
40
48
|
delay: options.delay,
|
|
@@ -51,14 +59,13 @@ export async function runCloudLogin(options = {}) {
|
|
|
51
59
|
},
|
|
52
60
|
openBrowser: openBrowserImpl,
|
|
53
61
|
});
|
|
54
|
-
if (result.ok) {
|
|
55
|
-
spinner?.
|
|
56
|
-
|
|
57
|
-
return
|
|
62
|
+
if (!result.ok) {
|
|
63
|
+
spinner?.stop();
|
|
64
|
+
ui.error(result.message);
|
|
65
|
+
return null;
|
|
58
66
|
}
|
|
59
|
-
spinner?.
|
|
60
|
-
|
|
61
|
-
return null;
|
|
67
|
+
spinner?.success('Authorized');
|
|
68
|
+
return await commitCredential(sink, result.credentials, baseUrl, options);
|
|
62
69
|
}
|
|
63
70
|
catch (err) {
|
|
64
71
|
spinner?.stop();
|
|
@@ -72,40 +79,186 @@ export async function runCloudLogin(options = {}) {
|
|
|
72
79
|
return null;
|
|
73
80
|
}
|
|
74
81
|
}
|
|
75
|
-
|
|
82
|
+
/** Resolve the credential store a sink addresses (and gitignore a per-project store). */
|
|
83
|
+
function resolveSinkStore(sink) {
|
|
76
84
|
if (sink.kind === 'project') {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
ensureProjectStoreGitignored(sink.projectPath);
|
|
86
|
+
return openProjectStore(sink.projectPath);
|
|
87
|
+
}
|
|
88
|
+
return openMachineStore(sink.storeBaseDir);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The D6/F7 confirmation used when the caller supplies none: `--yes` auto-confirms; a TTY
|
|
92
|
+
* prompts; a non-interactive session DECLINES (fail closed — cli-core then revokes the
|
|
93
|
+
* just-minted family and leaves the store untouched).
|
|
94
|
+
*/
|
|
95
|
+
function buildConfirmAccountSwitch(options) {
|
|
96
|
+
if (options.confirmAccountSwitch)
|
|
97
|
+
return options.confirmAccountSwitch;
|
|
98
|
+
return async ({ storedSubject, newSubject }) => {
|
|
99
|
+
if (options.assumeYes)
|
|
100
|
+
return true;
|
|
101
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
102
|
+
ui.error(`This machine is signed in as a different account (${storedSubject}). ` +
|
|
103
|
+
'Re-run with --yes to replace it with the new account.');
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
return ui.confirm(`This machine is signed in as account ${storedSubject}; you are signing in as ${newSubject}. ` +
|
|
107
|
+
'Replace the machine credential (signs the old account out of all tools on this machine)?');
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Commit the mint via the shared cli-core helpers and report the outcome. */
|
|
111
|
+
async function commitCredential(sink, credentials, baseUrl, options) {
|
|
112
|
+
const store = resolveSinkStore(sink);
|
|
113
|
+
const confirmAccountSwitch = buildConfirmAccountSwitch(options);
|
|
114
|
+
const clientId = godotAdapter.clientId;
|
|
115
|
+
if (options.toolsOnly) {
|
|
116
|
+
const commit = await commitToolsOnlyLogin({
|
|
117
|
+
store,
|
|
118
|
+
clientId,
|
|
119
|
+
credentials,
|
|
120
|
+
confirmAccountSwitch,
|
|
121
|
+
fetchImpl: options.fetchImpl,
|
|
122
|
+
onWarning: ui.warn,
|
|
123
|
+
});
|
|
124
|
+
if (commit.status === 'committed') {
|
|
125
|
+
return pluginAccessToken(commit.document);
|
|
83
126
|
}
|
|
84
|
-
|
|
85
|
-
|
|
127
|
+
if (commit.status === 'switch-declined') {
|
|
128
|
+
ui.error('Login aborted: the stored account was kept and the new credential was revoked.');
|
|
129
|
+
return null;
|
|
86
130
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
131
|
+
ui.error('Login aborted: the credential store changed concurrently. Re-run `godot-cli login`.');
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const exchangeClient = options.exchangeClient ??
|
|
135
|
+
new HttpTokenExchangeClient({
|
|
136
|
+
defaultServerBaseUrl: baseUrl,
|
|
137
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
91
138
|
});
|
|
92
|
-
|
|
139
|
+
const commit = await commitAgentLogin({
|
|
140
|
+
store,
|
|
141
|
+
exchangeClient,
|
|
142
|
+
clientId,
|
|
143
|
+
credentials,
|
|
144
|
+
confirmAccountSwitch,
|
|
145
|
+
fetchImpl: options.fetchImpl,
|
|
146
|
+
onWarning: ui.warn,
|
|
147
|
+
});
|
|
148
|
+
if (commit.status === 'committed') {
|
|
149
|
+
return pluginAccessToken(commit.document);
|
|
93
150
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
let existing = {};
|
|
98
|
-
try {
|
|
99
|
-
existing = readMachineCredentials(sink.storeBaseDir) ?? {};
|
|
151
|
+
if (commit.status === 'switch-declined') {
|
|
152
|
+
ui.error('Login aborted: the stored account was kept and the new credential was revoked.');
|
|
153
|
+
return null;
|
|
100
154
|
}
|
|
101
|
-
|
|
102
|
-
|
|
155
|
+
if (commit.status === 'aborted') {
|
|
156
|
+
ui.error('Login aborted: the credential store changed concurrently ' +
|
|
157
|
+
`(${commit.reason}). Re-run \`godot-cli login\`.`);
|
|
158
|
+
return null;
|
|
103
159
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
160
|
+
// `partial` (F1 failure path): the agent family IS committed; retry the derivation leg once
|
|
161
|
+
// with backoff before surfacing the partial state.
|
|
162
|
+
ui.warn('Partially authorized: the plugin credential could not be derived yet. Retrying...');
|
|
163
|
+
const delay = options.delay ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
|
|
164
|
+
await delay(2000);
|
|
165
|
+
const derived = await derivePluginFamily({
|
|
166
|
+
store,
|
|
167
|
+
exchangeClient,
|
|
168
|
+
clientId,
|
|
169
|
+
agentAccessToken: credentials.accessToken ?? '',
|
|
170
|
+
...(credentials.subject !== undefined ? { expectedSubject: credentials.subject } : {}),
|
|
108
171
|
serverTarget: baseUrl,
|
|
109
|
-
|
|
172
|
+
fetchImpl: options.fetchImpl,
|
|
173
|
+
onWarning: ui.warn,
|
|
174
|
+
});
|
|
175
|
+
if (derived.status === 'derived') {
|
|
176
|
+
return pluginAccessToken(derived.document);
|
|
177
|
+
}
|
|
178
|
+
ui.error('Partially authorized: your account is signed in, but the tools credential could not be ' +
|
|
179
|
+
'derived. Re-run `godot-cli login` to finish signing in.');
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
/** The plugin-plane access token of a committed document (falls back to the v1 mirror). */
|
|
183
|
+
function pluginAccessToken(document) {
|
|
184
|
+
const families = effectiveFamilies(document);
|
|
185
|
+
return families.plugin?.accessToken ?? families.legacy?.accessToken ?? document.accessToken ?? null;
|
|
186
|
+
}
|
|
187
|
+
/** Classify a stored document for the `login` gate (see {@link LoginState}). */
|
|
188
|
+
export function classifyLoginState(document, baseUrl) {
|
|
189
|
+
if (!document || document.serverTarget !== baseUrl)
|
|
190
|
+
return 'signed-out';
|
|
191
|
+
if (hasPluginPlaneCredential(document))
|
|
192
|
+
return 'signed-in';
|
|
193
|
+
const agent = effectiveFamilies(document).agent;
|
|
194
|
+
if (typeof agent?.accessToken === 'string' && agent.accessToken.trim().length > 0)
|
|
195
|
+
return 'partial';
|
|
196
|
+
return 'signed-out';
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Finish a partially-authorized login (03 F1 failure path): the agent family is already
|
|
200
|
+
* committed, so re-run ONLY the derivation leg — obtain a fresh agent access token through the
|
|
201
|
+
* provider (refreshing under the lock if it expired) and {@link derivePluginFamily} from it.
|
|
202
|
+
* **No second device flow, no browser.** On failure nothing is written and the agent family
|
|
203
|
+
* survives for the next attempt.
|
|
204
|
+
*
|
|
205
|
+
* Returns the derived plugin-plane access token, or null (errors printed, store untouched).
|
|
206
|
+
*/
|
|
207
|
+
export async function completePartialLogin(options = {}) {
|
|
208
|
+
const baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\/$/, '');
|
|
209
|
+
const sink = options.sink ?? { kind: 'machine' };
|
|
210
|
+
const store = resolveSinkStore(sink);
|
|
211
|
+
let document;
|
|
212
|
+
try {
|
|
213
|
+
document = store.read();
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
ui.error(`The credential store is unreadable (${err instanceof Error ? err.message : String(err)}). ` +
|
|
217
|
+
'Run `godot-cli login --force` to re-authorize.');
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
if (classifyLoginState(document, baseUrl) !== 'partial') {
|
|
221
|
+
ui.error('No partially-authorized sign-in found for this server. Run `godot-cli login`.');
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
// A FRESH agent access token: the provider serves the agent plane, refreshing under the
|
|
225
|
+
// cross-process lock when the stored one is (about to be) expired.
|
|
226
|
+
const provider = createMachineCredentialProvider({
|
|
227
|
+
storeDir: store.baseDirectory,
|
|
228
|
+
serverBaseUrl: baseUrl,
|
|
229
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
230
|
+
onWarning: ui.warn,
|
|
231
|
+
});
|
|
232
|
+
let agentAccessToken;
|
|
233
|
+
try {
|
|
234
|
+
agentAccessToken = await provider.getAccessToken({ family: 'agent' });
|
|
235
|
+
}
|
|
236
|
+
catch (err) {
|
|
237
|
+
ui.error(`The partially-authorized sign-in can no longer be used (${err instanceof Error ? err.message : String(err)}). ` +
|
|
238
|
+
'Run `godot-cli login --force` to start a fresh sign-in.');
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
const exchangeClient = options.exchangeClient ??
|
|
242
|
+
new HttpTokenExchangeClient({
|
|
243
|
+
defaultServerBaseUrl: baseUrl,
|
|
244
|
+
...(options.fetchImpl ? { fetchImpl: options.fetchImpl } : {}),
|
|
245
|
+
});
|
|
246
|
+
const derived = await derivePluginFamily({
|
|
247
|
+
store,
|
|
248
|
+
exchangeClient,
|
|
249
|
+
clientId: godotAdapter.clientId,
|
|
250
|
+
agentAccessToken,
|
|
251
|
+
...(document?.subject !== undefined ? { expectedSubject: document.subject } : {}),
|
|
252
|
+
serverTarget: document?.serverTarget ?? baseUrl,
|
|
253
|
+
fetchImpl: options.fetchImpl,
|
|
254
|
+
onWarning: ui.warn,
|
|
255
|
+
});
|
|
256
|
+
if (derived.status === 'derived') {
|
|
257
|
+
return pluginAccessToken(derived.document);
|
|
258
|
+
}
|
|
259
|
+
ui.error(derived.status === 'exchange-failed'
|
|
260
|
+
? `Could not derive the tools credential (${derived.reason}).`
|
|
261
|
+
: `Could not derive the tools credential — the credential store changed concurrently (${derived.reason}).`);
|
|
262
|
+
return null;
|
|
110
263
|
}
|
|
111
264
|
//# sourceMappingURL=cloud-login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud-login.js","sourceRoot":"","sources":["../../src/utils/cloud-login.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,
|
|
1
|
+
{"version":3,"file":"cloud-login.js","sourceRoot":"","sources":["../../src/utils/cloud-login.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,16 +41,21 @@ export declare function resolveAndValidateProjectPath(positionalPath: string | u
|
|
|
41
41
|
* Token priority:
|
|
42
42
|
* 1. --token flag (explicit override)
|
|
43
43
|
* 2. GODOT_MCP_TOKEN env
|
|
44
|
-
* 3. persisted cloud
|
|
45
|
-
* hosted marker) —
|
|
46
|
-
* login)
|
|
47
|
-
*
|
|
48
|
-
*
|
|
44
|
+
* 3. persisted cloud credential (cloud targets only — env Cloud mode OR an enrolled
|
|
45
|
+
* hosted marker) — see {@link resolveCloudAccessToken}: the per-project store
|
|
46
|
+
* `<project>/.ai-game-dev/` (a `--project` login), then the legacy read-fallback
|
|
47
|
+
* `<project>/.godot-mcp/credentials.json` (migrate-on-touch, never written — 06 D7),
|
|
48
|
+
* then the shared machine store `~/.ai-game-dev/` (a default `godot-cli login`), so a
|
|
49
|
+
* sign-once-per-machine credential is picked up here too. Machine/per-project stores are
|
|
50
|
+
* served through the cli-core {@link createMachineCredentialProvider provider}, which
|
|
51
|
+
* proactively refreshes an (about-to-)expired token under the cross-process lock — the CLI
|
|
52
|
+
* works through expiry instead of handing out a stale bearer.
|
|
53
|
+
* An enrolled cloud project therefore authenticates with zero env config.
|
|
49
54
|
*/
|
|
50
|
-
export declare function resolveConnection(projectPath: string, options: ConnectionOptions): {
|
|
55
|
+
export declare function resolveConnection(projectPath: string, options: ConnectionOptions): Promise<{
|
|
51
56
|
url: string;
|
|
52
57
|
token: string | undefined;
|
|
53
|
-
}
|
|
58
|
+
}>;
|
|
54
59
|
/**
|
|
55
60
|
* Resolve the auth token to inject into the launched editor's environment for
|
|
56
61
|
* the `open` command. The editor inherits the CLI's environment, so a set
|
|
@@ -64,4 +69,4 @@ export declare function resolveConnection(projectPath: string, options: Connecti
|
|
|
64
69
|
export declare function resolveOpenAuthToken(projectPath: string, options: {
|
|
65
70
|
token?: string;
|
|
66
71
|
mode?: string;
|
|
67
|
-
}): string | undefined
|
|
72
|
+
}): Promise<string | undefined>;
|
package/dist/utils/connection.js
CHANGED
|
@@ -2,8 +2,8 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { verbose } from './ui.js';
|
|
4
4
|
import * as ui from './ui.js';
|
|
5
|
-
import { readCloudToken } from './credentials.js';
|
|
6
|
-
import {
|
|
5
|
+
import { readCredentials, readCloudToken } from './credentials.js';
|
|
6
|
+
import { createMachineCredentialProvider, openMachineStore, openMachineStoreLock, openProjectStore, resolveProjectStoreDir, hasUsableFamily, } from './machine-store.js';
|
|
7
7
|
import { deriveProjectIdentityV2 } from './project-identity.js';
|
|
8
8
|
import { readProjectMarker, isLocalhostUrl } from './project-marker.js';
|
|
9
9
|
// --- Godot MCP connection constants (mirror addons/godot_mcp GodotMcpConfig). ---
|
|
@@ -158,13 +158,18 @@ function resolveTargetUrl(projectPath, options) {
|
|
|
158
158
|
* Token priority:
|
|
159
159
|
* 1. --token flag (explicit override)
|
|
160
160
|
* 2. GODOT_MCP_TOKEN env
|
|
161
|
-
* 3. persisted cloud
|
|
162
|
-
* hosted marker) —
|
|
163
|
-
* login)
|
|
164
|
-
*
|
|
165
|
-
*
|
|
161
|
+
* 3. persisted cloud credential (cloud targets only — env Cloud mode OR an enrolled
|
|
162
|
+
* hosted marker) — see {@link resolveCloudAccessToken}: the per-project store
|
|
163
|
+
* `<project>/.ai-game-dev/` (a `--project` login), then the legacy read-fallback
|
|
164
|
+
* `<project>/.godot-mcp/credentials.json` (migrate-on-touch, never written — 06 D7),
|
|
165
|
+
* then the shared machine store `~/.ai-game-dev/` (a default `godot-cli login`), so a
|
|
166
|
+
* sign-once-per-machine credential is picked up here too. Machine/per-project stores are
|
|
167
|
+
* served through the cli-core {@link createMachineCredentialProvider provider}, which
|
|
168
|
+
* proactively refreshes an (about-to-)expired token under the cross-process lock — the CLI
|
|
169
|
+
* works through expiry instead of handing out a stale bearer.
|
|
170
|
+
* An enrolled cloud project therefore authenticates with zero env config.
|
|
166
171
|
*/
|
|
167
|
-
export function resolveConnection(projectPath, options) {
|
|
172
|
+
export async function resolveConnection(projectPath, options) {
|
|
168
173
|
const { url, isCloud } = resolveTargetUrl(projectPath, options);
|
|
169
174
|
let token = options.token ?? normalizeEnv(process.env[ENV_TOKEN]);
|
|
170
175
|
if (options.token) {
|
|
@@ -174,14 +179,110 @@ export function resolveConnection(projectPath, options) {
|
|
|
174
179
|
verbose(`Using ${ENV_TOKEN}`);
|
|
175
180
|
}
|
|
176
181
|
else if (isCloud) {
|
|
177
|
-
|
|
178
|
-
if (persisted) {
|
|
179
|
-
token = persisted;
|
|
180
|
-
verbose('Using persisted cloud token (project store, then machine store)');
|
|
181
|
-
}
|
|
182
|
+
token = await resolveCloudAccessToken(projectPath);
|
|
182
183
|
}
|
|
183
184
|
return { url, token };
|
|
184
185
|
}
|
|
186
|
+
/**
|
|
187
|
+
* Resolve the persisted cloud access token for a cloud target, working through expiry via the
|
|
188
|
+
* cli-core `MachineCredentialProvider` (unified-machine-auth 02/04 — proactive refresh under the
|
|
189
|
+
* cross-process lock, presenting each family's stored `clientId`):
|
|
190
|
+
*
|
|
191
|
+
* 1. **Per-project store** `<project>/.ai-game-dev/` (a `login --project` credential) — when it
|
|
192
|
+
* holds a usable credential it WINS and its unusable states are surfaced, never silently
|
|
193
|
+
* shadowed by the machine account.
|
|
194
|
+
* 2. **Legacy read-fallback** `<project>/.godot-mcp/credentials.json` (transition window, 06
|
|
195
|
+
* D7): still honored for one release, NEVER written, and **migrated on touch** into the
|
|
196
|
+
* machine store (under the lock) when the machine store is empty — so the credential
|
|
197
|
+
* survives the f4 removal of this fallback.
|
|
198
|
+
* 3. **Machine store** `~/.ai-game-dev/` via the provider.
|
|
199
|
+
*
|
|
200
|
+
* Returns undefined when signed out / the store is unusable — the command then proceeds
|
|
201
|
+
* unauthenticated exactly as before (the server answers 401 and the user is pointed at `login`).
|
|
202
|
+
*/
|
|
203
|
+
async function resolveCloudAccessToken(projectPath) {
|
|
204
|
+
// 1. Per-project store (a `login --project` credential). Its unusable states are surfaced
|
|
205
|
+
// honestly (04 §1 / F11.4): an UNREADABLE store is never silently shadowed by the machine
|
|
206
|
+
// account — that would run the command as a different account than the project chose.
|
|
207
|
+
const projectStore = openProjectStore(projectPath);
|
|
208
|
+
const projectState = projectStore.readState();
|
|
209
|
+
if (projectState.status === 'unreadable') {
|
|
210
|
+
ui.warn(`The per-project credential store (${projectStore.credentialsPath}) is unreadable ` +
|
|
211
|
+
`(${projectState.reason}). Not falling back to the machine credential — ` +
|
|
212
|
+
'run `godot-cli login --project <path>` to re-authorize this project.');
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
if (projectState.status === 'ok' && hasUsableFamily(projectState.credentials)) {
|
|
216
|
+
const provider = createMachineCredentialProvider({
|
|
217
|
+
storeDir: resolveProjectStoreDir(projectPath),
|
|
218
|
+
onWarning: ui.warn,
|
|
219
|
+
});
|
|
220
|
+
try {
|
|
221
|
+
const token = await provider.getAccessToken();
|
|
222
|
+
verbose('Using persisted cloud token (per-project store)');
|
|
223
|
+
return token;
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
verbose(`Per-project credential unusable: ${err instanceof Error ? err.message : String(err)}`);
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// 2. Legacy project-store read-fallback (+ migrate-on-touch; never written — 06 D7, f4 removes).
|
|
231
|
+
const legacyToken = readCloudToken(projectPath);
|
|
232
|
+
if (legacyToken) {
|
|
233
|
+
await migrateLegacyProjectCredential(projectPath, legacyToken);
|
|
234
|
+
verbose('Using persisted cloud token (legacy project store read-fallback)');
|
|
235
|
+
return legacyToken;
|
|
236
|
+
}
|
|
237
|
+
// 3. Shared machine store via the provider (refreshes through expiry).
|
|
238
|
+
const provider = createMachineCredentialProvider({ onWarning: ui.warn });
|
|
239
|
+
try {
|
|
240
|
+
const token = await provider.getAccessToken();
|
|
241
|
+
verbose('Using persisted cloud token (machine store)');
|
|
242
|
+
return token;
|
|
243
|
+
}
|
|
244
|
+
catch (err) {
|
|
245
|
+
verbose(`No usable machine credential: ${err instanceof Error ? err.message : String(err)}`);
|
|
246
|
+
return undefined;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* F11.2 migrate-on-touch: on first use of a legacy `<project>/.godot-mcp/credentials.json`
|
|
251
|
+
* credential, adopt it into the shared machine store — as a `families.legacy` family (mint
|
|
252
|
+
* client unknown by definition), under the 04 §2 cross-process lock, and ONLY when the machine
|
|
253
|
+
* store is empty (a present credential is never overwritten by a migration). The legacy file
|
|
254
|
+
* itself is left untouched: the read-fallback stays for this release and f4 removes it.
|
|
255
|
+
* Best-effort — a busy lock or unreadable store never blocks the command.
|
|
256
|
+
*/
|
|
257
|
+
async function migrateLegacyProjectCredential(projectPath, legacyToken) {
|
|
258
|
+
try {
|
|
259
|
+
const store = openMachineStore();
|
|
260
|
+
if (store.readState().status !== 'missing')
|
|
261
|
+
return;
|
|
262
|
+
const serverTarget = safeRead(() => readCredentials(projectPath))?.cloudBaseUrl;
|
|
263
|
+
const lock = openMachineStoreLock();
|
|
264
|
+
await lock.withLock(() => {
|
|
265
|
+
// Double-checked under the lock: a peer may have signed in while we waited.
|
|
266
|
+
if (store.readState().status !== 'missing')
|
|
267
|
+
return;
|
|
268
|
+
store.writeFamily('legacy', { accessToken: legacyToken }, { serverTarget: typeof serverTarget === 'string' ? serverTarget : DEFAULT_CLOUD_BASE_URL });
|
|
269
|
+
verbose('Migrated the legacy project credential into the machine store (families.legacy)');
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
catch (err) {
|
|
273
|
+
// Never log token material; the reason is safe.
|
|
274
|
+
verbose(`Legacy credential migration skipped: ${err instanceof Error ? err.message : String(err)}`);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
/** Run a store read, mapping any throw (malformed/unreadable) to null. */
|
|
278
|
+
function safeRead(read) {
|
|
279
|
+
try {
|
|
280
|
+
return read();
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
185
286
|
/**
|
|
186
287
|
* Resolve the auth token to inject into the launched editor's environment for
|
|
187
288
|
* the `open` command. The editor inherits the CLI's environment, so a set
|
|
@@ -192,7 +293,7 @@ export function resolveConnection(projectPath, options) {
|
|
|
192
293
|
* Returns the token to pass as `openProject({ token })`, or undefined to leave
|
|
193
294
|
* `open`'s env exactly as before (explicit env var / no token).
|
|
194
295
|
*/
|
|
195
|
-
export function resolveOpenAuthToken(projectPath, options) {
|
|
296
|
+
export async function resolveOpenAuthToken(projectPath, options) {
|
|
196
297
|
if (options.token !== undefined) {
|
|
197
298
|
return options.token;
|
|
198
299
|
}
|
|
@@ -202,7 +303,7 @@ export function resolveOpenAuthToken(projectPath, options) {
|
|
|
202
303
|
}
|
|
203
304
|
const selectedMode = options.mode ?? normalizeEnv(process.env[ENV_CONNECTION_MODE]);
|
|
204
305
|
if (selectedMode !== undefined && selectedMode.toLowerCase() === 'cloud') {
|
|
205
|
-
return
|
|
306
|
+
return resolveCloudAccessToken(projectPath);
|
|
206
307
|
}
|
|
207
308
|
return undefined;
|
|
208
309
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/utils/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../../src/utils/connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* READ-FALLBACK for the legacy project-local cloud credential sink — transition window only
|
|
3
|
+
* (unified-machine-auth 06 D7 / F11.2).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* purely the CLI's in-project pickup surface, mirroring the Unity CLI's
|
|
13
|
-
* `cloudToken` config field.
|
|
5
|
+
* Older CLI releases persisted the cloud bearer token to `<project>/.godot-mcp/credentials.json`.
|
|
6
|
+
* The CLI **no longer writes this file anywhere** — a default `login` commits to the shared
|
|
7
|
+
* machine store (`~/.ai-game-dev/`), and `login --project` commits to the per-project store
|
|
8
|
+
* (`<project>/.ai-game-dev/`), both via `@baizor/gamedev-cli-core`. This module only READS a
|
|
9
|
+
* pre-existing legacy file so those users keep working for one release; on first use the
|
|
10
|
+
* credential is migrated into the machine store (`connection.ts` migrate-on-touch), and the f4
|
|
11
|
+
* follow-up removes this fallback entirely. There is deliberately no write function left here —
|
|
12
|
+
* a v2-era write to this sink must never ship.
|
|
14
13
|
*/
|
|
15
14
|
export declare const CREDENTIALS_RELATIVE_PATH = ".godot-mcp/credentials.json";
|
|
16
15
|
export interface GodotMcpCredentials {
|
|
@@ -21,16 +20,11 @@ export interface GodotMcpCredentials {
|
|
|
21
20
|
[key: string]: unknown;
|
|
22
21
|
}
|
|
23
22
|
export declare function getCredentialsPath(projectPath: string): string;
|
|
24
|
-
/** Read the credentials file. Returns null when absent; throws on malformed JSON. */
|
|
23
|
+
/** Read the legacy credentials file. Returns null when absent; throws on malformed JSON. */
|
|
25
24
|
export declare function readCredentials(projectPath: string): GodotMcpCredentials | null;
|
|
26
25
|
/**
|
|
27
|
-
*
|
|
28
|
-
* ensuring `credentials.json` is git-ignored so the token is never committed.
|
|
29
|
-
*/
|
|
30
|
-
export declare function writeCredentials(projectPath: string, credentials: GodotMcpCredentials): void;
|
|
31
|
-
/**
|
|
32
|
-
* Convenience reader for the persisted cloud token. Swallows a missing or
|
|
26
|
+
* Convenience reader for the persisted legacy cloud token. Swallows a missing or
|
|
33
27
|
* malformed file (returns undefined) so a broken credentials file can never
|
|
34
|
-
* crash `open` / `run-tool`; `login`
|
|
28
|
+
* crash `open` / `run-tool`; `login` writes the cli-core stores instead.
|
|
35
29
|
*/
|
|
36
30
|
export declare function readCloudToken(projectPath: string): string | undefined;
|