@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 +45 -0
- package/build/_shared.mjs +54 -5
- package/build/prod.mjs +12 -3
- package/package.json +2 -2
- package/packages/awb-cli/package.json +2 -2
- package/packages/awb-core/package.json +1 -1
- package/packages/awb-core/src/api.js +31 -0
- package/packages/awb-core/src/commands.js +141 -39
- package/packages/awb-core/src/common.js +20 -0
- package/packages/awb-core/src/output.js +176 -9
- package/packages/awb-core/src/services.js +1767 -198
- package/packages/awb-core/src/standalone.js +116 -12
- package/packages/awb-core/src/update.js +327 -0
- package/skills/lj-awb/SKILL.md +30 -9
- package/skills/lj-awb/VERSION +1 -1
- package/skills/lj-awb/compat.json +3 -3
- package/skills/lj-awb/modules/asset.md +10 -1
- package/skills/lj-awb/modules/auth.md +9 -1
- package/skills/lj-awb/modules/create-contract.md +5 -2
- package/skills/lj-awb/modules/create.md +4 -2
- package/skills/lj-awb/modules/credits.md +19 -2
- package/skills/lj-awb/modules/driver.md +1 -0
- package/skills/lj-awb/modules/image.md +3 -1
- package/skills/lj-awb/modules/model.md +5 -4
- package/skills/lj-awb/modules/task.md +4 -1
- package/skills/lj-awb/modules/upload.md +1 -1
- package/skills/lj-awb/modules/video.md +11 -2
- package/skills/lj-awb/modules/workflows.md +3 -1
- package/skills/lj-awb/references/error-codes.md +41 -0
- package/skills/lj-awb/references/model-options-read.md +7 -6
- package/skills/lj-awb/references/output-fields.md +10 -5
- package/skills/lj-awb/scripts/resolve-lj-awb-cmd.sh +106 -4
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(
|
|
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.
|
|
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.
|
|
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.
|
|
16
|
+
"@lingjingai/awb-core": "0.4.6"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -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,
|