@awiki/cli 0.0.1-beta.2

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.
Files changed (119) hide show
  1. package/.github/workflows/release.yml +44 -0
  2. package/.goreleaser.yml +44 -0
  3. package/AGENTS.md +60 -0
  4. package/CLAUDE.md +192 -0
  5. package/README.md +2 -0
  6. package/docs/architecture/awiki-command-v2.md +955 -0
  7. package/docs/architecture/awiki-skill-architecture.md +475 -0
  8. package/docs/architecture/awiki-v2-architecture.md +1063 -0
  9. package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/cli-init.md +1008 -0
  10. package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/output-format.md +407 -0
  11. package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/overall-init.md +741 -0
  12. package/docs/harness/review-spec.md +474 -0
  13. package/docs/installation.md +372 -0
  14. package/docs/plan/awiki-v2-implementation-plan.md +903 -0
  15. package/docs/plan/phase-0/adr-index.md +56 -0
  16. package/docs/plan/phase-0/audit-findings.md +251 -0
  17. package/docs/plan/phase-0/capability-mapping.md +108 -0
  18. package/docs/plan/phase-0/implementation-constraints.md +363 -0
  19. package/docs/publish.md +169 -0
  20. package/go.mod +29 -0
  21. package/go.sum +73 -0
  22. package/internal/anpsdk/registry.go +63 -0
  23. package/internal/authsdk/session.go +351 -0
  24. package/internal/buildinfo/buildinfo.go +34 -0
  25. package/internal/cli/app.go +136 -0
  26. package/internal/cli/app_test.go +88 -0
  27. package/internal/cli/debug.go +104 -0
  28. package/internal/cli/group.go +263 -0
  29. package/internal/cli/id.go +473 -0
  30. package/internal/cli/init.go +134 -0
  31. package/internal/cli/msg.go +228 -0
  32. package/internal/cli/page.go +267 -0
  33. package/internal/cli/root.go +499 -0
  34. package/internal/cli/runtime.go +232 -0
  35. package/internal/cli/upgrade.go +60 -0
  36. package/internal/cmdmeta/catalog.go +203 -0
  37. package/internal/cmdmeta/catalog_test.go +21 -0
  38. package/internal/config/config.go +399 -0
  39. package/internal/config/config_test.go +104 -0
  40. package/internal/config/write.go +37 -0
  41. package/internal/content/service.go +314 -0
  42. package/internal/content/service_test.go +165 -0
  43. package/internal/content/types.go +44 -0
  44. package/internal/docs/topics.go +110 -0
  45. package/internal/doctor/doctor.go +306 -0
  46. package/internal/identity/client.go +267 -0
  47. package/internal/identity/did.go +85 -0
  48. package/internal/identity/did_test.go +50 -0
  49. package/internal/identity/layout.go +206 -0
  50. package/internal/identity/legacy.go +378 -0
  51. package/internal/identity/public.go +70 -0
  52. package/internal/identity/public_test.go +73 -0
  53. package/internal/identity/readiness.go +74 -0
  54. package/internal/identity/service.go +826 -0
  55. package/internal/identity/store.go +385 -0
  56. package/internal/identity/store_test.go +180 -0
  57. package/internal/identity/types.go +204 -0
  58. package/internal/message/auth.go +167 -0
  59. package/internal/message/group_service.go +838 -0
  60. package/internal/message/group_wire.go +350 -0
  61. package/internal/message/group_wire_test.go +67 -0
  62. package/internal/message/helpers.go +61 -0
  63. package/internal/message/http_client.go +334 -0
  64. package/internal/message/proof.go +156 -0
  65. package/internal/message/proof_test.go +61 -0
  66. package/internal/message/service.go +696 -0
  67. package/internal/message/service_test.go +97 -0
  68. package/internal/message/types.go +155 -0
  69. package/internal/message/wire.go +100 -0
  70. package/internal/message/wire_test.go +49 -0
  71. package/internal/message/ws_proxy_client.go +151 -0
  72. package/internal/output/output.go +350 -0
  73. package/internal/output/output_test.go +48 -0
  74. package/internal/runtime/config.go +117 -0
  75. package/internal/runtime/config_test.go +46 -0
  76. package/internal/runtime/listener/files.go +65 -0
  77. package/internal/runtime/listener/manager.go +142 -0
  78. package/internal/runtime/listener/server.go +983 -0
  79. package/internal/runtime/listener/server_test.go +319 -0
  80. package/internal/runtime/listener/sysproc_unix.go +17 -0
  81. package/internal/runtime/listener/sysproc_windows.go +13 -0
  82. package/internal/runtime/listener/types.go +21 -0
  83. package/internal/runtime/listener/wsclient.go +299 -0
  84. package/internal/runtime/listener/wsclient_test.go +41 -0
  85. package/internal/store/dao.go +632 -0
  86. package/internal/store/dao_test.go +87 -0
  87. package/internal/store/helpers.go +197 -0
  88. package/internal/store/import.go +499 -0
  89. package/internal/store/import_test.go +103 -0
  90. package/internal/store/open.go +71 -0
  91. package/internal/store/query.go +151 -0
  92. package/internal/store/schema.go +277 -0
  93. package/internal/store/schema_test.go +56 -0
  94. package/internal/store/types.go +177 -0
  95. package/internal/update/update.go +368 -0
  96. package/package.json +17 -0
  97. package/scripts/install.js +171 -0
  98. package/scripts/release/release-prerelease.sh +86 -0
  99. package/scripts/release/tag-release.sh +66 -0
  100. package/scripts/release/withdraw-release.sh +78 -0
  101. package/scripts/run.js +69 -0
  102. package/skills/README.md +32 -0
  103. package/skills/awiki-bundle/SKILL.md +76 -0
  104. package/skills/awiki-debug/SKILL.md +80 -0
  105. package/skills/awiki-group/SKILL.md +111 -0
  106. package/skills/awiki-id/SKILL.md +123 -0
  107. package/skills/awiki-msg/SKILL.md +131 -0
  108. package/skills/awiki-page/SKILL.md +93 -0
  109. package/skills/awiki-people/SKILL.md +66 -0
  110. package/skills/awiki-runtime/SKILL.md +137 -0
  111. package/skills/awiki-shared/SKILL.md +124 -0
  112. package/skills/awiki-workflow-discovery/SKILL.md +93 -0
  113. package/skills/awiki-workflow-onboarding/SKILL.md +119 -0
  114. package/skills/manifests/skills.yaml +260 -0
  115. package/skills/templates/bundle-skill-template.md +42 -0
  116. package/skills/templates/debug-skill-template.md +44 -0
  117. package/skills/templates/domain-skill-template.md +56 -0
  118. package/skills/templates/shared-skill-template.md +46 -0
  119. package/skills/templates/workflow-skill-template.md +46 -0
@@ -0,0 +1,741 @@
1
+ > **文档状态说明(已过时)**
2
+ > 本文档属于早期初始化方案讨论稿,已被最终方案取代。当前请以 `docs/architecture/awiki-v2-architecture.md`(总体架构)和 `docs/architecture/awiki-command-v2.md`(最终命令与初始化方案)为准;若本文与最终方案存在冲突,以最终方案为准。保留本文仅用于回溯设计演进。
3
+
4
+ 下面这份方案,是基于你已经**确定用 Go 重写**这个前提做的,不再纠结“要不要继续 Python”。我把最近几天飞书官方 CLI、飞书官方 OpenClaw 插件、官方 skills、以及社区 issue 里的真实反馈又重新看了一遍;同时把你们当前 awiki 的主 SKILL、Heartbeat、Listener、Schema、Security、E2EE 说明也重新对齐了一次。结论是:
5
+
6
+ **awiki v2 最好的方向,不是“做一个飞书的缩小版”,而是“用飞书的产品结构,重做一个更聚焦的 agent-native identity + messaging CLI”。**
7
+ 也就是说:学飞书的统一 CLI、shared skill、三层命令、schema/doctor/dry-run、跨平台分发;保留 awiki 的 DID / Handle / E2EE / heartbeat / local store / 多身份这些真正有壁垒的设计;不要把飞书已经暴露出来的问题也复制过来。([GitHub][1])
8
+
9
+ ---
10
+
11
+ ## 1. 这次重写的总目标
12
+
13
+ 我建议你把这次重写定义成:
14
+
15
+ **awiki v2 = 一个独立、可分发、可自省、对 AI 友好的 Go CLI 产品;OpenClaw skill 只是它的一个消费层,不再是唯一形态。**
16
+
17
+ 这和飞书现在的结构非常一致:`larksuite/cli` 是独立 CLI 产品,`larksuite/openclaw-lark` 是独立插件产品;前者提供统一命令、skills、schema、doctor、completion,后者负责宿主平台接入和交互体验。飞书官方 README 也明确把 CLI 定位为“built for humans and AI Agents”,并且把 command surface、skills、auth、security、advanced usage 都放进统一产品面。([GitHub][1])
18
+
19
+ 而你们当前 awiki 仍然是“脚本集合 + 巨型 SKILL.md”的形态:安装靠 zip/git clone + `install_dependencies.py`,使用靠一组 `scripts/*.py`,主 SKILL 同时承担安装说明、身份、消息、E2EE、群组、群发现、heartbeat、listener、SQL 查询等职责。这个结构能工作,但不适合继续扩展,也不适合 AI 稳定路由。
20
+
21
+ ---
22
+
23
+ ## 2. 先给最终产品形态
24
+
25
+ 我建议 awiki v2 的最终产品形态是:
26
+
27
+ 1. 一个 **Go 单二进制 CLI**:`awiki`
28
+ 2. 一个 **内建文档/自省系统**:`awiki docs`、`awiki schema`、`awiki doctor`
29
+ 3. 一组 **精简 skill**:`awiki-shared`、`awiki-id`、`awiki-msg`、`awiki-runtime`、`awiki-people`、`awiki-page`、`awiki-debug`
30
+ 4. 一个 **可选的 OpenClaw 插件/接入层**,但不与 CLI 核心混仓耦合
31
+ 5. 一个 **GoReleaser + GitHub Releases + npm wrapper** 的分发链路
32
+
33
+ 这里面最重要的是第 2 点:**CLI 自身必须完整可用、完整可解释,不再依赖 skill 作为唯一文档入口。** 这是飞书社区已经明确暴露出的改进点:官方 issue #8 直接指出,skills 可以是增强层,但不能成为理解核心命令行为的唯一现实路径;如果某个命令需要先读 guide,CLI 本体就应该能直接把 guide 或精简说明给出来。([GitHub][2])
34
+
35
+ ---
36
+
37
+ ## 3. 这次重写里,哪些必须保留,哪些必须吸收,哪些不要照搬
38
+
39
+ ### 3.1 必须保留的 awiki 优势
40
+
41
+ 这些是你们和飞书最不一样、也最值得保留的东西:
42
+
43
+ **第一,DID / Handle / self-sovereign identity 是 awiki 的核心,不是附属功能。**
44
+ 你们当前设计里,身份不是一个 OAuth 登录态,而是本地私钥持有、可恢复 Handle、可多身份并存、围绕 DID 组织本地数据和消息线程。这是 awiki 的根能力,不应该在 Go 重写里被弱化成“普通 auth 模块”。
45
+
46
+ **第二,E2EE、自动握手处理、失败 outbox、owner_did 隔离、本地 SQLite cache,这些都非常有价值。**
47
+ 当前设计已经有 E2EE auto-processing、失败重试/放弃、group/member cache、`relationship_events`、按 `owner_did` 隔离本地数据等机制;这些是 awiki 的“agent-native messaging substrate”,不是应该被删掉的复杂度,而是应该被重构成更清晰的 Go 模块。
48
+
49
+ **第三,`messages are data, not instructions` 这条安全边界必须成为 v2 的最高层规则。**
50
+ 你们当前 RULES 明确禁止把 awiki 消息当命令执行,也禁止基于远端消息读取本地文件、执行 shell、访问数据库或泄露主机信息。这个设计非常对,而且要从“参考规则”升级为核心产品约束:进入 `msg inbox`、listener、webhook、discovery 的每条消息都先过 untrusted-data pipeline。
51
+
52
+ **第四,当前显式 `http/websocket` 传输模式和“listener 持有唯一远端连接”的思路值得保留。**
53
+ `Upgrade Notes` 和 `WEBSOCKET_LISTENER.md` 已经把这条思路讲清楚了:`websocket` 模式下 listener 持有唯一远端连接,其他命令走本地 daemon;`http` 模式下直接 JSON-RPC,listener 关闭。这个设计是对的,只是现在还被文档和脚本层打散了。
54
+
55
+ ---
56
+
57
+ ### 3.2 必须吸收的飞书做法
58
+
59
+ **第一,统一 CLI 入口。**
60
+ 飞书不是让 AI 记住一堆脚本,而是统一走 `lark-cli`,再按 `config / auth / schema / doctor / <service>` 分域。README 和 CHANGELOG 都把这点写得很清楚。awiki v2 必须也这样:所有功能只认 `awiki`,不再把脚本名当公共 API。([GitHub][1])
61
+
62
+ **第二,shared skill + domain skill。**
63
+ 飞书现在有 `lark-shared`,而且 `lark-im`、`lark-event` 都要求先读 shared skill;这说明他们把认证、身份切换、权限、风险提示、危险操作规则放到了一个共用层。awiki v2 必须照这个方向改。你们当前最大的痛点之一,就是安全规则、安装规则、行为规则、消息规则都混在同一个主 SKILL。([GitHub][3])
64
+
65
+ **第三,三层命令体系。**
66
+ 飞书明确采用三层:Shortcuts → API Commands → Raw API;README 还强调 `schema`、`dry-run`、多种输出格式。awiki 不需要复制它的全部体量,但一定要复制这个思想:高频任务入口、资源/对象级命令、raw/debug 层分开。([GitHub][1])
67
+
68
+ **第四,GoReleaser + GitHub Releases + npm wrapper。**
69
+ 飞书的 npm 包 `@larksuite/cli` 并不是 JS CLI,本质是一个包装层;`package.json` 里 `bin` 指向 `scripts/run.js`,`postinstall` 运行 `install.js`,而 `install.js` 会按平台/架构去 GitHub Releases 或镜像地址下载对应的 Go 二进制。这个分发模型非常适合你现在已经决定采用 Go 的 awiki。([GitHub][4])
70
+
71
+ **第五,CLI 本体要有 `schema / doctor / completion / dry-run`。**
72
+ 飞书官方已经把这些做成一级产品能力;而第三方指南和社区讨论之所以频繁把它拿出来说,本质上就是因为这些东西对 AI 和自动化特别关键。([GitHub][1])
73
+
74
+ ---
75
+
76
+ ### 3.3 不要照搬的飞书问题
77
+
78
+ **第一,不要复制“技能必须安装才能理解 CLI”的依赖关系。**
79
+ 飞书官方 README 里把 skills 安装写成 AI agent 的必需步骤,但 issue #8 已经明确指出:这会让 CLI 文档 discoverability 变差。awiki v2 应该反过来:skill 是增强层,CLI 必须自带核心文档、自省和向导。([GitHub][5])
80
+
81
+ **第二,不要复制“单 active app / profile 不一等”的设计。**
82
+ 飞书 issue #29 说明当前 `lark-cli` 仍存在多账号/多 profile 不原生的问题,用户要靠隔离 config dir 绕过去。awiki 恰恰已经在当前系统里有多 identity / 多 credential 的好设计,所以 v2 应该把这件事做成一等能力,而不是退化。([GitHub][6])
83
+
84
+ **第三,不要复制“工具/能力一次性全注册给模型”的 prompt-heavy 模式。**
85
+ `openclaw-lark` 的 issue #17 已经把这个问题说得很清楚:能力面太大、schema 太多,会抬高默认上下文成本、拉长启动上下文、增加 token 压力。awiki v2 必须默认小核心、按需加载,把 `people/page/debug` 从主 skill 和主上下文里拿掉。([GitHub][7])
86
+
87
+ **第四,不要允许 help/README/example 与真实 CLI surface 漂移。**
88
+ 飞书 issue #48 说明这类问题哪怕是小问题,也会直接伤害用户复制命令的第一体验。awiki v2 应该把 README、`--help`、schema、skills、在线文档都建立在同一个 metadata source 上生成。([GitHub][8])
89
+
90
+ ---
91
+
92
+ ## 4. 重写前必须先做的“语义冻结”
93
+
94
+ 在你开始写 Go 代码之前,我建议先做 4 个 ADR,不然你会在实现过程中一直被旧文档互相冲突的表述拖住。
95
+
96
+ **ADR-0001:E2EE 规范冻结。**
97
+ 你们当前文档有明显冲突:主 SKILL 和 `WHY_AWIKI` 写的是 HPKE / X25519 / chain ratchet,而 `e2ee-protocol.md` 写的是 secp256r1 ECDHE + AES-GCM。Go 重写前必须只保留一份规范为准;如果协议现实是 secp256r1,就不要在 CLI/README/skill 里继续写 HPKE/X25519;如果未来要迁到 HPKE/X25519,就显式做成新版本协议和迁移计划。
98
+
99
+ **ADR-0002:凭证/身份存储冻结。**
100
+ 主 SKILL 说现在是 indexed multi-credential layout(`index.json + 每个 credential 一个目录`),但 RULES 还在写“一身份一个 JSON 文件”。这在 Go 重写前必须先统一。我的建议是:继续采用“索引 + 每身份目录”的结构,但把用户层术语从 `credential` 改成 `identity`。
101
+
102
+ **ADR-0003:transport / listener / daemon 的责任边界冻结。**
103
+ `Upgrade Notes` 和 listener 文档已经把 `http` / `websocket` 模式边界讲清楚了,所以 v2 不要再把 transport 暴露到业务命令层;它应该只出现在 `runtime`。
104
+
105
+ **ADR-0004:group discovery 从“隐式自动工作流”改为“显式 workflow”。**
106
+ 当前 SKILL 把发现型群组的 post-join 行为设计得非常自动化,但 Heartbeat 文档又强调不能在没有用户确认的情况下自动 follow/save/DM。v2 最好把它显式化成 `people discover ...` 工作流,而不是“只要 join 就自动跑完整分析”。这保留了你们的关系发现设计,又降低了副作用。
107
+
108
+ ---
109
+
110
+ ## 5. 我建议的 v2 仓库结构
111
+
112
+ 如果你就用当前仓库重写,我建议直接把它变成一个 **Go monorepo**,但从目录层就把“核心 CLI / skills / docs / legacy import”切开:
113
+
114
+ ```text
115
+ /
116
+ ├── cmd/
117
+ │ └── awiki/
118
+ ├── internal/
119
+ │ ├── app/
120
+ │ ├── cli/
121
+ │ ├── config/
122
+ │ ├── docs/
123
+ │ ├── schema/
124
+ │ ├── doctor/
125
+ │ ├── output/
126
+ │ ├── identity/
127
+ │ ├── messaging/
128
+ │ ├── group/
129
+ │ ├── secure/
130
+ │ ├── runtime/
131
+ │ ├── transport/
132
+ │ │ ├── http/
133
+ │ │ ├── websocket/
134
+ │ │ └── ipc/
135
+ │ ├── store/
136
+ │ ├── people/
137
+ │ ├── page/
138
+ │ └── migrate/
139
+ ├── pkg/
140
+ │ └── awikiapi/ # 只有你确定要对外复用时才保留
141
+ ├── skills/
142
+ │ ├── awiki-shared/
143
+ │ ├── awiki-id/
144
+ │ ├── awiki-msg/
145
+ │ ├── awiki-runtime/
146
+ │ ├── awiki-people/
147
+ │ ├── awiki-page/
148
+ │ └── awiki-debug/
149
+ ├── docs/
150
+ ├── npm/
151
+ │ ├── package.json
152
+ │ ├── scripts/install.js
153
+ │ └── scripts/run.js
154
+ ├── migrations/
155
+ ├── testdata/
156
+ └── legacy/
157
+ └── python-v1-import/
158
+ ```
159
+
160
+ 这个结构一方面保留单仓开发和 release 简单度,另一方面已经为未来“单独 OpenClaw 插件仓库”预留了边界。它本质上是学习飞书的 `cli` 与 `openclaw-lark` 分离方式,但不要求你第一天就拆成两个 repo。([GitHub][9])
161
+
162
+ ---
163
+
164
+ ## 6. Go 技术栈建议
165
+
166
+ 既然你已经确定 Go,我建议栈尽量“稳、少、可交叉编译”:
167
+
168
+ * **CLI 框架:Cobra**
169
+ 飞书官方现在就是 Cobra 风格的命令树;公开 pkg 文档里 `schema` 命令也是 `*cobra.Command`。这条线成熟、completion 现成、help 体系完整。([Go Packages][10])
170
+
171
+ * **配置层:Koanf**
172
+ 不建议上来就用 Viper 的全局魔法。Koanf 更适合做“flag > env > file > default”的显式优先级合并,也更方便测试。
173
+
174
+ * **日志:`log/slog`**
175
+ 标准库足够,结合 JSON log 即可。
176
+
177
+ * **本地存储:`database/sql` + `modernc.org/sqlite` + `goose` + `sqlc`**
178
+ 这样可以保持**无 CGO 跨平台编译**,同时继续享受你们当前 SQLite schema 的表达力。现有 schema 和 query 复杂度已经足够高,`sqlc` 比 ORM 更适合。你们当前 schema 里 `owner_did`、`groups`、`group_members`、`relationship_events` 这些设计都值得继续保留。
179
+
180
+ * **WebSocket:`github.com/coder/websocket`**
181
+ 比继续走 Python service/daemon 链路更干净,适合单二进制实现 long-lived listener。
182
+
183
+ * **系统服务:`kardianos/service`**
184
+ 方便做 macOS LaunchAgent / systemd / Windows Service。
185
+
186
+ * **表格输出:`go-pretty/table`**
187
+ 只在 `--format table` 时启用。
188
+
189
+ * **凭证/令牌:`99designs/keyring`**
190
+ 但我建议**只把 bearer-like token 和 daemon token 放 keychain**,不要把 DID 私钥完全塞进 OS keychain。
191
+
192
+ 这里最关键的不是“Go 化”,而是**为单二进制跨平台发布让路**。飞书能用 GoReleaser 稳定覆盖 macOS / Linux / Windows,本质上也是因为底层尽量避免重依赖和平台特例。([GitHub][11])
193
+
194
+ ---
195
+
196
+ ## 7. 凭证与本地状态:保留 awiki 的好设计,但做得更像产品
197
+
198
+ 我建议 v2 把秘密分成两类存储:
199
+
200
+ **A. 身份类私钥材料:文件存储,受权限保护,可导出备份。**
201
+ 包括 DID 私钥、E2EE 私钥、identity metadata。因为 awiki 的 identity 是可迁移、可恢复、可跨环境导入的,完全锁进系统 keychain 反而会削弱它的可移植性。
202
+
203
+ **B. 会话类密钥/令牌:优先 keychain,失败时加密文件回退。**
204
+ 包括 JWT/refresh token、local daemon token、webhook token 等。
205
+
206
+ 目录可以这样设计:
207
+
208
+ ```text
209
+ ~/.awiki/
210
+ config/config.json
211
+ identities/index.json
212
+ identities/alice/
213
+ identity.json
214
+ did.json
215
+ keys/
216
+ e2ee/
217
+ data/alice/awiki.db
218
+ state/
219
+ logs/
220
+ ```
221
+
222
+ 如果检测到现有 `.openclaw` 目录,就支持兼容导入:
223
+
224
+ ```bash
225
+ awiki migrate from-v1
226
+ ```
227
+
228
+ 这样既保留 awiki 的多身份与 owner_did 隔离,又吸收飞书的“OS-native keychain credential storage”优点。飞书官方 README 明确把 keychain 放进了其安全卖点之一;而你们当前 RULES 对私钥、JWT、E2EE key 的保密要求也已经非常清楚。([GitHub][1])
229
+
230
+ ---
231
+
232
+ ## 8. 命令体系:学飞书的三层,但不要照搬 `+` 语法
233
+
234
+ 飞书的三层命令思想非常好,但 awiki 的业务域没那么多,所以不必机械复制 `+shortcut` 语法。我的建议是:
235
+
236
+ ### 第一层:Task Layer(AI 默认层)
237
+
238
+ 这是 AI 默认应使用的层:
239
+
240
+ ```bash
241
+ awiki init
242
+ awiki status
243
+ awiki id register ...
244
+ awiki id bind ...
245
+ awiki msg send ...
246
+ awiki msg inbox
247
+ awiki msg history ...
248
+ awiki group join ...
249
+ awiki runtime setup ...
250
+ ```
251
+
252
+ ### 第二层:Resource Layer(对象级)
253
+
254
+ 这是资源/对象级命令:
255
+
256
+ ```bash
257
+ awiki id resolve ...
258
+ awiki id recover ...
259
+ awiki msg secure init ...
260
+ awiki msg secure repair ...
261
+ awiki group members ...
262
+ awiki group code refresh ...
263
+ awiki people discover start ...
264
+ ```
265
+
266
+ ### 第三层:Raw / Debug Layer
267
+
268
+ 这是调试和兜底层:
269
+
270
+ ```bash
271
+ awiki api ...
272
+ awiki debug db query ...
273
+ awiki debug state dump ...
274
+ ```
275
+
276
+ 这样你吸收了飞书的“三层架构”,但不引入对 awiki 来说没必要的额外语法负担。飞书的 `Shortcuts → API Commands → Raw API` 之所以成立,是因为它有 200+ 命令和 10+ 业务域;awiki 的核心域更窄,所以更适合直接用清晰的动词树来承载 task layer。([GitHub][1])
277
+
278
+ ---
279
+
280
+ ## 9. 我建议的 awiki v2 顶级命令树
281
+
282
+ 这是我建议直接作为 v2 目标的命令树:
283
+
284
+ ```bash
285
+ awiki init
286
+ awiki status
287
+ awiki config ...
288
+ awiki id ...
289
+ awiki msg ...
290
+ awiki group ...
291
+ awiki people ...
292
+ awiki page ...
293
+ awiki runtime ...
294
+ awiki docs ...
295
+ awiki schema ...
296
+ awiki doctor
297
+ awiki completion
298
+ awiki api ...
299
+ awiki debug ...
300
+ ```
301
+
302
+ 其中最核心的是这六个业务域:
303
+
304
+ ```bash
305
+ awiki id
306
+ awiki msg
307
+ awiki group
308
+ awiki runtime
309
+ awiki people
310
+ awiki page
311
+ ```
312
+
313
+ 再补五个产品控制命令:
314
+
315
+ ```bash
316
+ awiki init
317
+ awiki config
318
+ awiki docs
319
+ awiki schema
320
+ awiki doctor
321
+ ```
322
+
323
+ 这就是“参考飞书,但更克制”的版本。飞书的官方命令里 `auth / config / schema / doctor / completion` 是一级产品能力;awiki v2 也应该这么做,只是业务域更少。([GitHub][11])
324
+
325
+ ---
326
+
327
+ ## 10. 业务命令怎么设计
328
+
329
+ ### 10.1 `awiki id`
330
+
331
+ ```bash
332
+ awiki id status
333
+ awiki id create --name "Alice"
334
+ awiki id register --handle alice --phone +8613800138000 [--otp 123456] [--invite-code ABC123]
335
+ awiki id register --handle alice --email user@example.com [--wait]
336
+ awiki id bind --phone +8613800138000 [--otp 123456]
337
+ awiki id bind --email user@example.com [--wait]
338
+ awiki id resolve --handle alice
339
+ awiki id resolve --did did:wba:...
340
+ awiki id recover --handle alice --phone +8613800138000 --otp 123456
341
+ awiki id list
342
+ awiki id use alice
343
+ awiki id current
344
+ awiki id profile get [--self | --handle alice | --did did:wba:...]
345
+ awiki id profile set --name "Alice" --bio "..." --tags "did,e2ee"
346
+ ```
347
+
348
+ 这里有一个我建议你**明确不要学飞书**的点:
349
+ 飞书社区对 `--profile` 的诉求,是因为它现在还没有把多账户做成一等能力;而 awiki 已经有“身份就是产品核心”的基础,所以不要把用户层概念叫 `profile`,否则会和 social profile 冲突。v2 应该统一叫 `identity`。([GitHub][6])
350
+
351
+ ---
352
+
353
+ ### 10.2 `awiki msg`
354
+
355
+ ```bash
356
+ awiki msg send (--to TARGET | --group GID) --text "Hello" [--type text|event] [--secure off|on]
357
+ awiki msg inbox [--scope all|direct|group] [--group GID] [--mark-read]
358
+ awiki msg history --with TARGET
359
+ awiki msg mark-read MSG_ID...
360
+ awiki msg secure status [--with TARGET]
361
+ awiki msg secure init --with TARGET
362
+ awiki msg secure repair --with TARGET
363
+ awiki msg secure failed
364
+ awiki msg secure retry OUTBOX_ID
365
+ awiki msg secure drop OUTBOX_ID
366
+ ```
367
+
368
+ 这里坚持一条原则:
369
+
370
+ **所有“发送消息”都统一进 `awiki msg send`。**
371
+
372
+ 也就是说:
373
+
374
+ ```bash
375
+ awiki msg send --to alice --text "Hello"
376
+ awiki msg send --to alice --text "Secret" --secure on
377
+ awiki msg send --group grp_xxx --text "Hello everyone"
378
+ ```
379
+
380
+ 这样你把当前 `send_message.py`、`e2ee_messaging.py --send`、`manage_group.py --post-message` 三个入口,收敛成了一个统一意图入口。你保留了 awiki 的 direct/group + plain/e2ee 模型,但把它变成 AI 能稳定理解的命令语义。当前主 SKILL 正是这三件事分散在不同脚本和章节里。
381
+
382
+ ---
383
+
384
+ ### 10.3 `awiki group`
385
+
386
+ ```bash
387
+ awiki group create ...
388
+ awiki group get --group GROUP_DID
389
+ awiki group join --group GROUP_DID
390
+ awiki group add --group GROUP_DID --member DID
391
+ awiki group remove --group GROUP_DID --member DID
392
+ awiki group members --group GROUP_DID
393
+ awiki group messages --group GROUP_DID [--cursor 120]
394
+ awiki group update --group GROUP_DID ...
395
+ awiki group leave --group GROUP_DID
396
+ ```
397
+
398
+ 这里我建议把 **group 生命周期** 做成 top-level `group`,但把 **群消息发送** 仍然统一在 `msg send --group`。
399
+ 这样一方面继承了你“消息是核心”的设计,另一方面又让 group lifecycle 更可发现。当前 awiki 文档里 group 的概念已经明显超过“只是消息目标”,它有 members、doc_url、policy、profile 等完整对象语义。
400
+
401
+ ---
402
+
403
+ ### 10.4 `awiki runtime`
404
+
405
+ ```bash
406
+ awiki runtime status
407
+ awiki runtime setup [--mode http|websocket]
408
+ awiki runtime mode get
409
+ awiki runtime mode set http|websocket
410
+ awiki runtime listener status
411
+ awiki runtime listener install
412
+ awiki runtime listener uninstall
413
+ awiki runtime listener start
414
+ awiki runtime listener stop
415
+ awiki runtime daemon run
416
+ awiki runtime heartbeat status
417
+ ```
418
+
419
+ 这个命令组对应你当前的 `setup_realtime.py`、`ws_listener.py`、heartbeat 规则,但有两个重要改进:
420
+
421
+ 1. **transport 只出现在 runtime 层**
422
+ 2. **websocket 模式下本地 CLI 与 listener 的通信优先走 IPC,而不是 localhost TCP**
423
+
424
+ 也就是说,v2 不再默认用 `127.0.0.1 + token` 作为唯一 daemon 通道,而是优先使用:
425
+
426
+ * Unix Domain Socket(macOS / Linux)
427
+ * Named Pipe(Windows)
428
+ * 仅在必要时 fallback 到 localhost
429
+
430
+ 这条不是飞书直接给你的答案,而是你基于 awiki 当前 daemon/listener 设计向前迈一步。你当前 listener 文档和 upgrade notes 已经证明“单连接 + 本地代理”是对的,Go 版只需要把这层做得更安全。
431
+
432
+ ---
433
+
434
+ ### 10.5 `awiki people`
435
+
436
+ ```bash
437
+ awiki people search "alice"
438
+ awiki people follow --did ...
439
+ awiki people unfollow --did ...
440
+ awiki people following
441
+ awiki people followers
442
+ awiki people contacts list
443
+ awiki people contacts save ...
444
+ awiki people discover start --group GID
445
+ awiki people discover status --group GID
446
+ awiki people discover stop --group GID
447
+ awiki people discover run-once --group GID
448
+ ```
449
+
450
+ 这是我最建议你从主 skill 里“降级”的一块。
451
+ 也就是:保留你们当前的群发现、推荐、DM 草稿、local relationship sedimentation 这些好设计,但把它从“join 后默认自动跑”的主路径,改成显式 workflow。这样既能保留 `GROUP_DISCOVERY_GUIDE` 和 `relationship_events` 的价值,又能降低副作用、上下文压力和错误自动化。
452
+
453
+ ---
454
+
455
+ ## 11. docs / schema / doctor 是 v2 的产品核心,不是附加件
456
+
457
+ 这是你重写里一定要抄飞书、而且要比它做得更彻底的地方。
458
+
459
+ ### `awiki docs`
460
+
461
+ ```bash
462
+ awiki docs onboarding
463
+ awiki docs identity
464
+ awiki docs secure-messaging
465
+ awiki docs transport-modes
466
+ awiki docs discovery-groups
467
+ ```
468
+
469
+ ### `awiki schema`
470
+
471
+ ```bash
472
+ awiki schema
473
+ awiki schema msg.send
474
+ awiki schema id.register
475
+ awiki schema group.create
476
+ ```
477
+
478
+ 输出里建议包含:
479
+
480
+ * 参数定义
481
+ * 是否有副作用
482
+ * 是否必须用户确认
483
+ * 是否支持 `--dry-run`
484
+ * 支持的 target 类型
485
+ * transport 兼容性
486
+ * 需要的本地前置状态
487
+ * 返回 JSON 结构
488
+ * 常见错误码
489
+
490
+ ### `awiki doctor`
491
+
492
+ ```bash
493
+ awiki doctor
494
+ awiki doctor identity
495
+ awiki doctor transport
496
+ awiki doctor e2ee
497
+ awiki doctor store
498
+ ```
499
+
500
+ 飞书官方把 `schema / doctor / completion` 都列成一级能力;社区 issue #8 又明确抱怨“CLI 本体缺少 first-class in-product docs”;issue #48 又说明 help/example drift 是实打实的 UX 伤害。对 awiki 来说,这三件事应该一次性解决:
501
+ **CLI 自带 docs,自带 schema,自带 doctor;skills 只做 AI routing 和策略,而不是承载全部说明。** ([GitHub][11])
502
+
503
+ ---
504
+
505
+ ## 12. skill 的新结构
506
+
507
+ 我建议 skill 最终拆成这 7 份:
508
+
509
+ ```text
510
+ awiki-shared
511
+ awiki-id
512
+ awiki-msg
513
+ awiki-runtime
514
+ awiki-people
515
+ awiki-page
516
+ awiki-debug
517
+ ```
518
+
519
+ ### 设计原则
520
+
521
+ * `awiki-shared` 自动加载或由其他 skill 强依赖
522
+ * 每份 skill 控制在 50–120 行
523
+ * skill 只讲:何时用、先做什么、默认安全规则、常见工作流
524
+ * 复杂参考说明一律交给 `awiki docs` / `awiki schema`
525
+ * 所有 skill 都不要再直接写大量 bash 示例路径
526
+
527
+ 这就是从飞书 `lark-shared + lark-im + lark-event` 学来的最有价值的部分。你甚至可以让 `awiki-msg` 在开头直接写:
528
+
529
+ > CRITICAL — 开始前先读取 `awiki-shared`
530
+
531
+ 飞书就是这么做的。([GitHub][3])
532
+
533
+ ---
534
+
535
+ ## 13. 文档生成策略:一定要“一处定义,多处生成”
536
+
537
+ 为了避免飞书 issue #48 这种 help / README / 实际命令漂移,你的 Go 重写最好从第一天就采用 metadata-driven 生成:
538
+
539
+ ```go
540
+ type CommandMeta struct {
541
+ Name string
542
+ Domain string
543
+ ReadOnly bool
544
+ RequiresConfirm bool
545
+ SupportsDryRun bool
546
+ SupportsFormats []string
547
+ Examples []Example
548
+ Schema CommandSchema
549
+ GuideTopics []string
550
+ }
551
+ ```
552
+
553
+ 然后自动生成:
554
+
555
+ * Cobra `--help`
556
+ * `awiki schema`
557
+ * `docs/cli/*.md`
558
+ * `skills/*/SKILL.md` 中的引用片段
559
+ * README 命令示例
560
+ * Golden tests
561
+
562
+ 也就是说,**不要再手写“主文档示例”和“命令帮助”两套源。**
563
+
564
+ ---
565
+
566
+ ## 14. 分发方案:我建议你几乎完整复用飞书这套
567
+
568
+ 既然你已经选 Go,我建议分发就直接走飞书这条成熟路线。
569
+
570
+ ### 推荐分发链路
571
+
572
+ **主渠道**
573
+
574
+ * GitHub Releases:发布原生二进制
575
+ * npm wrapper:`@awiki/cli`
576
+
577
+ **二级渠道**
578
+
579
+ * Homebrew tap(macOS / Linux)
580
+ * Scoop 或 winget(Windows)
581
+
582
+ **国内镜像**
583
+
584
+ * npm wrapper 的 `install.js` 增加 GitHub Releases 失败后的镜像回退
585
+ * 可用你自己的 CDN 或 npmmirror 风格镜像
586
+
587
+ 飞书官方现在正是这个模型:Go 编译出的原生二进制通过 release 分发,npm 包只负责安装和转发。`package.json` 里 `postinstall` 触发安装脚本,安装脚本根据平台/架构计算 release asset 名称,然后从 GitHub Releases 或镜像拉取。([GitHub][4])
588
+
589
+ ### 我建议你的包名
590
+
591
+ * 二进制:`awiki`
592
+ * npm:`@awiki/cli`
593
+ * GitHub Releases asset:
594
+
595
+ * `awiki_2.0.0_darwin_amd64.tar.gz`
596
+ * `awiki_2.0.0_darwin_arm64.tar.gz`
597
+ * `awiki_2.0.0_linux_amd64.tar.gz`
598
+ * `awiki_2.0.0_linux_arm64.tar.gz`
599
+ * `awiki_2.0.0_windows_amd64.zip`
600
+ * `awiki_2.0.0_windows_arm64.zip`
601
+
602
+ ### 安装路径
603
+
604
+ 我建议对外只保留两条主路径:
605
+
606
+ ```bash
607
+ npm install -g @awiki/cli
608
+ # AI agent 如需 skills
609
+ npx skills add agentconnect/awiki-cli -y -g
610
+ ```
611
+
612
+ 和:
613
+
614
+ ```bash
615
+ brew install agentconnect/tap/awiki
616
+ ```
617
+
618
+ 不要再把 zip + git clone + `install_dependencies.py` 当主安装路径。你们当前 SKILL 的安装方式在 Go 重写后应该彻底退出主路径。
619
+
620
+ ---
621
+
622
+ ## 15. 对 OpenClaw 的关系:参考飞书,但不要现在就拆仓
623
+
624
+ 飞书现在已经把 CLI 和 OpenClaw 插件拆开了:`larksuite/cli` 做命令和 skills,`larksuite/openclaw-lark` 做宿主侧集成、卡片、交互、群策略等。这个方向是对的。([GitHub][9])
625
+
626
+ 对你来说,最稳妥的做法不是马上拆成两个 repo,而是:
627
+
628
+ * v2 第一阶段先保持一个仓库
629
+ * 代码层把 `core CLI` 与 `host/plugin adapter` 解耦
630
+ * 等命令树、存储布局、技能层稳定之后,再单独抽 `openclaw-awiki`
631
+
632
+ 这样你不会在“协议重写 + CLI 重写 + 插件拆分”三个方向同时冒风险。
633
+
634
+ ---
635
+
636
+ ## 16. 互联网和社区反馈里,最值得吸收到 awiki 的 4 个点
637
+
638
+ 除了官方结构,最近外部评价里我觉得最值得你吸收的有四条:
639
+
640
+ **1. CLI 应该是“执行桥”,不是“编排器”。**
641
+ 第三方指南对飞书 CLI 的一个很稳定的定位是:它的价值在于把 agent 输出和团队系统连接起来,但它本身不是 orchestration layer。这个观点我非常赞同,也很适合 awiki:heartbeat / discovery / listener / retry 这些可以是 runtime/workflow,但不要把整个 CLI 设计成“自动化总控平台”。([Verdent AI][12])
642
+
643
+ **2. `--dry-run` 是 AI 时代的安全网。**
644
+ 不管是第三方教程还是社区讨论,大家反复强调的都是:AI 会自己做决策,所以 preview-before-write 非常重要。awiki v2 应该把 `--dry-run` 作为所有有副作用命令的统一能力。([GitHub][1])
645
+
646
+ **3. `schema` 是 AI 的“自描述接口”。**
647
+ 外部讨论普遍认为,schema/introspection 解决的是“AI 看不到 GUI,只能靠文本理解工具”的根问题。awiki v2 也应该把 `schema` 当一等公民,而不是只给 README 示例。([GitHub][1])
648
+
649
+ **4. 默认上下文面要小。**
650
+ `openclaw-lark` 的上下文开销 issue 本质上说明:功能越多,越要模块化和按需暴露。awiki v2 的默认 skill 集不应包含 discovery/page/debug 这些非核心域。([GitHub][7])
651
+
652
+ ---
653
+
654
+ ## 17. 重写实施顺序
655
+
656
+ 我建议你按下面顺序推进,而不是一次性全推倒。
657
+
658
+ ### Phase 0:冻结旧版并做审计
659
+
660
+ * 打 `python-v1-final` tag
661
+ * 写 4 个 ADR:E2EE、storage、transport、discovery
662
+ * 列出现有功能对照表
663
+ * 选定 v2 CLI nouns
664
+
665
+ ### Phase 1:先搭空壳
666
+
667
+ * `awiki`
668
+ * `config / docs / schema / doctor / completion`
669
+ * 输出协议、错误码、`--format`、`--dry-run`
670
+ * GoReleaser 初版
671
+
672
+ ### Phase 2:身份模块
673
+
674
+ * `id create / register / bind / resolve / recover / profile`
675
+ * 多 identity 一等支持
676
+ * v1 数据导入器
677
+
678
+ ### Phase 3:消息与群
679
+
680
+ * `msg send / inbox / history`
681
+ * `group create / join / members / messages`
682
+ * 统一 send 语义
683
+ * SQLite v2 schema & migrations
684
+
685
+ ### Phase 4:E2EE
686
+
687
+ * secure session engine
688
+ * auto-process incoming control frames
689
+ * outbox failure / retry / drop
690
+ * 只保留一个协议规范源
691
+
692
+ ### Phase 5:runtime
693
+
694
+ * `http` / `websocket` mode
695
+ * single remote connection
696
+ * daemon IPC
697
+ * service install/start/stop/status
698
+
699
+ ### Phase 6:扩展域
700
+
701
+ * `people`
702
+ * `page`
703
+ * `debug`
704
+ * discovery workflow 显式化
705
+
706
+ ### Phase 7:skills & docs 生成
707
+
708
+ * `awiki-shared` 等 modular skills
709
+ * `awiki docs` 与 skill 内容对齐
710
+ * 生成式 help/schema/readme
711
+
712
+ ### Phase 8:发布切换
713
+
714
+ * GitHub Releases
715
+ * npm wrapper
716
+ * optional Homebrew
717
+ * skill install path
718
+ * migration guide
719
+
720
+ ---
721
+
722
+ ## 18. 我给你的最终定版建议
723
+
724
+ 如果让我把整个方案压缩成一句话,那就是:
725
+
726
+ **awiki v2 应该是一个 Go 写的、独立分发的、带 `docs/schema/doctor/dry-run` 的统一 CLI;核心只围绕 identity / messaging / runtime 三大层重建;skills 采用 `shared + domain` 模式;保留 awiki 的 DID、E2EE、多身份、heartbeat、本地状态与安全边界;吸收飞书的统一入口、三层命令、跨平台发布与 agent-first 设计;但明确避免飞书已经暴露出的文档依赖、profile 不原生、schema 过重和 help 漂移问题。** ([GitHub][1])
727
+
728
+ 下一步最适合做的,不是继续讨论理念,而是我直接给你产出一份 **awiki v2 CLI 规范文档**:包含命令树、参数规范、输出协议、错误码、`schema` 结构、repo 目录、Go 包划分,以及首批 7 个 skill 的骨架。
729
+
730
+ [1]: https://github.com/larksuite/cli/blob/main/README.md "cli/README.md at main · larksuite/cli · GitHub"
731
+ [2]: https://github.com/larksuite/cli/issues/8 "CLI needs first-class in-product docs; skills should be optional enhancement, not required path · Issue #8 · larksuite/cli · GitHub"
732
+ [3]: https://github.com/larksuite/cli/blob/main/skills/lark-shared/SKILL.md "cli/skills/lark-shared/SKILL.md at main · larksuite/cli · GitHub"
733
+ [4]: https://github.com/larksuite/cli/blob/main/package.json "cli/package.json at main · larksuite/cli · GitHub"
734
+ [5]: https://github.com/larksuite/cli?utm_source=chatgpt.com "larksuite/cli: The official Lark/Feishu ..."
735
+ [6]: https://github.com/larksuite/cli/issues/29 "Feature Request: Multi-account / Profile support · Issue #29 · larksuite/cli · GitHub"
736
+ [7]: https://github.com/larksuite/openclaw-lark/issues/17 "Reduce context overhead by exposing Feishu capabilities via CLI/on-demand bridge instead of registering all as tools · Issue #17 · larksuite/openclaw-lark · GitHub"
737
+ [8]: https://github.com/larksuite/cli/issues/48 "Help and README examples drift from the current CLI surface · Issue #48 · larksuite/cli · GitHub"
738
+ [9]: https://github.com/larksuite/openclaw-lark "GitHub - larksuite/openclaw-lark: 飞书官方出品的 OpenClaw 飞书/Lark Channel 插件 · GitHub"
739
+ [10]: https://pkg.go.dev/github.com/larksuite/cli/cmd/schema?utm_source=chatgpt.com "schema package - github.com/larksuite/cli/cmd ..."
740
+ [11]: https://github.com/larksuite/cli/blob/main/CHANGELOG.md "cli/CHANGELOG.md at main · larksuite/cli · GitHub"
741
+ [12]: https://www.verdent.ai/guides/lark-cli-ai-coding-agent-workflow?utm_source=chatgpt.com "How Lark CLI Fits Into an AI Coding Agent Workflow"