@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.
- package/.github/workflows/release.yml +44 -0
- package/.goreleaser.yml +44 -0
- package/AGENTS.md +60 -0
- package/CLAUDE.md +192 -0
- package/README.md +2 -0
- package/docs/architecture/awiki-command-v2.md +955 -0
- package/docs/architecture/awiki-skill-architecture.md +475 -0
- package/docs/architecture/awiki-v2-architecture.md +1063 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/cli-init.md +1008 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/output-format.md +407 -0
- package/docs/architecture//345/217/202/350/200/203/346/226/207/346/241/243/overall-init.md +741 -0
- package/docs/harness/review-spec.md +474 -0
- package/docs/installation.md +372 -0
- package/docs/plan/awiki-v2-implementation-plan.md +903 -0
- package/docs/plan/phase-0/adr-index.md +56 -0
- package/docs/plan/phase-0/audit-findings.md +251 -0
- package/docs/plan/phase-0/capability-mapping.md +108 -0
- package/docs/plan/phase-0/implementation-constraints.md +363 -0
- package/docs/publish.md +169 -0
- package/go.mod +29 -0
- package/go.sum +73 -0
- package/internal/anpsdk/registry.go +63 -0
- package/internal/authsdk/session.go +351 -0
- package/internal/buildinfo/buildinfo.go +34 -0
- package/internal/cli/app.go +136 -0
- package/internal/cli/app_test.go +88 -0
- package/internal/cli/debug.go +104 -0
- package/internal/cli/group.go +263 -0
- package/internal/cli/id.go +473 -0
- package/internal/cli/init.go +134 -0
- package/internal/cli/msg.go +228 -0
- package/internal/cli/page.go +267 -0
- package/internal/cli/root.go +499 -0
- package/internal/cli/runtime.go +232 -0
- package/internal/cli/upgrade.go +60 -0
- package/internal/cmdmeta/catalog.go +203 -0
- package/internal/cmdmeta/catalog_test.go +21 -0
- package/internal/config/config.go +399 -0
- package/internal/config/config_test.go +104 -0
- package/internal/config/write.go +37 -0
- package/internal/content/service.go +314 -0
- package/internal/content/service_test.go +165 -0
- package/internal/content/types.go +44 -0
- package/internal/docs/topics.go +110 -0
- package/internal/doctor/doctor.go +306 -0
- package/internal/identity/client.go +267 -0
- package/internal/identity/did.go +85 -0
- package/internal/identity/did_test.go +50 -0
- package/internal/identity/layout.go +206 -0
- package/internal/identity/legacy.go +378 -0
- package/internal/identity/public.go +70 -0
- package/internal/identity/public_test.go +73 -0
- package/internal/identity/readiness.go +74 -0
- package/internal/identity/service.go +826 -0
- package/internal/identity/store.go +385 -0
- package/internal/identity/store_test.go +180 -0
- package/internal/identity/types.go +204 -0
- package/internal/message/auth.go +167 -0
- package/internal/message/group_service.go +838 -0
- package/internal/message/group_wire.go +350 -0
- package/internal/message/group_wire_test.go +67 -0
- package/internal/message/helpers.go +61 -0
- package/internal/message/http_client.go +334 -0
- package/internal/message/proof.go +156 -0
- package/internal/message/proof_test.go +61 -0
- package/internal/message/service.go +696 -0
- package/internal/message/service_test.go +97 -0
- package/internal/message/types.go +155 -0
- package/internal/message/wire.go +100 -0
- package/internal/message/wire_test.go +49 -0
- package/internal/message/ws_proxy_client.go +151 -0
- package/internal/output/output.go +350 -0
- package/internal/output/output_test.go +48 -0
- package/internal/runtime/config.go +117 -0
- package/internal/runtime/config_test.go +46 -0
- package/internal/runtime/listener/files.go +65 -0
- package/internal/runtime/listener/manager.go +142 -0
- package/internal/runtime/listener/server.go +983 -0
- package/internal/runtime/listener/server_test.go +319 -0
- package/internal/runtime/listener/sysproc_unix.go +17 -0
- package/internal/runtime/listener/sysproc_windows.go +13 -0
- package/internal/runtime/listener/types.go +21 -0
- package/internal/runtime/listener/wsclient.go +299 -0
- package/internal/runtime/listener/wsclient_test.go +41 -0
- package/internal/store/dao.go +632 -0
- package/internal/store/dao_test.go +87 -0
- package/internal/store/helpers.go +197 -0
- package/internal/store/import.go +499 -0
- package/internal/store/import_test.go +103 -0
- package/internal/store/open.go +71 -0
- package/internal/store/query.go +151 -0
- package/internal/store/schema.go +277 -0
- package/internal/store/schema_test.go +56 -0
- package/internal/store/types.go +177 -0
- package/internal/update/update.go +368 -0
- package/package.json +17 -0
- package/scripts/install.js +171 -0
- package/scripts/release/release-prerelease.sh +86 -0
- package/scripts/release/tag-release.sh +66 -0
- package/scripts/release/withdraw-release.sh +78 -0
- package/scripts/run.js +69 -0
- package/skills/README.md +32 -0
- package/skills/awiki-bundle/SKILL.md +76 -0
- package/skills/awiki-debug/SKILL.md +80 -0
- package/skills/awiki-group/SKILL.md +111 -0
- package/skills/awiki-id/SKILL.md +123 -0
- package/skills/awiki-msg/SKILL.md +131 -0
- package/skills/awiki-page/SKILL.md +93 -0
- package/skills/awiki-people/SKILL.md +66 -0
- package/skills/awiki-runtime/SKILL.md +137 -0
- package/skills/awiki-shared/SKILL.md +124 -0
- package/skills/awiki-workflow-discovery/SKILL.md +93 -0
- package/skills/awiki-workflow-onboarding/SKILL.md +119 -0
- package/skills/manifests/skills.yaml +260 -0
- package/skills/templates/bundle-skill-template.md +42 -0
- package/skills/templates/debug-skill-template.md +44 -0
- package/skills/templates/domain-skill-template.md +56 -0
- package/skills/templates/shared-skill-template.md +46 -0
- package/skills/templates/workflow-skill-template.md +46 -0
|
@@ -0,0 +1,955 @@
|
|
|
1
|
+
可以。下面这份我按“**最终定版**”来写:它保留了 `cli-init.md` 和 `output-format.md` 里的核心内容——统一 CLI、core/extension 分层、消息三维模型、`schema`、`--dry-run`、`--jq`、shortcut、结构化输出、skill 拆分、legacy 映射——但把实现语言、工程结构和发布方式正式切换成 **Go CLI**。
|
|
2
|
+
|
|
3
|
+
我下面统一使用 **`awiki-cli`** 作为最终命令名和主二进制名;项目名仍保持 awiki 体系,skill 命名继续保留 `awiki-*`。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# awiki-cli v2 最终可执行方案(Go 版)
|
|
8
|
+
|
|
9
|
+
## 1. 定版目标
|
|
10
|
+
|
|
11
|
+
awiki-cli v2 的目标不是“把旧 Python 脚本逐个翻译成 Go”,而是建立一个**对 AI 和人都稳定可路由的任务模型**:
|
|
12
|
+
|
|
13
|
+
* 按**用户意图**组织,而不是按脚本实现组织。
|
|
14
|
+
* 命令默认**非交互**。
|
|
15
|
+
* 所有有副作用的命令都支持 `--dry-run`。
|
|
16
|
+
* 所有命令都支持**结构化输出**。
|
|
17
|
+
* 提供可机器读取的 `schema`。
|
|
18
|
+
* skill 拆成 `shared + domain`,不再把所有内容塞进一个巨型 `SKILL.md`。
|
|
19
|
+
|
|
20
|
+
这次语言切换到 Go 后,**命令契约不变**,变的是实现和发布:
|
|
21
|
+
|
|
22
|
+
* 命令树、参数语义、shortcut 规则、输出协议,保持 v2 设计;
|
|
23
|
+
* 实现层改成 Go;
|
|
24
|
+
* 发布改成多平台原生二进制;
|
|
25
|
+
* 文档、schema、shell completion、man page 从代码自动生成。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. 产品边界与核心模型
|
|
30
|
+
|
|
31
|
+
### 2.1 核心能力
|
|
32
|
+
|
|
33
|
+
CLI 的主线只有三块:
|
|
34
|
+
|
|
35
|
+
* `id`:身份生命周期
|
|
36
|
+
* `msg`:消息生命周期
|
|
37
|
+
* `runtime`:运行时与接收机制
|
|
38
|
+
|
|
39
|
+
辅助命令:
|
|
40
|
+
|
|
41
|
+
* `status`
|
|
42
|
+
* `schema`
|
|
43
|
+
* `doctor`
|
|
44
|
+
* `docs`
|
|
45
|
+
* `version`
|
|
46
|
+
* `completion`
|
|
47
|
+
|
|
48
|
+
扩展能力单独分组:
|
|
49
|
+
|
|
50
|
+
* `people`
|
|
51
|
+
* `page`
|
|
52
|
+
* `discovery`
|
|
53
|
+
* `debug`
|
|
54
|
+
|
|
55
|
+
### 2.2 统一消息模型
|
|
56
|
+
|
|
57
|
+
主文档里建议直接写死:
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
Message =
|
|
61
|
+
Target(scope: direct | group)
|
|
62
|
+
× Security(plain | e2ee)
|
|
63
|
+
× ReceiveMode(pull | realtime)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
其中 AI 需要主动选择的只有:
|
|
67
|
+
|
|
68
|
+
* `scope`:私聊 / 群聊
|
|
69
|
+
* `security`:明文 / E2EE
|
|
70
|
+
|
|
71
|
+
`ReceiveMode` 属于 `runtime`,不属于 `msg` 路由。当前支持矩阵建议明确为:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
direct + plain = supported
|
|
75
|
+
direct + e2ee = supported
|
|
76
|
+
group + plain = supported
|
|
77
|
+
group + e2ee = not supported yet
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## 3. 最终命令树
|
|
85
|
+
|
|
86
|
+
## 3.1 canonical 命令树
|
|
87
|
+
|
|
88
|
+
这是最终冻结的主命令树:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
awiki-cli status
|
|
92
|
+
awiki-cli docs [TOPIC]
|
|
93
|
+
awiki-cli schema [COMMAND]
|
|
94
|
+
awiki-cli doctor
|
|
95
|
+
awiki-cli version
|
|
96
|
+
awiki-cli init [--home PATH]
|
|
97
|
+
awiki-cli completion <bash|zsh|fish|powershell>
|
|
98
|
+
|
|
99
|
+
awiki-cli id status
|
|
100
|
+
awiki-cli id create --name "Alice" [--identity alice]
|
|
101
|
+
awiki-cli id register --handle alice (--phone +8613800138000 [--otp 123456] [--invite-code ABC123] | --email user@example.com [--wait]) [--identity alice]
|
|
102
|
+
awiki-cli id bind (--phone +8613800138000 [--otp 123456] | --email user@example.com [--wait]) [--identity alice]
|
|
103
|
+
awiki-cli id resolve (--handle alice | --did did:wba:...)
|
|
104
|
+
awiki-cli id recover --handle alice --phone +8613800138000 --otp 123456 [--identity alice]
|
|
105
|
+
awiki-cli id list
|
|
106
|
+
awiki-cli id current
|
|
107
|
+
awiki-cli id use alice
|
|
108
|
+
awiki-cli id profile get [--self | --handle alice | --did did:wba:...]
|
|
109
|
+
awiki-cli id profile set [--display-name "Alice"] [--bio "..."] [--tags "ai,did,agent"] [--markdown "# About Me"] [--markdown-file ./profile.md]
|
|
110
|
+
|
|
111
|
+
awiki-cli msg send (--to TARGET | --group GROUP_DID) [--text "Hello"] [--text-file ./message.txt] [--type text|event] [--secure off|on] [--identity alice]
|
|
112
|
+
awiki-cli msg inbox [--scope all|direct|group] [--with TARGET] [--group GROUP_DID] [--unread] [--limit 20] [--mark-read] [--identity alice]
|
|
113
|
+
awiki-cli msg history --with TARGET [--limit 50] [--cursor CURSOR] [--identity alice]
|
|
114
|
+
awiki-cli msg mark-read MSG_ID...
|
|
115
|
+
|
|
116
|
+
awiki-cli group create --name "Agent War Room" [--description "..."] [--discoverability private|listed|public] [--admission-mode admin-add|open-join] [--slug agent-war-room] [--goal "..."] [--rules "..."] [--message-prompt "..."] [--doc-url "https://..."] [--attachments-allowed] [--max-members 500] [--member-max-messages 10] [--member-max-total-chars 2000] [--identity alice]
|
|
117
|
+
awiki-cli group get --group GROUP_DID [--identity alice]
|
|
118
|
+
awiki-cli group join --group GROUP_DID [--reason "..."] [--identity alice]
|
|
119
|
+
awiki-cli group add --group GROUP_DID --member did:wba:... [--role member|admin] [--reason "..."] [--identity alice]
|
|
120
|
+
awiki-cli group remove --group GROUP_DID --member did:wba:... [--reason "..."] [--identity alice]
|
|
121
|
+
awiki-cli group members --group GROUP_DID [--limit 100] [--identity alice]
|
|
122
|
+
awiki-cli group messages --group GROUP_DID [--limit 50] [--cursor CURSOR] [--identity alice]
|
|
123
|
+
awiki-cli group update --group GROUP_DID [--name "..."] [--description "..."] [--discoverability private|listed|public] [--admission-mode admin-add|open-join] [--slug "..."] [--goal "..."] [--rules "..."] [--message-prompt "..."] [--doc-url "https://..."] [--attachments-allowed=true|false] [--max-members 500] [--member-max-messages 10] [--member-max-total-chars 2000] [--identity alice]
|
|
124
|
+
awiki-cli group leave --group GROUP_DID [--identity alice]
|
|
125
|
+
|
|
126
|
+
测试与示例约定:
|
|
127
|
+
|
|
128
|
+
- DID / Group DID 的 profile 段默认使用 `e1_...` 形式,例如 `did:wba:example.com:user:alice:e1_alice`、`did:wba:example.com:groups:demo:e1_group`。
|
|
129
|
+
- 不再新增裸 `:e1` 的测试 fixture 或命令示例。
|
|
130
|
+
|
|
131
|
+
awiki-cli msg secure status [--with TARGET] [--identity alice]
|
|
132
|
+
awiki-cli msg secure init --with TARGET [--identity alice]
|
|
133
|
+
awiki-cli msg secure repair --with TARGET [--identity alice]
|
|
134
|
+
awiki-cli msg secure failed [--identity alice]
|
|
135
|
+
awiki-cli msg secure retry OUTBOX_ID [--identity alice]
|
|
136
|
+
awiki-cli msg secure drop OUTBOX_ID [--identity alice]
|
|
137
|
+
|
|
138
|
+
awiki-cli runtime status [--identity NAME]
|
|
139
|
+
awiki-cli runtime setup [--mode http|websocket] [--identity NAME]
|
|
140
|
+
awiki-cli runtime mode get
|
|
141
|
+
awiki-cli runtime mode set http|websocket
|
|
142
|
+
awiki-cli runtime listener status
|
|
143
|
+
awiki-cli runtime listener install
|
|
144
|
+
awiki-cli runtime listener start
|
|
145
|
+
awiki-cli runtime listener stop
|
|
146
|
+
awiki-cli runtime listener restart
|
|
147
|
+
awiki-cli runtime listener uninstall
|
|
148
|
+
awiki-cli runtime heartbeat status
|
|
149
|
+
awiki-cli runtime heartbeat install [--every 15m]
|
|
150
|
+
awiki-cli runtime heartbeat run-once
|
|
151
|
+
|
|
152
|
+
awiki-cli people search "AI agent"
|
|
153
|
+
awiki-cli people follow TARGET
|
|
154
|
+
awiki-cli people unfollow TARGET
|
|
155
|
+
awiki-cli people status TARGET
|
|
156
|
+
awiki-cli people followers
|
|
157
|
+
awiki-cli people following
|
|
158
|
+
awiki-cli people contacts list
|
|
159
|
+
awiki-cli people contacts save --did DID --handle HANDLE --reason "..."
|
|
160
|
+
|
|
161
|
+
awiki-cli page create --slug jd --title "Hiring" --markdown-file ./jd.md [--visibility public|draft|unlisted]
|
|
162
|
+
awiki-cli page list
|
|
163
|
+
awiki-cli page get --slug jd
|
|
164
|
+
awiki-cli page update --slug jd [--title "..."] [--markdown "..."] [--markdown-file ./x.md] [--visibility public|draft|unlisted]
|
|
165
|
+
awiki-cli page rename --slug jd --to hiring
|
|
166
|
+
awiki-cli page delete --slug hiring
|
|
167
|
+
|
|
168
|
+
awiki-cli discovery scan --group GROUP_ID
|
|
169
|
+
awiki-cli discovery recommend --group GROUP_ID
|
|
170
|
+
awiki-cli discovery draft-intro --group GROUP_ID
|
|
171
|
+
awiki-cli discovery draft-dm --group GROUP_ID --member DID
|
|
172
|
+
|
|
173
|
+
awiki-cli debug db query "SELECT ..."
|
|
174
|
+
awiki-cli debug raw rpc ...
|
|
175
|
+
awiki-cli debug schema-cache
|
|
176
|
+
awiki-cli debug logs [--follow]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
这棵树延续了两份文档的核心设计:`status / docs / schema / doctor / id / msg / runtime` 作为核心,`people / page / discovery / debug` 作为扩展;其中**所有发送动作都统一收敛到 `msg send`**,不再按“私聊脚本 / 群发脚本 / E2EE 脚本”分裂。
|
|
180
|
+
|
|
181
|
+
## 3.2 新增的 Go 标准命令
|
|
182
|
+
|
|
183
|
+
相比原草案,我建议在 Go 版里正式加入:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
awiki-cli docs [TOPIC]
|
|
187
|
+
awiki-cli init [--home PATH]
|
|
188
|
+
awiki-cli completion <bash|zsh|fish|powershell>
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`docs` 作为一级命令,用于承载 onboarding、identity、secure-messaging、transport-modes 等产品内建文档。
|
|
192
|
+
|
|
193
|
+
`init` 作为显式初始化命令,用于:
|
|
194
|
+
|
|
195
|
+
* 帮用户创建工作目录(默认是 `~/.awiki-cli`,或由 `AWIKI_HOME` 指定)及其子目录;
|
|
196
|
+
* 在首次需要时生成一份最小的 `config.json` 骨架;
|
|
197
|
+
|
|
198
|
+
Cobra 本身就是面向现代 Go CLI 的命令树框架,支持子命令、flag、自动 help;官方文档也明确支持 shell completion,以及从命令树生成 Markdown/man page 文档。用它来做 awiki-cli,正好能把命令、帮助、completion、文档和 LLM 索引统一起来。([GitHub][1])
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 4. shortcut 设计
|
|
203
|
+
|
|
204
|
+
shortcut 要加,但**只能是 canonical command 的别名**,不能形成第二套语义。这个原则保留。
|
|
205
|
+
|
|
206
|
+
建议保留 8 个以内:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
awiki-cli setup # = awiki-cli runtime setup
|
|
210
|
+
awiki-cli register ... # = awiki-cli id register ...
|
|
211
|
+
awiki-cli whoami # = awiki-cli id current
|
|
212
|
+
awiki-cli inbox # = awiki-cli msg inbox
|
|
213
|
+
awiki-cli dm alice "hello" # = awiki-cli msg send --to alice --text "hello"
|
|
214
|
+
awiki-cli secure alice "secret" # = awiki-cli msg send --to alice --text "secret" --secure on
|
|
215
|
+
awiki-cli group get --group did:wba:... # top-level canonical group lifecycle entry
|
|
216
|
+
awiki-cli history alice # = awiki-cli msg history --with alice
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
最终规则:
|
|
220
|
+
|
|
221
|
+
* shortcut 只能是 alias
|
|
222
|
+
* shortcut 不能有独占语义
|
|
223
|
+
* shortcut 数量控制在 6–8 个
|
|
224
|
+
* 文档先写 canonical,再写 shortcut
|
|
225
|
+
* 不引入飞书那种 `+xxx` 作为主语法
|
|
226
|
+
|
|
227
|
+
另外,**canonical 命令默认 JSON,shortcut 默认 pretty/table**。这点保留 output-format 的结论:协议层以 JSON 为主,展示层可以更友好。
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
## 5. 参数命名与冲突收敛
|
|
232
|
+
|
|
233
|
+
这里我把两份文档里不一致的地方做了统一。
|
|
234
|
+
|
|
235
|
+
## 5.1 全局参数
|
|
236
|
+
|
|
237
|
+
最终定为:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
--identity <name> # canonical
|
|
241
|
+
--credential <name> # legacy alias
|
|
242
|
+
|
|
243
|
+
--format json|pretty|table|ndjson
|
|
244
|
+
--output ... # legacy alias of --format
|
|
245
|
+
--json # alias of --format json
|
|
246
|
+
--jq '<expr>'
|
|
247
|
+
--dry-run
|
|
248
|
+
--yes
|
|
249
|
+
--verbose
|
|
250
|
+
--no-color
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
这样做有两个好处:
|
|
254
|
+
|
|
255
|
+
第一,把 `cli-init.md` 里的 `--output` 和 `output-format.md` 里的 `--format` 收敛到一个最终名字:**`--format`**。
|
|
256
|
+
第二,把 `human` 收敛成 `pretty`;如果你还想兼容旧写法,可以把 `human` 当成 `pretty` 的 deprecated alias。
|
|
257
|
+
|
|
258
|
+
## 5.2 目标与身份参数
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
--to <handle|did>
|
|
262
|
+
--group <group-id>
|
|
263
|
+
--did <did>
|
|
264
|
+
--handle <handle>
|
|
265
|
+
--with <target>
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
规则:
|
|
269
|
+
|
|
270
|
+
* 发消息只用 `--to` 或 `--group`
|
|
271
|
+
* 历史、secure peer 用 `--with`
|
|
272
|
+
* 只有显式解析场景才用 `--did` / `--handle`
|
|
273
|
+
* `--peer`、`--target-did` 不再扩散
|
|
274
|
+
|
|
275
|
+
## 5.3 内容参数
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
--text "..."
|
|
279
|
+
--text-file ./message.txt
|
|
280
|
+
|
|
281
|
+
--markdown "..."
|
|
282
|
+
--markdown-file ./doc.md
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
规则:
|
|
286
|
+
|
|
287
|
+
* 消息一律 `--text`
|
|
288
|
+
* Markdown 一律 `--markdown`
|
|
289
|
+
* 不再混用 `--content` / `--body` / `--profile-md`
|
|
290
|
+
|
|
291
|
+
## 5.4 控制参数
|
|
292
|
+
|
|
293
|
+
```bash
|
|
294
|
+
--secure off|on
|
|
295
|
+
--mode http|websocket
|
|
296
|
+
--wait
|
|
297
|
+
--limit 50
|
|
298
|
+
--cursor CURSOR
|
|
299
|
+
--force
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
`--wait` 只允许轮询,不允许 CLI 内部 prompt;CLI 仍然保持非交互默认。
|
|
303
|
+
|
|
304
|
+
---
|
|
305
|
+
|
|
306
|
+
## 6. 返回协议:JSON 为契约,pretty/table/ndjson 为视图
|
|
307
|
+
|
|
308
|
+
这里按 `output-format.md` 直接定版:**CLI 的标准返回是 JSON,自然语言只是 JSON 里的字段,不是命令契约本身。** `pretty`、`table`、`ndjson` 都是 JSON 的渲染形式。
|
|
309
|
+
|
|
310
|
+
## 6.1 默认输出规则
|
|
311
|
+
|
|
312
|
+
* canonical command:默认 `--format json`
|
|
313
|
+
* shortcut:默认 `--format pretty` 或 `table`
|
|
314
|
+
* 流式命令:只允许 `--format ndjson`
|
|
315
|
+
|
|
316
|
+
## 6.2 成功/失败统一信封
|
|
317
|
+
|
|
318
|
+
我建议最终 Go 代码里统一成这一套:
|
|
319
|
+
|
|
320
|
+
```json
|
|
321
|
+
{
|
|
322
|
+
"ok": true,
|
|
323
|
+
"command": "awiki-cli msg send",
|
|
324
|
+
"data": {},
|
|
325
|
+
"warnings": [],
|
|
326
|
+
"summary": "",
|
|
327
|
+
"_notice": {},
|
|
328
|
+
"meta": {
|
|
329
|
+
"version": "2.0.0",
|
|
330
|
+
"identity": {
|
|
331
|
+
"name": "alice",
|
|
332
|
+
"did": "did:wba:awiki.ai:user:abc...xyz"
|
|
333
|
+
},
|
|
334
|
+
"dry_run": false,
|
|
335
|
+
"format": "json"
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
```json
|
|
341
|
+
{
|
|
342
|
+
"ok": false,
|
|
343
|
+
"error": {
|
|
344
|
+
"code": "permission_denied",
|
|
345
|
+
"message": "Missing required permission",
|
|
346
|
+
"hint": "Run awiki-cli id use alice or refresh identity",
|
|
347
|
+
"retryable": false,
|
|
348
|
+
"details": {}
|
|
349
|
+
},
|
|
350
|
+
"_notice": {},
|
|
351
|
+
"meta": {
|
|
352
|
+
"version": "2.0.0",
|
|
353
|
+
"dry_run": false,
|
|
354
|
+
"format": "json"
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
这里我也做了一个冲突收敛:
|
|
360
|
+
`cli-init.md` 里有 `notice`,`output-format.md` 里用的是 `_notice`。最终建议统一为 **`_notice`**;`notice` 只在 legacy 模式兼容,不再作为新输出字段。
|
|
361
|
+
|
|
362
|
+
## 6.3 命令类别与返回内容
|
|
363
|
+
|
|
364
|
+
查询类命令返回**事实状态**:
|
|
365
|
+
|
|
366
|
+
* `status`
|
|
367
|
+
* `id status`
|
|
368
|
+
* `msg inbox`
|
|
369
|
+
* `msg history`
|
|
370
|
+
* `people search`
|
|
371
|
+
|
|
372
|
+
写操作返回**发生了什么变更**:
|
|
373
|
+
|
|
374
|
+
* `id register`
|
|
375
|
+
* `msg send`
|
|
376
|
+
* `msg group join`
|
|
377
|
+
* `people follow`
|
|
378
|
+
* `page create`
|
|
379
|
+
|
|
380
|
+
异步命令返回**任务状态**:
|
|
381
|
+
|
|
382
|
+
* `runtime setup`
|
|
383
|
+
* `listener install`
|
|
384
|
+
* `discovery scan`(如做异步)
|
|
385
|
+
* 大批量同步/发布
|
|
386
|
+
|
|
387
|
+
流式命令一律 `ndjson`:
|
|
388
|
+
|
|
389
|
+
* `runtime listener logs --follow`
|
|
390
|
+
* 未来的 `msg watch`
|
|
391
|
+
* 未来的 `heartbeat watch`
|
|
392
|
+
|
|
393
|
+
这部分保持 output-format 文档的原结论。
|
|
394
|
+
|
|
395
|
+
## 6.4 `--dry-run`
|
|
396
|
+
|
|
397
|
+
所有有副作用的命令都必须支持 `--dry-run`,并返回 `plan`。
|
|
398
|
+
`--dry-run` 时允许参数校验、本地只读检查、安全的 GET 预检;禁止发送 OTP、邮件、消息,禁止远端写入,禁止本地持久化。
|
|
399
|
+
|
|
400
|
+
## 6.5 `--jq`
|
|
401
|
+
|
|
402
|
+
`--jq` 必须做,而且建议直接嵌入 `gojq`。`gojq` 官方仓库明确说明它是 jq 的纯 Go 实现,而且可以嵌入到 Go 产品里。对 awiki-cli 来说,这正好对应 `--jq` 的需求。([GitHub][2])
|
|
403
|
+
|
|
404
|
+
## 6.6 错误码与退出码
|
|
405
|
+
|
|
406
|
+
错误码集合定为:
|
|
407
|
+
|
|
408
|
+
```text
|
|
409
|
+
invalid_argument
|
|
410
|
+
identity_required
|
|
411
|
+
auth_required
|
|
412
|
+
permission_denied
|
|
413
|
+
not_found
|
|
414
|
+
conflict
|
|
415
|
+
network_error
|
|
416
|
+
transport_unavailable
|
|
417
|
+
secure_session_required
|
|
418
|
+
unsupported_mode
|
|
419
|
+
partial_failure
|
|
420
|
+
internal_error
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
退出码定为:
|
|
424
|
+
|
|
425
|
+
```text
|
|
426
|
+
0 success
|
|
427
|
+
1 generic error
|
|
428
|
+
2 invalid argument
|
|
429
|
+
3 identity/auth missing
|
|
430
|
+
4 permission denied
|
|
431
|
+
5 not found
|
|
432
|
+
6 partial failure
|
|
433
|
+
7 confirmation required but not provided
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## 7. `schema`:从“命令说明”升级成“机器契约”
|
|
439
|
+
|
|
440
|
+
`schema` 不是文档别名,而是**命令元数据接口**。这是两份文档里最值得保留的设计之一。
|
|
441
|
+
|
|
442
|
+
最终形态:
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
awiki-cli schema
|
|
446
|
+
awiki-cli schema msg.send
|
|
447
|
+
awiki-cli schema id.register
|
|
448
|
+
awiki-cli schema runtime.listener.install
|
|
449
|
+
awiki-cli schema --skills
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
返回结构至少包括:
|
|
453
|
+
|
|
454
|
+
```json
|
|
455
|
+
{
|
|
456
|
+
"name": "awiki-cli msg send",
|
|
457
|
+
"summary": "Send a direct or group message",
|
|
458
|
+
"aliases": ["awiki-cli dm"],
|
|
459
|
+
"side_effect": true,
|
|
460
|
+
"confirm_required": false,
|
|
461
|
+
"dry_run_supported": true,
|
|
462
|
+
"identity_required": true,
|
|
463
|
+
"output_formats": ["json", "pretty", "table", "ndjson"],
|
|
464
|
+
"capabilities": {
|
|
465
|
+
"direct_plain": true,
|
|
466
|
+
"direct_e2ee": true,
|
|
467
|
+
"group_plain": true,
|
|
468
|
+
"group_e2ee": false
|
|
469
|
+
},
|
|
470
|
+
"args": [],
|
|
471
|
+
"returns": {},
|
|
472
|
+
"errors": [],
|
|
473
|
+
"examples": [],
|
|
474
|
+
"legacy_maps_to": [
|
|
475
|
+
"scripts/send_message.py",
|
|
476
|
+
"scripts/e2ee_messaging.py --send",
|
|
477
|
+
"scripts/manage_group.py --post-message"
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
最终文件布局:
|
|
483
|
+
|
|
484
|
+
```text
|
|
485
|
+
schemas/
|
|
486
|
+
cli.json
|
|
487
|
+
commands/
|
|
488
|
+
awiki-cli.status.json
|
|
489
|
+
awiki-cli.id.register.json
|
|
490
|
+
awiki-cli.msg.send.json
|
|
491
|
+
awiki-cli.msg.group.join.json
|
|
492
|
+
awiki-cli.runtime.setup.json
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
并且要求:
|
|
496
|
+
|
|
497
|
+
* `awiki-cli schema` 从代码内的 command registry 直接生成
|
|
498
|
+
* `CLI_REFERENCE.md` 从 schema 生成
|
|
499
|
+
* `skills/*/SKILL.md` 中的命令引用由 CI 校验
|
|
500
|
+
* shell help、Markdown docs、man pages 一起自动生成
|
|
501
|
+
|
|
502
|
+
Cobra 官方现在已经明确支持从命令树生成 Markdown/man page,并专门有 “LLM-ready CLI docs” 的文档路径;这非常适合 awiki-cli 把命令树、skill 文档和 schema 保持同步。([cobra.dev][3])
|
|
503
|
+
|
|
504
|
+
---
|
|
505
|
+
|
|
506
|
+
## 8. Go 实现架构
|
|
507
|
+
|
|
508
|
+
## 8.1 技术选型
|
|
509
|
+
|
|
510
|
+
我建议 Go 版固定为这套:
|
|
511
|
+
|
|
512
|
+
* 命令树:**Cobra**
|
|
513
|
+
* JSON 编码:标准库 `encoding/json`
|
|
514
|
+
* `--jq`:**gojq**
|
|
515
|
+
* 发布:**GoReleaser**
|
|
516
|
+
* GitHub Actions 发布:**goreleaser-action**
|
|
517
|
+
* 后台 listener/service:**kardianos/service**
|
|
518
|
+
* 本地 SQLite:**modernc.org/sqlite**(默认 pure Go 方案)
|
|
519
|
+
|
|
520
|
+
Cobra 官方仓库把它定义为“用于现代 Go CLI 的命令框架”,并且是 Kubernetes、Hugo、GitHub CLI 等项目在用的同类方案;它天然适合 awiki-cli 这种深层子命令树。([GitHub][1])
|
|
521
|
+
|
|
522
|
+
GoReleaser 官方把自己定位为“简化发布工程”,而 `goreleaser-action` 则直接给出了 tag 触发发布、上传 artifacts、签名等 CI 模式,正适合 awiki-cli 的多平台二进制分发。([GitHub][4])
|
|
523
|
+
|
|
524
|
+
`kardianos/service` 官方 README 明确说明它可以用同一套 API 在 Windows、Linux(systemd/Upstart/SysV)和 macOS Launchd 上安装、启动、停止服务,这正好对应 `runtime listener install/start/stop/uninstall`。([GitHub][5])
|
|
525
|
+
|
|
526
|
+
`modernc.org/sqlite` 是 CGo-free 的 SQLite 驱动,并明确列出 darwin/linux/windows 多平台支持;对一个要靠 GoReleaser 做多平台发布的 CLI 来说,这比强依赖 CGO 的方案更稳。([Go Packages][6])
|
|
527
|
+
|
|
528
|
+
## 8.2 工程目录
|
|
529
|
+
|
|
530
|
+
我建议 repo 最终长这样:
|
|
531
|
+
|
|
532
|
+
```text
|
|
533
|
+
.
|
|
534
|
+
├── cmd/
|
|
535
|
+
│ └── awiki-cli/
|
|
536
|
+
│ └── main.go
|
|
537
|
+
├── internal/
|
|
538
|
+
│ ├── cli/
|
|
539
|
+
│ │ ├── root.go
|
|
540
|
+
│ │ ├── globalflags/
|
|
541
|
+
│ │ ├── shortcuts/
|
|
542
|
+
│ │ ├── render/
|
|
543
|
+
│ │ ├── schema/
|
|
544
|
+
│ │ └── commands/
|
|
545
|
+
│ │ ├── status/
|
|
546
|
+
│ │ ├── doctor/
|
|
547
|
+
│ │ ├── id/
|
|
548
|
+
│ │ ├── msg/
|
|
549
|
+
│ │ ├── runtime/
|
|
550
|
+
│ │ ├── people/
|
|
551
|
+
│ │ ├── page/
|
|
552
|
+
│ │ ├── discovery/
|
|
553
|
+
│ │ └── debug/
|
|
554
|
+
│ ├── app/
|
|
555
|
+
│ │ ├── identity/
|
|
556
|
+
│ │ ├── messaging/
|
|
557
|
+
│ │ ├── runtime/
|
|
558
|
+
│ │ ├── people/
|
|
559
|
+
│ │ ├── page/
|
|
560
|
+
│ │ └── discovery/
|
|
561
|
+
│ ├── transport/
|
|
562
|
+
│ │ ├── http/
|
|
563
|
+
│ │ └── websocket/
|
|
564
|
+
│ ├── store/
|
|
565
|
+
│ │ ├── sqlite/
|
|
566
|
+
│ │ ├── credentials/
|
|
567
|
+
│ │ └── migrations/
|
|
568
|
+
│ ├── legacy/
|
|
569
|
+
│ └── security/
|
|
570
|
+
├── skills/
|
|
571
|
+
│ ├── awiki-bundle/
|
|
572
|
+
│ ├── awiki-shared/
|
|
573
|
+
│ ├── awiki-id/
|
|
574
|
+
│ ├── awiki-msg/
|
|
575
|
+
│ ├── awiki-runtime/
|
|
576
|
+
│ ├── awiki-people/
|
|
577
|
+
│ ├── awiki-discovery/
|
|
578
|
+
│ ├── awiki-page/
|
|
579
|
+
│ └── awiki-debug/
|
|
580
|
+
├── references/
|
|
581
|
+
├── schemas/
|
|
582
|
+
├── docs/
|
|
583
|
+
│ └── cli/
|
|
584
|
+
├── .goreleaser.yaml
|
|
585
|
+
├── Makefile
|
|
586
|
+
└── go.mod
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
这里 skill 目录我建议**继续保留 `awiki-*` 命名**,因为现有 skill 和服务生态都还是 awiki;CLI 命令名统一改成 `awiki-cli`,避免与项目名、skill 名和服务域混淆。
|
|
590
|
+
|
|
591
|
+
## 8.3 代码分层
|
|
592
|
+
|
|
593
|
+
强制遵守这条规则:
|
|
594
|
+
|
|
595
|
+
* Cobra command 层只负责参数解析、校验、调用 handler
|
|
596
|
+
* handler 只返回**typed result**
|
|
597
|
+
* 所有 stdout/stderr 输出统一走 renderer
|
|
598
|
+
* 业务层不直接打印
|
|
599
|
+
* `schema`、help、docs、skill 引用全部来自统一 registry
|
|
600
|
+
|
|
601
|
+
这能避免最常见的 CLI 漂移:代码、help、docs、skill 四套说法各自为政。
|
|
602
|
+
|
|
603
|
+
## 8.4 推荐的核心 Go 类型
|
|
604
|
+
|
|
605
|
+
建议从一开始就把“输出契约”和“schema 契约”写成显式类型:
|
|
606
|
+
|
|
607
|
+
```go
|
|
608
|
+
type Envelope[T any] struct {
|
|
609
|
+
OK bool `json:"ok"`
|
|
610
|
+
Command string `json:"command"`
|
|
611
|
+
Data *T `json:"data,omitempty"`
|
|
612
|
+
Error *ErrBody `json:"error,omitempty"`
|
|
613
|
+
Warnings []Warning `json:"warnings,omitempty"`
|
|
614
|
+
Summary string `json:"summary,omitempty"`
|
|
615
|
+
Notice *Notice `json:"_notice,omitempty"`
|
|
616
|
+
Meta Meta `json:"meta"`
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
type ErrBody struct {
|
|
620
|
+
Code string `json:"code"`
|
|
621
|
+
Message string `json:"message"`
|
|
622
|
+
Hint string `json:"hint,omitempty"`
|
|
623
|
+
Retryable bool `json:"retryable"`
|
|
624
|
+
Details map[string]any `json:"details,omitempty"`
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
type CommandSpec struct {
|
|
628
|
+
Name string `json:"name"`
|
|
629
|
+
Aliases []string `json:"aliases,omitempty"`
|
|
630
|
+
Summary string `json:"summary"`
|
|
631
|
+
SideEffect bool `json:"side_effect"`
|
|
632
|
+
ConfirmRequired bool `json:"confirm_required"`
|
|
633
|
+
DryRunSupported bool `json:"dry_run_supported"`
|
|
634
|
+
IdentityRequired bool `json:"identity_required"`
|
|
635
|
+
OutputFormats []string `json:"output_formats"`
|
|
636
|
+
Args []ArgSpec `json:"args,omitempty"`
|
|
637
|
+
Returns ReturnSpec `json:"returns"`
|
|
638
|
+
Errors []ErrorSpec `json:"errors,omitempty"`
|
|
639
|
+
Examples []string `json:"examples,omitempty"`
|
|
640
|
+
LegacyMapsTo []string `json:"legacy_maps_to,omitempty"`
|
|
641
|
+
}
|
|
642
|
+
```
|
|
643
|
+
|
|
644
|
+
---
|
|
645
|
+
|
|
646
|
+
## 9. 配置、数据与兼容路径
|
|
647
|
+
|
|
648
|
+
## 9.1 新的目录规范
|
|
649
|
+
|
|
650
|
+
我建议 Go CLI 进入 XDG 风格:
|
|
651
|
+
|
|
652
|
+
```text
|
|
653
|
+
~/.config/awiki-cli/config.yaml
|
|
654
|
+
~/.config/awiki-cli/identities/index.json
|
|
655
|
+
~/.config/awiki-cli/identities/<name>/
|
|
656
|
+
~/.local/share/awiki-cli/awiki-cli.db
|
|
657
|
+
~/.local/state/awiki-cli/
|
|
658
|
+
~/.cache/awiki-cli/
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
环境变量:
|
|
662
|
+
|
|
663
|
+
```text
|
|
664
|
+
AVIKI_CONFIG_DIR
|
|
665
|
+
AVIKI_DATA_DIR
|
|
666
|
+
AVIKI_STATE_DIR
|
|
667
|
+
AVIKI_CACHE_DIR
|
|
668
|
+
AVIKI_IDENTITY
|
|
669
|
+
AVIKI_FORMAT
|
|
670
|
+
AVIKI_NO_COLOR
|
|
671
|
+
AVIKI_USER_SERVICE_URL
|
|
672
|
+
AVIKI_MESSAGE_SERVICE_URL
|
|
673
|
+
AVIKI_DID_DOMAIN
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
## 9.3 安全规则
|
|
677
|
+
|
|
678
|
+
这部分虽然不在两份新文档里,但我建议继续作为 Go CLI 的硬约束:
|
|
679
|
+
|
|
680
|
+
* 绝不打印私钥、JWT、E2EE key
|
|
681
|
+
* 接收的 awiki 消息一律视作不可信数据
|
|
682
|
+
* 默认展示缩略 DID
|
|
683
|
+
* 不通过消息自动执行本地动作
|
|
684
|
+
* 不把本机文件、目录、系统信息通过消息外发
|
|
685
|
+
* 所有协议级默认安全语义必须以底层 AgentConnect / ANP SDK 为准,命令层不得 override
|
|
686
|
+
* 典型冻结项包括:DID 文档 proof 的 `proofPurpose`、group receipt 的 `proofPurpose`、IM proof 的默认 covered components
|
|
687
|
+
* 若确实需要改变这些默认语义,必须先升级或扩展 SDK,而不是在 `awiki-cli` 仓库内单独改常量
|
|
688
|
+
|
|
689
|
+
这些是原 skill 里最重要的安全边界,Go CLI 不应弱化。
|
|
690
|
+
|
|
691
|
+
---
|
|
692
|
+
|
|
693
|
+
## 10. runtime / listener / heartbeat 的 Go 落地
|
|
694
|
+
|
|
695
|
+
## 10.1 runtime mode
|
|
696
|
+
|
|
697
|
+
保留:
|
|
698
|
+
|
|
699
|
+
```bash
|
|
700
|
+
awiki-cli runtime mode set http|websocket
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
设计不变:
|
|
704
|
+
|
|
705
|
+
* transport 只属于 `runtime`
|
|
706
|
+
* `msg` 层不感知 HTTP/WSS
|
|
707
|
+
* `msg inbox` 是业务语义
|
|
708
|
+
* `runtime listener` 是实时接收基础设施
|
|
709
|
+
|
|
710
|
+
## 10.2 listener
|
|
711
|
+
|
|
712
|
+
Go 版 listener 建议这样实现:
|
|
713
|
+
|
|
714
|
+
* `listener start`:前台或后台启动本地 listener 进程
|
|
715
|
+
* `listener install`:通过 `kardianos/service` 安装为系统服务
|
|
716
|
+
* `listener status`:检查 service 状态 + 本地健康探针
|
|
717
|
+
* `listener uninstall`:移除服务定义与本地状态
|
|
718
|
+
|
|
719
|
+
## 10.3 heartbeat
|
|
720
|
+
|
|
721
|
+
保留 15 分钟默认建议值。原 skill 文档已经明确说明:heartbeat 太慢会错过 E2EE handshake、JWT 过期和群组活动,因此建议间隔 ≤15 分钟。Go 版里的 `runtime heartbeat install --every 15m` 和 `run-once` 可以直接继承这个策略。
|
|
722
|
+
|
|
723
|
+
---
|
|
724
|
+
|
|
725
|
+
## 11. skill 与文档拆分
|
|
726
|
+
|
|
727
|
+
这部分照搬前面 CLI 方案,不再回退成一个大文档。
|
|
728
|
+
|
|
729
|
+
## 11.1 skill 目录
|
|
730
|
+
|
|
731
|
+
```text
|
|
732
|
+
skills/
|
|
733
|
+
awiki-bundle/
|
|
734
|
+
awiki-shared/
|
|
735
|
+
awiki-id/
|
|
736
|
+
awiki-msg/
|
|
737
|
+
awiki-runtime/
|
|
738
|
+
awiki-people/
|
|
739
|
+
awiki-discovery/
|
|
740
|
+
awiki-page/
|
|
741
|
+
awiki-debug/
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
职责分别是:
|
|
745
|
+
|
|
746
|
+
* `awiki-bundle`:只做导航
|
|
747
|
+
* `awiki-shared`:共享规则、安全、输出协议、schema、dry-run、确认规则
|
|
748
|
+
* `awiki-id`:身份
|
|
749
|
+
* `awiki-msg`:消息
|
|
750
|
+
* `awiki-runtime`:listener / heartbeat / mode
|
|
751
|
+
* `awiki-people`:search/follow/contacts
|
|
752
|
+
* `awiki-discovery`:群发现工作流
|
|
753
|
+
* `awiki-page`:内容页
|
|
754
|
+
* `awiki-debug`:raw/debug/db
|
|
755
|
+
|
|
756
|
+
## 11.2 references 目录
|
|
757
|
+
|
|
758
|
+
```text
|
|
759
|
+
references/
|
|
760
|
+
SECURITY.md
|
|
761
|
+
CLI_REFERENCE.md
|
|
762
|
+
IDENTITY.md
|
|
763
|
+
MESSAGING.md
|
|
764
|
+
RUNTIME.md
|
|
765
|
+
PEOPLE.md
|
|
766
|
+
DISCOVERY.md
|
|
767
|
+
PAGE.md
|
|
768
|
+
DEBUG.md
|
|
769
|
+
UPGRADE.md
|
|
770
|
+
WHY_AWIKI.md
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
原则不变:
|
|
774
|
+
|
|
775
|
+
* 一个主题只有一个权威文档
|
|
776
|
+
* `SKILL.md` 只做路由与默认行为
|
|
777
|
+
* CLI 细节全部下沉到 `CLI_REFERENCE.md`
|
|
778
|
+
* discovery 不再挤占 `msg` 主路径
|
|
779
|
+
|
|
780
|
+
---
|
|
781
|
+
|
|
782
|
+
## 12. 旧脚本迁移映射
|
|
783
|
+
|
|
784
|
+
这一部分直接保留,但目标从 Python wrapper 改成 Go CLI:
|
|
785
|
+
|
|
786
|
+
```text
|
|
787
|
+
scripts/check_status.py -> awiki-cli status
|
|
788
|
+
scripts/setup_identity.py -> awiki-cli id create / id list / id use
|
|
789
|
+
scripts/send_verification_code.py -> awiki-cli id register / id bind
|
|
790
|
+
scripts/register_handle.py -> awiki-cli id register
|
|
791
|
+
scripts/bind_contact.py -> awiki-cli id bind
|
|
792
|
+
scripts/resolve_handle.py -> awiki-cli id resolve
|
|
793
|
+
scripts/recover_handle.py -> awiki-cli id recover
|
|
794
|
+
scripts/get_profile.py -> awiki-cli id profile get
|
|
795
|
+
scripts/update_profile.py -> awiki-cli id profile set
|
|
796
|
+
scripts/send_message.py -> awiki-cli msg send --secure off
|
|
797
|
+
scripts/e2ee_messaging.py --send -> awiki-cli msg send --secure on
|
|
798
|
+
scripts/check_inbox.py -> awiki-cli msg inbox / msg history / msg mark-read
|
|
799
|
+
scripts/manage_group.py -> awiki-cli msg group ...
|
|
800
|
+
scripts/manage_group.py --post-message -> awiki-cli msg send --group ...
|
|
801
|
+
scripts/setup_realtime.py -> awiki-cli runtime setup
|
|
802
|
+
scripts/ws_listener.py -> awiki-cli runtime listener ...
|
|
803
|
+
scripts/query_db.py -> awiki-cli debug db query
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
这层映射建议做成:
|
|
807
|
+
|
|
808
|
+
* `legacy/` 中的兼容说明
|
|
809
|
+
* `schema` 里的 `legacy_maps_to`
|
|
810
|
+
* `doctor` 的迁移提示
|
|
811
|
+
* 旧脚本执行时输出 deprecation hint
|
|
812
|
+
|
|
813
|
+
这部分正是 `cli-init.md` 里最适合直接继承的内容。
|
|
814
|
+
|
|
815
|
+
---
|
|
816
|
+
|
|
817
|
+
## 13. 包发布与安装
|
|
818
|
+
|
|
819
|
+
既然已经切到 Go,我建议发布路径也跟着定:
|
|
820
|
+
|
|
821
|
+
## 13.1 首发方式
|
|
822
|
+
|
|
823
|
+
首发只做:
|
|
824
|
+
|
|
825
|
+
* GitHub Releases
|
|
826
|
+
* npm wrapper(`@awiki/cli`)
|
|
827
|
+
* 多平台二进制:
|
|
828
|
+
|
|
829
|
+
* macOS: amd64 / arm64
|
|
830
|
+
* Linux: amd64 / arm64
|
|
831
|
+
* Windows: amd64 / arm64
|
|
832
|
+
* checksum
|
|
833
|
+
* shell completions
|
|
834
|
+
* man pages
|
|
835
|
+
* `docs/cli` Markdown 文档
|
|
836
|
+
|
|
837
|
+
GoReleaser 和它的 GitHub Action 已经把 tag 触发发布、上传 artifacts、签名和产物输出说明得很清楚,适合作为标准发布链路。([GitHub][4])
|
|
838
|
+
|
|
839
|
+
## 13.2 安装方式
|
|
840
|
+
|
|
841
|
+
建议四种:
|
|
842
|
+
|
|
843
|
+
```bash
|
|
844
|
+
# 1) 直接下载 release 压缩包
|
|
845
|
+
# 2) npm install -g @awiki/cli
|
|
846
|
+
# 3) curl 安装脚本(官方自建)
|
|
847
|
+
# 4) go install(仅开发者/高级用户)
|
|
848
|
+
go install github.com/AgentConnect/awiki-cli/cmd/awiki-cli@latest
|
|
849
|
+
```
|
|
850
|
+
|
|
851
|
+
首发阶段直接支持 **npm wrapper**。
|
|
852
|
+
推荐同时提供 GitHub Releases、npm wrapper 和 `go install`:人类用户可以走 npm / release,开发者和 CI 可以直接走原生二进制或 `go install`。
|
|
853
|
+
|
|
854
|
+
## 13.3 发布文件
|
|
855
|
+
|
|
856
|
+
建议发布这些:
|
|
857
|
+
|
|
858
|
+
```text
|
|
859
|
+
awiki-cli_Darwin_x86_64.tar.gz
|
|
860
|
+
awiki-cli_Darwin_arm64.tar.gz
|
|
861
|
+
awiki-cli_Linux_x86_64.tar.gz
|
|
862
|
+
awiki-cli_Linux_arm64.tar.gz
|
|
863
|
+
awiki-cli_Windows_x86_64.zip
|
|
864
|
+
awiki-cli_Windows_arm64.zip
|
|
865
|
+
checksums.txt
|
|
866
|
+
npm/
|
|
867
|
+
awiki-cli.bash
|
|
868
|
+
awiki-cli.zsh
|
|
869
|
+
awiki-cli.fish
|
|
870
|
+
awiki-cli.ps1
|
|
871
|
+
manpages/
|
|
872
|
+
docs/cli/
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
---
|
|
876
|
+
|
|
877
|
+
## 14. 开发与测试计划
|
|
878
|
+
|
|
879
|
+
为了让这个方案真的能落地,我建议按 4 个阶段做。
|
|
880
|
+
|
|
881
|
+
## Phase 1:冻结契约
|
|
882
|
+
|
|
883
|
+
先只做:
|
|
884
|
+
|
|
885
|
+
* root command tree
|
|
886
|
+
* `status / docs / schema / doctor / id / msg / runtime`
|
|
887
|
+
* 全局 flags
|
|
888
|
+
* JSON envelope
|
|
889
|
+
* `--format`
|
|
890
|
+
* `--dry-run`
|
|
891
|
+
* `--jq`
|
|
892
|
+
* `schema`
|
|
893
|
+
* `completion`
|
|
894
|
+
|
|
895
|
+
这个阶段重点是**命令契约稳定**,不是功能全做完。
|
|
896
|
+
|
|
897
|
+
## Phase 2:把 core 跑通
|
|
898
|
+
|
|
899
|
+
实现:
|
|
900
|
+
|
|
901
|
+
* identity create/register/bind/resolve/recover/profile
|
|
902
|
+
* direct/group send/inbox/history
|
|
903
|
+
* secure send/init/repair/retry/drop
|
|
904
|
+
* runtime mode/listener/heartbeat
|
|
905
|
+
* SQLite store
|
|
906
|
+
* legacy import
|
|
907
|
+
|
|
908
|
+
## Phase 3:扩展命令
|
|
909
|
+
|
|
910
|
+
实现:
|
|
911
|
+
|
|
912
|
+
* people
|
|
913
|
+
* page
|
|
914
|
+
* discovery
|
|
915
|
+
* debug
|
|
916
|
+
|
|
917
|
+
## Phase 4:自动化与文档闭环
|
|
918
|
+
|
|
919
|
+
补齐:
|
|
920
|
+
|
|
921
|
+
* docs/cli 自动生成
|
|
922
|
+
* skill 引用校验
|
|
923
|
+
* shell completion
|
|
924
|
+
* man page
|
|
925
|
+
* release pipeline
|
|
926
|
+
* golden tests / integration tests / migration tests
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
## 15. 最终定版结论
|
|
931
|
+
|
|
932
|
+
我建议你直接按下面 10 条拍板:
|
|
933
|
+
|
|
934
|
+
1. **命令名与主二进制名统一定为 `awiki-cli`。**
|
|
935
|
+
2. **canonical CLI 定为:**
|
|
936
|
+
`status / docs / schema / doctor / version / completion / id / msg / runtime`
|
|
937
|
+
3. **消息发送统一入口:**
|
|
938
|
+
`awiki-cli msg send`
|
|
939
|
+
4. **transport 只属于 runtime,msg 层不感知 HTTP/WSS。**
|
|
940
|
+
5. **shortcut 要加,但只做 alias,不做 `+` 第二语法。**
|
|
941
|
+
6. **标准返回是 JSON;pretty/table/ndjson 都是视图。**
|
|
942
|
+
7. **全局格式参数统一为 `--format`;`--output` 仅做兼容别名。**
|
|
943
|
+
8. **`schema`、`--dry-run`、`--jq` 必须是第一天就有的一等能力。**
|
|
944
|
+
9. **Go 技术栈固定为:Cobra + gojq + GoReleaser + kardianos/service + modernc.org/sqlite。**
|
|
945
|
+
10. **skill 和文档按 `shared + domain` 拆分,同时分发支持 GitHub Releases + npm wrapper。** ([GitHub][1])
|
|
946
|
+
|
|
947
|
+
如果你要,我下一步可以直接继续给你两份可落地内容:
|
|
948
|
+
**1)`cmd/awiki-cli` 的 Go 项目目录初始化方案**,以及 **2)`CLI_REFERENCE.md` 的最终文档定稿**。
|
|
949
|
+
|
|
950
|
+
[1]: https://github.com/spf13/cobra "GitHub - spf13/cobra: A Commander for modern Go CLI interactions · GitHub"
|
|
951
|
+
[2]: https://github.com/itchyny/gojq "GitHub - itchyny/gojq: Pure Go implementation of jq · GitHub"
|
|
952
|
+
[3]: https://cobra.dev/docs/how-to-guides/clis-for-llms/?utm_source=chatgpt.com "Generate LLM‑Ready CLI Docs with Cobra"
|
|
953
|
+
[4]: https://github.com/goreleaser/goreleaser "GitHub - goreleaser/goreleaser: Release engineering, simplified · GitHub"
|
|
954
|
+
[5]: https://github.com/kardianos/service?utm_source=chatgpt.com "kardianos/service: Run go programs as ..."
|
|
955
|
+
[6]: https://pkg.go.dev/modernc.org/sqlite "sqlite package - modernc.org/sqlite - Go Packages"
|