@yixinkj/priority-buyer-alert-cli 0.1.25 → 0.1.41
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/index.js +81 -0
- package/package.json +1 -1
- package/skill/SKILL.md +10 -8
- package/skills.json +3 -3
package/index.js
CHANGED
|
@@ -684,9 +684,88 @@ function prepareMacBinaries(target) {
|
|
|
684
684
|
}
|
|
685
685
|
}
|
|
686
686
|
|
|
687
|
+
/// 同机保留的运行时版本数(含当前正在用的这一版)。
|
|
688
|
+
///
|
|
689
|
+
/// 每升一版就多留一份二进制,从来没人删。真机上 public-customer-reactivation 攒了 16 份
|
|
690
|
+
/// 共 94M,三个 Skill 合计 164M,而任何时刻真正被执行的只有一份。
|
|
691
|
+
/// 不设成 1 是因为同一台机器会交替跑不同 dist-tag(例如 latest 与 beta),
|
|
692
|
+
/// 只留当前版会让每次切换都重新下载一遍。
|
|
693
|
+
const RUNTIME_VERSIONS_TO_KEEP = 2;
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* 清理旧版本运行时目录,按最近使用时间保留最新的若干份。
|
|
697
|
+
*
|
|
698
|
+
* 尽力而为:删不掉就算了,绝不因为清理失败影响本次运行。
|
|
699
|
+
* @returns {string[]} 实际删掉的版本目录名。
|
|
700
|
+
*/
|
|
701
|
+
function pruneOldRuntimeVersions(
|
|
702
|
+
versionsRoot = path.dirname(VERSION_ROOT),
|
|
703
|
+
active = path.basename(VERSION_ROOT),
|
|
704
|
+
keepCount = RUNTIME_VERSIONS_TO_KEEP
|
|
705
|
+
) {
|
|
706
|
+
let entries;
|
|
707
|
+
try {
|
|
708
|
+
entries = fs.readdirSync(versionsRoot, { withFileTypes: true });
|
|
709
|
+
} catch {
|
|
710
|
+
return [];
|
|
711
|
+
}
|
|
712
|
+
// 先把当前版本的时间戳刷新成现在:保留依据是「最近用过」而不是「最近装的」,
|
|
713
|
+
// 否则交替使用两个版本时,先装的那个会被误判成最旧的。
|
|
714
|
+
try {
|
|
715
|
+
const now = new Date();
|
|
716
|
+
fs.utimesSync(path.join(versionsRoot, active), now, now);
|
|
717
|
+
} catch {
|
|
718
|
+
// 目录还没建好(首次安装前)就跳过,不影响后面的判断。
|
|
719
|
+
}
|
|
720
|
+
const ranked = entries
|
|
721
|
+
.filter((entry) => entry.isDirectory())
|
|
722
|
+
.map((entry) => entry.name)
|
|
723
|
+
// 排除 v<版本>.staging-<pid>:那可能是另一个进程正在写的半成品。
|
|
724
|
+
.filter((name) => /^v\d/.test(name) && !name.includes('.staging-'))
|
|
725
|
+
.map((name) => {
|
|
726
|
+
let usedAt = 0;
|
|
727
|
+
try {
|
|
728
|
+
usedAt = fs.statSync(path.join(versionsRoot, name)).mtimeMs;
|
|
729
|
+
} catch {
|
|
730
|
+
usedAt = 0;
|
|
731
|
+
}
|
|
732
|
+
return { name, usedAt };
|
|
733
|
+
})
|
|
734
|
+
.sort((a, b) => b.usedAt - a.usedAt);
|
|
735
|
+
|
|
736
|
+
const keep = new Set(ranked.slice(0, keepCount).map((item) => item.name));
|
|
737
|
+
keep.add(active);
|
|
738
|
+
|
|
739
|
+
const removed = [];
|
|
740
|
+
for (const { name } of ranked) {
|
|
741
|
+
if (keep.has(name)) continue;
|
|
742
|
+
try {
|
|
743
|
+
fs.rmSync(path.join(versionsRoot, name), { recursive: true, force: true });
|
|
744
|
+
removed.push(name);
|
|
745
|
+
} catch {
|
|
746
|
+
// 正被占用或权限不足都不是本次运行该处理的问题,留到下次。
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
return removed;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* 每次启动都清理一次旧版本,并把删掉的版本写到 stderr。
|
|
754
|
+
*
|
|
755
|
+
* 放在「已安装」的快路径上也要跑:只在新装时清理的话,一台停止升级的机器会把
|
|
756
|
+
* 历史版本永远留着。
|
|
757
|
+
*/
|
|
758
|
+
function reportPrunedRuntimeVersions() {
|
|
759
|
+
const removed = pruneOldRuntimeVersions();
|
|
760
|
+
if (removed.length > 0) {
|
|
761
|
+
console.error(`[${SKILL_ID}] 已清理旧版本运行时:${removed.join('、')}`);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
687
765
|
async function ensureInstalled(target) {
|
|
688
766
|
if (isInstalled(target)) {
|
|
689
767
|
prepareMacBinaries(target);
|
|
768
|
+
reportPrunedRuntimeVersions();
|
|
690
769
|
return;
|
|
691
770
|
}
|
|
692
771
|
const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), `${SKILL_ID}-install-`));
|
|
@@ -713,6 +792,7 @@ async function ensureInstalled(target) {
|
|
|
713
792
|
fs.rmSync(VERSION_ROOT, { recursive: true, force: true });
|
|
714
793
|
fs.renameSync(stagingRoot, VERSION_ROOT);
|
|
715
794
|
prepareMacBinaries(target);
|
|
795
|
+
reportPrunedRuntimeVersions();
|
|
716
796
|
} finally {
|
|
717
797
|
fs.rmSync(stagingRoot, { recursive: true, force: true });
|
|
718
798
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
@@ -926,6 +1006,7 @@ export {
|
|
|
926
1006
|
isHelpRequest,
|
|
927
1007
|
isInstalled,
|
|
928
1008
|
parseSkillMetadata,
|
|
1009
|
+
pruneOldRuntimeVersions,
|
|
929
1010
|
releaseUrls,
|
|
930
1011
|
resolveSkillGate,
|
|
931
1012
|
runtimeManifestUrl,
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: 哨兵预警-0812
|
|
3
3
|
description: 重点买家未回复预警。只读扫描阿里国际站询盘列表,挑出重点买家(金品店铺为 L2 及以上真实档;出口通店铺只有 L1+ 一个值,它是 L1–L4 的合集,必然包含 L1),判断买家最后一句是否超过 SLA 仍没有真人业务员回复,并输出中文预警清单;机器人自动接待不算人工回复。Use when 用户要求检查重点买家有没有超时未回复、查询盘超时提醒、看 L3/L4 有没有快凉的,或要求运行重点买家预警。
|
|
4
|
-
version: "0.1.
|
|
4
|
+
version: "0.1.41"
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# 重点买家预警
|
|
@@ -19,7 +19,7 @@ version: "0.1.25"
|
|
|
19
19
|
## 运行入口
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
22
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
23
23
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
24
24
|
--start
|
|
25
25
|
```
|
|
@@ -36,10 +36,11 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
36
36
|
- `--re-alert 30`:仍未回复时每隔多少分钟升级重提。不传表示同一轮等待只提醒一次。
|
|
37
37
|
- `--mark`:推进提醒水位与升级计数。只有无人值守的心跳式调用才使用;人工查看不要带。
|
|
38
38
|
- `--verify-all-replied`:对全部「末条是我方发出」的重点买家都做详情核验,更慢更全。
|
|
39
|
+
- `--detail-limit 40`:单轮最多打开多少条详情核验,默认 40,最多 300。**它直接决定「本轮没覆盖多少条」**:忙店铺一轮覆盖不完是已知代价,剩下的靠下一轮心跳滚动补齐。人工要一次看全时才显式放宽(例如 `--detail-limit 200`),代价是单轮耗时成比例增长,不要用在心跳里。
|
|
39
40
|
|
|
40
41
|
### 关于买家等级
|
|
41
42
|
|
|
42
|
-
阿里国际站买家等级共 **L0–L4 五档,L4
|
|
43
|
+
阿里国际站买家等级共 **L0–L4 五档,L4 封顶**:
|
|
43
44
|
|
|
44
45
|
| 等级 | 站内名称 | 中文 | 判定 |
|
|
45
46
|
| --- | --- | --- | --- |
|
|
@@ -67,7 +68,7 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
67
68
|
按返回的 `poll_after_seconds` 静默轮询,不逐条播报进度:
|
|
68
69
|
|
|
69
70
|
```bash
|
|
70
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
71
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
71
72
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
72
73
|
--poll-run "run_id"
|
|
73
74
|
```
|
|
@@ -86,6 +87,7 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
86
87
|
- 有预警时按文件已有顺序逐条转述:谁的(负责人)、哪个买家和国家、哪一档等级、已等待多久、买家最后那句话。顺序已按等级和等待时长排好,不要重排。
|
|
87
88
|
- 语气是「这条重点客户该接了」,不是追责。`提醒次数` 达到 3 次以上时可以建议同步主管。
|
|
88
89
|
- 每条可以顺带提议起草回复,但只建议、不替发。
|
|
90
|
+
- **「因超过单轮核验上限没有核验」这一条必须转述**,不能省。它意味着本轮结论没有覆盖那些询盘:`alerts_reported == 0` 的正确读法是「已核验的那些里没有超时未回复」,不是「没有风险」。要一次看全,让用户用 `--detail-limit` 放宽后重跑。
|
|
89
91
|
- 文件末尾的「数据提醒」如实转述,不要把没抓到等级的询盘当成重点买家。其中「没能取回买家资料」和「因超过单轮核验上限没有核验」都意味着本轮结论没有覆盖这些询盘,不能说成「已确认没有风险」。
|
|
90
92
|
- 「盲区大小」那一条是当前等级口径没有覆盖的等待买家数量。如实转述,但不要据此自行把它们当作预警冒泡。
|
|
91
93
|
- 不输出原始 JSON、绝对路径、买家邮箱电话或任何 token。
|
|
@@ -96,7 +98,7 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
96
98
|
Skill 起草第一次回复。
|
|
97
99
|
|
|
98
100
|
```bash
|
|
99
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
101
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
100
102
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
101
103
|
--first-response-scan --since 24
|
|
102
104
|
```
|
|
@@ -159,12 +161,12 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
159
161
|
|
|
160
162
|
```bash
|
|
161
163
|
# 排查预警判定
|
|
162
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
164
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
163
165
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
164
166
|
--start --explain 10
|
|
165
167
|
|
|
166
168
|
# 排查新询盘判定
|
|
167
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
169
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
168
170
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
169
171
|
--first-response-scan --since 24 --explain 10
|
|
170
172
|
```
|
|
@@ -192,7 +194,7 @@ npx -y @yixinkj/priority-buyer-alert-cli@beta \
|
|
|
192
194
|
```
|
|
193
195
|
|
|
194
196
|
```bash
|
|
195
|
-
npx -y @yixinkj/priority-buyer-alert-cli@
|
|
197
|
+
npx -y @yixinkj/priority-buyer-alert-cli@latest \
|
|
196
198
|
--skill-path "本次实际读取的 SKILL.md 绝对路径" \
|
|
197
199
|
--start --minutes 30 --re-alert 30 --mark
|
|
198
200
|
```
|
package/skills.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"runtimeVersion": "0.1.
|
|
2
|
+
"runtimeVersion": "0.1.33",
|
|
3
3
|
"platforms": {
|
|
4
4
|
"darwin-arm64": {
|
|
5
5
|
"id": "mac-arm64",
|
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
},
|
|
20
20
|
"bridge": {
|
|
21
21
|
"package": "@yixinkj/yixin-bridge-cli",
|
|
22
|
-
"minVersion": "1.0.
|
|
22
|
+
"minVersion": "1.0.7"
|
|
23
23
|
},
|
|
24
24
|
"skill": {
|
|
25
25
|
"name": "哨兵预警-0812",
|
|
26
26
|
"id": "priority-buyer-alert",
|
|
27
|
-
"version": "0.1.
|
|
27
|
+
"version": "0.1.41",
|
|
28
28
|
"bin": "priority-buyer-alert-cli"
|
|
29
29
|
}
|
|
30
30
|
}
|