@qfeius/everyline-cli 0.1.0
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 +81 -0
- package/bin/checksums.txt +6 -0
- package/bin/darwin-amd64/everyline-cli +0 -0
- package/bin/darwin-arm64/everyline-cli +0 -0
- package/bin/linux-amd64/everyline-cli +0 -0
- package/bin/linux-arm64/everyline-cli +0 -0
- package/bin/windows-amd64/everyline-cli.exe +0 -0
- package/bin/windows-arm64/everyline-cli.exe +0 -0
- package/package.json +35 -0
- package/scripts/install.js +15 -0
- package/scripts/package-version.js +26 -0
- package/scripts/platform.js +20 -0
- package/scripts/run.js +37 -0
- package/scripts/verify-package-version.js +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# everyline-cli
|
|
2
|
+
|
|
3
|
+
智审开放平台 V3 的 Go 命令行客户端。覆盖接口文档中的 25 个远端 operation 映射:Profile/tenant token、合同审查工作流、审查清单以及规则分组/规则管理;其中 21 项已开放真实调用,4 项缺字段级详情的批量写操作失败关闭。文件快照和字段捷径接口按当前 CLI 范围暂不纳入同步。
|
|
4
|
+
|
|
5
|
+
## 构建
|
|
6
|
+
|
|
7
|
+
需要 Go 1.24 或更高版本。
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
make test
|
|
11
|
+
make build
|
|
12
|
+
./bin/everyline-cli version
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 快速开始
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
everyline-cli config add dev \
|
|
19
|
+
--env dev \
|
|
20
|
+
--app-id cli_xxx
|
|
21
|
+
|
|
22
|
+
export EVERYLINE_APP_SECRET='replace-me'
|
|
23
|
+
everyline-cli auth login
|
|
24
|
+
|
|
25
|
+
everyline-cli review run --input review-run.json --output json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
URL 来源的一键审查输入还需提供 `businessId` 与对应文件内容的 SHA-256 `fileHash`,因为标准 URL 上传接口的响应只返回 `fileId`。
|
|
29
|
+
|
|
30
|
+
`appType=CLM` 时,本地文件上传也必须提供 `businessId`;CLI 会在上传前校验这一条件。
|
|
31
|
+
|
|
32
|
+
也可以使用内置环境地址创建 `test`、`blue` 或线上 `prod` Profile(`app-id` 仍需替换为该环境的应用 ID):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
everyline-cli config add test --env test --app-id cli_test_xxx
|
|
36
|
+
everyline-cli config add blue --env blue --app-id cli_blue_xxx
|
|
37
|
+
everyline-cli config add prod --env prod --app-id cli_prod_xxx
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
`app_secret` 不写入 Profile,也不提供明文命令行参数。可使用 `EVERYLINE_APP_SECRET`、Profile 专用变量或 `auth login --app-secret-stdin`。专用变量以 `EVERYLINE_APP_SECRET_` 开头;常见的小写字母映射为大写,数字保持不变,其他 UTF-8 字节(包括原始大写字母)编码为 `_XX`,因此后缀可逆且不会因大小写或符号碰撞。例如 `prod-eu`、`prod.eu`、`prod_eu` 分别对应 `EVERYLINE_APP_SECRET_PROD_2DEU`、`EVERYLINE_APP_SECRET_PROD_2EEU`、`EVERYLINE_APP_SECRET_PROD_5FEU`。token 缓存在权限为 `0600` 的 `~/.everyline-cli/tokens.json`;CI 可用 `EVERYLINE_ACCESS_TOKEN` 覆盖。
|
|
41
|
+
|
|
42
|
+
CLI 同时支持 `app` 和 `user` 两种身份。`--env` 会自动写入每个环境对应的智审自有认证页面:dev 为 `https://dev-contract-agent.qtech.cn`、test 为 `https://test-contract-agent.qtech.cn`、blue 为 `https://blue-contract-agent.qtech.cn`、prod 为 `https://contract-agent.qfei.cn`。用户在页面完成认证后,将页面交接的 access token 通过 stdin 或 `EVERYLINE_USER_ACCESS_TOKEN` 注入 CLI:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
everyline-cli auth login --as user --access-token-stdin
|
|
46
|
+
everyline-cli auth use --as user
|
|
47
|
+
everyline-cli review run --as user --input review-run.json --output json
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`auth login --as user` 缺少 token 时会输出当前 Profile 的自有认证页面地址;CLI 不猜测页面内部协议。app/user token 在本地缓存中隔离保存。
|
|
51
|
+
|
|
52
|
+
## 一键审查输入
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"source": {
|
|
57
|
+
"type": "file",
|
|
58
|
+
"path": "./contract.pdf",
|
|
59
|
+
"name": "采购合同.pdf"
|
|
60
|
+
},
|
|
61
|
+
"businessId": "biz-001",
|
|
62
|
+
"appType": "THIRD_PARTY",
|
|
63
|
+
"config": {},
|
|
64
|
+
"extractSubjects": true,
|
|
65
|
+
"wait": true
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
完整命令和 25 项接口映射见 [命令参考](docs/command-reference.md) 与 [API 映射](docs/api-mapping.md)。清单、规则分组和规则的所有删除操作都要求显式 `--yes`;`--dry-run` 不调用远端。
|
|
70
|
+
|
|
71
|
+
可通过 `everyline-cli completion bash|fish|powershell|zsh` 生成 shell 补全脚本。四个尚缺字段级详情页的批量创建/更新命令仅开放 `--dry-run`,真实请求会失败关闭,具体清单见 API 映射。
|
|
72
|
+
|
|
73
|
+
## npm/npx 包装
|
|
74
|
+
|
|
75
|
+
Node 包只负责启动对应平台的 Go 二进制,CLI 本体没有 Node 运行时依赖。发布前运行 `scripts/build-release-assets.sh` 生成六个平台架构的 `bin/<platform>-<arch>/everyline-cli`。CI 会把 tag 或提交版本规范化为 SemVer、同步到 npm manifest,并产出带正确版本号的 `.tgz` 制品。
|
|
76
|
+
|
|
77
|
+
安装 scoped npm 包后,执行文件名仍为 `everyline-cli`:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
npx @qfeius/everyline-cli version
|
|
81
|
+
```
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
dfdda90355f81c7664bac25259861a37b6b6aaf8ee992e3a1a840325fc2976ba bin/darwin-amd64/everyline-cli
|
|
2
|
+
f787c5d8b54cf14535539adc776bee653562e334a0cf144706cd0cb248d25367 bin/darwin-arm64/everyline-cli
|
|
3
|
+
8a2dfb62c84e525c74cc6da27ff68e216c5e58c26b9cbb152053fbc1cf565d15 bin/linux-amd64/everyline-cli
|
|
4
|
+
fe8cef0cbee70134643aaf3785a8ab86c6f4b25327e9e6ec0b89d29285e6f80c bin/linux-arm64/everyline-cli
|
|
5
|
+
4517cf530bb5471c1564a9e93b7edf6ff963055d9b38cd9b16bb1b87a20a807e bin/windows-amd64/everyline-cli.exe
|
|
6
|
+
e1634c4036ca5c67e6d1ccabe24bfd3baba55d0858f98b61d10ece0471ba6db0 bin/windows-arm64/everyline-cli.exe
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qfeius/everyline-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "智审开放平台 V3 命令行客户端的 npm/npx 薄包装",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/yuwenGueen/everyline-cli.git"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"everyline-cli": "scripts/run.js"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"bin/checksums.txt",
|
|
15
|
+
"bin/darwin-amd64/",
|
|
16
|
+
"bin/darwin-arm64/",
|
|
17
|
+
"bin/linux-amd64/",
|
|
18
|
+
"bin/linux-arm64/",
|
|
19
|
+
"bin/windows-amd64/",
|
|
20
|
+
"bin/windows-arm64/",
|
|
21
|
+
"scripts/install.js",
|
|
22
|
+
"scripts/package-version.js",
|
|
23
|
+
"scripts/platform.js",
|
|
24
|
+
"scripts/run.js",
|
|
25
|
+
"scripts/verify-package-version.js"
|
|
26
|
+
],
|
|
27
|
+
"scripts": {
|
|
28
|
+
"postinstall": "node scripts/install.js",
|
|
29
|
+
"prepack": "node scripts/verify-package-version.js",
|
|
30
|
+
"test": "node --test tests/release/platform.test.js"
|
|
31
|
+
},
|
|
32
|
+
"engines": {
|
|
33
|
+
"node": ">=18"
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { chmodSync, existsSync } = require("node:fs");
|
|
4
|
+
const { join } = require("node:path");
|
|
5
|
+
const { resolvePlatformTarget } = require("./platform");
|
|
6
|
+
|
|
7
|
+
// npm 安装必须确认当前平台产物真实存在,防止留下“安装成功但无法运行”的包。
|
|
8
|
+
const executable = process.platform === "win32" ? "everyline-cli.exe" : "everyline-cli";
|
|
9
|
+
const binary = join(__dirname, "..", "bin", resolvePlatformTarget(), executable);
|
|
10
|
+
if (!existsSync(binary)) {
|
|
11
|
+
throw new Error(`npm 包缺少当前平台二进制: ${binary}`);
|
|
12
|
+
}
|
|
13
|
+
if (process.platform !== "win32") {
|
|
14
|
+
chmodSync(binary, 0o755);
|
|
15
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* normalizePackageVersion 将 Git tag 或提交描述转换为 npm 可接受且可追溯的 SemVer。
|
|
5
|
+
* 入参:value string,为发布 tag、CI 版本或 git describe 结果。
|
|
6
|
+
* 返回值:string;合法 SemVer 保留并去掉前导 v,其他值映射为 0.0.0-build-* 预发布版本。
|
|
7
|
+
*/
|
|
8
|
+
function normalizePackageVersion(value) {
|
|
9
|
+
const source = String(value || "").trim();
|
|
10
|
+
const candidate = source.replace(/^v(?=\d)/, "");
|
|
11
|
+
const semver = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
12
|
+
if (semver.test(candidate)) {
|
|
13
|
+
return candidate;
|
|
14
|
+
}
|
|
15
|
+
const normalized = source
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^0-9a-z-]+/g, "-")
|
|
18
|
+
.replace(/^-+|-+$/g, "") || "development";
|
|
19
|
+
return `0.0.0-build-${normalized}`;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (require.main === module) {
|
|
23
|
+
process.stdout.write(normalizePackageVersion(process.argv[2]));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = { normalizePackageVersion };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const platformMap = Object.freeze({ darwin: "darwin", linux: "linux", win32: "windows" });
|
|
4
|
+
const architectureMap = Object.freeze({ x64: "amd64", arm64: "arm64" });
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* resolvePlatformTarget 将 Node 平台名映射为 GoReleaser/npm 产物目录名。
|
|
8
|
+
* 入参:platform string 为 Node process.platform;architecture string 为 Node process.arch。
|
|
9
|
+
* 返回值:string,格式为 goos-goarch;不支持的平台或架构会抛出 Error。
|
|
10
|
+
*/
|
|
11
|
+
function resolvePlatformTarget(platform = process.platform, architecture = process.arch) {
|
|
12
|
+
const targetPlatform = platformMap[platform];
|
|
13
|
+
const targetArchitecture = architectureMap[architecture];
|
|
14
|
+
if (!targetPlatform || !targetArchitecture) {
|
|
15
|
+
throw new Error(`不支持的平台或架构: ${platform}/${architecture}`);
|
|
16
|
+
}
|
|
17
|
+
return `${targetPlatform}-${targetArchitecture}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = { resolvePlatformTarget };
|
package/scripts/run.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawnSync } = require("node:child_process");
|
|
4
|
+
const { existsSync } = require("node:fs");
|
|
5
|
+
const { dirname, join } = require("node:path");
|
|
6
|
+
const { resolvePlatformTarget } = require("./platform");
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* resolveBinary 根据 Node 平台和架构定位 npm 包内的原生二进制。
|
|
10
|
+
* 入参:无,读取 process.platform/process.arch 和可选 EVERYLINE_CLI_BINARY。
|
|
11
|
+
* 返回值:string,可执行文件路径;找不到时抛出 Error。
|
|
12
|
+
*/
|
|
13
|
+
function resolveBinary() {
|
|
14
|
+
if (process.env.EVERYLINE_CLI_BINARY) {
|
|
15
|
+
return process.env.EVERYLINE_CLI_BINARY;
|
|
16
|
+
}
|
|
17
|
+
const executable = process.platform === "win32" ? "everyline-cli.exe" : "everyline-cli";
|
|
18
|
+
const packageRoot = join(dirname(__filename), "..");
|
|
19
|
+
const binary = join(packageRoot, "bin", resolvePlatformTarget(), executable);
|
|
20
|
+
if (!existsSync(binary)) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`当前 npm 包缺少 ${process.platform}/${process.arch} 二进制;请使用原生发布包,或设置 EVERYLINE_CLI_BINARY`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return binary;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const result = spawnSync(resolveBinary(), process.argv.slice(2), { stdio: "inherit" });
|
|
30
|
+
if (result.error) {
|
|
31
|
+
throw result.error;
|
|
32
|
+
}
|
|
33
|
+
process.exitCode = result.status ?? 1;
|
|
34
|
+
} catch (error) {
|
|
35
|
+
process.stderr.write(`everyline-cli: ${error.message}\n`);
|
|
36
|
+
process.exitCode = 1;
|
|
37
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const { readFileSync } = require("node:fs");
|
|
4
|
+
const { join } = require("node:path");
|
|
5
|
+
const { normalizePackageVersion } = require("./package-version");
|
|
6
|
+
|
|
7
|
+
const packagePath = join(__dirname, "..", "package.json");
|
|
8
|
+
const packageData = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
9
|
+
if (packageData.version === "0.0.0-development" || normalizePackageVersion(packageData.version) !== packageData.version) {
|
|
10
|
+
throw new Error(`拒绝打包未同步的 npm 版本: ${packageData.version}`);
|
|
11
|
+
}
|