evolcore 0.0.32 → 0.0.34
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 +61 -0
- package/bin/ec.js +3 -2
- package/bin/install-codex-managed-hooks.mjs +135 -37
- package/dist/agents/baseagent-availability.js +20 -36
- package/dist/agents/claude-runner.js +111 -15
- package/dist/agents/codex/app-server-client.js +3 -0
- package/dist/agents/codex/diagnostics.js +112 -54
- package/dist/agents/codex-runner.js +241 -63
- package/dist/agents/ecagent-runner.js +78 -33
- package/dist/agents/runner-types.js +5 -6
- package/dist/aun/aid/identity.js +1 -1
- package/dist/aun/group/operations.js +0 -1
- package/dist/aun/msg/history.js +1 -0
- package/dist/aun/msg/p2p.js +0 -1
- package/dist/aun/outbox.js +50 -1
- package/dist/channels/aun.js +44 -8
- package/dist/channels/daemon.js +261 -3
- package/dist/cli/agent-command.js +58 -24
- package/dist/cli/agent.js +1 -1
- package/dist/cli/aun-commands.js +368 -31
- package/dist/cli/contact.js +8 -2
- package/dist/cli/ctl-command.js +3 -1
- package/dist/cli/daemon-commands.js +197 -27
- package/dist/cli/debug-mode.js +154 -0
- package/dist/cli/fs-command.js +2 -1
- package/dist/cli/handoff-command.js +3 -0
- package/dist/cli/index.js +98 -67
- package/dist/cli/init.js +2 -2
- package/dist/cli/integrity-command.js +196 -0
- package/dist/cli/managed-command-guard.js +5 -0
- package/dist/cli/memory-command.js +166 -146
- package/dist/cli/queue-command.js +9 -4
- package/dist/cli/session-command.js +194 -0
- package/dist/cli/skill-command.js +78 -2
- package/dist/cli/task-context.js +1 -0
- package/dist/cli/thread-command.js +622 -0
- package/dist/cli/trigger-command.js +10 -3
- package/dist/config/builtin-roles.js +1 -0
- package/dist/config/config-field-policy.js +6 -3
- package/dist/config/config-manager.js +26 -2
- package/dist/config/contact-book-store.js +5 -0
- package/dist/config/resolved-config-op.js +3 -0
- package/dist/config/role-service.js +13 -0
- package/dist/config/runtime-env.js +16 -0
- package/dist/config-store.js +45 -0
- package/dist/core/audit/log-integrity.js +3 -1
- package/dist/core/auth/agent-delegation.js +133 -36
- package/dist/core/auth/debug-context.js +139 -0
- package/dist/core/auth/delegation-diagnostics.js +414 -0
- package/dist/core/auth/operation-authorizer.js +25 -2
- package/dist/core/auth/operation-catalog.js +49 -0
- package/dist/core/background-session/session-cleanup.js +212 -0
- package/dist/core/background-session/types.js +10 -0
- package/dist/core/bootstrap-messages.js +1 -1
- package/dist/core/bootstrap-service.js +6 -3
- package/dist/core/command/agent-control.js +18 -26
- package/dist/core/command/command-handler.js +197 -27
- package/dist/core/command/daemon-diagnostics.js +1 -0
- package/dist/core/command/memory-slash.js +6 -2
- package/dist/core/command/menu-catalog.js +51 -1
- package/dist/core/command/menu-handler.js +114 -23
- package/dist/core/command/menu-protocol.js +25 -1
- package/dist/core/command/skill-slash.js +322 -0
- package/dist/core/command/slash-gate.js +6 -4
- package/dist/core/command/slash-handler.js +195 -13
- package/dist/core/command/topic-slash.js +528 -0
- package/dist/core/daemon-bootstrap.js +4 -7
- package/dist/core/evolagent-registry.js +20 -5
- package/dist/core/file-integrity/read.js +61 -0
- package/dist/core/file-integrity/store.js +262 -0
- package/dist/core/handoff/runtime.js +5 -11
- package/dist/core/handoff/store.js +5 -0
- package/dist/core/ipc-registration.js +175 -3
- package/dist/core/memory/batch-meta.js +132 -0
- package/dist/core/memory/consolidation-context.js +83 -29
- package/dist/core/memory/consolidation-ops-records.js +49 -16
- package/dist/core/memory/consolidation-queue-format.js +21 -0
- package/dist/core/memory/consolidation.js +264 -205
- package/dist/core/memory/index-manager.js +19 -28
- package/dist/core/memory/memory-admin.js +19 -14
- package/dist/core/memory/memory-document.js +53 -9
- package/dist/core/memory/memory-writer.js +30 -15
- package/dist/core/message/aun-ipc-sender.js +161 -6
- package/dist/core/message/im-renderer.js +169 -10
- package/dist/core/message/message-bridge.js +15 -4
- package/dist/core/message/message-log.js +1 -0
- package/dist/core/message/peer-mode.js +6 -1
- package/dist/core/message/response-engine.js +929 -110
- package/dist/core/message/subtask-tool-projection.js +140 -0
- package/dist/core/model/catalog-service.js +17 -12
- package/dist/core/permission/ec-command-parser.js +217 -9
- package/dist/core/permission/protected-paths.js +5 -1
- package/dist/core/permission/readonly-shell-query.js +43 -5
- package/dist/core/permission/session-path-grants.js +334 -0
- package/dist/core/permission/tool-canonical.js +226 -0
- package/dist/core/permission/tool-policy.js +30 -62
- package/dist/core/role/runtime-policy.js +21 -10
- package/dist/core/session/session-fs-store.js +123 -8
- package/dist/core/session/session-idle-monitor.js +249 -22
- package/dist/core/session/session-manager.js +129 -14
- package/dist/core/skill/command-parser.js +13 -0
- package/dist/core/skill/index-generator.js +21 -4
- package/dist/core/skill/startup.js +41 -0
- package/dist/core/skill/switch-resolver.js +55 -29
- package/dist/core/system-session/grants.js +40 -0
- package/dist/core/system-session/memory.js +222 -0
- package/dist/core/system-session/registry.js +74 -0
- package/dist/core/system-session/types.js +14 -0
- package/dist/core/thread/command-parser.js +125 -0
- package/dist/core/thread/index.js +1 -0
- package/dist/core/thread/ipc-operation.js +95 -0
- package/dist/core/thread/thread-context-storage.js +131 -0
- package/dist/core/thread/thread-operation.js +258 -0
- package/dist/core/thread/thread-route.js +33 -0
- package/dist/core/thread/thread-service.js +770 -0
- package/dist/core/thread/types.js +1 -0
- package/dist/eck/kit-renderer.js +7 -2
- package/dist/eck/manifest-engine.js +24 -4
- package/dist/eck/message-renderer.js +35 -0
- package/dist/index.js +19 -7
- package/dist/ipc.js +140 -50
- package/dist/paths.js +93 -0
- package/dist/response-system/engines/v1/proactive-flow.js +169 -80
- package/dist/stats/billing.js +20 -8
- package/dist/trigger/authorization.js +57 -28
- package/dist/trigger/feedback.js +13 -2
- package/dist/trigger/parser.js +70 -1
- package/dist/trigger/system-definitions.js +3 -3
- package/dist/trigger/validation.js +14 -0
- package/dist/utils/cross-platform.js +11 -2
- package/dist/utils/error-dict.json +18 -4
- package/dist/utils/error-utils.js +143 -1
- package/dist/utils/instance-registry.js +13 -8
- package/dist/utils/log-writer.js +12 -0
- package/dist/utils/process-introspect.js +11 -0
- package/kits/docs/context-assembly.md +1 -1
- package/kits/docs/evolcore/INDEX.md +1 -0
- package/kits/docs/evolcore/agent-create.md +40 -28
- package/kits/docs/evolcore/agent.md +21 -6
- package/kits/docs/evolcore/config.md +2 -2
- package/kits/docs/evolcore/ctl.md +2 -2
- package/kits/docs/evolcore/ec-capabilities.md +5 -1
- package/kits/docs/evolcore/fs-architecture.md +4 -5
- package/kits/docs/evolcore/fs.md +1 -1
- package/kits/docs/evolcore/group-collaboration.md +4 -6
- package/kits/docs/evolcore/group.md +11 -12
- package/kits/docs/evolcore/memory-architecture.md +4 -5
- package/kits/docs/evolcore/memory-consolidation.md +19 -15
- package/kits/docs/evolcore/memory-tags.md +3 -1
- package/kits/docs/evolcore/memory.md +24 -12
- package/kits/docs/evolcore/menu-exec-schema-commands.md +2 -2
- package/kits/docs/evolcore/menu-protocol.md +7 -0
- package/kits/docs/evolcore/model.md +16 -0
- package/kits/docs/evolcore/msg.md +8 -11
- package/kits/docs/evolcore/thread-chain.md +267 -0
- package/kits/docs/prompt-loading-architecture.md +1 -1
- package/kits/eck_manifest.json +55 -40
- package/kits/eck_manifest.memory.json +0 -12
- package/kits/eck_message_manifest.json +169 -10
- package/kits/rules/01-overview.md +11 -0
- package/kits/rules/03-identity.md +6 -3
- package/kits/rules/05-venue.md +1 -1
- package/kits/rules/06-channel.md +1 -1
- package/kits/rules/07-memory-and-thread.md +199 -0
- package/kits/schemas/_meta.json +7 -1
- package/kits/schemas/agent-config.schema.13.json +1 -1
- package/kits/schemas/daemon.schema.7.json +140 -0
- package/kits/schemas/relation-config.schema.9.json +18 -3
- package/kits/schemas/role-config.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.1.json +6 -6
- package/kits/schemas/single-session.schema.2.json +6 -6
- package/kits/schemas/single-session.schema.3.json +6 -6
- package/kits/skills/.switches.json +12 -1
- package/kits/skills/ec-group/SKILL.md +234 -0
- package/kits/skills/ec-skill/SKILL.md +10 -1
- package/kits/skills/ec-skill/scripts/cli.mjs +16 -2
- package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
- package/kits/skills/scrapling-article-fetch/SKILL.md +128 -0
- package/kits/skills/scrapling-article-fetch/scripts/check_python_env.py +54 -0
- package/kits/skills/scrapling-article-fetch/scripts/render_markdown_reply.py +35 -0
- package/kits/skills/scrapling-article-fetch/scripts/run_pipeline.sh +16 -0
- package/kits/skills/scrapling-article-fetch/scripts/scrapling_fetch.py +344 -0
- package/kits/skills/thread-ops/SKILL.md +492 -0
- package/kits/skills/wechat-article-media-download/SKILL.md +65 -0
- package/kits/skills/wechat-article-media-download/scripts/download.py +163 -0
- package/kits/skills/wechat-article-reader/SKILL.md +97 -0
- package/kits/skills/wechat-article-reader/scripts/fetch.mjs +256 -0
- package/kits/templates/bootstrap-welcome.md +7 -7
- package/kits/templates/memory-consolidation/forget.md +7 -2
- package/kits/templates/memory-consolidation/generalize.md +9 -4
- package/kits/templates/memory-consolidation/notes.md +11 -11
- package/kits/templates/memory-consolidation/profile.md +8 -3
- package/kits/templates/memory-consolidation/promote.md +8 -3
- package/kits/templates/memory-consolidation/workflow.md +6 -6
- package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
- package/kits/templates/message-fragments/item.md +2 -1
- package/kits/templates/message-fragments/thread-context.md +6 -0
- package/kits/templates/message-fragments/trigger-session.md +2 -0
- package/kits/templates/message-fragments/trigger-thread-check.md +2 -0
- package/kits/templates/roles/member.json +2 -0
- package/kits/templates/roles/visitor.json +2 -0
- package/kits/templates/system-fragments/bootstrap.md +67 -72
- package/kits/templates/system-fragments/channel.md +3 -6
- package/kits/templates/system-fragments/commands.md +1 -0
- package/kits/templates/system-fragments/managed-runtime.md +15 -0
- package/kits/templates/system-fragments/memory.md +16 -9
- package/kits/templates/system-fragments/reply.md +7 -6
- package/kits/templates/system-fragments/session.md +5 -14
- package/package.json +6 -3
- package/dist/core/memory/memory-session-policy.js +0 -41
- package/dist/core/memory/memory-signature.js +0 -257
- package/kits/docs/evolcore/group-fs.md +0 -17
- package/kits/docs/venues/aun-group.md +0 -45
- package/kits/docs/venues/group.md +0 -43
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: thread-ops
|
|
3
|
+
description: >-
|
|
4
|
+
话题链(Thread Chain)操作规程与**话题总结**。教会 agent 如何在跨会话协作中:
|
|
5
|
+
发起委托(选话题、发消息、按需创建 Trigger)、处理收到的委托(判断是否回复)、
|
|
6
|
+
以及汇报回来源话题。也负责维护话题自身——**总结话题**(用户说"总结一下话题"
|
|
7
|
+
"总结话题""给这个话题写个总结""summarize this topic"时:用 summary show 拿到
|
|
8
|
+
上次覆盖游标 coveredThroughTs,用 history --after 读增量,再 summary set 写入)、
|
|
9
|
+
必要时**重命名话题**(名称还是"你好""话题会话"等占位词时)。
|
|
10
|
+
核心是时序语义:发出即结束 turn、Trigger 是唤醒信号不是执行脚本、
|
|
11
|
+
决策权归 agent 自己、无等齐原语靠主动查询合并。
|
|
12
|
+
适用场景:需要另一个 agent 输入 / 收到任务委托需代为联系第三方("你帮我问一下 X"、
|
|
13
|
+
"转告 Y"、"去查 Z 那边的情况")/ 作为中间人需要向当前对端以外转发请求或查询 /
|
|
14
|
+
需要总结 / 整理当前话题的场景。
|
|
15
|
+
license: MIT
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
# `thread-ops` 操作规程
|
|
19
|
+
|
|
20
|
+
## 一、Skill 的定位
|
|
21
|
+
|
|
22
|
+
本 skill 是**操作性 skill**,面向 agent 在跨会话协作中使用。
|
|
23
|
+
|
|
24
|
+
**核心价值:教会 agent 话题链的时序语义,而非命令清单。**
|
|
25
|
+
|
|
26
|
+
- `ec thread list --help` 告诉 agent"这条命令有哪些参数"
|
|
27
|
+
- 本 skill 告诉 agent"什么时候用这条命令、用完后会发生什么、下一步该做什么"
|
|
28
|
+
|
|
29
|
+
本 skill 不添加工具,不改变系统权限。
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 二、加载判据:何时必须加载本 skill
|
|
34
|
+
|
|
35
|
+
### 必须加载(L2 跨 agent 委派)
|
|
36
|
+
|
|
37
|
+
以下任一条件成立时加载:
|
|
38
|
+
|
|
39
|
+
1. **收到话题链消息**:上下文注入了"当前任务来源 = 话题 X / 对端 Y"
|
|
40
|
+
2. **收到任务委托、需要转去联系第三方**:对方(人或 agent)让你去问另一个人或 agent,完成任务的下一步需要联系当前对端以外的对象——先加载本 skill,再按流程 A 操作
|
|
41
|
+
3. **需要给当前对端以外的对象发消息**:只凭当前会话直发会被拒绝,必须走话题
|
|
42
|
+
4. **需要委托另一个 agent**:判断当前任务需要对方的输入
|
|
43
|
+
5. **并发问多方**:同时向 C 和 D 发出委托,等两个都回后再汇总
|
|
44
|
+
6. **要汇报回来源话题**:任务完成,需要回复到来源话题
|
|
45
|
+
|
|
46
|
+
> 判据 2 和 3 不依赖是否已有话题链注入:只要任务需要联系当前对端/当前群以外的对象,就直接按下方流程 A 操作。
|
|
47
|
+
|
|
48
|
+
**为什么必须加载 skill(反直觉的关键点)**:
|
|
49
|
+
|
|
50
|
+
- **发出即结束**(反直觉):`ec msg send --thread T2` 返回后,当前 turn 立刻终止,不阻塞等待
|
|
51
|
+
- **Trigger 是唤醒信号,不是执行脚本**(新概念):到期时提醒检查对端是否回复,不保证对端已回、不强制回复、不指示执行任何操作;收到 Trigger 通知后,agent 自主决定下一步
|
|
52
|
+
- **决策权在自己**(与 handoff 完全相反):要不要回、何时回、回什么,完全自主
|
|
53
|
+
- **无"等齐"原语**(分支合并的核心):想合并多方回复,就在各自 turn 里主动用 `ec thread history` 查另一话题
|
|
54
|
+
|
|
55
|
+
### 不需要 skill(L0/L1 本地操作)
|
|
56
|
+
|
|
57
|
+
**L0 — 本会话元数据管理**:改当前话题名/标签/状态,查看当前话题元数据。命令自解释,`--help` 足够。
|
|
58
|
+
|
|
59
|
+
**L1 — 跨会话查询**:列出与某对端的话题,读某话题的历史,查看话题摘要。纯查询,无时序复杂度。
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 三、核心概念速查
|
|
64
|
+
|
|
65
|
+
| 概念 | 定义 |
|
|
66
|
+
|---|---|
|
|
67
|
+
| 话题(topic/thread) | agent 与对端之间一条独立的讨论线 |
|
|
68
|
+
| threadId | 话题的跨端统一标识符,格式 `thread-<ms>-<seq4>-<rand4>` |
|
|
69
|
+
| 主会话 | threadId 为空的会话,每对 agent–对端关系各有一个 |
|
|
70
|
+
| 话题的双端结构 | 同一个 threadId,在通信双方各有一个本地会话(S1A / S1B) |
|
|
71
|
+
| 跨话题路由 | 在会话 A 上调用 `send --thread T`,消息实际从话题 T 的会话发出 |
|
|
72
|
+
| 跨话题 Trigger | 发消息后可选创建,N 分钟后唤醒 agent 检查对端是否回复 |
|
|
73
|
+
| 基础传播单元 | 四条消息:A 委托 B → B 问 C → C 回 B → B 回 A |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 四、使用流程
|
|
78
|
+
|
|
79
|
+
### 流程 0:发现对端和话题(标准起点)
|
|
80
|
+
|
|
81
|
+
**场景**:需要查看某个 agent 的话题列表,或生成工作报告。
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
# 第一步:找到所有本机 agent
|
|
85
|
+
ec agent list
|
|
86
|
+
|
|
87
|
+
# 第二步:找到某 agent 的所有真实对端(过滤内部 daemon 话题)
|
|
88
|
+
ec thread peers --self <selfAid>
|
|
89
|
+
|
|
90
|
+
# 第三步:列出与某对端的所有话题(含消息统计和摘要)
|
|
91
|
+
ec thread list <peer> --self <selfAid>
|
|
92
|
+
# 输出包含:话题名、创建/活跃时间、消息(24h/总计)、最后消息截断、摘要
|
|
93
|
+
|
|
94
|
+
# 第四步:翻页(页脚自动给出完整翻页命令)
|
|
95
|
+
ec thread list <peer> --self <selfAid> --page 2 --limit 10 --sort recent
|
|
96
|
+
|
|
97
|
+
# 第五步:查看某话题的近期消息
|
|
98
|
+
ec thread history <peer>/<threadId> --self <selfAid> --limit 20
|
|
99
|
+
|
|
100
|
+
# 按时间范围过滤(如查最近一周)
|
|
101
|
+
SINCE=$(python3 -c "import time; print(int((time.time()-7*86400)*1000))")
|
|
102
|
+
ec thread history <peer>/<threadId> --self <selfAid> --after $SINCE --limit 100
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
### 流程 A:发起跨会话委托(核心)
|
|
108
|
+
|
|
109
|
+
**场景**:B 在话题 T1(与 A 对话)中,判断需要问 C。
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 步骤 1:找到或新建与 C 的话题
|
|
113
|
+
ec thread list <C的AID>
|
|
114
|
+
# 如果有合适的话题(如 T2),记下 threadId
|
|
115
|
+
# 如果没有,新建:
|
|
116
|
+
ec thread create <C的AID> --name "项目进度查询"
|
|
117
|
+
# 返回:{ threadId: "thread-xxx", ... }
|
|
118
|
+
|
|
119
|
+
# 步骤 2:发消息(--check-every 一步搞定复查)
|
|
120
|
+
ec msg send "项目当前进度如何?" --thread <T2的threadId> --check-every 5m
|
|
121
|
+
# --check-every 跨话题时必填(如 5m / 30m / 2h),周期唤醒直到显式 cancel
|
|
122
|
+
# 返回:{ message_id: "m-yyy", ... }
|
|
123
|
+
# 副作用:本端写入 thread-inbox + 创建周期复查 Trigger(kind=thread-check)
|
|
124
|
+
|
|
125
|
+
# 步骤 3:当前 turn 结束
|
|
126
|
+
# B 在 T1 的这个 turn 到此为止,不阻塞等待 C 的回复
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**关键时序**:
|
|
130
|
+
- `ec msg send --thread T2 --check-every 5m` 返回后,当前 turn **立刻结束**
|
|
131
|
+
- 消息从 B 与 C 的话题 T2 发出到达 C
|
|
132
|
+
- 5 分钟后,Trigger 唤醒 T2 的新 turn(在 B 侧)
|
|
133
|
+
- 如果 C 在此之前已回复,新 turn 的上下文里会包含 C 的回复
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### 流程 B:处理收到的委托
|
|
138
|
+
|
|
139
|
+
**场景**:C 收到 B 的消息,当前会话是 B 与 C 的话题 T2(C 侧)。
|
|
140
|
+
|
|
141
|
+
上下文注入示例(由渲染层自动添加):
|
|
142
|
+
```
|
|
143
|
+
当前任务来源:话题 thread-xxx,对端 b.agentid.cn
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# 步骤 1:处理任务(C 执行相应操作)
|
|
148
|
+
|
|
149
|
+
# 步骤 2:决定是否回复
|
|
150
|
+
# 情况 A:直接回复 B(在当前话题 T2 上)
|
|
151
|
+
ec msg send "进度 70%,预计下周完成"
|
|
152
|
+
# 不带 --thread,消息发在当前话题上
|
|
153
|
+
# 托管会话中不需要指定 from 和 to,系统推断
|
|
154
|
+
|
|
155
|
+
# 情况 B:不回复,什么都不做,turn 结束
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**关键点**:要不要回复完全由 C 自己决定,系统不强制。
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### 流程 C:Trigger 到期后的处理
|
|
163
|
+
|
|
164
|
+
**场景**:5 分钟后,Trigger 唤醒 B 在 T2 的新 turn。
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# 步骤 1:检查 C 是否已回复
|
|
168
|
+
ec thread history current --limit 10
|
|
169
|
+
# 或从上下文直接判断
|
|
170
|
+
|
|
171
|
+
# 步骤 2A:C 已回复 → 处理回复,汇报回 A
|
|
172
|
+
ec msg send "C 回复:进度 70%" --thread <T1的threadId> --check-every 30m
|
|
173
|
+
# 汇报回 A 也是跨话题发送,同样必填 --check-every
|
|
174
|
+
|
|
175
|
+
# 步骤 2B:C 还没回 → 决定下一步
|
|
176
|
+
# 选项 1:继续等 → 什么都不做,原 Trigger 下个周期会再次唤醒
|
|
177
|
+
# (如需调整频率:ec trigger update <triggerId> --every 5m)
|
|
178
|
+
# 选项 2:放弃等待,直接回 A
|
|
179
|
+
ec msg send "C 暂无回复" --thread <T1的threadId> --check-every 30m
|
|
180
|
+
|
|
181
|
+
# 选项 3:什么都不做,turn 结束
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**关键点**:Trigger 只是唤醒信号,不携带执行指令,不保证 C 已回复。
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 流程 D:并发委托多方
|
|
189
|
+
|
|
190
|
+
**场景**:B 需要同时问 C 和 D,等两个都回后再汇总。
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# 步骤 1:同时发出两条委托,各自创建周期复查 Trigger(--check-every 一步搞定)
|
|
194
|
+
ec msg send "技术评估" --thread <T2> --check-every 10m
|
|
195
|
+
ec msg send "产品评估" --thread <T3> --check-every 10m
|
|
196
|
+
# turn 结束
|
|
197
|
+
|
|
198
|
+
# 10 分钟后,T2 和 T3 各自触发新 turn
|
|
199
|
+
|
|
200
|
+
# 在 T2 的 turn 里(C 已回复):
|
|
201
|
+
# 检查 D 是否也回了
|
|
202
|
+
ec thread history <D的AID>/<T3> --limit 5
|
|
203
|
+
# 如果 D 还没回,turn 结束,等 T3 的 turn
|
|
204
|
+
|
|
205
|
+
# 在 T3 的 turn 里(D 已回复):
|
|
206
|
+
# 检查 C 是否也回了
|
|
207
|
+
ec thread history <C的AID>/<T2> --limit 5
|
|
208
|
+
# C 也回了,合并结果
|
|
209
|
+
ec msg send "综合评估:技术……产品……" --thread <T1> --check-every 30m
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**关键点**:没有"等齐"原语。想合并就在后到的 turn 里主动读另一话题,手动判断是否齐全。
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### 流程 E:追问(同话题多轮)
|
|
217
|
+
|
|
218
|
+
**场景**:C 第一次回复不够详细,B 继续追问。
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# S2B 收到 C 的第一次回复:"卡在 Redis 并发问题"
|
|
222
|
+
# B 判断需要更多细节
|
|
223
|
+
|
|
224
|
+
ec msg send "Redis 并发问题影响范围多大?"
|
|
225
|
+
# 不带 --thread,继续在当前话题上
|
|
226
|
+
# 同话题追问无需 --check-every(不跨话题,不创建复查 Trigger)
|
|
227
|
+
|
|
228
|
+
# C 再次回复后,触发新 turn
|
|
229
|
+
# B 整合两轮对话,回 A
|
|
230
|
+
ec msg send "C 反馈:Redis 问题影响……" --thread <T1>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
### 流程 F:话题历史查询
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# 查看当前话题
|
|
239
|
+
ec thread show current
|
|
240
|
+
|
|
241
|
+
# 列出与某对端的所有话题
|
|
242
|
+
ec thread list <peer-AID>
|
|
243
|
+
|
|
244
|
+
# 读当前话题的历史
|
|
245
|
+
ec thread history current --limit 20
|
|
246
|
+
|
|
247
|
+
# 读另一个话题的历史(跨话题只读)
|
|
248
|
+
ec thread history <peer>/<threadId> --limit 50
|
|
249
|
+
|
|
250
|
+
# 按时间过滤(查看空洞期消息)
|
|
251
|
+
ec thread history <peer>/<threadId> --after <timestamp>
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### 流程 G:修改话题属性
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
ec thread rename current "新名称"
|
|
260
|
+
ec thread label current "开发"
|
|
261
|
+
ec thread status current in_progress
|
|
262
|
+
# 状态值:pending | in_progress | completed | archived
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### 流程 H:Trigger 操作(跨话题跟进场景)
|
|
268
|
+
|
|
269
|
+
#### 场景一:对端回复时的 Trigger 决策
|
|
270
|
+
|
|
271
|
+
当你在某个话题被对端唤醒,跨会话上下文注入里会带上关联的复查 Trigger:
|
|
272
|
+
|
|
273
|
+
```
|
|
274
|
+
‹跨会话上下文 · 来源话题:thread-T1 · 对端:alice.agentid.cn · 发送于:...›
|
|
275
|
+
🔔 复查 Trigger:trig_1791765199642_5371c8ff(尚未触发/待处理)
|
|
276
|
+
【原消息内容】
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**操作流程**:
|
|
280
|
+
|
|
281
|
+
1. **判断对端回复是否完整**:
|
|
282
|
+
- 如果对端已给最终答案 → 继续第 2 步
|
|
283
|
+
- 如果对端还在处理中 → 保留 trigger,本次不操作
|
|
284
|
+
|
|
285
|
+
2. **检查来源话题是否有新指示**(如果系统提示有空洞期消息):
|
|
286
|
+
```bash
|
|
287
|
+
ec thread history <来源peer>/<来源threadId> --after <timestamp>
|
|
288
|
+
```
|
|
289
|
+
- 如果来源话题有"取消任务"等新指示 → 处理后取消 trigger
|
|
290
|
+
- 如果来源话题无新消息 → 继续第 3 步
|
|
291
|
+
|
|
292
|
+
3. **决定 Trigger 操作**:
|
|
293
|
+
- **任务完成** → 取消 trigger(用 **id**,即上面注入的 `trig_…`;用名称会报 trigger not found):
|
|
294
|
+
```bash
|
|
295
|
+
ec trigger cancel trig_1791765199642_5371c8ff
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
- **需要加快跟进** → 调整周期:
|
|
299
|
+
```bash
|
|
300
|
+
ec trigger update trig_1791765199642_5371c8ff --every 30m
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
#### 场景二:Trigger 触发时的主动复查
|
|
304
|
+
|
|
305
|
+
当 trigger 定期触发时,你会被唤醒并看到 trigger 的 prompt(信封头标注 `Trigger 复查 · 话题:... ← 来源:...`):
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
【Trigger 复查】话题 thread-T2(对端 C)
|
|
309
|
+
这是周期复查:每 5m 唤醒一次,直到你显式结束它。
|
|
310
|
+
|
|
311
|
+
请检查该话题的最新进度,根据情况:继续等待、调整周期(ec trigger update trig_1791765199642_5371c8ff --every <时长>)或结束复查(ec trigger cancel trig_1791765199642_5371c8ff)。
|
|
312
|
+
|
|
313
|
+
参考命令:
|
|
314
|
+
ec thread history <C的AID>/thread-T2 --limit 10
|
|
315
|
+
ec thread history <来源peer>/thread-T1 --after <timestamp>
|
|
316
|
+
ec trigger cancel trig_1791765199642_5371c8ff
|
|
317
|
+
ec trigger update trig_1791765199642_5371c8ff --every <时长>
|
|
318
|
+
Trigger id:trig_1791765199642_5371c8ff
|
|
319
|
+
Trigger 名称:check-<目标threadId>-from-<来源threadId>-<唯一后缀>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**操作流程**:
|
|
323
|
+
|
|
324
|
+
1. **检查目标话题是否有新消息**:
|
|
325
|
+
```bash
|
|
326
|
+
ec thread history <目标peer>/<目标threadId> --limit 10
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
2. **检查来源话题是否有新指示**:
|
|
330
|
+
```bash
|
|
331
|
+
ec thread history <来源peer>/<来源threadId> --after <上次检查时间>
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
3. **根据检查结果决策**:
|
|
335
|
+
- **目标话题有回复** → 处理回复,判断是否取消 trigger(同场景一)
|
|
336
|
+
- **来源话题有新指示**(如"别管了")→ 通知目标话题,取消 trigger
|
|
337
|
+
- **两边都无更新** → 保留 trigger 继续等待
|
|
338
|
+
- **发现会话不可用** → 回复来源话题说联系不上,取消 trigger
|
|
339
|
+
|
|
340
|
+
4. **错误处理**:
|
|
341
|
+
- 发送消息失败(暂时性)→ 保留 trigger,下次再试
|
|
342
|
+
- 发送消息失败(永久性,如拉黑)→ 取消 trigger,回复来源话题
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
### 流程 I:总结话题("总结一下话题")
|
|
347
|
+
|
|
348
|
+
**触发词**:用户说"总结一下话题""总结话题""给这个话题写个总结""这个话题总结一下"
|
|
349
|
+
"更新一下摘要""summarize this topic" 时,**直接执行下面的序列**,不要反问"总结什么"。
|
|
350
|
+
|
|
351
|
+
**核心两步**:① 拿到"上次总结覆盖到哪"→ ② 读那之后的增量 → ③ 写新摘要。
|
|
352
|
+
`--name` **必填**:总结时往往正好把主题想清楚,一次命令同时写摘要 + 改标题;
|
|
353
|
+
确实要保留原标题时显式传 `--name -`(显式表达意图,比省略更难被忽略)。
|
|
354
|
+
`summary show` 会打印 `coveredThroughTs`(覆盖游标),它就是你读增量的起点。
|
|
355
|
+
`summary set` 会自动把游标推进到当时话题的最新一条,你不用管。
|
|
356
|
+
|
|
357
|
+
**情形 A:在当前话题内总结**(对话就在上下文里,不用读历史)
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
# 1. 看上次摘要内容和覆盖游标(没有摘要时输出"(暂无 summary)")
|
|
361
|
+
ec thread summary show current
|
|
362
|
+
|
|
363
|
+
# 2. 自己写摘要(100 字以内,见下方规范)。
|
|
364
|
+
# 增量就是本轮对话,无需再读历史;游标自动推进。
|
|
365
|
+
# --name 必填:一次写完摘要 + 标题。不想改名就显式传 `-`。
|
|
366
|
+
ec thread summary set current "写好的摘要内容" --name "动词短语描述的核心动作"
|
|
367
|
+
ec thread summary set current "写好的摘要内容" --name - # 保持原话题名
|
|
368
|
+
# 多人协作同一话题时带 CAS 防覆盖
|
|
369
|
+
ec thread summary set current "写好的摘要内容" --name "标题" --if-rev <步骤1的rev>
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**情形 B:从别的话题(或别处)总结某话题**(需要读增量)
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# 1. 看上次摘要 + 覆盖游标
|
|
376
|
+
ec thread summary show <peer>/<threadId>
|
|
377
|
+
# 输出中 coveredThroughTs 是上次覆盖到的时间戳;没有该字段说明是首次/旧摘要,需全量读
|
|
378
|
+
|
|
379
|
+
# 2. 读游标之后的增量(首次总结则省略 --after,全量读)
|
|
380
|
+
ec thread history <peer>/<threadId> --after <coveredThroughTs> --limit 50
|
|
381
|
+
|
|
382
|
+
# 3. 增量较多时往回翻页(history 支持 before 逆序分页)
|
|
383
|
+
ec thread history <peer>/<threadId> --before <本页最早一条的ts> --limit 50
|
|
384
|
+
# 翻到覆盖游标之前即可停;注意 before 是闭区间,用 <最早ts - 1> 避免边界重复
|
|
385
|
+
|
|
386
|
+
# 4. 读完增量后写摘要(游标自动推进到现在);--name 必填,不改名传 -
|
|
387
|
+
ec thread summary set <peer>/<threadId> "写好的摘要内容" --name "新名称"
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
**关键约束**:`summary set` 把游标设为**当时话题的最新一条**,所以跨话题总结**必须先把增量读完再写**。
|
|
391
|
+
若没读完就写,游标会越过未读的消息,它们下次不会被返回(永久跳过)。
|
|
392
|
+
|
|
393
|
+
**首次总结**:`summary show` 没有 `coveredThroughTs`(本话题从未总结过,或是只带 `updatedAt` 的旧记录)。
|
|
394
|
+
此时从最新往回翻,一直翻到你认为已覆盖的开头,再写摘要。
|
|
395
|
+
|
|
396
|
+
**为什么用 `--after <coveredThroughTs>` 而不是拍脑袋定 `--limit`**:游标是上次真正覆盖到的位置,
|
|
397
|
+
从它之后读既不多读(省 token)也不少读(不漏消息)。翻页用 `--before`,天然支持"往回看"。
|
|
398
|
+
|
|
399
|
+
**话题名称命名规范**(由 `summary set --name` 一并写入,不必单独跑 rename):
|
|
400
|
+
- 名称应反映话题的核心主题,不超过20字
|
|
401
|
+
- 避免使用创建时的随机短语("你好"、"话题会话"),改为有意义的描述
|
|
402
|
+
- 好的名称示例:"skill 索引热更新 bug 修复"、"manifest 注入与 CLAUDE.md 冗余问题"
|
|
403
|
+
- 名称是本端的,对端可能有不同名称,这是正常的
|
|
404
|
+
|
|
405
|
+
**摘要写作规范**:
|
|
406
|
+
- 摘要应在100字以内,概括话题的背景、进展和结果
|
|
407
|
+
- 格式:[谁]做了[什么],结果是[什么],遗留[什么](如有)
|
|
408
|
+
- 摘要是给下次进入该话题时快速恢复上下文用的,不是给对端看的
|
|
409
|
+
- 示例:"leiliang 要求安装 fetch 技能,tl3 完成依赖下载和链路验证,技能安装完成。"
|
|
410
|
+
|
|
411
|
+
#### 何时顺手做(不等用户开口)
|
|
412
|
+
|
|
413
|
+
用户明确说"总结"时按上面序列执行。此外以下时机**主动**做,不要等对端问:
|
|
414
|
+
|
|
415
|
+
| 时机 | 操作 |
|
|
416
|
+
|---|---|
|
|
417
|
+
| 话题名称仍是创建时的随机短语("你好"、"话题会话"等)时 | 更新名称 |
|
|
418
|
+
| 一个明确的任务或阶段完成时 | 写入/更新摘要 |
|
|
419
|
+
| 话题方向发生重大转变(原来讨论A,现在转向B) | 更新名称 + 摘要 |
|
|
420
|
+
| 即将离开话题去处理其他事(跨话题路由前) | 写入摘要,记录当前状态 |
|
|
421
|
+
| 话题进入 completed 状态前 | 写入最终摘要,记录成果 |
|
|
422
|
+
| 下次被唤醒时发现摘要是"未总结" | 回顾历史后补写摘要 |
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### 流程 J:生成 agent 工作报告
|
|
427
|
+
|
|
428
|
+
**场景**:需要总结某 agent 与某对端最近一段时间的工作内容。
|
|
429
|
+
|
|
430
|
+
```bash
|
|
431
|
+
SELF=<selfAid>
|
|
432
|
+
PEER=<peer>
|
|
433
|
+
# 最近一周的时间戳(毫秒)
|
|
434
|
+
SINCE=$(python3 -c "import time; print(int((time.time()-7*86400)*1000))")
|
|
435
|
+
|
|
436
|
+
# 第一步:列出所有话题(含消息统计)
|
|
437
|
+
ec thread list $PEER --self $SELF --limit 100
|
|
438
|
+
|
|
439
|
+
# 第二步:对24h消息数>0或总消息数较多的话题,读取最近消息
|
|
440
|
+
ec thread history $PEER/<threadId> --self $SELF --after $SINCE --limit 50
|
|
441
|
+
|
|
442
|
+
# 第三步:查看每个话题的 summary
|
|
443
|
+
ec thread summary show $PEER/<threadId> --self $SELF
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**报告结构建议**:
|
|
447
|
+
1. **时间范围**:报告覆盖的时间段
|
|
448
|
+
2. **话题总览**:共多少话题,活跃话题数(24h有消息)
|
|
449
|
+
3. **逐话题摘要**:按活跃时间排序,每个话题一段,包含:
|
|
450
|
+
- 话题名称和时间范围
|
|
451
|
+
- 主要内容(从 summary 或消息读取)
|
|
452
|
+
- 完成状态
|
|
453
|
+
4. **结论**:主要完成了什么,有什么遗留
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
## 五、常见错误
|
|
458
|
+
|
|
459
|
+
| 错误码 | 含义 | 处理 |
|
|
460
|
+
|---|---|---|
|
|
461
|
+
| `TOPIC_NOT_FOUND` | `--thread` 指定的话题在本端不存在 | 先 `ec thread create` 新建 |
|
|
462
|
+
| `TOPIC_CONFLICT` | 创建时名称与已有话题重名 | 换名字,或直接使用已有话题 |
|
|
463
|
+
| `TOPIC_BUSY` | 话题有正在执行的任务,无法删除 | 等任务完成后再删除 |
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## 六、不应该做的事
|
|
468
|
+
|
|
469
|
+
1. **不要在发送消息后阻塞等待回复**:`send --thread T2` 返回后 turn 就结束了,回复会触发新 turn。
|
|
470
|
+
|
|
471
|
+
2. **不要忘记创建 Trigger**:如果不创建,对端不回复时你永远不会知道。分支合并场景必须用 Trigger。
|
|
472
|
+
|
|
473
|
+
3. **不要在托管会话中手动指定 from 和 to**:`ec msg send "文本" --thread T2` 就够了。
|
|
474
|
+
|
|
475
|
+
4. **不要把 Trigger 当作"强制回复"或"执行脚本"**:Trigger 只是唤醒信号,到期后 agent 自主决定下一步。
|
|
476
|
+
|
|
477
|
+
5. **不要期望话题名双端一致**:话题名是本端概念,threadId 才是跨端统一标识符。
|
|
478
|
+
|
|
479
|
+
6. **不要在并发场景期望"等齐"原语**:想合并就在后到的 turn 里用 `ec thread history` 主动读。
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## 七、加载本 skill 后 agent 应该明白的七条核心点
|
|
484
|
+
|
|
485
|
+
1. **话题是路由单位**:消息必须发在某个话题上,不带 `--thread` 时发在当前话题。
|
|
486
|
+
2. **跨话题路由不阻塞**:`send --thread T2` 返回后当前 turn 立刻结束,不等回复。
|
|
487
|
+
3. **Trigger 是唤醒信号,不是执行脚本**:到期时提醒检查,不指示执行任何操作,不保证对端已回复。
|
|
488
|
+
4. **决策权在自己**:收到委托要不要回、何时回、回什么,完全自主判断。
|
|
489
|
+
5. **分支合并靠主动查询**:想等多个对端都回,就在各自 turn 里用 `ec thread history` 读另一话题。
|
|
490
|
+
6. **from/to 托管会话中不需要**:会话唯一确定对端,命令简化为 `ec msg send "文本" --thread T`。
|
|
491
|
+
7. **话题名是本端的**:对端可能改名,threadId 才是跨端统一标识。
|
|
492
|
+
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wechat-article-media-download
|
|
3
|
+
description: >-
|
|
4
|
+
从微信公众号文章链接下载视频和图片。当用户提供 mp.weixin.qq.com/s/... 格式的公众号文章
|
|
5
|
+
链接,并要求"下载视频""保存图片""抓取媒体""下载公众号文章里的视频/图片"时使用。
|
|
6
|
+
无需微信客户端、无需登录、零第三方依赖(纯 Python 3.7+ 标准库)。
|
|
7
|
+
不适用于视频号(Channels)来源的视频,也不适用于需要粉丝关注才可见的付费文章。
|
|
8
|
+
license: MIT
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# 微信公众号文章媒体下载
|
|
12
|
+
|
|
13
|
+
从公众号文章页面提取并下载视频和图片,无需微信客户端或登录态。
|
|
14
|
+
|
|
15
|
+
## 原理
|
|
16
|
+
|
|
17
|
+
- **图片**:从 `data-src="https://mmbiz.qpic.cn/..."` 属性中提取,带 WeChat referer 头下载。
|
|
18
|
+
- **视频**:签名直链已内嵌于文章页面末尾的 JS 数据块,解码 HTML 实体后用正则提取。
|
|
19
|
+
每个视频有多种清晰度(format_id),优先选 `10002`(超清 H.264),
|
|
20
|
+
依次回退 `10102 → 10004 → 10104`。
|
|
21
|
+
- 签名 URL 约一周内有效,建议下载后立即使用。
|
|
22
|
+
- 来自视频号(Channels)的视频不包含可提取的直链,此工具无法下载。
|
|
23
|
+
|
|
24
|
+
## 用法
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
python3 "<技能目录>/scripts/download.py" "<文章URL>" "<输出目录>"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**示例:**
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
python3 "<技能目录>/scripts/download.py" \
|
|
34
|
+
"https://mp.weixin.qq.com/s/xxxxxx" \
|
|
35
|
+
"./wechat-output"
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
输出结构:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
<输出目录>/
|
|
42
|
+
├── videos/ # 按序号命名的 .mp4 文件
|
|
43
|
+
├── images/ # 按序号命名的图片文件
|
|
44
|
+
└── sources.json # 原始链接清单,含格式、大小、下载状态
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 步骤
|
|
48
|
+
|
|
49
|
+
1. 确认用户提供了有效的 `mp.weixin.qq.com/s/...` 链接。
|
|
50
|
+
2. 确定输出目录(用户未指定时默认 `./wechat-output`)。
|
|
51
|
+
3. 用绝对路径运行脚本:
|
|
52
|
+
```bash
|
|
53
|
+
python3 "<技能目录绝对路径>/scripts/download.py" "<文章URL>" "<输出目录>"
|
|
54
|
+
```
|
|
55
|
+
4. 脚本打印每个文件的 OK/FAIL 状态和大小;结束后输出汇总。
|
|
56
|
+
5. 下载完成后,告知用户各类文件数量及输出路径。
|
|
57
|
+
|
|
58
|
+
## 边界与注意事项
|
|
59
|
+
|
|
60
|
+
- **零依赖**:只用 Python 3.7+ 标准库,无需 `pip install`。
|
|
61
|
+
- **并发下载**:每个文件一个线程,速度快。
|
|
62
|
+
- **视频号视频**:无直链,无法下载,脚本会跳过并标注。
|
|
63
|
+
- **付费/仅粉丝文章**:页面返回 403 或空内容,脚本会报错退出。
|
|
64
|
+
- **链接有效期**:签名 URL 约 7 天,过期后需重新运行脚本。
|
|
65
|
+
- **路径规则**:执行时必须用脚本的绝对路径,不可依赖 cwd。
|