cbs-4px-merchant-cli 0.0.2 → 0.0.4
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.4px.md +3 -3
- package/README.cainiao.md +3 -3
- package/README.md +3 -3
- package/dist/cli.js +51 -34
- package/dist/cli.js.map +1 -1
- package/dist/commands/auth.js +1 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/config.js +1 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/skill.d.ts +15 -0
- package/dist/commands/skill.js +374 -0
- package/dist/commands/skill.js.map +1 -0
- package/dist/commands/update.d.ts +1 -1
- package/dist/commands/update.js +72 -9
- package/dist/commands/update.js.map +1 -1
- package/dist/errors.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/services/skill-installer.d.ts +174 -0
- package/dist/services/skill-installer.js +540 -0
- package/dist/services/skill-installer.js.map +1 -0
- package/package.json +7 -5
- package/scripts/postinstall.js +31 -161
- package/skill/SKILL.md +9 -10
- package/skill/package.json +25 -0
- package/skill/reference/auth.md +7 -3
- package/skill/reference/config.md +1 -1
- package/skill/reference/index.md +7 -1
- package/skill/reference/update.md +99 -14
package/scripts/postinstall.js
CHANGED
|
@@ -1,184 +1,54 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Postinstall
|
|
4
|
+
* Postinstall hook — a best-effort convenience wrapper, nothing more.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* All skill logic lives in `src/services/skill-installer.ts` and is reachable
|
|
7
|
+
* as `<bin> skill install`; this hook only spawns that command so users on npm
|
|
8
|
+
* versions that still run install scripts get the skill without a second step.
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
+
* It deliberately owns no logic of its own, because it cannot be relied upon:
|
|
11
|
+
* npm 11 blocks dependency install scripts by default and *still exits 0*, so
|
|
12
|
+
* anything that must happen cannot live here. When the hook is skipped, the
|
|
13
|
+
* install docs' second step (`<bin> skill install`) covers it.
|
|
14
|
+
*
|
|
15
|
+
* Never fails the install: any problem exits 0 with a short hint on stderr.
|
|
10
16
|
*/
|
|
11
17
|
|
|
12
|
-
import {
|
|
13
|
-
existsSync,
|
|
14
|
-
mkdirSync,
|
|
15
|
-
copyFileSync,
|
|
16
|
-
cpSync,
|
|
17
|
-
openSync,
|
|
18
|
-
writeSync,
|
|
19
|
-
writeFileSync,
|
|
20
|
-
closeSync,
|
|
21
|
-
readFileSync,
|
|
22
|
-
} from 'fs';
|
|
18
|
+
import { existsSync, readFileSync } from 'fs';
|
|
23
19
|
import { join, dirname } from 'path';
|
|
24
|
-
import { homedir } from 'os';
|
|
25
20
|
import { fileURLToPath } from 'url';
|
|
26
|
-
import {
|
|
21
|
+
import { spawnSync } from 'child_process';
|
|
27
22
|
|
|
28
23
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
if (!existsSync(skillSource)) {
|
|
33
|
-
process.exit(0);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// ── Site metadata (generated at build time by scripts/build.js) ──
|
|
37
|
-
// Falls back to safe defaults so a source checkout without a build still runs.
|
|
38
|
-
const siteMeta = (() => {
|
|
39
|
-
const defaults = {
|
|
40
|
-
siteId: '4px',
|
|
41
|
-
env: 'prod',
|
|
42
|
-
baseUrl: 'https://b.4px.com',
|
|
43
|
-
akUrl: 'https://b.4px.com/site/ak-manage',
|
|
44
|
-
packageName: 'cbs-merchant-cli',
|
|
45
|
-
binName: 'mc',
|
|
46
|
-
};
|
|
47
|
-
try {
|
|
48
|
-
const metaPath = join(__dirname, '..', 'site-meta.json');
|
|
49
|
-
const parsed = JSON.parse(readFileSync(metaPath, 'utf-8'));
|
|
50
|
-
return { ...defaults, ...parsed };
|
|
51
|
-
} catch {
|
|
52
|
-
return defaults;
|
|
53
|
-
}
|
|
54
|
-
})();
|
|
55
|
-
|
|
56
|
-
// Skill install dir name derived from package name (e.g. cbs-4px-merchant-cli).
|
|
57
|
-
const skillDirName = siteMeta.packageName.replace(/^@[^/]+\//, '');
|
|
58
|
-
|
|
59
|
-
// Site-specific CLI command name (e.g. fmc / cmc); falls back to mc.
|
|
60
|
-
const bin = siteMeta.binName || 'mc';
|
|
61
|
-
|
|
62
|
-
const home = homedir();
|
|
24
|
+
const ROOT = join(__dirname, '..');
|
|
25
|
+
const ENTRY = join(ROOT, 'dist', 'index.js');
|
|
63
26
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{ root: join(home, '.claude'), label: 'Claude Code' },
|
|
67
|
-
{ root: join(home, '.cline'), label: 'Cline' },
|
|
68
|
-
{ root: join(home, '.qwen'), label: 'QwenCode' },
|
|
69
|
-
{ root: join(home, '.cursor'), label: 'Cursor' },
|
|
70
|
-
{ root: join(home, '.qoderwork'), label: 'QoderWork' },
|
|
71
|
-
{ root: join(home, '.codex'), label: 'Codex' },
|
|
72
|
-
{ root: join(home, '.kilo'), label: 'Kilo Code' },
|
|
73
|
-
{ root: join(home, '.openclaw'), label: 'OpenCLaw' },
|
|
74
|
-
{ root: join(home, '.config', 'opencode'), label: 'OpenCode' },
|
|
75
|
-
];
|
|
76
|
-
|
|
77
|
-
const available = targets.filter(({ root }) => existsSync(root));
|
|
78
|
-
|
|
79
|
-
if (available.length === 0) {
|
|
27
|
+
// Source checkout that has not been built yet — nothing to install.
|
|
28
|
+
if (!existsSync(ENTRY) || !existsSync(join(ROOT, 'skill', 'SKILL.md'))) {
|
|
80
29
|
process.exit(0);
|
|
81
30
|
}
|
|
82
31
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
ttyFd = openSync('/dev/tty', 'w');
|
|
87
|
-
} catch {
|
|
88
|
-
ttyFd = null;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function ttyPrint(msg) {
|
|
92
|
-
if (ttyFd != null) {
|
|
93
|
-
writeSync(ttyFd, msg + '\n');
|
|
94
|
-
} else {
|
|
95
|
-
// Fallback for environments without /dev/tty (e.g. Claude Code, CI agents)
|
|
96
|
-
console.log(msg);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
ttyPrint(
|
|
101
|
-
`\n🚀 Installing BPortal Merchant CLI skill to ${available.length} AI coding tool(s):`,
|
|
102
|
-
);
|
|
32
|
+
const result = spawnSync(process.execPath, [ENTRY, 'skill', 'install'], {
|
|
33
|
+
stdio: ['ignore', 'ignore', 'inherit'],
|
|
34
|
+
});
|
|
103
35
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (existsSync(referenceDirSource)) {
|
|
110
|
-
cpSync(referenceDirSource, join(targetDir, 'reference'), {
|
|
111
|
-
recursive: true,
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
// Write version marker for drift detection at CLI runtime
|
|
115
|
-
const pkgJsonPath = join(__dirname, '..', 'package.json');
|
|
116
|
-
let skillVersion = 'unknown';
|
|
117
|
-
try {
|
|
118
|
-
const pkg = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
|
|
119
|
-
if (typeof pkg.version === 'string') skillVersion = pkg.version;
|
|
120
|
-
} catch { /* fallback to unknown */ }
|
|
121
|
-
writeFileSync(join(targetDir, '.skill-version'), skillVersion);
|
|
122
|
-
ttyPrint(` ✓ ${label} (v${skillVersion})`);
|
|
123
|
-
} catch {
|
|
124
|
-
// Silent fail — don't block npm install
|
|
125
|
-
}
|
|
36
|
+
if (result.status !== 0) {
|
|
37
|
+
const bin = resolveBinName();
|
|
38
|
+
process.stderr.write(
|
|
39
|
+
`\n⚠ skill 自动注册未完成,请手动执行: ${bin} skill install\n\n`,
|
|
40
|
+
);
|
|
126
41
|
}
|
|
127
42
|
|
|
128
|
-
|
|
129
|
-
const configPath = join(home, '.bportal', 'config.json');
|
|
130
|
-
let hasApiKey = false;
|
|
43
|
+
process.exit(0);
|
|
131
44
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
if (!hasApiKey && existsSync(configPath)) {
|
|
45
|
+
/** Site-specific command name (fmc / cmc); falls back to the base name. */
|
|
46
|
+
function resolveBinName() {
|
|
136
47
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
48
|
+
// site-meta.json is written by scripts/build.js; absent in an unbuilt checkout.
|
|
49
|
+
const meta = JSON.parse(readFileSync(join(ROOT, 'site-meta.json'), 'utf-8'));
|
|
50
|
+
return meta.binName || 'mc';
|
|
139
51
|
} catch {
|
|
140
|
-
|
|
52
|
+
return 'mc';
|
|
141
53
|
}
|
|
142
54
|
}
|
|
143
|
-
|
|
144
|
-
if (hasApiKey) {
|
|
145
|
-
ttyPrint('');
|
|
146
|
-
ttyPrint('🎯 Try these commands:');
|
|
147
|
-
ttyPrint('');
|
|
148
|
-
ttyPrint(` ${bin} track get <orderNo> 查询物流轨迹`);
|
|
149
|
-
ttyPrint(` ${bin} label get <orderNo> 获取面单 PDF`);
|
|
150
|
-
ttyPrint(` ${bin} order get <orderNo> 查看订单详情`);
|
|
151
|
-
ttyPrint(` ${bin} order get <orderNo> --output json`);
|
|
152
|
-
ttyPrint('');
|
|
153
|
-
} else {
|
|
154
|
-
ttyPrint('');
|
|
155
|
-
ttyPrint('💡 Set up your API Key to get started:');
|
|
156
|
-
ttyPrint('');
|
|
157
|
-
ttyPrint(' 1️⃣ Get an API Key:');
|
|
158
|
-
ttyPrint(` ${siteMeta.akUrl}`);
|
|
159
|
-
ttyPrint('');
|
|
160
|
-
ttyPrint(' 2️⃣ Sign in:');
|
|
161
|
-
ttyPrint(` ${bin} auth login --api-key SK_xxxxx`);
|
|
162
|
-
ttyPrint('');
|
|
163
|
-
ttyPrint(' 3️⃣ Then try:');
|
|
164
|
-
ttyPrint(` ${bin} track get <orderNo>`);
|
|
165
|
-
ttyPrint(` ${bin} order get <orderNo>`);
|
|
166
|
-
ttyPrint('');
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
// ── PATH check ──
|
|
170
|
-
try {
|
|
171
|
-
execSync(`which ${bin}`, { stdio: 'ignore' });
|
|
172
|
-
} catch {
|
|
173
|
-
ttyPrint(`⚠️ Command "${bin}" not found in PATH.`);
|
|
174
|
-
ttyPrint(' Your npm global bin directory may not be on PATH.');
|
|
175
|
-
ttyPrint(' Run `npm config get prefix` and add its `bin/` to your PATH,');
|
|
176
|
-
ttyPrint(' or reinstall with:');
|
|
177
|
-
ttyPrint('');
|
|
178
|
-
ttyPrint(` npm install -g ${siteMeta.packageName}`);
|
|
179
|
-
ttyPrint('');
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (ttyFd != null) {
|
|
183
|
-
closeSync(ttyFd);
|
|
184
|
-
}
|
package/skill/SKILL.md
CHANGED
|
@@ -37,7 +37,7 @@ description: >-
|
|
|
37
37
|
| 地址簿 | [`reference/order.md`](reference/order.md) | 确认参数格式 |
|
|
38
38
|
| 国家查询 | [`reference/order.md`](reference/order.md) | 确认参数格式 |
|
|
39
39
|
| 产品推荐 | [`reference/product.md`](reference/product.md) | 参数多(国家/重量/电池/邮编等),必须确认 |
|
|
40
|
-
| 理赔查询 | [`reference/
|
|
40
|
+
| 理赔查询 | [`reference/service.md`](reference/service.md) | 参数多(单号/时间/状态/分页),必须确认 |
|
|
41
41
|
| 异常件管理 | [`reference/problem.md`](reference/problem.md) | 确认子命令和参数格式 |
|
|
42
42
|
| 服务中心 | [`reference/service.md`](reference/service.md) | 确认子命令和参数格式 |
|
|
43
43
|
| 财务管理 | [`reference/finance.md`](reference/finance.md) | 确认子命令和参数格式 |
|
|
@@ -61,7 +61,7 @@ description: >-
|
|
|
61
61
|
| `label` | 面单打印:获取面单 PDF 链接 | [`reference/label.md`](reference/label.md) |
|
|
62
62
|
| `order` | 订单管理:查看订单详情、订单列表、地址簿、目的国搜索 | [`reference/order.md`](reference/order.md) |
|
|
63
63
|
| `product` | 产品推荐:推荐产品、产品列表、产品详情、时效查询、搜索产品 | [`reference/product.md`](reference/product.md) |
|
|
64
|
-
| `claim` |
|
|
64
|
+
| `claim` | 理赔查询:按单号/时间/状态查询理赔列表(挂在 `service` 下,即 `fmc service claim ...`) | [`reference/service.md`](reference/service.md) |
|
|
65
65
|
| `problem` | 异常件管理:问题件列表、AI处理建议、通知件、尾程异常、欠费件、拦截件 | [`reference/problem.md`](reference/problem.md) |
|
|
66
66
|
| `service` | 服务中心:售后工单、查件、投诉、服务单详情、处理记录、理赔详情 | [`reference/service.md`](reference/service.md) |
|
|
67
67
|
| `finance` | 财务管理:账户余额、账单、每日费用、未出账汇总及明细、充值记录(在线及线下)、计费明细 | [`reference/finance.md`](reference/finance.md) |
|
|
@@ -86,7 +86,7 @@ description: >-
|
|
|
86
86
|
用户提到"试算运费/运费计算" → `fmc product recommend`
|
|
87
87
|
用户提到"时效/预估时效" → `fmc product eta`
|
|
88
88
|
用户提到"搜索产品/找产品" → `fmc product search`
|
|
89
|
-
用户提到"理赔/索赔/赔偿/丢件赔付" → `fmc claim list`
|
|
89
|
+
用户提到"理赔/索赔/赔偿/丢件赔付" → `fmc service claim list`
|
|
90
90
|
用户提到"异常件/问题件/异常单/异常订单" → `fmc problem list`
|
|
91
91
|
用户提到"处理建议/异常建议/AI建议" → `fmc problem suggest`
|
|
92
92
|
用户提到"通知件" → `fmc problem notify`
|
|
@@ -116,10 +116,10 @@ description: >-
|
|
|
116
116
|
|-----------|---------|--------|------|
|
|
117
117
|
| "查一下这个单号" | `track get`(默认) | — | 无额外上下文时默认查轨迹;若用户要费用/收件人则走 `order get` |
|
|
118
118
|
| "这个包裹的详情" | `order get` | `track get` | "详情"含收件人/费用等结构化信息 |
|
|
119
|
-
| "我的包裹丢了" | `claim list` | `track get` | 用户意图是理赔而非查轨迹 |
|
|
119
|
+
| "我的包裹丢了" | `service claim list` | `track get` | 用户意图是理赔而非查轨迹 |
|
|
120
120
|
| "寄快递/发货选什么" | `product recommend` | — | 发货前选品,需要国家参数 |
|
|
121
121
|
| "运费多少" | `product recommend` | `order get` | 发货前询价用 product;已发货查费用用 order |
|
|
122
|
-
| "查理赔" | `claim list` | `service claim
|
|
122
|
+
| "查理赔" | `service claim list` | `service claim detail` | 前者查列表,后者按理赔单号查详情 |
|
|
123
123
|
| "我的订单" | `order list` | `order get` | 前者是列表,后者按单号查详情 |
|
|
124
124
|
| "运费/多少钱" | `product recommend`(发货前询价) | `order get`(已发货查费用) | 发货前用 product recommend 试算;已发货查费用用 order get |
|
|
125
125
|
|
|
@@ -129,10 +129,10 @@ description: >-
|
|
|
129
129
|
|
|
130
130
|
```bash
|
|
131
131
|
# 配置 API Key(持久化到 ~/.bportal/config.json)
|
|
132
|
-
fmc auth login --api-key
|
|
132
|
+
fmc auth login --api-key sk-xxxxx
|
|
133
133
|
|
|
134
134
|
# 或通过环境变量
|
|
135
|
-
export BPORTAL_API_KEY=
|
|
135
|
+
export BPORTAL_API_KEY=sk-xxxxx
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
获取 API Key: https://b.4px.com/site/ak-manage
|
|
@@ -172,7 +172,7 @@ fmc order list --status IN_TRANSIT
|
|
|
172
172
|
fmc product recommend --country US
|
|
173
173
|
|
|
174
174
|
# 查询理赔列表(按单号)
|
|
175
|
-
fmc claim list --biz-no FPX12345678
|
|
175
|
+
fmc service claim list --biz-no FPX12345678
|
|
176
176
|
|
|
177
177
|
# 查询异常件
|
|
178
178
|
fmc problem list
|
|
@@ -217,9 +217,8 @@ fmc config set baseUrl https://b.4px.com
|
|
|
217
217
|
- [`reference/label.md`](reference/label.md) — 面单打印详细参数
|
|
218
218
|
- [`reference/order.md`](reference/order.md) — 订单管理详细参数
|
|
219
219
|
- [`reference/product.md`](reference/product.md) — 产品推荐与查询详细参数
|
|
220
|
-
- [`reference/claim.md`](reference/claim.md) — 理赔查询详细参数
|
|
221
220
|
- [`reference/problem.md`](reference/problem.md) — 异常件管理详细参数
|
|
222
|
-
- [`reference/service.md`](reference/service.md) —
|
|
221
|
+
- [`reference/service.md`](reference/service.md) — 服务中心与理赔查询详细参数
|
|
223
222
|
- [`reference/finance.md`](reference/finance.md) — 财务管理详细参数
|
|
224
223
|
- [`reference/pickup.md`](reference/pickup.md) — 揽收管理详细参数
|
|
225
224
|
- [`reference/notice.md`](reference/notice.md) — 系统公告详细参数
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cbs-4px-merchant-cli",
|
|
3
|
+
"version": "0.0.4",
|
|
4
|
+
"description": "BPortal Merchant CLI (fmc) skill — BPortal",
|
|
5
|
+
"files": [
|
|
6
|
+
"SKILL.md",
|
|
7
|
+
"package.json",
|
|
8
|
+
"reference/auth.md",
|
|
9
|
+
"reference/config.md",
|
|
10
|
+
"reference/customs.md",
|
|
11
|
+
"reference/finance.md",
|
|
12
|
+
"reference/index.md",
|
|
13
|
+
"reference/label.md",
|
|
14
|
+
"reference/notice.md",
|
|
15
|
+
"reference/order.md",
|
|
16
|
+
"reference/pickup.md",
|
|
17
|
+
"reference/problem.md",
|
|
18
|
+
"reference/product.md",
|
|
19
|
+
"reference/service.md",
|
|
20
|
+
"reference/track.md",
|
|
21
|
+
"reference/update.md"
|
|
22
|
+
],
|
|
23
|
+
"installSource": "cbs-4px-merchant-cli",
|
|
24
|
+
"installMethod": "cli"
|
|
25
|
+
}
|
package/skill/reference/auth.md
CHANGED
|
@@ -21,14 +21,18 @@
|
|
|
21
21
|
|
|
22
22
|
| Flag | Type | Required | Description |
|
|
23
23
|
| --- | --- | --- | --- |
|
|
24
|
-
| `--api-key <key>` | string | yes | API Key
|
|
24
|
+
| `--api-key <key>` | string | yes | API Key(控制台生成的原串,常见前缀 `SK_` 或 `sk-`) |
|
|
25
25
|
|
|
26
26
|
获取 API Key: https://b.4px.com/site/ak-manage
|
|
27
27
|
|
|
28
|
+
> **不要校验或改写用户给的 Key。** 后端同时接受 `SK_xxx` 与 `sk-xxx` 两种前缀,CLI 也不做格式校验。
|
|
29
|
+
> 原样传入即可 —— 因为“看起来格式不对”而拒用、或自行转成大写,只会把一个有效的 Key 弄坏。
|
|
30
|
+
> 有效性以调用结果为准:返回 401 才是无效。
|
|
31
|
+
|
|
28
32
|
#### Examples
|
|
29
33
|
|
|
30
34
|
```bash
|
|
31
|
-
fmc auth login --api-key
|
|
35
|
+
fmc auth login --api-key sk-xxxxx
|
|
32
36
|
```
|
|
33
37
|
|
|
34
38
|
### `fmc auth status`
|
|
@@ -57,6 +61,6 @@ fmc auth status --output json
|
|
|
57
61
|
Authentication Status:
|
|
58
62
|
Status: ✔ 已认证
|
|
59
63
|
Source: ~/.bportal/config.json
|
|
60
|
-
Key:
|
|
64
|
+
Key: sk-1***3456
|
|
61
65
|
Base URL: https://b.4px.com
|
|
62
66
|
```
|
package/skill/reference/index.md
CHANGED
|
@@ -63,6 +63,9 @@ Command **details** are in sibling `<group>.md` files in this directory.
|
|
|
63
63
|
| `fmc customs hscode search` | 查询海关编码 | [customs.md](customs.md) |
|
|
64
64
|
| `fmc customs registration info` | 查询客户备案信息 | [customs.md](customs.md) |
|
|
65
65
|
| `fmc update` | 升级 CLI 及对应 skill 到最新版本 | [update.md](update.md) |
|
|
66
|
+
| `fmc skill install` | 把当前版本的 skill 同步到本机 AI 工具 | [update.md](update.md) |
|
|
67
|
+
| `fmc skill status` | 查看各 AI 工具的 skill 安装与版本状态 | [update.md](update.md) |
|
|
68
|
+
| `fmc skill uninstall` | 移除本 CLI 安装的 skill | [update.md](update.md) |
|
|
66
69
|
|
|
67
70
|
## By group
|
|
68
71
|
|
|
@@ -81,6 +84,7 @@ Command **details** are in sibling `<group>.md` files in this directory.
|
|
|
81
84
|
| `notice` | `list`, `detail`, `message list`, `message detail`, `message unread` | [notice.md](notice.md) |
|
|
82
85
|
| `customs` | `cargo list`, `commodity list`, `commodity detail`, `hscode search`, `registration info` | [customs.md](customs.md) |
|
|
83
86
|
| `update` | (no subcommand) | [update.md](update.md) |
|
|
87
|
+
| `skill` | `install`, `status`, `uninstall` | [update.md](update.md) |
|
|
84
88
|
|
|
85
89
|
## Global flags
|
|
86
90
|
|
|
@@ -95,7 +99,9 @@ Command **details** are in sibling `<group>.md` files in this directory.
|
|
|
95
99
|
## Notes
|
|
96
100
|
|
|
97
101
|
- `track get` 命令无需认证即可使用。
|
|
98
|
-
- 其余大部分命令需要先配置 API Key:`fmc auth login --api-key <
|
|
102
|
+
- 其余大部分命令需要先配置 API Key:`fmc auth login --api-key <key>`。Key 是控制台生成的原串(常见前缀 `SK_` 或 `sk-`),原样传入,不要校验或改写。
|
|
99
103
|
- 新增的 `problem`、`service`、`finance`、`pickup`、`notice`、`customs` 模块均需要 API Key 认证。`order` 模块下的 `address-book`、`country` 子命令也需要认证。
|
|
100
104
|
- 配置文件位于 `~/.bportal/config.json`;升级状态缓存位于 `~/.bportal/update-state.json`。
|
|
101
105
|
- 当检测到新版本可用时,stderr 会输出 `{"_notice":{"type":"update",...}}`;设置环境变量 `BPORTAL_NO_UPDATE_NOTIFIER=1` 可关闭。
|
|
106
|
+
- 当已安装的 skill 版本与 CLI 不一致时,stderr 会输出 `{"_notice":{"type":"skills",...}}`;执行 `fmc skill install` 即可同步。
|
|
107
|
+
- `npm install -g cbs-4px-merchant-cli` **不保证**会自动注册 skill(npm 11 默认拦截安装期脚本,且仍退出 0),安装后应显式执行 `fmc skill install`。
|
|
@@ -1,23 +1,31 @@
|
|
|
1
|
-
# `fmc update`
|
|
1
|
+
# `fmc update` / `fmc skill`
|
|
2
2
|
|
|
3
|
-
升级 CLI
|
|
3
|
+
升级 CLI 本体,以及把当前版本的 skill 同步到本机 AI 工具。
|
|
4
4
|
|
|
5
5
|
## Synopsis
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
fmc update [--check] [--tag <tag>] [--force] [-y] [--output <format>]
|
|
9
|
+
fmc skill install|status|uninstall [--agent <ids>] [--force] [--dry-run] [--output <format>]
|
|
9
10
|
```
|
|
10
11
|
|
|
11
12
|
## Description
|
|
12
13
|
|
|
13
|
-
`fmc update` 通过 npm 全局安装机制,将 CLI 升级到 npm registry
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
`fmc update` 通过 npm 全局安装机制,将 CLI 升级到 npm registry 上的最新版本,
|
|
15
|
+
完成后自动调用一次 `fmc skill install`,把新版 SKILL.md 同步到所有已检测到的
|
|
16
|
+
AI 工具目录(`~/.qoder/skills/`、`~/.claude/skills/`、`~/.cursor/skills/` 等)。
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
> **为何不靠 npm postinstall:**npm 11 默认拦截依赖包的安装期脚本,**且跳过时仍然退出 0**。
|
|
19
|
+
> 所以 skill 铺设不能依赖生命周期钩子,`fmc skill install` 才是唯一可靠的入口;
|
|
20
|
+
> postinstall 仅作为“能跑就顺便跑”的便利钩子保留。
|
|
21
|
+
|
|
22
|
+
**升级目标**:当前 site 的 npm 包 `cbs-4px-merchant-cli`。registry 以本机 `npm config get registry` 为准,
|
|
23
|
+
可用 `BPORTAL_REGISTRY` 临时覆盖。
|
|
18
24
|
|
|
19
25
|
## Options
|
|
20
26
|
|
|
27
|
+
### `update`
|
|
28
|
+
|
|
21
29
|
| Flag | Description |
|
|
22
30
|
| --- | --- |
|
|
23
31
|
| `--check` | 只检查是否有新版本,不执行升级 |
|
|
@@ -26,6 +34,15 @@ fmc update [--check] [--tag <tag>] [--force] [-y] [--output <format>]
|
|
|
26
34
|
| `-y, --yes` | 跳过交互式确认 |
|
|
27
35
|
| `--output <format>` | 输出格式: `text` \| `json`(TTY 默认 text,管道默认 json) |
|
|
28
36
|
|
|
37
|
+
### `skill install` / `skill status` / `skill uninstall`
|
|
38
|
+
|
|
39
|
+
| Flag | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `--agent <ids>` | 只处理指定 AI 工具(逗号分隔,可重复);非法值会报错并列出全部合法 id |
|
|
42
|
+
| `--force` | 覆盖 / 删除非本 CLI 安装的目录(默认拒绝) |
|
|
43
|
+
| `--dry-run` | 只打印将要执行的操作,不写入任何文件 |
|
|
44
|
+
| `--output <format>` | 输出格式: `text` \| `json` |
|
|
45
|
+
|
|
29
46
|
## Environment variables
|
|
30
47
|
|
|
31
48
|
| Variable | Description |
|
|
@@ -53,22 +70,40 @@ fmc update --force -y
|
|
|
53
70
|
|
|
54
71
|
# 临时切换 registry 后升级(不修改 ~/.npmrc)
|
|
55
72
|
BPORTAL_REGISTRY=https://registry.npmjs.org fmc update --check
|
|
73
|
+
|
|
74
|
+
# 把 skill 重新铺到本机所有 AI 工具(安装后的第二步,可反复执行)
|
|
75
|
+
fmc skill install
|
|
76
|
+
|
|
77
|
+
# 先看将要发生什么,不写入任何文件
|
|
78
|
+
fmc skill install --dry-run --output json
|
|
79
|
+
|
|
80
|
+
# 只铺到指定工具
|
|
81
|
+
fmc skill install --agent claude-code,qoder
|
|
82
|
+
|
|
83
|
+
# 查看各工具的安装与版本状态
|
|
84
|
+
fmc skill status --output json
|
|
85
|
+
|
|
86
|
+
# 移除本 CLI 安装的 skill
|
|
87
|
+
fmc skill uninstall
|
|
56
88
|
```
|
|
57
89
|
|
|
58
90
|
## JSON envelope (`--output json`)
|
|
59
91
|
|
|
92
|
+
### `update`
|
|
93
|
+
|
|
60
94
|
```json
|
|
61
95
|
{
|
|
62
96
|
"ok": true,
|
|
63
97
|
"action": "updated",
|
|
64
98
|
"package": "cbs-4px-merchant-cli",
|
|
65
|
-
"registry": "https://registry.
|
|
99
|
+
"registry": "https://registry.npmjs.org",
|
|
66
100
|
"tag": "latest",
|
|
67
|
-
"previous_version": "
|
|
68
|
-
"current_version": "
|
|
69
|
-
"latest_version": "
|
|
101
|
+
"previous_version": "0.0.2",
|
|
102
|
+
"current_version": "0.0.3",
|
|
103
|
+
"latest_version": "0.0.3",
|
|
70
104
|
"install_method": "npm",
|
|
71
|
-
"
|
|
105
|
+
"skill_sync": "ok",
|
|
106
|
+
"message": "已升级到 v0.0.3,skill 已同步。重新打开终端使生效。"
|
|
72
107
|
}
|
|
73
108
|
```
|
|
74
109
|
|
|
@@ -82,16 +117,63 @@ BPORTAL_REGISTRY=https://registry.npmjs.org fmc update --check
|
|
|
82
117
|
| `manual_required` | CLI 非 npm 全局安装,需手动升级 |
|
|
83
118
|
| `error` | 失败(详见 `error.code`:`NETWORK` / `NPM_NOT_FOUND` / `NPM_INSTALL_FAILED` / `EACCES`) |
|
|
84
119
|
|
|
85
|
-
|
|
120
|
+
`skill_sync` 取值 `ok` \| `failed`。注意:**skill 同步失败不会把 `ok` 置为 false**,
|
|
121
|
+
因为二进制确实升级成功了;此时 `hint` 会提示手动执行 `fmc skill install`。
|
|
122
|
+
|
|
123
|
+
### `skill install` / `skill status` / `skill uninstall`
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"ok": true,
|
|
128
|
+
"action": "installed",
|
|
129
|
+
"package": "cbs-4px-merchant-cli",
|
|
130
|
+
"skill": { "name": "cbs-4px-merchant-cli", "version": "0.0.3" },
|
|
131
|
+
"api_key_configured": false,
|
|
132
|
+
"targets": [
|
|
133
|
+
{
|
|
134
|
+
"agent": "claude-code",
|
|
135
|
+
"label": "Claude Code",
|
|
136
|
+
"dir": "/Users/me/.claude/skills/cbs-4px-merchant-cli",
|
|
137
|
+
"outcome": "updated",
|
|
138
|
+
"previous_version": "0.0.2",
|
|
139
|
+
"removed": ["reference/claim.md"]
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"summary": { "total": 1, "installed": 0, "updated": 1, "skipped": 0, "failed": 0 },
|
|
143
|
+
"hint": "尚未配置 API Key。申请地址: https://b.4px.com/site/ak-manage,然后执行 fmc auth login --api-key <key>"
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`outcome` 取值:
|
|
148
|
+
|
|
149
|
+
| Value | Meaning |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `installed` | 全新安装(目录原本不存在或为空) |
|
|
152
|
+
| `updated` | 覆盖升级,`removed` 列出被清理的孤儿文件 |
|
|
153
|
+
| `skipped` | 目录归属不明或属于其他安装器,未触碰(`reason` 说明原因,`--force` 可覆盖) |
|
|
154
|
+
| `failed` | 写入失败(`reason` 为错误信息) |
|
|
155
|
+
|
|
156
|
+
`api_key_configured` 只是存在性布尔值,**不会回显 Key 本身**。
|
|
157
|
+
`fmc skill status` 的 `targets` 则携带 `state` / `installed_version` / `installed_source`,
|
|
158
|
+
用于分辨“我装的”和“别人装的”。
|
|
159
|
+
|
|
160
|
+
## Passive notifiers
|
|
86
161
|
|
|
87
162
|
普通命令运行后(如 `fmc track get ...`),若本地缓存(`~/.bportal/update-state.json`,
|
|
88
163
|
TTL 24 小时)发现 registry 上有新版本,stderr 会输出一条 JSON 通知:
|
|
89
164
|
|
|
90
165
|
```json
|
|
91
|
-
{"_notice":{"type":"update","package":"cbs-4px-merchant-cli","current":"
|
|
166
|
+
{"_notice":{"type":"update","package":"cbs-4px-merchant-cli","current":"0.0.2","latest":"0.0.3","hint":"Run: fmc update to upgrade"}}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
若本机已安装的 skill 版本与 CLI 不一致,还会额外输出一条漂移通知:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{"_notice":{"type":"skills","current":"0.0.2","expected":"0.0.3","hint":"Run: fmc skill install to sync skills with CLI v0.0.3"}}
|
|
92
173
|
```
|
|
93
174
|
|
|
94
|
-
|
|
175
|
+
漂移检测会扫描**所有**已安装目录;多个工具版本不一致时 `current` 为数组。
|
|
176
|
+
AI Agent 可据此提示用户升级或同步。设置 `BPORTAL_NO_UPDATE_NOTIFIER=1` 即可关闭升级提示。
|
|
95
177
|
|
|
96
178
|
## Failure handling
|
|
97
179
|
|
|
@@ -100,3 +182,6 @@ AI Agent 可据此提示用户升级。设置 `BPORTAL_NO_UPDATE_NOTIFIER=1` 即
|
|
|
100
182
|
或使用 `sudo`。
|
|
101
183
|
- **网络/registry 不可达**:检查 VPN,或用 `BPORTAL_REGISTRY` 临时切换。
|
|
102
184
|
- **非 npm 安装**:`action=manual_required`,envelope 内 `upgrade_command` 字段给出确切的手动升级命令。
|
|
185
|
+
- **skill 同步失败**:`skill_sync=failed`,二进制已升级,手动执行 `fmc skill install` 即可。
|
|
186
|
+
- **目录被跳过**:`outcome=skipped` 说明该目录不是本 CLI 装的(比如技能市场装的)。
|
|
187
|
+
先用 `fmc skill status` 看 `installed_source` 确认归属,确实该覆盖再加 `--force`。
|