@remixmate/cli 0.9.71 → 0.9.73
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/LICENSE +45 -21
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/argv.js +1 -51
- package/dist/auth/auth-lock.js +1 -100
- package/dist/auth/auto-login.js +7 -75
- package/dist/auth/commands.js +40 -290
- package/dist/auth/credential-store.js +1 -143
- package/dist/auth/device-flow-runner.js +13 -110
- package/dist/auth/device-flow.js +1 -132
- package/dist/auth/ensure.js +1 -62
- package/dist/auth/environment.js +1 -69
- package/dist/auth/pending-store.js +1 -45
- package/dist/auth/resolve.js +1 -44
- package/dist/billing.js +3 -76
- package/dist/capabilities.js +1 -75
- package/dist/cli.js +39 -211
- package/dist/diagnostics.js +2 -70
- package/dist/doctor.js +9 -188
- package/dist/errors.js +1 -33
- package/dist/exec.js +4 -47
- package/dist/handlers/gen-digital-human.js +33 -264
- package/dist/handlers/gen-image.js +9 -113
- package/dist/handlers/gen-post.js +15 -188
- package/dist/handlers/gen-video.js +7 -185
- package/dist/handlers/gen-voice.js +19 -133
- package/dist/handlers/index.js +1 -20
- package/dist/handlers/shared.js +1 -66
- package/dist/handlers/template-init.js +1 -21
- package/dist/http.js +3 -155
- package/dist/index.js +1 -8
- package/dist/install.js +40 -448
- package/dist/manifest.json +53 -13
- package/dist/progress.js +2 -15
- package/dist/project/commands.js +34 -156
- package/dist/project/host.js +1 -151
- package/dist/project/resolve.js +1 -65
- package/dist/project/store.js +2 -97
- package/dist/project/take.js +1 -106
- package/dist/project/trace.js +5 -278
- package/dist/registry.js +3 -70
- package/dist/runner.js +7 -225
- package/dist/skill-schema.js +1 -194
- package/dist/template/args.js +1 -69
- package/dist/template/check.js +2 -30
- package/dist/template/commands.js +34 -163
- package/dist/template/constants.js +1 -46
- package/dist/template/init.js +5 -133
- package/dist/template/list.js +1 -46
- package/dist/template/preview.js +7 -318
- package/dist/template/proc.js +1 -43
- package/dist/template/project.js +6 -161
- package/dist/template/publish.js +5 -185
- package/dist/template/render-client.js +2 -79
- package/dist/template/upgrade.js +4 -123
- package/dist/text.js +1 -15
- package/package.json +2 -35
- package/skills/doc-parse/scripts/extract_via_render.py +32 -32
- package/skills/export-jianying/scripts/gen_jianying_draft.py +188 -188
- package/skills/gen-post/SKILL.md +23 -13
- package/skills/gen-post/skill.json +9 -10
- package/skills/gen-script/SKILL.md +23 -1
- package/skills/gen-script/scripts/gen_script.py +644 -551
- package/skills/gen-script/skill.json +12 -0
- package/skills/gen-script/version.json +1 -1
- package/skills/prepare-video-assets/scripts/prepare_video_assets.py +21 -21
- package/skills/render-video/scripts/_chrome_vendor.py +17 -17
- package/skills/render-video/scripts/_digital_human_segments.py +34 -34
- package/skills/render-video/scripts/_video_probe.py +33 -33
- package/skills/render-video/scripts/_vod_polling.py +13 -13
- package/skills/render-video/scripts/remote_renderer_client.py +42 -42
- package/skills/render-video/scripts/render_video.py +639 -639
- package/skills/render-video/scripts/required_props.py +37 -37
- package/skills/render-video/scripts/upload_video.py +35 -35
- package/skills/render-video/version.json +1 -1
- package/skills/template-registry/SKILL.md +16 -0
- package/skills/template-registry/scripts/countdown_spec.py +92 -92
- package/skills/template-registry/scripts/doc_extract.py +40 -40
- package/skills/template-registry/scripts/list_templates.py +303 -191
- package/skills/template-registry/scripts/log_diagnostics.py +1 -1
- package/skills/template-registry/scripts/match_template.py +87 -87
- package/skills/template-registry/scripts/payload_hydrator.py +89 -89
- package/skills/template-registry/scripts/registry_loader.py +159 -159
- package/skills/template-registry/scripts/render_job_client.py +75 -75
- package/skills/template-registry/scripts/showcase_loader.py +44 -44
- package/skills/template-registry/skill.json +4 -1
- package/skills/template-registry/version.json +1 -1
- package/skills/template-registry/video_dsl/runtime/__init__.py +8 -8
- package/skills/template-registry/video_dsl/runtime/dsl_validator.py +329 -329
- package/skills/template-registry/video_dsl/runtime/narration_budget.py +36 -36
- package/skills/template-registry/video_dsl/runtime/payload_contract.py +7 -7
- package/skills/template-registry/video_dsl/runtime/prompt_enhancer.py +98 -98
- package/skills/template-registry/video_dsl/runtime/timeline_compiler.py +127 -127
- package/skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json +14 -1
- package/skills/video-parser/scripts/analyze_video.py +173 -173
- package/skills/video-parser/scripts/deconstruct_video.py +91 -91
- package/skills/video-parser/scripts/parse_via_render.py +21 -21
- package/skills/web-screenshot/scripts/_media_screenshot/__init__.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/bootstrap.py +7 -7
- package/skills/web-screenshot/scripts/_media_screenshot/browser.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/cli_args.py +4 -4
- package/skills/web-screenshot/scripts/_media_screenshot/js_loader.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/overlay.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/reader.py +40 -40
- package/skills/web-screenshot/scripts/_media_screenshot/recording.py +11 -11
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/__init__.py +8 -8
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/arrow.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/caption.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/click.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/code_lines.py +5 -5
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/focus.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/highlight.py +3 -3
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/hover.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/redact.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/scroll.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/sequence.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/title_card.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/type.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/wait.py +1 -1
- package/skills/web-screenshot/scripts/_media_screenshot/scenes/zoom.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/screenshot.py +15 -15
- package/skills/web-screenshot/scripts/_media_screenshot/storyboard.py +2 -2
- package/skills/web-screenshot/scripts/_media_screenshot/template.py +11 -11
- package/skills/web-screenshot/scripts/_media_screenshot/trim.py +10 -10
- package/skills/web-screenshot/scripts/_media_screenshot/urlguard.py +22 -22
- package/skills/web-screenshot/scripts/_media_upload.py +33 -33
- package/skills/web-screenshot/scripts/read_page.py +15 -15
- package/skills/web-screenshot/scripts/record.py +26 -26
- package/skills/web-screenshot/scripts/screenshot.py +5 -5
- package/dist/argv.d.ts +0 -15
- package/dist/auth/auth-lock.d.ts +0 -26
- package/dist/auth/auto-login.d.ts +0 -20
- package/dist/auth/commands.d.ts +0 -8
- package/dist/auth/credential-store.d.ts +0 -60
- package/dist/auth/device-flow-runner.d.ts +0 -58
- package/dist/auth/device-flow.d.ts +0 -52
- package/dist/auth/ensure.d.ts +0 -55
- package/dist/auth/environment.d.ts +0 -38
- package/dist/auth/pending-store.d.ts +0 -33
- package/dist/auth/resolve.d.ts +0 -30
- package/dist/billing.d.ts +0 -44
- package/dist/capabilities.d.ts +0 -63
- package/dist/cli.d.ts +0 -13
- package/dist/diagnostics.d.ts +0 -24
- package/dist/doctor.d.ts +0 -22
- package/dist/errors.d.ts +0 -29
- package/dist/exec.d.ts +0 -18
- package/dist/handlers/gen-digital-human.d.ts +0 -17
- package/dist/handlers/gen-image.d.ts +0 -20
- package/dist/handlers/gen-post.d.ts +0 -21
- package/dist/handlers/gen-video.d.ts +0 -19
- package/dist/handlers/gen-voice.d.ts +0 -26
- package/dist/handlers/index.d.ts +0 -20
- package/dist/handlers/shared.d.ts +0 -26
- package/dist/handlers/template-init.d.ts +0 -10
- package/dist/http.d.ts +0 -72
- package/dist/index.d.ts +0 -9
- package/dist/install.d.ts +0 -71
- package/dist/progress.d.ts +0 -23
- package/dist/project/commands.d.ts +0 -19
- package/dist/project/host.d.ts +0 -91
- package/dist/project/resolve.d.ts +0 -43
- package/dist/project/store.d.ts +0 -31
- package/dist/project/take.d.ts +0 -50
- package/dist/project/trace.d.ts +0 -98
- package/dist/registry.d.ts +0 -30
- package/dist/runner.d.ts +0 -39
- package/dist/skill-schema.d.ts +0 -138
- package/dist/template/args.d.ts +0 -25
- package/dist/template/check.d.ts +0 -23
- package/dist/template/commands.d.ts +0 -25
- package/dist/template/constants.d.ts +0 -39
- package/dist/template/init.d.ts +0 -28
- package/dist/template/list.d.ts +0 -23
- package/dist/template/preview.d.ts +0 -60
- package/dist/template/proc.d.ts +0 -26
- package/dist/template/project.d.ts +0 -47
- package/dist/template/publish.d.ts +0 -43
- package/dist/template/render-client.d.ts +0 -39
- package/dist/template/upgrade.d.ts +0 -44
- package/dist/text.d.ts +0 -8
package/LICENSE
CHANGED
|
@@ -1,21 +1,45 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
1
|
+
Remixmate Commercial License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Remixmate. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software, including its source code, object code, skill definitions,
|
|
6
|
+
scripts and documentation (the "Software"), is proprietary to Remixmate and is
|
|
7
|
+
protected by copyright law. The Software is licensed, not sold.
|
|
8
|
+
|
|
9
|
+
1. Grant of use. Subject to these terms and to the Remixmate Terms of Service
|
|
10
|
+
(https://www.remixmate.ai), Remixmate grants you a limited, non-exclusive,
|
|
11
|
+
non-transferable, non-sublicensable, revocable license to install and run
|
|
12
|
+
the Software, unmodified, solely to access Remixmate services with a valid
|
|
13
|
+
Remixmate account.
|
|
14
|
+
|
|
15
|
+
2. Restrictions. Except as expressly permitted above or required by applicable
|
|
16
|
+
law, you may not:
|
|
17
|
+
(a) copy, modify, translate or create derivative works of the Software;
|
|
18
|
+
(b) redistribute, sell, rent, lease, sublicense, publish or otherwise make
|
|
19
|
+
the Software available to any third party, including as part of another
|
|
20
|
+
product or service;
|
|
21
|
+
(c) reverse engineer, decompile, disassemble, deobfuscate or otherwise
|
|
22
|
+
attempt to derive the source code, algorithms or internal logic of the
|
|
23
|
+
Software;
|
|
24
|
+
(d) use the Software, or any part of it, to build a competing product or
|
|
25
|
+
service, or to access Remixmate services other than through the
|
|
26
|
+
interfaces the Software provides;
|
|
27
|
+
(e) remove or alter any copyright, license or proprietary notice.
|
|
28
|
+
|
|
29
|
+
3. Ownership. Remixmate retains all right, title and interest in and to the
|
|
30
|
+
Software. No rights are granted other than those expressly stated here.
|
|
31
|
+
|
|
32
|
+
4. Termination. This license terminates automatically if you breach any of its
|
|
33
|
+
terms or your Remixmate account is terminated. On termination you must stop
|
|
34
|
+
using and delete all copies of the Software.
|
|
35
|
+
|
|
36
|
+
5. Disclaimer. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
37
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
38
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
39
|
+
|
|
40
|
+
6. Limitation of liability. TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT
|
|
41
|
+
SHALL REMIXMATE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
42
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
43
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
44
|
+
|
|
45
|
+
For licensing inquiries, contact Remixmate via https://www.remixmate.ai.
|
package/README.md
CHANGED
|
@@ -316,4 +316,4 @@ remixmate template-registry --list-templates
|
|
|
316
316
|
|
|
317
317
|
## License
|
|
318
318
|
|
|
319
|
-
|
|
319
|
+
Commercial license, all rights reserved. You may install and run it unmodified with a valid Remixmate account; copying, modification, redistribution and reverse engineering are not permitted. See [LICENSE](./LICENSE).
|
package/README.zh-CN.md
CHANGED
package/dist/argv.js
CHANGED
|
@@ -1,51 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Argv parser shared by cli.ts and python passthrough.
|
|
3
|
-
*
|
|
4
|
-
* Convention (matches ab-agent's buildCliArgs):
|
|
5
|
-
* --foo-bar value → foo_bar: 'value'
|
|
6
|
-
* --foo-bar → foo_bar: true
|
|
7
|
-
* --foo-bar a --foo-bar b → foo_bar: ['a', 'b']
|
|
8
|
-
* -p value → short flags also supported as-is (kebab → snake)
|
|
9
|
-
*
|
|
10
|
-
* Booleans are detected when the next token starts with '--' or is absent.
|
|
11
|
-
* Negative number values (-1.5) are NOT supported as flag values in this
|
|
12
|
-
* parser — Python skills handle them via argparse downstream when needed.
|
|
13
|
-
*/
|
|
14
|
-
function flagToKey(flag) {
|
|
15
|
-
return flag.replace(/^--?/, '').replace(/-/g, '_');
|
|
16
|
-
}
|
|
17
|
-
export function parseArgv(argv) {
|
|
18
|
-
const out = {};
|
|
19
|
-
let i = 0;
|
|
20
|
-
while (i < argv.length) {
|
|
21
|
-
const token = argv[i];
|
|
22
|
-
if (!token.startsWith('-')) {
|
|
23
|
-
i++;
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
const key = flagToKey(token);
|
|
27
|
-
const next = argv[i + 1];
|
|
28
|
-
if (next === undefined || next.startsWith('--')) {
|
|
29
|
-
out[key] = true;
|
|
30
|
-
i++;
|
|
31
|
-
continue;
|
|
32
|
-
}
|
|
33
|
-
// Treat next token as value.
|
|
34
|
-
const existing = out[key];
|
|
35
|
-
if (existing === undefined) {
|
|
36
|
-
out[key] = next;
|
|
37
|
-
}
|
|
38
|
-
else if (Array.isArray(existing)) {
|
|
39
|
-
existing.push(next);
|
|
40
|
-
}
|
|
41
|
-
else if (typeof existing === 'string') {
|
|
42
|
-
out[key] = [existing, next];
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
// Was boolean — overwrite (last write wins; unusual case)
|
|
46
|
-
out[key] = next;
|
|
47
|
-
}
|
|
48
|
-
i += 2;
|
|
49
|
-
}
|
|
50
|
-
return out;
|
|
51
|
-
}
|
|
1
|
+
var f=Object.defineProperty;var o=(t,e)=>f(t,"name",{value:e,configurable:!0});function u(t){return t.replace(/^--?/,"").replace(/-/g,"_")}o(u,"flagToKey");function a(t){const e={};let n=0;for(;n<t.length;){const c=t[n];if(!c.startsWith("-")){n++;continue}const s=u(c),i=t[n+1];if(i===void 0||i.startsWith("--")){e[s]=!0,n++;continue}const r=e[s];r===void 0?e[s]=i:Array.isArray(r)?r.push(i):typeof r=="string"?e[s]=[r,i]:e[s]=i,n+=2}return e}o(a,"parseArgv");export{a as parseArgv};
|
package/dist/auth/auth-lock.js
CHANGED
|
@@ -1,100 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Cross-process file lock for the auto device-login flow.
|
|
3
|
-
*
|
|
4
|
-
* When several skill processes start without a token at the same time, only one
|
|
5
|
-
* should drive the Device Flow (= open one browser). The rest wait for the
|
|
6
|
-
* winner to write the credential, then read it. This lock coordinates that.
|
|
7
|
-
*
|
|
8
|
-
* The lock file lives next to the credential store, contains only non-secret
|
|
9
|
-
* metadata, and self-heals: a lock left behind by a crashed process is reclaimed
|
|
10
|
-
* once it is older than `staleMs` (Requirement 3.1/3.4/3.5).
|
|
11
|
-
*/
|
|
12
|
-
import { createHash } from 'node:crypto';
|
|
13
|
-
import { promises as fs } from 'node:fs';
|
|
14
|
-
import { join } from 'node:path';
|
|
15
|
-
import { CRED_DIR, getCredential } from './credential-store.js';
|
|
16
|
-
/** Stable short hash so different apiBaseUrls never block each other. */
|
|
17
|
-
function lockPathFor(apiBaseUrl) {
|
|
18
|
-
const hash = createHash('sha256').update(apiBaseUrl).digest('hex').slice(0, 12);
|
|
19
|
-
return join(CRED_DIR, `auth-${hash}.lock`);
|
|
20
|
-
}
|
|
21
|
-
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
22
|
-
async function writeLockFile(lockPath) {
|
|
23
|
-
const payload = { pid: process.pid, createdAt: Date.now() };
|
|
24
|
-
// `wx` fails if the file already exists → atomic acquire.
|
|
25
|
-
await fs.writeFile(lockPath, JSON.stringify(payload), { flag: 'wx', mode: 0o600 });
|
|
26
|
-
}
|
|
27
|
-
/** Best-effort removal; never throws. */
|
|
28
|
-
async function safeUnlink(lockPath) {
|
|
29
|
-
try {
|
|
30
|
-
await fs.unlink(lockPath);
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
// already gone / not ours — nothing to do
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Try to acquire the auth lock for `apiBaseUrl`.
|
|
38
|
-
* - Returns a handle when acquired.
|
|
39
|
-
* - Returns null when another live process holds it.
|
|
40
|
-
* - Reclaims a stale lock (older than `staleMs`) and retries once.
|
|
41
|
-
*/
|
|
42
|
-
export async function acquireLock(apiBaseUrl, staleMs) {
|
|
43
|
-
await fs.mkdir(CRED_DIR, { recursive: true, mode: 0o700 });
|
|
44
|
-
const lockPath = lockPathFor(apiBaseUrl);
|
|
45
|
-
try {
|
|
46
|
-
await writeLockFile(lockPath);
|
|
47
|
-
return makeHandle(lockPath);
|
|
48
|
-
}
|
|
49
|
-
catch {
|
|
50
|
-
// Lock exists — decide whether it is stale.
|
|
51
|
-
}
|
|
52
|
-
let stale = false;
|
|
53
|
-
try {
|
|
54
|
-
const stat = await fs.stat(lockPath);
|
|
55
|
-
stale = Date.now() - stat.mtimeMs > staleMs;
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
// Disappeared between the failed create and the stat → treat as free.
|
|
59
|
-
stale = true;
|
|
60
|
-
}
|
|
61
|
-
if (!stale)
|
|
62
|
-
return null;
|
|
63
|
-
// Reclaim the stale lock and retry exactly once.
|
|
64
|
-
await safeUnlink(lockPath);
|
|
65
|
-
try {
|
|
66
|
-
await writeLockFile(lockPath);
|
|
67
|
-
return makeHandle(lockPath);
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
// Someone else won the race after we cleared it.
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
function makeHandle(lockPath) {
|
|
75
|
-
let released = false;
|
|
76
|
-
return {
|
|
77
|
-
async release() {
|
|
78
|
-
if (released)
|
|
79
|
-
return;
|
|
80
|
-
released = true;
|
|
81
|
-
await safeUnlink(lockPath);
|
|
82
|
-
},
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Poll the credential store until a usable credential for `apiBaseUrl` appears
|
|
87
|
-
* or `timeoutMs` elapses. Used by processes that did NOT win the lock.
|
|
88
|
-
*/
|
|
89
|
-
export async function waitForCredential(apiBaseUrl, timeoutMs) {
|
|
90
|
-
const deadline = Date.now() + timeoutMs;
|
|
91
|
-
const intervalMs = 1_000;
|
|
92
|
-
while (Date.now() < deadline) {
|
|
93
|
-
const cred = await getCredential(apiBaseUrl);
|
|
94
|
-
if (cred && cred.privToken.trim())
|
|
95
|
-
return true;
|
|
96
|
-
await sleep(intervalMs);
|
|
97
|
-
}
|
|
98
|
-
const cred = await getCredential(apiBaseUrl);
|
|
99
|
-
return !!(cred && cred.privToken.trim());
|
|
100
|
-
}
|
|
1
|
+
var m=Object.defineProperty;var r=(t,e)=>m(t,"name",{value:e,configurable:!0});import{createHash as d}from"node:crypto";import{promises as o}from"node:fs";import{join as p}from"node:path";import{CRED_DIR as s,getCredential as l}from"./credential-store.js";function h(t){const e=d("sha256").update(t).digest("hex").slice(0,12);return p(s,`auth-${e}.lock`)}r(h,"lockPathFor");const k=r(t=>new Promise(e=>setTimeout(e,t)),"sleep");async function u(t){const e={pid:process.pid,createdAt:Date.now()};await o.writeFile(t,JSON.stringify(e),{flag:"wx",mode:384})}r(u,"writeLockFile");async function w(t){try{await o.unlink(t)}catch{}}r(w,"safeUnlink");async function F(t,e){await o.mkdir(s,{recursive:!0,mode:448});const a=h(t);try{return await u(a),f(a)}catch{}let n=!1;try{const i=await o.stat(a);n=Date.now()-i.mtimeMs>e}catch{n=!0}if(!n)return null;await w(a);try{return await u(a),f(a)}catch{return null}}r(F,"acquireLock");function f(t){let e=!1;return{async release(){e||(e=!0,await w(t))}}}r(f,"makeHandle");async function C(t,e){const a=Date.now()+e,n=1e3;for(;Date.now()<a;){const c=await l(t);if(c&&c.privToken.trim())return!0;await k(n)}const i=await l(t);return!!(i&&i.privToken.trim())}r(C,"waitForCredential");export{F as acquireLock,C as waitForCredential};
|
package/dist/auth/auto-login.js
CHANGED
|
@@ -1,75 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
* canAutoAuth gate → acquire lock
|
|
9
|
-
* ├─ won : runDeviceFlow(short wait) → on approval re-read the store
|
|
10
|
-
* └─ lost : wait for whoever holds the lock to write a credential
|
|
11
|
-
*
|
|
12
|
-
* Always bounded by `maxWaitMs` so it can never block a host tool call forever.
|
|
13
|
-
*/
|
|
14
|
-
import { resolvePrivToken } from './resolve.js';
|
|
15
|
-
import { canAutoAuth } from './environment.js';
|
|
16
|
-
import { acquireLock, waitForCredential } from './auth-lock.js';
|
|
17
|
-
import { runDeviceFlow } from './device-flow-runner.js';
|
|
18
|
-
/**
|
|
19
|
-
* How long a skill call waits for the user to approve in the browser.
|
|
20
|
-
*
|
|
21
|
-
* 90s, not 25s: when an agent host relays the link into a chat, the clock
|
|
22
|
-
* includes the user reading the message, switching to a browser and clicking —
|
|
23
|
-
* 25s reliably expired before a human could react. The ceiling is set by the
|
|
24
|
-
* host's own tool-call timeout (Claude Code's Bash tool defaults to 120s), so
|
|
25
|
-
* this must stay comfortably under that or the wait gets truncated anyway.
|
|
26
|
-
*/
|
|
27
|
-
const DEFAULT_WAIT_MS = 90_000;
|
|
28
|
-
/** Extra slack on top of the wait window before a held lock is considered stale. */
|
|
29
|
-
const STALE_SLACK_MS = 10_000;
|
|
30
|
-
/** Resolve the short-wait window from env, falling back to the default. */
|
|
31
|
-
function waitMs() {
|
|
32
|
-
const raw = Number(process.env.REMIXMATE_AUTH_WAIT_SECONDS);
|
|
33
|
-
return Number.isFinite(raw) && raw > 0 ? raw * 1000 : DEFAULT_WAIT_MS;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Attempt to obtain a token via automatic browser authorization. Returns the
|
|
37
|
-
* resolved token on success, or null when auto auth is not applicable / did not
|
|
38
|
-
* complete in time (callers then fail fast with NOT_AUTHENTICATED_HINT).
|
|
39
|
-
*/
|
|
40
|
-
export async function attemptAutoLogin(apiBaseUrl) {
|
|
41
|
-
if (!canAutoAuth())
|
|
42
|
-
return null;
|
|
43
|
-
const max = waitMs();
|
|
44
|
-
const lock = await acquireLock(apiBaseUrl, max + STALE_SLACK_MS);
|
|
45
|
-
if (!lock) {
|
|
46
|
-
// Another process is driving the Device Flow — wait for its credential.
|
|
47
|
-
process.stderr.write('ℹ️ 另一个进程正在授权,等待其完成…\n');
|
|
48
|
-
const ok = await waitForCredential(apiBaseUrl, max);
|
|
49
|
-
return ok ? resolvePrivToken({ apiBaseUrl }) : null;
|
|
50
|
-
}
|
|
51
|
-
try {
|
|
52
|
-
const outcome = await runDeviceFlow(apiBaseUrl, { maxWaitMs: max });
|
|
53
|
-
switch (outcome.status) {
|
|
54
|
-
case 'approved':
|
|
55
|
-
process.stderr.write(`✅ 授权成功:${outcome.userLabel ?? ''}\n`);
|
|
56
|
-
return resolvePrivToken({ apiBaseUrl });
|
|
57
|
-
case 'timeout':
|
|
58
|
-
process.stderr.write('⏳ 已打开授权页但未在等待窗口内完成。请在浏览器完成授权后重跑同一命令。\n');
|
|
59
|
-
return null;
|
|
60
|
-
case 'denied':
|
|
61
|
-
process.stderr.write('❌ 授权被拒绝。\n');
|
|
62
|
-
return null;
|
|
63
|
-
case 'expired':
|
|
64
|
-
process.stderr.write('❌ 设备码已过期,请重跑命令重新授权。\n');
|
|
65
|
-
return null;
|
|
66
|
-
case 'error':
|
|
67
|
-
default:
|
|
68
|
-
process.stderr.write(`❌ 自动授权失败:${'message' in outcome ? outcome.message : '未知错误'}\n`);
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
finally {
|
|
73
|
-
await lock.release();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
1
|
+
var i=Object.defineProperty;var n=(r,e)=>i(r,"name",{value:e,configurable:!0});import{resolvePrivToken as o}from"./resolve.js";import{canAutoAuth as c}from"./environment.js";import{acquireLock as u,waitForCredential as a}from"./auth-lock.js";import{runDeviceFlow as l}from"./device-flow-runner.js";const m=9e4,w=1e4;function d(){const r=Number(process.env.REMIXMATE_AUTH_WAIT_SECONDS);return Number.isFinite(r)&&r>0?r*1e3:m}n(d,"waitMs");async function L(r){if(!c())return null;const e=d(),s=await u(r,e+w);if(!s)return process.stderr.write(`ℹ️ 另一个进程正在授权,等待其完成…
|
|
2
|
+
`),await a(r,e)?o({apiBaseUrl:r}):null;try{const t=await l(r,{maxWaitMs:e});switch(t.status){case"approved":return process.stderr.write(`✅ 授权成功:${t.userLabel??""}
|
|
3
|
+
`),o({apiBaseUrl:r});case"timeout":return process.stderr.write(`⏳ 已打开授权页但未在等待窗口内完成。请在浏览器完成授权后重跑同一命令。
|
|
4
|
+
`),null;case"denied":return process.stderr.write(`❌ 授权被拒绝。
|
|
5
|
+
`),null;case"expired":return process.stderr.write(`❌ 设备码已过期,请重跑命令重新授权。
|
|
6
|
+
`),null;default:return process.stderr.write(`❌ 自动授权失败:${"message"in t?t.message:"未知错误"}
|
|
7
|
+
`),null}}finally{await s.release()}}n(L,"attemptAutoLogin");export{L as attemptAutoLogin};
|