@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.
Files changed (181) hide show
  1. package/LICENSE +45 -21
  2. package/README.md +1 -1
  3. package/README.zh-CN.md +1 -1
  4. package/dist/argv.js +1 -51
  5. package/dist/auth/auth-lock.js +1 -100
  6. package/dist/auth/auto-login.js +7 -75
  7. package/dist/auth/commands.js +40 -290
  8. package/dist/auth/credential-store.js +1 -143
  9. package/dist/auth/device-flow-runner.js +13 -110
  10. package/dist/auth/device-flow.js +1 -132
  11. package/dist/auth/ensure.js +1 -62
  12. package/dist/auth/environment.js +1 -69
  13. package/dist/auth/pending-store.js +1 -45
  14. package/dist/auth/resolve.js +1 -44
  15. package/dist/billing.js +3 -76
  16. package/dist/capabilities.js +1 -75
  17. package/dist/cli.js +39 -211
  18. package/dist/diagnostics.js +2 -70
  19. package/dist/doctor.js +9 -188
  20. package/dist/errors.js +1 -33
  21. package/dist/exec.js +4 -47
  22. package/dist/handlers/gen-digital-human.js +33 -264
  23. package/dist/handlers/gen-image.js +9 -113
  24. package/dist/handlers/gen-post.js +15 -188
  25. package/dist/handlers/gen-video.js +7 -185
  26. package/dist/handlers/gen-voice.js +19 -133
  27. package/dist/handlers/index.js +1 -20
  28. package/dist/handlers/shared.js +1 -66
  29. package/dist/handlers/template-init.js +1 -21
  30. package/dist/http.js +3 -155
  31. package/dist/index.js +1 -8
  32. package/dist/install.js +40 -448
  33. package/dist/manifest.json +53 -13
  34. package/dist/progress.js +2 -15
  35. package/dist/project/commands.js +34 -156
  36. package/dist/project/host.js +1 -151
  37. package/dist/project/resolve.js +1 -65
  38. package/dist/project/store.js +2 -97
  39. package/dist/project/take.js +1 -106
  40. package/dist/project/trace.js +5 -278
  41. package/dist/registry.js +3 -70
  42. package/dist/runner.js +7 -225
  43. package/dist/skill-schema.js +1 -194
  44. package/dist/template/args.js +1 -69
  45. package/dist/template/check.js +2 -30
  46. package/dist/template/commands.js +34 -163
  47. package/dist/template/constants.js +1 -46
  48. package/dist/template/init.js +5 -133
  49. package/dist/template/list.js +1 -46
  50. package/dist/template/preview.js +7 -318
  51. package/dist/template/proc.js +1 -43
  52. package/dist/template/project.js +6 -161
  53. package/dist/template/publish.js +5 -185
  54. package/dist/template/render-client.js +2 -79
  55. package/dist/template/upgrade.js +4 -123
  56. package/dist/text.js +1 -15
  57. package/package.json +2 -35
  58. package/skills/doc-parse/scripts/extract_via_render.py +32 -32
  59. package/skills/export-jianying/scripts/gen_jianying_draft.py +188 -188
  60. package/skills/gen-post/SKILL.md +23 -13
  61. package/skills/gen-post/skill.json +9 -10
  62. package/skills/gen-script/SKILL.md +23 -1
  63. package/skills/gen-script/scripts/gen_script.py +644 -551
  64. package/skills/gen-script/skill.json +12 -0
  65. package/skills/gen-script/version.json +1 -1
  66. package/skills/prepare-video-assets/scripts/prepare_video_assets.py +21 -21
  67. package/skills/render-video/scripts/_chrome_vendor.py +17 -17
  68. package/skills/render-video/scripts/_digital_human_segments.py +34 -34
  69. package/skills/render-video/scripts/_video_probe.py +33 -33
  70. package/skills/render-video/scripts/_vod_polling.py +13 -13
  71. package/skills/render-video/scripts/remote_renderer_client.py +42 -42
  72. package/skills/render-video/scripts/render_video.py +639 -639
  73. package/skills/render-video/scripts/required_props.py +37 -37
  74. package/skills/render-video/scripts/upload_video.py +35 -35
  75. package/skills/render-video/version.json +1 -1
  76. package/skills/template-registry/SKILL.md +16 -0
  77. package/skills/template-registry/scripts/countdown_spec.py +92 -92
  78. package/skills/template-registry/scripts/doc_extract.py +40 -40
  79. package/skills/template-registry/scripts/list_templates.py +303 -191
  80. package/skills/template-registry/scripts/log_diagnostics.py +1 -1
  81. package/skills/template-registry/scripts/match_template.py +87 -87
  82. package/skills/template-registry/scripts/payload_hydrator.py +89 -89
  83. package/skills/template-registry/scripts/registry_loader.py +159 -159
  84. package/skills/template-registry/scripts/render_job_client.py +75 -75
  85. package/skills/template-registry/scripts/showcase_loader.py +44 -44
  86. package/skills/template-registry/skill.json +4 -1
  87. package/skills/template-registry/version.json +1 -1
  88. package/skills/template-registry/video_dsl/runtime/__init__.py +8 -8
  89. package/skills/template-registry/video_dsl/runtime/dsl_validator.py +329 -329
  90. package/skills/template-registry/video_dsl/runtime/narration_budget.py +36 -36
  91. package/skills/template-registry/video_dsl/runtime/payload_contract.py +7 -7
  92. package/skills/template-registry/video_dsl/runtime/prompt_enhancer.py +98 -98
  93. package/skills/template-registry/video_dsl/runtime/timeline_compiler.py +127 -127
  94. package/skills/template-registry/video_dsl/schema/video-dsl-v1alpha1.json +14 -1
  95. package/skills/video-parser/scripts/analyze_video.py +173 -173
  96. package/skills/video-parser/scripts/deconstruct_video.py +91 -91
  97. package/skills/video-parser/scripts/parse_via_render.py +21 -21
  98. package/skills/web-screenshot/scripts/_media_screenshot/__init__.py +4 -4
  99. package/skills/web-screenshot/scripts/_media_screenshot/bootstrap.py +7 -7
  100. package/skills/web-screenshot/scripts/_media_screenshot/browser.py +4 -4
  101. package/skills/web-screenshot/scripts/_media_screenshot/cli_args.py +4 -4
  102. package/skills/web-screenshot/scripts/_media_screenshot/js_loader.py +2 -2
  103. package/skills/web-screenshot/scripts/_media_screenshot/overlay.py +1 -1
  104. package/skills/web-screenshot/scripts/_media_screenshot/reader.py +40 -40
  105. package/skills/web-screenshot/scripts/_media_screenshot/recording.py +11 -11
  106. package/skills/web-screenshot/scripts/_media_screenshot/scenes/__init__.py +8 -8
  107. package/skills/web-screenshot/scripts/_media_screenshot/scenes/arrow.py +2 -2
  108. package/skills/web-screenshot/scripts/_media_screenshot/scenes/caption.py +1 -1
  109. package/skills/web-screenshot/scripts/_media_screenshot/scenes/click.py +1 -1
  110. package/skills/web-screenshot/scripts/_media_screenshot/scenes/code_lines.py +5 -5
  111. package/skills/web-screenshot/scripts/_media_screenshot/scenes/focus.py +1 -1
  112. package/skills/web-screenshot/scripts/_media_screenshot/scenes/highlight.py +3 -3
  113. package/skills/web-screenshot/scripts/_media_screenshot/scenes/hover.py +1 -1
  114. package/skills/web-screenshot/scripts/_media_screenshot/scenes/redact.py +1 -1
  115. package/skills/web-screenshot/scripts/_media_screenshot/scenes/scroll.py +1 -1
  116. package/skills/web-screenshot/scripts/_media_screenshot/scenes/sequence.py +1 -1
  117. package/skills/web-screenshot/scripts/_media_screenshot/scenes/title_card.py +1 -1
  118. package/skills/web-screenshot/scripts/_media_screenshot/scenes/type.py +1 -1
  119. package/skills/web-screenshot/scripts/_media_screenshot/scenes/wait.py +1 -1
  120. package/skills/web-screenshot/scripts/_media_screenshot/scenes/zoom.py +2 -2
  121. package/skills/web-screenshot/scripts/_media_screenshot/screenshot.py +15 -15
  122. package/skills/web-screenshot/scripts/_media_screenshot/storyboard.py +2 -2
  123. package/skills/web-screenshot/scripts/_media_screenshot/template.py +11 -11
  124. package/skills/web-screenshot/scripts/_media_screenshot/trim.py +10 -10
  125. package/skills/web-screenshot/scripts/_media_screenshot/urlguard.py +22 -22
  126. package/skills/web-screenshot/scripts/_media_upload.py +33 -33
  127. package/skills/web-screenshot/scripts/read_page.py +15 -15
  128. package/skills/web-screenshot/scripts/record.py +26 -26
  129. package/skills/web-screenshot/scripts/screenshot.py +5 -5
  130. package/dist/argv.d.ts +0 -15
  131. package/dist/auth/auth-lock.d.ts +0 -26
  132. package/dist/auth/auto-login.d.ts +0 -20
  133. package/dist/auth/commands.d.ts +0 -8
  134. package/dist/auth/credential-store.d.ts +0 -60
  135. package/dist/auth/device-flow-runner.d.ts +0 -58
  136. package/dist/auth/device-flow.d.ts +0 -52
  137. package/dist/auth/ensure.d.ts +0 -55
  138. package/dist/auth/environment.d.ts +0 -38
  139. package/dist/auth/pending-store.d.ts +0 -33
  140. package/dist/auth/resolve.d.ts +0 -30
  141. package/dist/billing.d.ts +0 -44
  142. package/dist/capabilities.d.ts +0 -63
  143. package/dist/cli.d.ts +0 -13
  144. package/dist/diagnostics.d.ts +0 -24
  145. package/dist/doctor.d.ts +0 -22
  146. package/dist/errors.d.ts +0 -29
  147. package/dist/exec.d.ts +0 -18
  148. package/dist/handlers/gen-digital-human.d.ts +0 -17
  149. package/dist/handlers/gen-image.d.ts +0 -20
  150. package/dist/handlers/gen-post.d.ts +0 -21
  151. package/dist/handlers/gen-video.d.ts +0 -19
  152. package/dist/handlers/gen-voice.d.ts +0 -26
  153. package/dist/handlers/index.d.ts +0 -20
  154. package/dist/handlers/shared.d.ts +0 -26
  155. package/dist/handlers/template-init.d.ts +0 -10
  156. package/dist/http.d.ts +0 -72
  157. package/dist/index.d.ts +0 -9
  158. package/dist/install.d.ts +0 -71
  159. package/dist/progress.d.ts +0 -23
  160. package/dist/project/commands.d.ts +0 -19
  161. package/dist/project/host.d.ts +0 -91
  162. package/dist/project/resolve.d.ts +0 -43
  163. package/dist/project/store.d.ts +0 -31
  164. package/dist/project/take.d.ts +0 -50
  165. package/dist/project/trace.d.ts +0 -98
  166. package/dist/registry.d.ts +0 -30
  167. package/dist/runner.d.ts +0 -39
  168. package/dist/skill-schema.d.ts +0 -138
  169. package/dist/template/args.d.ts +0 -25
  170. package/dist/template/check.d.ts +0 -23
  171. package/dist/template/commands.d.ts +0 -25
  172. package/dist/template/constants.d.ts +0 -39
  173. package/dist/template/init.d.ts +0 -28
  174. package/dist/template/list.d.ts +0 -23
  175. package/dist/template/preview.d.ts +0 -60
  176. package/dist/template/proc.d.ts +0 -26
  177. package/dist/template/project.d.ts +0 -47
  178. package/dist/template/publish.d.ts +0 -43
  179. package/dist/template/render-client.d.ts +0 -39
  180. package/dist/template/upgrade.d.ts +0 -44
  181. package/dist/text.d.ts +0 -8
package/LICENSE CHANGED
@@ -1,21 +1,45 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 aibearer
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
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
- MIT
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
@@ -256,4 +256,4 @@ remixmate template-registry --list-templates
256
256
 
257
257
  ## 许可证
258
258
 
259
- MIT
259
+ 商业许可,保留所有权利。仅允许在持有有效 Remixmate 账号的前提下安装并原样使用,禁止复制、修改、再分发和逆向工程。详见 [LICENSE](./LICENSE)。
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};
@@ -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};
@@ -1,75 +1,7 @@
1
- /**
2
- * Automatic Device Flow orchestration triggered when a skill call finds no
3
- * token. Only ever invoked AFTER resolvePrivToken() has confirmed all three
4
- * sources (flag / env / credential store) are empty, so the env-injected
5
- * (cloud) path never reaches this module — guaranteeing zero regression there.
6
- *
7
- * Flow (see design.md):
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};