@accio-ai/ecommerce-cli 0.0.1-rc.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,27 @@
1
+ # Changelog
2
+
3
+ 本文件记录 `@accio-ai/ecommerce-cli` 的版本变更,格式遵循 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [Semantic Versioning](https://semver.org/lang/zh-CN/)。
4
+
5
+ ## [Unreleased]
6
+
7
+ ### Added
8
+
9
+ - 新增相互隔离的正式版与 RC 发布入口;RC 自动使用 `-rc.N` 版本和 npm `rc` dist-tag,正式版固定使用 `latest`,两条通道共享完整 Windows 签名和安装验证门禁。
10
+ - 将根目录 `VERSION` 设为唯一发布版本源;npm staging 和 Go release build 自动注入版本,不再要求同步修改 `package.json` 与 Go 源码。
11
+ - 简化 Windows 签名交接:默认强制验证 Authenticode 与原始 payload,signer 证书 SHA-256 指纹改为可选加强项,不再要求每次发布手工输入。
12
+ - 将 Windows 替换与最终验签合并为单一 finalize 入口;正式版和 RC publish 自动执行完整门禁并固定发布到 npmjs,dry-run 降为可选步骤。
13
+ - 将公网 npm 包名统一为 `@accio-ai/ecommerce-cli`,固定使用 `accio-ai` scope、public access 和 npmjs registry。
14
+ - 将 npm 分发改为 1 个主包加 6 个按 `os`/`cpu` 限制的平台包;安装时只下载当前平台二进制,发布时平台包先于主包。
15
+
16
+ ## [0.0.1] - 2026-08-31
17
+
18
+ ### Added
19
+
20
+ - 新增 `ecomctl` Go CLI,提供 help、version、shell completion、text/JSON 输出及稳定的错误分类、标准流和退出码契约。
21
+ - 新增编译期静态 adapter registry、显式 composition root 和强类型 application 边界;第一版不公开尚未确定业务语义的命令。
22
+ - 新增 registry、adapter、输出、help/version、stdout/stderr、退出码、context 取消和依赖方向自动化测试。
23
+ - 新增 GoReleaser 跨平台归档、macOS 原生 CGO/Code Trust 构建约束、SHA-256 checksums、本地 GPG checksum 签名入口和版本一致性门禁。
24
+ - 新增 Windows amd64/arm64 Authenticode 离线交接、证书 SHA-256 指纹固定、signed/unsigned payload 绑定、双平台验签、raw/zip 原子替换、artifact/checksum 刷新和签名回执;正式 npm 发布必须通过 signed distribution 门禁。
25
+ - 新增包含平台二进制的 `@accio-ai/ecommerce-cli` npm 包、`ecomctl` launcher、安装校验、本地 pack、隔离安装 smoke 与受保护的 publish 流程。
26
+ - 新增调用完整源码、打包与安装门禁的 GitLab CI,并将 npm packaging 源码与 Windows signing 工具整理到职责明确的目录。
27
+ - 新增架构、CLI、扩展新业务能力和发布流程文档。
package/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # @accio-ai/ecommerce-cli npm package
2
+
3
+ This is the platform-independent launcher package for `ecomctl`.
4
+
5
+ It declares six exact-version optional dependencies. npm uses each dependency's `os` and `cpu` fields to install only the matching platform package, so users do not download binaries for other operating systems or architectures.
6
+
7
+ The platform package contains one statically compiled binary; this main package contains only the Node.js launcher, install checksum verification, README, and changelog. Installation does not read or write account state, credentials, user configuration, Agent skills, telemetry, or remote services.
8
+
9
+ Supported targets:
10
+
11
+ - macOS: arm64 and x64
12
+ - Linux: arm64 and x64
13
+ - Windows: arm64 and x64
14
+
15
+ Run `ecomctl --help` after installation.
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const childProcess = require("node:child_process");
6
+ const fs = require("node:fs");
7
+ const path = require("node:path");
8
+
9
+ const TARGETS = Object.freeze({
10
+ "darwin-arm64": { binary: "ecomctl" },
11
+ "darwin-x64": { binary: "ecomctl" },
12
+ "linux-arm64": { binary: "ecomctl" },
13
+ "linux-x64": { binary: "ecomctl" },
14
+ "win32-arm64": { binary: "ecomctl.exe" },
15
+ "win32-x64": { binary: "ecomctl.exe" },
16
+ });
17
+
18
+ const SIGNAL_EXIT_CODES = Object.freeze({
19
+ SIGHUP: 129,
20
+ SIGINT: 130,
21
+ SIGTERM: 143,
22
+ SIGBREAK: 149,
23
+ });
24
+
25
+ function platformKey(platform = process.platform, architecture = process.arch) {
26
+ const key = `${platform}-${architecture}`;
27
+ if (!TARGETS[key]) {
28
+ throw new Error(`unsupported platform ${key}`);
29
+ }
30
+ return key;
31
+ }
32
+
33
+ function basePackageName(packageRoot) {
34
+ const manifest = JSON.parse(fs.readFileSync(path.join(packageRoot, "package.json"), "utf8"));
35
+ return manifest.name;
36
+ }
37
+
38
+ function platformPackageName(
39
+ packageName,
40
+ platform = process.platform,
41
+ architecture = process.arch,
42
+ ) {
43
+ return `${packageName}-${platformKey(platform, architecture)}`;
44
+ }
45
+
46
+ function resolveBinaryPathForPackage(
47
+ packageName,
48
+ platform = process.platform,
49
+ architecture = process.arch,
50
+ resolveModule = require.resolve,
51
+ ) {
52
+ const key = platformKey(platform, architecture);
53
+ const manifestPath = resolveModule(
54
+ `${platformPackageName(packageName, platform, architecture)}/package.json`,
55
+ );
56
+ return path.join(path.dirname(manifestPath), TARGETS[key].binary);
57
+ }
58
+
59
+ function resolveBinaryPath(
60
+ packageRoot,
61
+ platform = process.platform,
62
+ architecture = process.arch,
63
+ resolveModule = require.resolve,
64
+ ) {
65
+ return resolveBinaryPathForPackage(
66
+ basePackageName(packageRoot),
67
+ platform,
68
+ architecture,
69
+ (specifier) => resolveModule(specifier, { paths: [packageRoot] }),
70
+ );
71
+ }
72
+
73
+ function run(args = process.argv.slice(2)) {
74
+ const packageRoot = path.resolve(__dirname, "..");
75
+ let key;
76
+ let packageName;
77
+ let platformPackage;
78
+ let binaryPath;
79
+ try {
80
+ key = platformKey();
81
+ packageName = basePackageName(packageRoot);
82
+ platformPackage = platformPackageName(packageName);
83
+ binaryPath = resolveBinaryPath(packageRoot);
84
+ } catch (error) {
85
+ if (!key) {
86
+ console.error(`ecomctl: ${error.message}`);
87
+ } else {
88
+ console.error(
89
+ `ecomctl: platform package ${platformPackage || key} is missing; reinstall ${packageName || "@accio-ai/ecommerce-cli"}`,
90
+ );
91
+ }
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ if (!fs.existsSync(binaryPath)) {
96
+ console.error(
97
+ `ecomctl: binary is missing from ${platformPackage}; reinstall ${packageName}`,
98
+ );
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+
103
+ let child = null;
104
+ let pendingSignal = null;
105
+ let forwardedSignal = null;
106
+ let spawnFailed = false;
107
+ const signals =
108
+ process.platform === "win32"
109
+ ? ["SIGINT", "SIGTERM", "SIGBREAK"]
110
+ : ["SIGHUP", "SIGINT", "SIGTERM"];
111
+
112
+ function forwardSignal(signal) {
113
+ forwardedSignal = signal;
114
+ if (child === null) {
115
+ pendingSignal = signal;
116
+ return;
117
+ }
118
+ if (child.exitCode !== null || child.signalCode !== null) {
119
+ return;
120
+ }
121
+ try {
122
+ child.kill(process.platform === "win32" ? "SIGTERM" : signal);
123
+ } catch (error) {
124
+ console.error(`ecomctl: failed to forward ${signal}: ${error.message}`);
125
+ }
126
+ }
127
+
128
+ function removeSignalHandlers() {
129
+ for (const signal of signals) {
130
+ process.removeAllListeners(signal);
131
+ }
132
+ }
133
+
134
+ for (const signal of signals) {
135
+ process.on(signal, () => forwardSignal(signal));
136
+ }
137
+
138
+ child = childProcess.spawn(binaryPath, args, {
139
+ env: process.env,
140
+ stdio: "inherit",
141
+ });
142
+ if (pendingSignal !== null) {
143
+ const signal = pendingSignal;
144
+ pendingSignal = null;
145
+ forwardSignal(signal);
146
+ }
147
+
148
+ child.on("error", (error) => {
149
+ spawnFailed = true;
150
+ console.error(`ecomctl: failed to start binary: ${error.message}`);
151
+ });
152
+ child.on("close", (code, signal) => {
153
+ removeSignalHandlers();
154
+ if (spawnFailed) {
155
+ process.exitCode = 1;
156
+ return;
157
+ }
158
+ if (Number.isInteger(code)) {
159
+ process.exitCode = code;
160
+ return;
161
+ }
162
+ process.exitCode = SIGNAL_EXIT_CODES[signal || forwardedSignal] || 1;
163
+ });
164
+ }
165
+
166
+ if (require.main === module) {
167
+ run();
168
+ }
169
+
170
+ module.exports = {
171
+ SIGNAL_EXIT_CODES,
172
+ TARGETS,
173
+ basePackageName,
174
+ platformKey,
175
+ platformPackageName,
176
+ resolveBinaryPath,
177
+ resolveBinaryPathForPackage,
178
+ run,
179
+ };
package/checksums.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "version": "0.0.1-rc.1",
3
+ "binaries": {
4
+ "darwin-arm64": {
5
+ "package": "@accio-ai/ecommerce-cli-darwin-arm64",
6
+ "file": "ecomctl",
7
+ "sha256": "cfc3e6221f67764d07dc203267aa007be903261fcdad3af4e7d518e226cc485d"
8
+ },
9
+ "darwin-x64": {
10
+ "package": "@accio-ai/ecommerce-cli-darwin-x64",
11
+ "file": "ecomctl",
12
+ "sha256": "a6c784bcf6e43450343df2c48d9cdb673b1e6579201b83490e5c800835e5abbf"
13
+ },
14
+ "linux-arm64": {
15
+ "package": "@accio-ai/ecommerce-cli-linux-arm64",
16
+ "file": "ecomctl",
17
+ "sha256": "b268f1d5f0d6379aecb748d353067f8f9ec1d229cd8894da4118003db5314ffb"
18
+ },
19
+ "linux-x64": {
20
+ "package": "@accio-ai/ecommerce-cli-linux-x64",
21
+ "file": "ecomctl",
22
+ "sha256": "66d64ea6c11245c495f7aaa83b43fb29f1b1a358e968861df6a383178c6b305d"
23
+ },
24
+ "win32-arm64": {
25
+ "package": "@accio-ai/ecommerce-cli-win32-arm64",
26
+ "file": "ecomctl.exe",
27
+ "sha256": "55e05ab72048f4ddd3c978b2e3195f382d1bb76ed9c86ac8e0eada0871d68a17"
28
+ },
29
+ "win32-x64": {
30
+ "package": "@accio-ai/ecommerce-cli-win32-x64",
31
+ "file": "ecomctl.exe",
32
+ "sha256": "0f6f3e265d7ec61210e93c047b8e95276eee8d55832a1ff8a16f82da676dd965"
33
+ }
34
+ }
35
+ }
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "@accio-ai/ecommerce-cli",
3
+ "version": "0.0.1-rc.1",
4
+ "description": "Local, statically compiled ecommerce automation toolkit",
5
+ "license": "UNLICENSED",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+ssh://git@gitlab.alibaba-inc.com/accio-core/ecommerce-cli.git"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public",
12
+ "registry": "https://registry.npmjs.org/"
13
+ },
14
+ "bin": {
15
+ "ecomctl": "bin/ecomctl.cjs"
16
+ },
17
+ "scripts": {
18
+ "postinstall": "node postinstall.cjs"
19
+ },
20
+ "optionalDependencies": {
21
+ "@accio-ai/ecommerce-cli-darwin-arm64": "0.0.1-rc.1",
22
+ "@accio-ai/ecommerce-cli-darwin-x64": "0.0.1-rc.1",
23
+ "@accio-ai/ecommerce-cli-linux-arm64": "0.0.1-rc.1",
24
+ "@accio-ai/ecommerce-cli-linux-x64": "0.0.1-rc.1",
25
+ "@accio-ai/ecommerce-cli-win32-arm64": "0.0.1-rc.1",
26
+ "@accio-ai/ecommerce-cli-win32-x64": "0.0.1-rc.1"
27
+ },
28
+ "files": [
29
+ "bin",
30
+ "postinstall.cjs",
31
+ "checksums.json",
32
+ "README.md",
33
+ "CHANGELOG.md"
34
+ ],
35
+ "engines": {
36
+ "node": ">=18"
37
+ }
38
+ }
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+
3
+ "use strict";
4
+
5
+ const crypto = require("node:crypto");
6
+ const fs = require("node:fs");
7
+ const path = require("node:path");
8
+ const {
9
+ basePackageName,
10
+ platformKey,
11
+ platformPackageName,
12
+ resolveBinaryPath,
13
+ } = require("./bin/ecomctl.cjs");
14
+
15
+ const packageRoot = __dirname;
16
+ let binaryPath;
17
+ let key;
18
+ let packageName;
19
+ let platformPackage;
20
+ try {
21
+ key = platformKey();
22
+ packageName = basePackageName(packageRoot);
23
+ platformPackage = platformPackageName(packageName);
24
+ binaryPath = resolveBinaryPath(packageRoot);
25
+ } catch (error) {
26
+ if (!key) {
27
+ fail(error.message);
28
+ }
29
+ fail(`platform package ${platformPackage || key} is missing; reinstall ${packageName || "the CLI package"}`);
30
+ }
31
+
32
+ if (!fs.existsSync(binaryPath)) {
33
+ fail(`binary is missing from ${platformPackage}`);
34
+ }
35
+
36
+ const checksums = JSON.parse(
37
+ fs.readFileSync(path.join(packageRoot, "checksums.json"), "utf8"),
38
+ );
39
+ const expected = checksums.binaries[key]?.sha256;
40
+ if (!expected) {
41
+ fail(`checksum is missing for ${key}`);
42
+ }
43
+ if (checksums.binaries[key]?.package !== platformPackage) {
44
+ fail(`checksum package does not match ${platformPackage}`);
45
+ }
46
+ const actual = crypto.createHash("sha256").update(fs.readFileSync(binaryPath)).digest("hex");
47
+ if (actual !== expected) {
48
+ fail(`binary checksum mismatch for ${key}`);
49
+ }
50
+ if (process.platform !== "win32") {
51
+ fs.chmodSync(binaryPath, 0o755);
52
+ }
53
+
54
+ console.log(`ecomctl ${checksums.version} installed from ${platformPackage}`);
55
+
56
+ function fail(message) {
57
+ console.error(`ecomctl: ${message}`);
58
+ process.exit(1);
59
+ }