@windaka-erp/erp-cli 0.3.2 → 0.4.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 CHANGED
@@ -33,13 +33,13 @@ npx skills add windaka-erp/erp-cli -y -g
33
33
 
34
34
  ```bash
35
35
  # 1. 初始化配置
36
- erp-cli --as me config init
36
+ erp-cli config init
37
37
 
38
38
  # 2. 登录
39
- erp-cli --as me auth login
39
+ erp-cli auth login
40
40
 
41
41
  # 3. 开始使用
42
- erp-cli --as me workorder +list
42
+ erp-cli workorder +list
43
43
  ```
44
44
 
45
45
  ### AI Agent
@@ -62,17 +62,17 @@ erp-cli --help
62
62
  ## 命令
63
63
 
64
64
  ```
65
- erp-cli --as <id> config init/show/set/remove # 配置管理
66
- erp-cli --as <id> auth login/login-start/login-wait # 登录
67
- erp-cli --as <id> auth status/logout/list # 认证状态
68
- erp-cli --as <id> api GET/POST <path> # 原始 API 调用
69
- erp-cli --as <id> knowledge +search/+list-datasets # 知识库检索
70
- erp-cli --as <id> workorder +list/+create # 工单操作
65
+ erp-cli config init/show/set/remove # 配置管理
66
+ erp-cli auth login/login-start/login-wait # 登录
67
+ erp-cli auth status/logout # 认证状态
68
+ erp-cli api GET/POST <path> # 原始 API 调用
69
+ erp-cli knowledge +search/+list-datasets # 知识库检索
70
+ erp-cli workorder +list/+create # 工单操作
71
71
  ```
72
72
 
73
73
  ## 参数
74
74
 
75
- - `--as <id>` — 用户标识(必填),企业微信用 Sender ID,本地用任意稳定标识(如 `me`)
75
+ - `--profile <name>` — 切换环境(prod/staging),默认 default
76
76
  - `--dry-run` — 预览请求内容,不实际执行
77
77
 
78
78
  ## Agent Skills
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "@windaka-erp/erp-cli",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "ERP CLI - command-line tool for Windaka ERP system",
5
5
  "bin": {
6
6
  "erp-cli": "scripts/run.js"
7
7
  },
8
- "scripts": {
9
- "postinstall": "node scripts/install.js"
10
- },
11
8
  "files": [
12
9
  "scripts/",
13
10
  "bin/",
@@ -36,8 +33,5 @@
36
33
  "cpu": [
37
34
  "x64",
38
35
  "arm64"
39
- ],
40
- "dependencies": {
41
- "@windaka-erp/erp-cli": "^0.2.0"
42
- }
36
+ ]
43
37
  }
package/scripts/run.js CHANGED
@@ -1,218 +1,53 @@
1
1
  #!/usr/bin/env node
2
- const { execFileSync, execSync } = require("child_process");
2
+ // run.js erp-cli 启动器。二进制已打包进 npm 包的 bin/ 目录,
3
+ // 按当前平台选择对应二进制执行。无需联网下载,不依赖 GitHub。
4
+ const { execFileSync } = require("child_process");
3
5
  const path = require("path");
4
6
  const fs = require("fs");
5
- const https = require("https");
6
- const http = require("http");
7
7
 
8
- const BINARY_NAME = "erp-cli";
9
- const VERSION = require("../package.json").version;
10
- const GITHUB_REPO = "windaka-erp/erp-cli";
11
- const GITEE_REPO = "xing-wenkai/erp-cli";
8
+ // Node 平台/架构 → 二进制文件名片段
9
+ const OS_MAP = { win32: "windows", darwin: "darwin", linux: "linux" };
10
+ const ARCH_MAP = { x64: "amd64", arm64: "arm64" };
12
11
 
13
- function getBinaryPath() {
14
- const binDir = path.join(__dirname, "..", "bin");
15
-
16
- const candidates = [
17
- path.join(binDir, `${BINARY_NAME}.exe`), // bin/erp-cli.exe (Windows)
18
- path.join(binDir, BINARY_NAME), // bin/erp-cli (macOS/Linux)
19
- path.join(__dirname, "..", `${BINARY_NAME}.exe`), // 根目录编译产物 (Windows)
20
- path.join(__dirname, "..", BINARY_NAME), // 根目录编译产物 (macOS/Linux)
21
- ];
22
-
23
- for (const p of candidates) {
24
- if (fs.existsSync(p)) return p;
25
- }
26
-
27
- console.error(`Error: ${BINARY_NAME} binary not found.`);
28
- console.error(`Please run: npm install`);
29
- process.exit(1);
30
- }
31
-
32
- // ── 静默自动更新 ──
33
-
34
- function getPlatformInfo() {
35
- const platform = process.platform;
36
- const arch = process.arch;
37
-
38
- const map = {
39
- win32_x64: { target: "windows-amd64", ext: ".exe" },
40
- win32_arm64: { target: "windows-arm64", ext: ".exe" },
41
- darwin_x64: { target: "darwin-amd64", ext: "" },
42
- darwin_arm64: { target: "darwin-arm64", ext: "" },
43
- linux_x64: { target: "linux-amd64", ext: "" },
44
- linux_arm64: { target: "linux-arm64", ext: "" },
45
- };
46
-
47
- return map[`${platform}_${arch}`] || null;
48
- }
49
-
50
- function getInstalledVersion(binaryPath) {
51
- try {
52
- const output = execSync(`"${binaryPath}" --version`, {
53
- encoding: "utf8",
54
- timeout: 5000,
55
- });
56
- const match = output.match(/version\s+v?(\S+)/i);
57
- return match ? match[1].replace(/^v/, "") : null;
58
- } catch {
59
- return null;
12
+ function getBinaryName() {
13
+ const os = OS_MAP[process.platform];
14
+ const arch = ARCH_MAP[process.arch];
15
+ if (!os || !arch) {
16
+ console.error(
17
+ `Error: unsupported platform ${process.platform}-${process.arch}.`
18
+ );
19
+ console.error(
20
+ `Supported: win32-x64, win32-arm64, darwin-x64, darwin-arm64, linux-x64, linux-arm64.`
21
+ );
22
+ process.exit(1);
60
23
  }
24
+ const ext = process.platform === "win32" ? ".exe" : "";
25
+ return `erp-cli-${os}-${arch}${ext}`;
61
26
  }
62
27
 
63
- function fetchJSON(url) {
64
- return new Promise((resolve, reject) => {
65
- const client = url.startsWith("https") ? https : http;
66
- client
67
- .get(url, { timeout: 5000 }, (res) => {
68
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
69
- fetchJSON(res.headers.location).then(resolve, reject);
70
- return;
71
- }
72
- if (res.statusCode !== 200) {
73
- reject(new Error(`HTTP ${res.statusCode}`));
74
- return;
75
- }
76
- let data = "";
77
- res.on("data", (chunk) => (data += chunk));
78
- res.on("end", () => {
79
- try {
80
- resolve(JSON.parse(data));
81
- } catch (e) {
82
- reject(e);
83
- }
84
- });
85
- })
86
- .on("error", reject)
87
- .on("timeout", function () {
88
- this.destroy();
89
- reject(new Error("timeout"));
90
- });
91
- });
92
- }
93
-
94
- function downloadFile(url, dest) {
95
- return new Promise((resolve, reject) => {
96
- const client = url.startsWith("https") ? https : http;
97
- client
98
- .get(url, (res) => {
99
- if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
100
- downloadFile(res.headers.location, dest).then(resolve, reject);
101
- return;
102
- }
103
- if (res.statusCode !== 200) {
104
- reject(new Error(`HTTP ${res.statusCode}`));
105
- return;
106
- }
107
- const stream = fs.createWriteStream(dest);
108
- res.pipe(stream);
109
- stream.on("finish", () => {
110
- stream.close();
111
- if (process.platform !== "win32") {
112
- fs.chmodSync(dest, 0o755);
113
- }
114
- resolve();
115
- });
116
- stream.on("error", reject);
117
- })
118
- .on("error", reject);
119
- });
120
- }
121
-
122
- async function silentAutoUpdate() {
123
- try {
124
- const binary = getBinaryPath();
125
- const installedVer = getInstalledVersion(binary);
126
-
127
- // 如果已安装版本和 package.json 一致,跳过
128
- if (installedVer === VERSION.replace(/^v/, "")) return;
129
-
130
- // 已安装版本比 package.json 新?跳过
131
- if (installedVer && installedVer > VERSION.replace(/^v/, "")) return;
28
+ function main() {
29
+ const binary = path.join(__dirname, "..", "bin", getBinaryName());
132
30
 
133
- // 检查上次更新时间,每天最多检查一次
134
- const updateMarker = path.join(
135
- require("os").homedir(),
136
- ".erp-cli",
137
- ".last-update-check"
31
+ if (!fs.existsSync(binary)) {
32
+ console.error(`Error: binary not found at ${binary}.`);
33
+ console.error(
34
+ `Try reinstalling: npm install -g @windaka-erp/erp-cli`
138
35
  );
139
- try {
140
- const lastCheck = parseInt(fs.readFileSync(updateMarker, "utf8"), 10);
141
- const ONE_DAY = 24 * 60 * 60 * 1000;
142
- if (Date.now() - lastCheck < ONE_DAY) return;
143
- } catch {
144
- // 文件不存在或读取失败,继续检查
145
- }
146
- if (installedVer && installedVer > VERSION.replace(/^v/, "")) return;
147
-
148
- // 需要更新:查询 Release 获取最新版本号(GitHub 优先,Gitee 回退)
149
- let release;
150
- try {
151
- release = await fetchJSON(
152
- `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`
153
- );
154
- } catch {
155
- // GitHub 不通,回退 Gitee API
156
- release = await fetchJSON(
157
- `https://gitee.com/api/v5/repos/${GITEE_REPO}/releases/latest`
158
- );
159
- }
160
-
161
- const latestTag = release.tag_name; // e.g. "v0.3.0"
162
- const latestVer = latestTag.replace(/^v/, "");
163
-
164
- // 最新版和 package.json 版本不一致?等 npm update 后再说
165
- if (latestVer !== VERSION.replace(/^v/, "")) return;
166
-
167
- // 下载新版本
168
- const info = getPlatformInfo();
169
- if (!info) return;
170
-
171
- const filename = `${BINARY_NAME}-${info.target}${info.ext}`;
172
- const asset = release.assets.find((a) => a.name === filename);
173
- if (!asset) return;
174
-
175
- const binDir = path.join(__dirname, "..", "bin");
176
- const binaryPath = path.join(binDir, `${BINARY_NAME}${info.ext}`);
177
-
178
- // 下载到临时文件,完成后原子替换
179
- const tmpPath = binaryPath + ".tmp";
180
- await downloadFile(asset.browser_download_url, tmpPath);
181
-
182
- // 替换旧二进制
183
- fs.renameSync(tmpPath, binaryPath);
36
+ process.exit(1);
37
+ }
184
38
 
185
- // 写入本次检查时间
39
+ // 非 Windows 确保可执行权限(npm 打包可能丢失)
40
+ if (process.platform !== "win32") {
186
41
  try {
187
- const markerDir = path.join(require("os").homedir(), ".erp-cli");
188
- if (!fs.existsSync(markerDir)) fs.mkdirSync(markerDir, { recursive: true });
189
- fs.writeFileSync(markerDir + "/.last-update-check", String(Date.now()));
42
+ fs.chmodSync(binary, 0o755);
190
43
  } catch {
191
- // 写入失败不影响
44
+ // 忽略权限错误
192
45
  }
193
- } catch {
194
- // 静默失败,不影响正常使用
195
- // 即使失败也写入检查时间,避免频繁重试
196
- try {
197
- const markerDir = path.join(require("os").homedir(), ".erp-cli");
198
- if (!fs.existsSync(markerDir)) fs.mkdirSync(markerDir, { recursive: true });
199
- fs.writeFileSync(markerDir + "/.last-update-check", String(Date.now()));
200
- } catch {}
201
46
  }
202
- }
203
47
 
204
- function main() {
205
- // 后台静默更新,不阻塞主流程
206
- silentAutoUpdate().catch(() => {});
207
-
208
- const binary = getBinaryPath();
209
48
  const args = process.argv.slice(2);
210
-
211
49
  try {
212
- execFileSync(binary, args, {
213
- stdio: "inherit",
214
- env: { ...process.env },
215
- });
50
+ execFileSync(binary, args, { stdio: "inherit" });
216
51
  } catch (err) {
217
52
  process.exitCode = err.status || 1;
218
53
  }
@@ -1,146 +0,0 @@
1
- const { execSync } = require("child_process");
2
- const path = require("path");
3
- const fs = require("fs");
4
-
5
- // ── 配置 ──
6
- const BINARY_NAME = "erp-cli";
7
- const VERSION = require("../package.json").version;
8
- const GITHUB_REPO = "windaka-erp/erp-cli";
9
- const GITEE_REPO = "xing-wenkai/erp-cli";
10
-
11
- // ── 平台映射 ──
12
- function getPlatformInfo() {
13
- const platform = process.platform;
14
- const arch = process.arch;
15
-
16
- const map = {
17
- win32_x64: { target: "windows-amd64", ext: ".exe" },
18
- win32_arm64: { target: "windows-arm64", ext: ".exe" },
19
- darwin_x64: { target: "darwin-amd64", ext: "" },
20
- darwin_arm64: { target: "darwin-arm64", ext: "" },
21
- linux_x64: { target: "linux-amd64", ext: "" },
22
- linux_arm64: { target: "linux-arm64", ext: "" },
23
- };
24
-
25
- const key = `${platform}_${arch}`;
26
- const info = map[key];
27
- if (!info) {
28
- console.error(`Unsupported platform: ${platform}-${arch}`);
29
- process.exit(1);
30
- }
31
- return info;
32
- }
33
-
34
- // ── 下载地址(GitHub 优先,Gitee 回退)──
35
- function getDownloadURLs(info) {
36
- const filename = `${BINARY_NAME}-${info.target}${info.ext}`;
37
- return [
38
- `https://github.com/${GITHUB_REPO}/releases/download/v${VERSION}/${filename}`,
39
- `https://gitee.com/${GITEE_REPO}/releases/download/v${VERSION}/${filename}`,
40
- ];
41
- }
42
-
43
- // ── 获取已安装二进制的版本号 ──
44
- function getInstalledVersion(binaryPath) {
45
- try {
46
- const output = execSync(`"${binaryPath}" --version`, {
47
- encoding: "utf8",
48
- timeout: 5000,
49
- });
50
- // 输出格式: "erp-cli version v0.2.0" 或 "erp-cli version 0.2.0"
51
- const match = output.match(/version\s+v?(\S+)/i);
52
- return match ? match[1] : null;
53
- } catch {
54
- return null;
55
- }
56
- }
57
-
58
- // ── 比较版本号 ──
59
- function isVersionOutdated(installed, expected) {
60
- if (!installed) return true;
61
- // 去掉 v 前缀统一比较
62
- const a = installed.replace(/^v/, "");
63
- const b = expected.replace(/^v/, "");
64
- return a !== b;
65
- }
66
-
67
- // ── 下载二进制 ──
68
- function downloadBinary(url, binaryPath) {
69
- if (process.platform === "win32") {
70
- execSync(
71
- `powershell -Command "Invoke-WebRequest -Uri '${url}' -OutFile '${binaryPath}'"`,
72
- { stdio: "inherit" }
73
- );
74
- } else {
75
- execSync(`curl -L -o "${binaryPath}" "${url}"`, {
76
- stdio: "inherit",
77
- });
78
- }
79
-
80
- // 设置可执行权限(非 Windows)
81
- if (process.platform !== "win32") {
82
- fs.chmodSync(binaryPath, 0o755);
83
- }
84
- }
85
-
86
- // ── 主流程 ──
87
- function install() {
88
- const pkgDir = path.join(__dirname, "..");
89
- const binDir = path.join(pkgDir, "bin");
90
- if (!fs.existsSync(binDir)) {
91
- fs.mkdirSync(binDir, { recursive: true });
92
- }
93
-
94
- const info = getPlatformInfo();
95
- const binaryPath = path.join(binDir, `${BINARY_NAME}${info.ext}`);
96
-
97
- // 1. 检查 bin/ 目录是否已有对应平台的二进制
98
- if (fs.existsSync(binaryPath)) {
99
- const installedVer = getInstalledVersion(binaryPath);
100
- if (!isVersionOutdated(installedVer, VERSION)) {
101
- console.log(`Found bundled binary: ${binaryPath} (v${installedVer})`);
102
- return;
103
- }
104
- // 版本不一致,需要更新
105
- console.log(
106
- `Binary version mismatch: installed v${installedVer}, expected v${VERSION}. Updating...`
107
- );
108
- }
109
-
110
- // 2. 检查项目根目录是否有本地编译产物(开发模式)
111
- const localBinary = path.join(pkgDir, `${BINARY_NAME}${info.ext}`);
112
- if (fs.existsSync(localBinary)) {
113
- console.log(`Found local binary, copying...`);
114
- fs.copyFileSync(localBinary, binaryPath);
115
- console.log(`Installed from local build: ${binaryPath}`);
116
- return;
117
- }
118
-
119
- // 3. 从 GitHub Releases 下载,失败回退 Gitee
120
- const urls = getDownloadURLs(info);
121
- console.log(`Downloading ${BINARY_NAME} v${VERSION} for ${info.target}...`);
122
-
123
- let downloaded = false;
124
- for (const url of urls) {
125
- console.log(` Trying: ${url}`);
126
- try {
127
- downloadBinary(url, binaryPath);
128
- downloaded = true;
129
- console.log(`Successfully installed ${BINARY_NAME} v${VERSION}`);
130
- break;
131
- } catch (err) {
132
- console.warn(` Failed: ${err.message}`);
133
- }
134
- }
135
-
136
- if (!downloaded) {
137
- console.error(`All download sources failed.`);
138
- console.error(`You can build from source:`);
139
- console.error(` git clone https://github.com/${GITHUB_REPO}.git`);
140
- console.error(` cd erp-cli && go build -o ${BINARY_NAME} .`);
141
- console.error(` Then copy the binary to: ${binaryPath}`);
142
- process.exit(1);
143
- }
144
- }
145
-
146
- install();