@lingjingai/lj-awb-cli-pre 0.4.0 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,6 +63,18 @@ lj-awb auth verify
63
63
 
64
64
  可用 `LINGJING_AWB_SKILL_INSTALL_DIR` 指定单一安装目录;如果传入的是以 `skills` 结尾的根目录,安装器会自动追加 `lj-awb`。也可用 `LINGJING_AWB_SKIP_SKILL_INSTALL=1` 跳过 skill 安装。
65
65
 
66
+ 只分发 skill 也可以作为完整入口:`skills/lj-awb/scripts/resolve-lj-awb-cmd.sh` 会在首次使用时检查 `lj-awb`,缺失或版本低于 `skills/lj-awb/compat.json` 的 `minCliVersion` 时自动执行:
67
+
68
+ ```bash
69
+ npm install -g @lingjingai/lj-awb-cli@<minCliVersion>
70
+ ```
71
+
72
+ 预发环境可在 bootstrap 前设置:
73
+
74
+ ```bash
75
+ export LINGJING_AWB_CLI_PACKAGE=@lingjingai/lj-awb-cli-pre
76
+ ```
77
+
66
78
  源码运行:
67
79
 
68
80
  ```bash
@@ -75,8 +87,37 @@ packages/awb-cli/bin/lj-awb auth status
75
87
 
76
88
  macOS 本地 wrapper `packages/awb-cli/bin/lj-awb` 会自动补充 Node 证书链,适合直接调试 HTTPS 平台接口。
77
89
 
90
+ 自动更新检查默认每天最多访问一次 npm registry,并会在源码 checkout、CI 或设置 `LINGJING_AWB_DISABLE_UPDATE_CHECK=1` / `AWB_DISABLE_UPDATE_CHECK=1` 时跳过。调试时可用 `LINGJING_AWB_UPDATE_CHECK=force` 强制检查。
91
+
78
92
  ## 认证
79
93
 
94
+ ### 浏览器授权登录(推荐)
95
+
96
+ 不需要手动复制 access key,直接登录:
97
+
98
+ ```bash
99
+ lj-awb auth login
100
+ ```
101
+
102
+ CLI 会创建登录任务、展示授权链接,等你在浏览器登录并确认授权后,自动拿到 access key 并保存到本地。命令默认阻塞轮询,最长约 10 分钟。
103
+
104
+ AI agent / 无法实时查看命令输出的场景,分两步走(避免阻塞):
105
+
106
+ ```bash
107
+ lj-awb auth login --no-wait --json # 返回 flowId / verifyUrl,把链接给用户去授权
108
+ lj-awb auth login --flow-id <flowId> # 用户授权后续轮询,拿到并保存 access key
109
+ ```
110
+
111
+ > 不要重复执行不带 `--flow-id` 的 login,否则会生成新的 flowId 导致旧授权链接失效。
112
+
113
+ 退出登录(清除本地 access key):
114
+
115
+ ```bash
116
+ lj-awb auth logout
117
+ ```
118
+
119
+ ### 直接使用 access key
120
+
80
121
  保存 access key 到本地认证文件:
81
122
 
82
123
  ```bash
@@ -110,6 +151,8 @@ lj-awb account info
110
151
  ```bash
111
152
  lj-awb doctor
112
153
  lj-awb doctor --verify
154
+ lj-awb update --check
155
+ lj-awb update
113
156
  lj-awb schema --brief -f json
114
157
  lj-awb schema -f json
115
158
  lj-awb schema --domain create -f json
@@ -159,6 +202,8 @@ lj-awb doctor --verify
159
202
 
160
203
  `auth status` 只检查本地是否配置 access key;`auth verify` 会联网校验 key 是否远端有效。`doctor` 默认只做本地检查;追加 `--verify` 后会联网校验 access key、当前用户和项目组。精确 `schema` 返回每个命令的 `options[].key`,Agent 应使用这些 key 生成 CLI 参数,而不是解析自然语言 help。
161
204
 
205
+ `lj-awb` 在普通命令结束后会做非阻塞更新检查;如果有新版本,JSON 输出会在 `meta._notice.update` 里带上更新提示。Skill / Agent 看到这个提示后,应在完成当前任务后告诉用户当前版本和最新版本,并建议或直接运行 `lj-awb update`。真正安装更新只走显式 `lj-awb update`,`--check` 只检查不安装。
206
+
162
207
  `schema` 还包含面向 Agent 的执行约束:
163
208
 
164
209
  - `requiredOptions`:必须提供的参数 key。
package/build/_shared.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync } from 'node:child_process';
3
- import { cpSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
3
+ import { cpSync, mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
+ import os from 'node:os';
4
5
  import path from 'node:path';
5
6
  import { fileURLToPath } from 'node:url';
6
7
 
@@ -19,13 +20,16 @@ export function run(command, args, options = {}) {
19
20
  process.stderr.write(`$ ${[command, ...args].join(' ')}\n`);
20
21
  const result = spawnSync(command, args, {
21
22
  cwd: options.cwd || repoRoot,
23
+ env: options.env ? { ...process.env, ...options.env } : process.env,
22
24
  stdio: 'inherit',
23
25
  });
24
26
  if (result.error) {
27
+ options.beforeExit?.();
25
28
  process.stderr.write(`${result.error.message}\n`);
26
29
  process.exit(1);
27
30
  }
28
31
  if (result.status !== 0) {
32
+ options.beforeExit?.();
29
33
  process.exit(result.status || 1);
30
34
  }
31
35
  }
@@ -33,11 +37,53 @@ export function run(command, args, options = {}) {
33
37
  export function capture(command, args, options = {}) {
34
38
  return spawnSync(command, args, {
35
39
  cwd: options.cwd || repoRoot,
40
+ env: options.env ? { ...process.env, ...options.env } : process.env,
36
41
  encoding: 'utf8',
37
42
  stdio: ['inherit', 'pipe', 'pipe'],
38
43
  });
39
44
  }
40
45
 
46
+ export function createNpmPublishAuthConfig(registry) {
47
+ const tokenSource = ['NPM_PUBLISH_TOKEN', 'NPM_TOKEN', 'NODE_AUTH_TOKEN']
48
+ .find((name) => process.env[name]?.trim());
49
+ if (!tokenSource) {
50
+ return {
51
+ env: {},
52
+ cleanup() {},
53
+ tokenSource: null,
54
+ };
55
+ }
56
+
57
+ const token = process.env[tokenSource].trim();
58
+ const normalizedRegistry = registry.endsWith('/') ? registry : `${registry}/`;
59
+ const registryUrl = new URL(normalizedRegistry);
60
+ const registryPath = registryUrl.pathname.endsWith('/') ? registryUrl.pathname : `${registryUrl.pathname}/`;
61
+ const npmrcDir = mkdtempSync(path.join(os.tmpdir(), 'lj-awb-npm-'));
62
+ const npmrcPath = path.join(npmrcDir, '.npmrc');
63
+ writeFileSync(
64
+ npmrcPath,
65
+ [
66
+ `registry=${normalizedRegistry}`,
67
+ `//${registryUrl.host}${registryPath}:_authToken=${token}`,
68
+ 'strict-ssl=false',
69
+ 'always-auth=true',
70
+ '',
71
+ ].join('\n'),
72
+ { mode: 0o600 },
73
+ );
74
+
75
+ return {
76
+ env: {
77
+ NPM_CONFIG_USERCONFIG: npmrcPath,
78
+ NPM_CONFIG_REGISTRY: normalizedRegistry,
79
+ },
80
+ cleanup() {
81
+ rmSync(npmrcDir, { recursive: true, force: true });
82
+ },
83
+ tokenSource,
84
+ };
85
+ }
86
+
41
87
  export function packageFilePaths(cwd = repoRoot) {
42
88
  const result = capture('npm', ['pack', '--dry-run', '--json'], { cwd });
43
89
  if (result.error) {
@@ -101,12 +147,13 @@ export function packTarball(stageDir) {
101
147
  return path.join(stageDir, tarball);
102
148
  }
103
149
 
104
- export function ensureLoggedIn(registry) {
105
- const result = capture('npm', ['whoami', `--registry=${registry}`]);
150
+ export function ensureLoggedIn(registry, options = {}) {
151
+ const result = capture('npm', ['whoami', `--registry=${registry}`], { env: options.env });
106
152
  if (result.status === 0) {
107
153
  process.stderr.write(`npm user: ${result.stdout.trim()}\n`);
108
154
  return;
109
155
  }
156
+ options.beforeExit?.();
110
157
  process.stderr.write([
111
158
  `npm is not logged in for ${registry}.`,
112
159
  `Run: npm login --registry=${registry}`,
@@ -115,14 +162,16 @@ export function ensureLoggedIn(registry) {
115
162
  process.exit(1);
116
163
  }
117
164
 
118
- export function ensureVersionNotPublished({ name, version, registry }) {
165
+ export function ensureVersionNotPublished({ name, version, registry }, options = {}) {
119
166
  const spec = `${name}@${version}`;
120
- const result = capture('npm', ['view', spec, 'version', `--registry=${registry}`]);
167
+ const result = capture('npm', ['view', spec, 'version', `--registry=${registry}`], { env: options.env });
121
168
  if (result.status === 0) {
169
+ options.beforeExit?.();
122
170
  process.stderr.write(`${spec} already exists on npm. Bump the version before publishing.\n`);
123
171
  process.exit(1);
124
172
  }
125
173
  if (!/E404|404 Not Found|Not found/i.test(`${result.stderr}\n${result.stdout}`)) {
174
+ options.beforeExit?.();
126
175
  process.stderr.write(`Could not verify whether ${spec} exists on npm.\n`);
127
176
  process.stderr.write(result.stderr || result.stdout || '');
128
177
  process.exit(1);
package/build/prod.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
  import { readFileSync } from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import {
5
+ createNpmPublishAuthConfig,
5
6
  ensureLoggedIn,
6
7
  ensureVersionNotPublished,
7
8
  findArgValue,
@@ -33,14 +34,21 @@ function ensureProductionDefaultApiOrigin() {
33
34
  ensureProductionDefaultApiOrigin();
34
35
 
35
36
  process.stderr.write(`Preparing ${pkg.name}@${pkg.version} for npm ${dryRun ? 'dry-run' : 'publish'} with default API origin ${PROD_API_ORIGIN}.\n`);
37
+ const publishAuth = createNpmPublishAuthConfig(registry);
38
+ if (!dryRun && publishAuth.tokenSource) {
39
+ process.stderr.write(`Using npm publish token from ${publishAuth.tokenSource}; NPM_CONFIG_USERCONFIG points to an isolated temporary npmrc.\n`);
40
+ }
36
41
 
37
42
  if (process.env.SKIP_CHECK !== '1') {
38
43
  run('npm', ['run', 'check:local']);
39
44
  }
40
45
 
41
- ensureVersionNotPublished({ name: pkg.name, version: pkg.version, registry });
46
+ ensureVersionNotPublished(
47
+ { name: pkg.name, version: pkg.version, registry },
48
+ { env: publishAuth.env, beforeExit: publishAuth.cleanup },
49
+ );
42
50
  if (!dryRun) {
43
- ensureLoggedIn(registry);
51
+ ensureLoggedIn(registry, { env: publishAuth.env, beforeExit: publishAuth.cleanup });
44
52
  }
45
53
 
46
54
  run('npm', [
@@ -49,4 +57,5 @@ run('npm', [
49
57
  'public',
50
58
  `--registry=${registry}`,
51
59
  ...passthroughArgs,
52
- ]);
60
+ ], { env: publishAuth.env, beforeExit: publishAuth.cleanup });
61
+ publishAuth.cleanup();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingjingai/lj-awb-cli-pre",
3
- "version": "0.4.0",
3
+ "version": "0.4.6",
4
4
  "description": "Lingjing AWB CLI monorepo with shared core, standalone CLI, and agent skills (pre-release build pointing to https://animeworkbench-pre.lingjingai.cn)",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -23,7 +23,7 @@
23
23
  "build:pre-publish": "node build/pre-publish.mjs",
24
24
  "build:prod": "node build/prod.mjs",
25
25
  "check": "npm run check:local && npm run check:real",
26
- "check:local": "node --check install.mjs && node --check packages/awb-core/src/common.js && node --check packages/awb-core/src/api.js && node --check packages/awb-core/src/artifact.js && node --check packages/awb-core/src/auth.js && node --check packages/awb-core/src/output.js && node --check packages/awb-core/src/services.js && node --check packages/awb-core/src/commands.js && node --check packages/awb-core/src/standalone.js && sh -n packages/awb-cli/bin/lj-awb && node --check packages/awb-cli/bin/lj-awb.js && node --check build/build.mjs && node --check build/_shared.mjs && node --check build/pre.mjs && node --check build/pre-publish.mjs && node --check build/prod.mjs && node --check scripts/run-openapi-cli-examples-real.mjs && node --check scripts/validate-cli-schema.mjs && node --check scripts/validate-cli-output-contract.mjs && node --check scripts/validate-cli-command-coverage.mjs && node scripts/validate-skill-meta.mjs && node scripts/validate-cli-schema.mjs && node scripts/validate-cli-command-coverage.mjs",
26
+ "check:local": "node --check install.mjs && node --check packages/awb-core/src/common.js && node --check packages/awb-core/src/api.js && node --check packages/awb-core/src/artifact.js && node --check packages/awb-core/src/auth.js && node --check packages/awb-core/src/output.js && node --check packages/awb-core/src/update.js && node --check packages/awb-core/src/services.js && node --check packages/awb-core/src/commands.js && node --check packages/awb-core/src/standalone.js && sh -n packages/awb-cli/bin/lj-awb && bash -n skills/lj-awb/scripts/resolve-lj-awb-cmd.sh && node --check packages/awb-cli/bin/lj-awb.js && node --check build/build.mjs && node --check build/_shared.mjs && node --check build/pre.mjs && node --check build/pre-publish.mjs && node --check build/prod.mjs && node --check scripts/run-openapi-cli-examples-real.mjs && node --check scripts/validate-cli-schema.mjs && node --check scripts/validate-cli-output-contract.mjs && node --check scripts/validate-cli-command-coverage.mjs && node scripts/validate-skill-meta.mjs && node scripts/validate-cli-schema.mjs && node scripts/validate-cli-command-coverage.mjs",
27
27
  "check:real": "node scripts/validate-cli-output-contract.mjs && node scripts/validate-openapi-cli-examples.mjs",
28
28
  "test:openapi-real": "node scripts/run-openapi-cli-examples-real.mjs",
29
29
  "smoke": "packages/awb-cli/bin/lj-awb --help && packages/awb-cli/bin/lj-awb auth status -f json && packages/awb-cli/bin/lj-awb system && packages/awb-cli/bin/lj-awb auth && packages/awb-cli/bin/lj-awb account && packages/awb-cli/bin/lj-awb project && packages/awb-cli/bin/lj-awb credits && packages/awb-cli/bin/lj-awb upload && packages/awb-cli/bin/lj-awb model && packages/awb-cli/bin/lj-awb create && packages/awb-cli/bin/lj-awb task && packages/awb-cli/bin/lj-awb artifact && packages/awb-cli/bin/lj-awb schema -f json >/dev/null",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingjingai/awb-cli-bin",
3
- "version": "0.4.0",
3
+ "version": "0.4.6",
4
4
  "description": "Standalone CLI for Lingjing AWB",
5
5
  "private": true,
6
6
  "license": "MIT",
@@ -13,6 +13,6 @@
13
13
  "README.md"
14
14
  ],
15
15
  "dependencies": {
16
- "@lingjingai/awb-core": "0.4.0"
16
+ "@lingjingai/awb-core": "0.4.6"
17
17
  }
18
18
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingjingai/awb-core",
3
- "version": "0.4.0",
3
+ "version": "0.4.6",
4
4
  "description": "Shared core runtime for Lingjing AWB CLI",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -109,6 +109,14 @@ export async function fetchUserInfo() {
109
109
  return await apiFetch('/api/anime/user/account/userInfo', { body: {} });
110
110
  }
111
111
 
112
+ export async function createLoginFlow() {
113
+ return await apiFetch('/api/anime/user/cli/createLoginFlow', { body: {}, auth: false });
114
+ }
115
+
116
+ export async function queryLoginFlowStatus(flowId) {
117
+ return await apiFetch('/api/anime/user/cli/queryFlowStatus', { body: { flowId }, auth: false });
118
+ }
119
+
112
120
  export async function fetchTeams() {
113
121
  return await apiFetch('/api/anime/user/group/getOwnGroupList', { body: {} });
114
122
  }
@@ -125,6 +133,15 @@ export async function fetchPoints() {
125
133
  return await apiFetch('/api/anime/member/benefits/queryGroupPoint', { body: {} });
126
134
  }
127
135
 
136
+ export async function redeemCode(code) {
137
+ // 后端 redeemCode 的 code 是无注解 Spring 参数(按 query / form 绑定,不读 JSON body),
138
+ // 且必须带 userId / groupId 请求头(由 buildHeaders 从环境变量注入)。
139
+ return await apiFetch('/api/anime/member/redemption/redeemCode', {
140
+ method: 'POST',
141
+ query: { code },
142
+ });
143
+ }
144
+
128
145
  export async function selectProjectGroup(projectGroupNo) {
129
146
  return await apiFetch('/api/anime/workbench/projectGroup/setLastProjectGroup', {
130
147
  body: { projectGroupNo },
@@ -230,6 +247,20 @@ export async function createVideoSubtitleRemovalTask(payload = {}) {
230
247
  return await apiFetch('/api/material/creation/videoSubtitleRemoval', { body: payload });
231
248
  }
232
249
 
250
+ export async function fetchVideoSuperResolutionFee(payload = {}) {
251
+ return await apiFetch('/api/material/creation/videoUpResolutionCal', {
252
+ method: 'GET',
253
+ query: payload,
254
+ });
255
+ }
256
+
257
+ export async function createVideoSuperResolutionTask(payload = {}) {
258
+ return await apiFetch('/api/material/creation/videoUpResolution', {
259
+ method: 'POST',
260
+ query: payload,
261
+ });
262
+ }
263
+
233
264
  export async function fetchTaskFeed(payload = {}) {
234
265
  return await apiFetch('/api/material/creation/task/feedPull', {
235
266
  query: payload,