@midscene/cli 1.16.2 → 1.16.5
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/dist/es/index.mjs +73 -170
- package/dist/es/index.mjs.map +1 -1
- package/dist/lib/framework/index.js +6 -2
- package/dist/lib/framework/index.js.map +1 -1
- package/dist/lib/index.js +78 -170
- package/dist/lib/index.js.map +1 -1
- package/package.json +10 -10
package/dist/lib/index.js
CHANGED
|
@@ -3342,7 +3342,7 @@ var __webpack_modules__ = {
|
|
|
3342
3342
|
return lines.join('\n');
|
|
3343
3343
|
};
|
|
3344
3344
|
const printer_formatYamlProgressSnapshot = (message, attempt, totalAttempts)=>totalAttempts > 1 ? `Attempt ${attempt}/${totalAttempts}\n${message}` : message;
|
|
3345
|
-
|
|
3345
|
+
var external_node_util_ = __webpack_require__("node:util");
|
|
3346
3346
|
var external_node_process_ = __webpack_require__("node:process");
|
|
3347
3347
|
const copyProperty = (to, from, property, ignoreNonConfigurable)=>{
|
|
3348
3348
|
if ('length' === property || 'prototype' === property) return;
|
|
@@ -3683,7 +3683,7 @@ var __webpack_modules__ = {
|
|
|
3683
3683
|
for (const content of contents){
|
|
3684
3684
|
const rows = content.split('\n');
|
|
3685
3685
|
for (const row of rows){
|
|
3686
|
-
const text = (0,
|
|
3686
|
+
const text = (0, external_node_util_.stripVTControlCharacters)(row);
|
|
3687
3687
|
count += Math.max(1, Math.ceil(text.length / columns));
|
|
3688
3688
|
}
|
|
3689
3689
|
}
|
|
@@ -4588,7 +4588,7 @@ defineYamlBatchTest(test, testOptions);
|
|
|
4588
4588
|
var core_ = __webpack_require__("@midscene/core");
|
|
4589
4589
|
const cli_namespaceObject = require("@midscene/shared/cli");
|
|
4590
4590
|
var package_namespaceObject = {
|
|
4591
|
-
rE: "1.16.
|
|
4591
|
+
rE: "1.16.5"
|
|
4592
4592
|
};
|
|
4593
4593
|
var external_node_fs_ = __webpack_require__("node:fs");
|
|
4594
4594
|
var external_node_fs_namespaceObject = /*#__PURE__*/ __webpack_require__.t(external_node_fs_, 2);
|
|
@@ -10273,7 +10273,7 @@ Usage:
|
|
|
10273
10273
|
type: 'boolean',
|
|
10274
10274
|
description: 'Whether to dismiss the HarmonyOS keyboard after text input'
|
|
10275
10275
|
}
|
|
10276
|
-
}).version('version', 'Show version number', "1.16.
|
|
10276
|
+
}).version('version', 'Show version number', "1.16.5").help().epilogue(`For complete list of configuration options, please visit:
|
|
10277
10277
|
• Web options: https://midscenejs.com/automate-with-scripts-in-yaml#the-web-part
|
|
10278
10278
|
• Android options: https://midscenejs.com/automate-with-scripts-in-yaml#the-android-part
|
|
10279
10279
|
• HarmonyOS options: https://midscenejs.com/automate-with-scripts-in-yaml#the-harmony-part
|
|
@@ -12527,22 +12527,36 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12527
12527
|
var framework = __webpack_require__("./src/framework/index.ts");
|
|
12528
12528
|
const external_node_child_process_namespaceObject = require("node:child_process");
|
|
12529
12529
|
var external_node_crypto_ = __webpack_require__("node:crypto");
|
|
12530
|
+
const ai_model_namespaceObject = require("@midscene/core/ai-model");
|
|
12530
12531
|
var chalk_source = __webpack_require__("../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/index.js");
|
|
12531
12532
|
var source_default = /*#__PURE__*/ __webpack_require__.n(chalk_source);
|
|
12532
12533
|
const external_node_os_namespaceObject = require("node:os");
|
|
12534
|
+
var external_node_util_ = __webpack_require__("node:util");
|
|
12535
|
+
function describeSiwcError(error) {
|
|
12536
|
+
return (0, external_node_util_.inspect)(error, {
|
|
12537
|
+
depth: null,
|
|
12538
|
+
colors: false,
|
|
12539
|
+
maxArrayLength: null,
|
|
12540
|
+
maxStringLength: null
|
|
12541
|
+
});
|
|
12542
|
+
}
|
|
12533
12543
|
const defaultCredentialsPath = ()=>(0, external_node_path_.join)((0, external_node_os_namespaceObject.homedir)(), '.midscene', 'siwc.json');
|
|
12534
12544
|
async function readCredentialsFile(path) {
|
|
12535
12545
|
const content = await (0, promises_namespaceObject.readFile)(path, 'utf8').catch((error)=>{
|
|
12536
12546
|
if ('ENOENT' === error.code) return;
|
|
12537
|
-
throw new
|
|
12547
|
+
throw new ai_model_namespaceObject.SiwcError('Unable to read the local SIWC credentials file.', {
|
|
12548
|
+
cause: error
|
|
12549
|
+
});
|
|
12538
12550
|
});
|
|
12539
12551
|
if (void 0 === content) return;
|
|
12540
12552
|
try {
|
|
12541
12553
|
const value = JSON.parse(content);
|
|
12542
|
-
if (!value || 'string' != typeof value.credentials?.ext_agent_host_id || !value.credentials.ext_agent_host_id) throw new
|
|
12554
|
+
if (!value || 'string' != typeof value.credentials?.ext_agent_host_id || !value.credentials.ext_agent_host_id) throw new ai_model_namespaceObject.SiwcError('Invalid SIWC credentials record.');
|
|
12543
12555
|
return value;
|
|
12544
|
-
} catch
|
|
12545
|
-
throw new
|
|
12556
|
+
} catch (error) {
|
|
12557
|
+
throw new ai_model_namespaceObject.SiwcError('Invalid local SIWC credentials file.', {
|
|
12558
|
+
cause: error
|
|
12559
|
+
});
|
|
12546
12560
|
}
|
|
12547
12561
|
}
|
|
12548
12562
|
async function readRegistration(path) {
|
|
@@ -12581,8 +12595,10 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12581
12595
|
mode: 448
|
|
12582
12596
|
});
|
|
12583
12597
|
} catch (error) {
|
|
12584
|
-
if ('EEXIST' === error.code) throw new
|
|
12585
|
-
throw new
|
|
12598
|
+
if ('EEXIST' === error.code) throw new ai_model_namespaceObject.SiwcError(`Another SIWC command holds ${lockPath}. If it was interrupted, remove this lock only after confirming that no SIWC command is running.`);
|
|
12599
|
+
throw new ai_model_namespaceObject.SiwcError('Unable to lock the local SIWC credentials file.', {
|
|
12600
|
+
cause: error
|
|
12601
|
+
});
|
|
12586
12602
|
}
|
|
12587
12603
|
return ()=>(0, promises_namespaceObject.rm)(lockPath, {
|
|
12588
12604
|
recursive: true,
|
|
@@ -12597,20 +12613,14 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12597
12613
|
'access_token',
|
|
12598
12614
|
'refresh_token',
|
|
12599
12615
|
'id_token'
|
|
12600
|
-
].some((key)=>'string' != typeof value[key] || !value[key]) || !Array.isArray(value.scopes) || !value.scopes.every((scope)=>'string' == typeof scope) || !Number.isFinite(value.expires_at)) throw new
|
|
12616
|
+
].some((key)=>'string' != typeof value[key] || !value[key]) || !Array.isArray(value.scopes) || !value.scopes.every((scope)=>'string' == typeof scope) || !Number.isFinite(value.expires_at)) throw new ai_model_namespaceObject.SiwcError('No valid SIWC credentials. Run midscene model siwc login first.');
|
|
12601
12617
|
return value;
|
|
12602
12618
|
}
|
|
12603
12619
|
const external_node_http_namespaceObject = require("node:http");
|
|
12604
|
-
const external_jose_namespaceObject = require("jose");
|
|
12605
|
-
const ISSUER = 'https://auth.openai.com';
|
|
12606
|
-
const RESOURCE = 'https://api.openai.com/v1';
|
|
12607
|
-
const SCOPES = 'openid profile email offline_access resource.invoke chatgpt.tokens.use.direct';
|
|
12608
12620
|
async function loginWithOpenAI(options, dependencies) {
|
|
12609
12621
|
const hostId = options.hostId ?? `urn:uuid:${(0, external_node_crypto_.randomUUID)()}`;
|
|
12610
12622
|
const existingClientId = options.clientId;
|
|
12611
|
-
const
|
|
12612
|
-
const nonce = (0, external_node_crypto_.randomBytes)(32).toString('base64url');
|
|
12613
|
-
const verifier = (0, external_node_crypto_.randomBytes)(32).toString('base64url');
|
|
12623
|
+
const context = {};
|
|
12614
12624
|
const signal = options.signal;
|
|
12615
12625
|
signal.throwIfAborted();
|
|
12616
12626
|
const server = (0, external_node_http_namespaceObject.createServer)();
|
|
@@ -12624,17 +12634,24 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12624
12634
|
response.setHeader('Referrer-Policy', 'no-referrer');
|
|
12625
12635
|
const url = new URL(request.url || '/', 'http://127.0.0.1');
|
|
12626
12636
|
if ('GET' !== request.method || '/auth/callback' !== url.pathname) return void response.writeHead(404).end('Not found');
|
|
12627
|
-
if (
|
|
12637
|
+
if (!context.attempt) return void response.writeHead(400).end('Authorization has not started.');
|
|
12628
12638
|
if (consumed.value) return void response.writeHead(409).end('Authorization already received.');
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12639
|
+
const parsed = (()=>{
|
|
12640
|
+
try {
|
|
12641
|
+
return (0, ai_model_namespaceObject.parseSiwcCallback)(new URL(request.url || '/', context.attempt.redirectUri).toString(), context.attempt);
|
|
12642
|
+
} catch (error) {
|
|
12643
|
+
response.writeHead(400).end('Invalid authorization callback.');
|
|
12644
|
+
if (url.searchParams.has('error')) {
|
|
12645
|
+
consumed.value = true;
|
|
12646
|
+
reject(error);
|
|
12647
|
+
}
|
|
12648
|
+
return;
|
|
12649
|
+
}
|
|
12650
|
+
})();
|
|
12651
|
+
if (!parsed) {
|
|
12652
|
+
if (!response.writableEnded) response.writeHead(400).end('Invalid login state. Use the original authorization link.');
|
|
12633
12653
|
return;
|
|
12634
12654
|
}
|
|
12635
|
-
const code = url.searchParams.get('code');
|
|
12636
|
-
const clientId = url.searchParams.get('client_id') || existingClientId;
|
|
12637
|
-
if (!code || !clientId || 'dynamic_agent_client' === clientId || existingClientId && clientId !== existingClientId || 1 !== url.searchParams.getAll('code').length || url.searchParams.getAll('client_id').length > 1) return void response.writeHead(400).end('Invalid authorization callback.');
|
|
12638
12655
|
consumed.value = true;
|
|
12639
12656
|
response.setHeader('Content-Type', 'text/html; charset=utf-8');
|
|
12640
12657
|
response.end(`<!doctype html>
|
|
@@ -12660,10 +12677,7 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12660
12677
|
</main>
|
|
12661
12678
|
</body>
|
|
12662
12679
|
</html>`);
|
|
12663
|
-
resolve(
|
|
12664
|
-
code,
|
|
12665
|
-
clientId
|
|
12666
|
-
});
|
|
12680
|
+
resolve(parsed);
|
|
12667
12681
|
});
|
|
12668
12682
|
server.on('error', reject);
|
|
12669
12683
|
});
|
|
@@ -12682,132 +12696,22 @@ Native cases/steps Test projects use the midscene-test command.`).wrap(yargs().t
|
|
|
12682
12696
|
});
|
|
12683
12697
|
signal.throwIfAborted();
|
|
12684
12698
|
const redirectUri = `http://127.0.0.1:${server.address().port}/auth/callback`;
|
|
12685
|
-
const
|
|
12686
|
-
|
|
12687
|
-
|
|
12688
|
-
|
|
12689
|
-
|
|
12690
|
-
},
|
|
12691
|
-
ext_agent_host_id: hostId,
|
|
12692
|
-
response_type: 'code',
|
|
12693
|
-
redirect_uri: redirectUri,
|
|
12694
|
-
scope: SCOPES,
|
|
12695
|
-
resource: RESOURCE,
|
|
12696
|
-
state,
|
|
12697
|
-
nonce,
|
|
12698
|
-
code_challenge_method: 'S256',
|
|
12699
|
-
code_challenge: (0, external_node_crypto_.createHash)('sha256').update(verifier).digest('base64url')
|
|
12700
|
-
}).toString();
|
|
12701
|
-
await options.onAuthorization(authorization.toString());
|
|
12702
|
-
const { code, clientId } = await callback;
|
|
12703
|
-
signal.throwIfAborted();
|
|
12704
|
-
const request = dependencies?.fetch ?? fetch;
|
|
12705
|
-
const result = await request(`${ISSUER}/api/accounts/oauth/token`, {
|
|
12706
|
-
method: 'POST',
|
|
12707
|
-
headers: {
|
|
12708
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
12709
|
-
},
|
|
12710
|
-
body: new URLSearchParams({
|
|
12711
|
-
grant_type: 'authorization_code',
|
|
12712
|
-
client_id: clientId,
|
|
12713
|
-
code,
|
|
12714
|
-
code_verifier: verifier,
|
|
12715
|
-
redirect_uri: redirectUri,
|
|
12716
|
-
resource: RESOURCE
|
|
12717
|
-
}),
|
|
12718
|
-
signal,
|
|
12719
|
-
redirect: 'error'
|
|
12699
|
+
const { attempt, url } = await (0, ai_model_namespaceObject.createSiwcAuthorization)({
|
|
12700
|
+
hostId,
|
|
12701
|
+
clientId: existingClientId,
|
|
12702
|
+
redirectUri,
|
|
12703
|
+
agentName: 'Midscene'
|
|
12720
12704
|
});
|
|
12721
|
-
|
|
12722
|
-
|
|
12723
|
-
|
|
12724
|
-
|
|
12725
|
-
if (!scopes.includes('chatgpt.tokens.use.direct')) throw new Error('ChatGPT plan usage was not authorized. Run midscene model siwc login again and grant access.');
|
|
12726
|
-
const keys = dependencies?.keys ?? (0, external_jose_namespaceObject.createRemoteJWKSet)(new URL(`${ISSUER}/.well-known/jwks.json`));
|
|
12727
|
-
const { payload } = await (0, external_jose_namespaceObject.jwtVerify)(tokens.id_token, keys, {
|
|
12728
|
-
issuer: ISSUER,
|
|
12729
|
-
audience: clientId,
|
|
12730
|
-
algorithms: [
|
|
12731
|
-
'RS256'
|
|
12732
|
-
],
|
|
12733
|
-
requiredClaims: [
|
|
12734
|
-
'sub',
|
|
12735
|
-
'exp',
|
|
12736
|
-
'iat',
|
|
12737
|
-
'nonce'
|
|
12738
|
-
]
|
|
12739
|
-
});
|
|
12740
|
-
if (payload.nonce !== nonce || !payload.sub) throw new Error('OpenAI login identity or nonce did not match.');
|
|
12741
|
-
signal.throwIfAborted();
|
|
12742
|
-
return {
|
|
12743
|
-
ext_agent_host_id: hostId,
|
|
12744
|
-
client_id: clientId,
|
|
12745
|
-
subject: payload.sub,
|
|
12746
|
-
issuer: ISSUER,
|
|
12747
|
-
...'string' == typeof payload.email ? {
|
|
12748
|
-
email: payload.email
|
|
12749
|
-
} : {},
|
|
12750
|
-
access_token: tokens.access_token,
|
|
12751
|
-
refresh_token: tokens.refresh_token,
|
|
12752
|
-
id_token: tokens.id_token,
|
|
12753
|
-
scopes,
|
|
12754
|
-
expires_at: Date.now() + 1000 * tokens.expires_in
|
|
12755
|
-
};
|
|
12705
|
+
context.attempt = attempt;
|
|
12706
|
+
await options.onAuthorization(url);
|
|
12707
|
+
const result = await (0, ai_model_namespaceObject.withSiwcStage)('Authorization callback', ()=>callback);
|
|
12708
|
+
return await (0, ai_model_namespaceObject.exchangeSiwcCode)(attempt, result, signal, dependencies);
|
|
12756
12709
|
} finally{
|
|
12757
12710
|
signal.removeEventListener('abort', abort);
|
|
12758
12711
|
server.closeAllConnections();
|
|
12759
12712
|
await new Promise((resolve)=>server.close(()=>resolve()));
|
|
12760
12713
|
}
|
|
12761
12714
|
}
|
|
12762
|
-
async function refreshOpenAICredentials(saved, signal, dependencies) {
|
|
12763
|
-
const issuer = 'https://auth.openai.com';
|
|
12764
|
-
signal.throwIfAborted();
|
|
12765
|
-
const response = await (dependencies?.fetch ?? fetch)(`${issuer}/api/accounts/oauth/token`, {
|
|
12766
|
-
method: 'POST',
|
|
12767
|
-
headers: {
|
|
12768
|
-
'Content-Type': 'application/x-www-form-urlencoded'
|
|
12769
|
-
},
|
|
12770
|
-
body: new URLSearchParams({
|
|
12771
|
-
grant_type: 'refresh_token',
|
|
12772
|
-
client_id: saved.client_id,
|
|
12773
|
-
refresh_token: saved.refresh_token,
|
|
12774
|
-
resource: 'https://api.openai.com/v1'
|
|
12775
|
-
}),
|
|
12776
|
-
signal,
|
|
12777
|
-
redirect: 'error'
|
|
12778
|
-
});
|
|
12779
|
-
if (!response.ok) throw new Error('OpenAI refresh failed.');
|
|
12780
|
-
const tokens = await response.json();
|
|
12781
|
-
if (!tokens || 'string' != typeof tokens.access_token || !tokens.access_token || 'string' != typeof tokens.refresh_token || !tokens.refresh_token || 'number' != typeof tokens.expires_in || !Number.isFinite(tokens.expires_in) || tokens.expires_in <= 0 || 'string' != typeof tokens.token_type || 'bearer' !== tokens.token_type.toLowerCase() || 'string' != typeof tokens.scope) throw new Error('OpenAI returned an invalid refresh response.');
|
|
12782
|
-
const scopes = tokens.scope.split(/\s+/);
|
|
12783
|
-
if (!scopes.includes('chatgpt.tokens.use.direct')) throw new Error('ChatGPT plan usage is no longer authorized.');
|
|
12784
|
-
if (void 0 !== tokens.id_token) {
|
|
12785
|
-
if ('string' != typeof tokens.id_token || !tokens.id_token) throw new Error('Invalid refreshed ID token.');
|
|
12786
|
-
const keys = dependencies?.keys ?? (0, external_jose_namespaceObject.createRemoteJWKSet)(new URL(`${issuer}/.well-known/jwks.json`));
|
|
12787
|
-
const { payload } = await (0, external_jose_namespaceObject.jwtVerify)(tokens.id_token, keys, {
|
|
12788
|
-
issuer,
|
|
12789
|
-
audience: saved.client_id,
|
|
12790
|
-
algorithms: [
|
|
12791
|
-
'RS256'
|
|
12792
|
-
],
|
|
12793
|
-
requiredClaims: [
|
|
12794
|
-
'sub',
|
|
12795
|
-
'exp',
|
|
12796
|
-
'iat'
|
|
12797
|
-
]
|
|
12798
|
-
});
|
|
12799
|
-
if (payload.sub !== saved.subject) throw new Error('Refreshed identity does not match the saved account.');
|
|
12800
|
-
}
|
|
12801
|
-
signal.throwIfAborted();
|
|
12802
|
-
return {
|
|
12803
|
-
...saved,
|
|
12804
|
-
access_token: tokens.access_token,
|
|
12805
|
-
refresh_token: tokens.refresh_token,
|
|
12806
|
-
id_token: tokens.id_token ?? saved.id_token,
|
|
12807
|
-
scopes,
|
|
12808
|
-
expires_at: Date.now() + 1000 * tokens.expires_in
|
|
12809
|
-
};
|
|
12810
|
-
}
|
|
12811
12715
|
const USAGE = `Usage:
|
|
12812
12716
|
midscene model siwc login [--no-open] [--port <port>]
|
|
12813
12717
|
midscene model siwc refresh
|
|
@@ -12880,7 +12784,7 @@ Options (login):
|
|
|
12880
12784
|
}
|
|
12881
12785
|
}
|
|
12882
12786
|
const unlock = await lockCredentials(credentialsPath).catch((error)=>{
|
|
12883
|
-
io.stderr(error
|
|
12787
|
+
io.stderr(describeSiwcError(error));
|
|
12884
12788
|
});
|
|
12885
12789
|
if (!unlock) return 1;
|
|
12886
12790
|
const controller = new AbortController();
|
|
@@ -12890,31 +12794,31 @@ Options (login):
|
|
|
12890
12794
|
process.once('SIGTERM', cancel);
|
|
12891
12795
|
try {
|
|
12892
12796
|
io.stderr(source_default().cyan.bold(`🔄 Starting OpenAI SIWC ${action}...`));
|
|
12893
|
-
const saved = await readRegistration(credentialsPath);
|
|
12797
|
+
const saved = await (0, ai_model_namespaceObject.withSiwcStage)('Read credentials', ()=>readRegistration(credentialsPath));
|
|
12894
12798
|
const credentials = await (async ()=>{
|
|
12895
|
-
if ('refresh' === action) return
|
|
12799
|
+
if ('refresh' === action) return (0, ai_model_namespaceObject.withSiwcStage)('Refresh', ()=>(0, ai_model_namespaceObject.refreshSiwcCredentials)(requireCredentials(saved), controller.signal));
|
|
12896
12800
|
const registration = saved ?? {
|
|
12897
12801
|
ext_agent_host_id: `urn:uuid:${(0, external_node_crypto_.randomUUID)()}`
|
|
12898
12802
|
};
|
|
12899
|
-
if (!saved) await saveRegistration(credentialsPath, registration);
|
|
12900
|
-
const result = await loginWithOpenAI({
|
|
12901
|
-
|
|
12902
|
-
|
|
12903
|
-
|
|
12904
|
-
|
|
12905
|
-
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
|
|
12909
|
-
|
|
12910
|
-
|
|
12803
|
+
if (!saved) await (0, ai_model_namespaceObject.withSiwcStage)('Save registration', ()=>saveRegistration(credentialsPath, registration));
|
|
12804
|
+
const result = await (0, ai_model_namespaceObject.withSiwcStage)('Login', ()=>loginWithOpenAI({
|
|
12805
|
+
port: portOptions.port,
|
|
12806
|
+
hostId: registration.ext_agent_host_id,
|
|
12807
|
+
clientId: registration.client_id,
|
|
12808
|
+
signal: controller.signal,
|
|
12809
|
+
onAuthorization: async (url)=>{
|
|
12810
|
+
io.stderr(`\n${source_default().bold('Continue with ChatGPT:')}\n${url}\n\n${source_default().gray('Waiting for authorization...')}`);
|
|
12811
|
+
if (!portOptions.noOpen) try {
|
|
12812
|
+
await openBrowser(url);
|
|
12813
|
+
} catch {
|
|
12814
|
+
io.stderr('Open the URL above in your browser to continue.');
|
|
12815
|
+
}
|
|
12911
12816
|
}
|
|
12912
|
-
}
|
|
12913
|
-
|
|
12914
|
-
if (registration.subject && result.subject !== registration.subject) throw new Error('Login identity does not match the saved account.');
|
|
12817
|
+
}));
|
|
12818
|
+
if (registration.subject && result.subject !== registration.subject) throw new ai_model_namespaceObject.SiwcError('Login identity does not match the saved account.');
|
|
12915
12819
|
return result;
|
|
12916
12820
|
})();
|
|
12917
|
-
await saveRegistration(credentialsPath, credentials);
|
|
12821
|
+
await (0, ai_model_namespaceObject.withSiwcStage)('Save credentials', ()=>saveRegistration(credentialsPath, credentials));
|
|
12918
12822
|
io.stderr('\n🔑 your Access token:');
|
|
12919
12823
|
io.stdout(credentials.access_token);
|
|
12920
12824
|
const expiresAt = new Intl.DateTimeFormat('en-GB', {
|
|
@@ -12928,8 +12832,8 @@ Options (login):
|
|
|
12928
12832
|
io.stderr(`\nExpires at: ${expiresAt} (${expiresIn})`);
|
|
12929
12833
|
io.stderr(`\n${source_default().green(`✅ SIWC ${action} succeeded.`)}\n\nYou can use this access token as your model API Key in Midscene by setting MIDSCENE_MODEL_API_KEY.\n\nFull credentials are saved locally to:\n${source_default().cyan(credentialsPath)}\n\n${source_default().gray('Midscene does not collect your credentials.')}`);
|
|
12930
12834
|
return 0;
|
|
12931
|
-
} catch
|
|
12932
|
-
io.stderr(source_default().red(controller.signal.aborted ? `OpenAI ${action} cancelled or timed out
|
|
12835
|
+
} catch (error) {
|
|
12836
|
+
io.stderr(source_default().red(controller.signal.aborted ? `OpenAI ${action} cancelled or timed out.\n${describeSiwcError(error)}` : `OpenAI ${action} failed.\n${describeSiwcError(error)}`));
|
|
12933
12837
|
return 1;
|
|
12934
12838
|
} finally{
|
|
12935
12839
|
clearTimeout(timer);
|
|
@@ -13123,6 +13027,10 @@ Options (login):
|
|
|
13123
13027
|
"use strict";
|
|
13124
13028
|
module.exports = require("node:url");
|
|
13125
13029
|
},
|
|
13030
|
+
"node:util" (module) {
|
|
13031
|
+
"use strict";
|
|
13032
|
+
module.exports = require("node:util");
|
|
13033
|
+
},
|
|
13126
13034
|
os (module) {
|
|
13127
13035
|
"use strict";
|
|
13128
13036
|
module.exports = require("os");
|