@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,407 @@
1
+ 我建议你把这个问题分成两层看:
2
+
3
+ **CLI 的“协议层返回”用 JSON。**
4
+ **给人看的“展示层返回”用 pretty / table / ndjson 等渲染。**
5
+
6
+ 也就是说,**不要把自然语言当命令返回的主契约**。
7
+ 自然语言适合 assistant 在拿到结构化结果之后再转述;CLI 本身最好返回稳定、可解析、可组合的结构化对象。
8
+
9
+ 飞书现在基本就是这个方向。官方 `lark-cli` README 把 `--format json` 写成默认输出,同时支持 `pretty`、`table`、`ndjson`、`csv`;shortcut 被描述为带 smart defaults、table output、dry-run previews;还提供 `schema` 来查看参数、请求体、响应结构以及身份与 scope 信息。最新的 v1.0.3 changelog 还新增了 `--jq` 用来过滤 JSON 输出,并补充说明 JSON 输出可以直接使用,不需要额外再做编码包装。([GitHub][1])
10
+
11
+ 从错误和通知设计看,飞书也明显是“结构化优先”。`lark-shared` 里明确提到:JSON 输出可能带 `_notice.update`,其中包含更新消息和升级命令;权限相关错误会带 `permission_violations`、`console_url` 和 `hint`;删除或危险写操作建议先 `--dry-run`。这说明它们不是靠一段自然语言来表达状态,而是在 JSON 里放稳定字段,再按场景渲染。([GitHub][2])
12
+
13
+ 从官方 issue 里还能看到它的实际返回风格:成功通常是顶层 `ok` 加结构化负载,比如 `{"ok": true, "data": {...}}`;异步任务返回 `status`、`task_id`、`tool`;`auth check` 还结合退出码使用,README 写的是 exit code 0 表示通过、1 表示缺权限。严格说 issue 里的例子不一定是最终稳定规范,但足够说明它们现在的产品方向就是“**结构化结果对象 + 多种展示格式**”。([GitHub][3])
14
+
15
+ 所以落到 awiki,我的建议很明确:
16
+
17
+ ## 结论
18
+
19
+ **awiki v2 的 canonical return 应该是 JSON。**
20
+ 自然语言不要作为 CLI 的默认返回。
21
+ human-friendly 输出应该是 JSON 的视图,而不是另一套语义。
22
+
23
+ ---
24
+
25
+ ## 我建议的返回策略
26
+
27
+ ### 1)默认返回:JSON
28
+
29
+ 对 awiki 这种“agent-native、协议本身又是 JSON-RPC 风格”的工具,最合适的是:
30
+
31
+ ```bash
32
+ awiki ... # 默认 json
33
+ awiki ... --format json # 显式 json
34
+ awiki ... --json # alias
35
+ ```
36
+
37
+ 原因很简单:
38
+
39
+ * AI/agent 最好消费 JSON
40
+ * shell pipeline 最好消费 JSON
41
+ * 日志、自动化、状态判断都依赖 JSON
42
+ * 你们后面做 `schema`、`--jq`、`--dry-run` 时,JSON 是最稳定的底座
43
+
44
+ ### 2)展示输出:pretty / table / ndjson
45
+
46
+ 在 JSON 之上再提供:
47
+
48
+ ```bash
49
+ --format pretty
50
+ --format table
51
+ --format ndjson
52
+ ```
53
+
54
+ 我建议:
55
+
56
+ * `pretty`:单对象、详情页、带缩进和少量颜色
57
+ * `table`:列表型结果,比如 inbox、search、groups、followers
58
+ * `ndjson`:流式或 watch 场景,比如 listener、heartbeat stream、group event stream
59
+
60
+ ### 3)自然语言只作为字段,不作为整体格式
61
+
62
+ 也就是说可以有:
63
+
64
+ ```json
65
+ {
66
+ "ok": true,
67
+ "data": {
68
+ "message_id": "msg_xxx",
69
+ "thread_id": "dm:...",
70
+ "secure": true
71
+ },
72
+ "summary": "消息已发送,已使用端到端加密。"
73
+ }
74
+ ```
75
+
76
+ 但不应该让命令只返回一句:
77
+
78
+ > 已经帮你发好了消息
79
+
80
+ 因为这句话对机器几乎没法可靠消费。
81
+
82
+ ---
83
+
84
+ ## 我建议你直接定的输出规范
85
+
86
+ ### 成功统一信封
87
+
88
+ ```json
89
+ {
90
+ "ok": true,
91
+ "command": "awiki msg send",
92
+ "data": {},
93
+ "warnings": [],
94
+ "summary": "",
95
+ "_notice": {},
96
+ "meta": {
97
+ "version": "2.0.0",
98
+ "identity": {
99
+ "name": "alice",
100
+ "did": "did:wba:awiki.ai:user:abc...xyz"
101
+ },
102
+ "dry_run": false,
103
+ "format": "json"
104
+ }
105
+ }
106
+ ```
107
+
108
+ ### 失败统一信封
109
+
110
+ ```json
111
+ {
112
+ "ok": false,
113
+ "error": {
114
+ "code": "permission_denied",
115
+ "message": "Missing required permission",
116
+ "hint": "Run awiki id use alice or refresh identity",
117
+ "retryable": false,
118
+ "details": {}
119
+ },
120
+ "_notice": {},
121
+ "meta": {
122
+ "version": "2.0.0",
123
+ "dry_run": false,
124
+ "format": "json"
125
+ }
126
+ }
127
+ ```
128
+
129
+ 这个结构和飞书现在的方向很接近,但更适合 awiki。
130
+
131
+ ---
132
+
133
+ ## 不同类型命令应该返回什么
134
+
135
+ ### 1. 查询类命令
136
+
137
+ 比如:
138
+
139
+ * `awiki status`
140
+ * `awiki id status`
141
+ * `awiki msg inbox`
142
+ * `awiki msg history`
143
+ * `awiki people search`
144
+
145
+ 返回重点是 **事实状态**,不要混业务文案。
146
+
147
+ 示例:
148
+
149
+ ```json
150
+ {
151
+ "ok": true,
152
+ "data": {
153
+ "identity": { "status": "ok", "name": "alice", "did": "did:wba:..." },
154
+ "runtime": { "mode": "websocket", "listener_running": true },
155
+ "inbox": { "unread": 3, "messages": [...] }
156
+ },
157
+ "summary": "alice 当前在线,有 3 条未读消息。"
158
+ }
159
+ ```
160
+
161
+ ### 2. 写操作命令
162
+
163
+ 比如:
164
+
165
+ * `awiki id register`
166
+ * `awiki msg send`
167
+ * `awiki msg group join`
168
+ * `awiki people follow`
169
+ * `awiki page create`
170
+
171
+ 返回重点是 **发生了什么变更**。
172
+
173
+ 示例:
174
+
175
+ ```json
176
+ {
177
+ "ok": true,
178
+ "data": {
179
+ "action": "send_message",
180
+ "target": {
181
+ "kind": "direct",
182
+ "handle": "alice.awiki.ai",
183
+ "did": "did:wba:..."
184
+ },
185
+ "message": {
186
+ "id": "msg_123",
187
+ "type": "text",
188
+ "secure": true
189
+ }
190
+ },
191
+ "summary": "已向 alice.awiki.ai 发送加密消息。"
192
+ }
193
+ ```
194
+
195
+ ### 3. 异步命令
196
+
197
+ 如果后面有些操作会异步执行,比如:
198
+
199
+ * 大批量同步
200
+ * discovery 扫描
201
+ * listener install / runtime setup 的复杂流程
202
+ * 页面发布队列
203
+
204
+ 就不要假装同步完成,而要像飞书那样返回任务状态:
205
+
206
+ ```json
207
+ {
208
+ "ok": true,
209
+ "data": {
210
+ "status": "running",
211
+ "task_id": "task_abc123",
212
+ "operation": "runtime_setup"
213
+ },
214
+ "summary": "运行时初始化已开始。"
215
+ }
216
+ ```
217
+
218
+ ### 4. 流式命令
219
+
220
+ 比如:
221
+
222
+ * `awiki msg watch`
223
+ * `awiki runtime listener logs --follow`
224
+ * `awiki heartbeat run --stream`
225
+
226
+ 就只允许:
227
+
228
+ ```bash
229
+ --format ndjson
230
+ ```
231
+
232
+ 每行一个对象:
233
+
234
+ ```json
235
+ {"type":"message","ts":"...","data":{...}}
236
+ {"type":"warning","ts":"...","data":{...}}
237
+ {"type":"status","ts":"...","data":{...}}
238
+ ```
239
+
240
+ ---
241
+
242
+ ## `--dry-run` 应该怎么返回
243
+
244
+ 这个点飞书很值得参考:**有副作用的命令先给 plan / preview**。([GitHub][1])
245
+
246
+ awiki 我建议 dry-run 一律返回 `plan`,而不是返回“不会真的执行”这种描述。
247
+
248
+ 示例:
249
+
250
+ ```json
251
+ {
252
+ "ok": true,
253
+ "data": {
254
+ "plan": {
255
+ "action": "send_message",
256
+ "target": {
257
+ "kind": "direct",
258
+ "input": "alice",
259
+ "resolved_handle": "alice.awiki.ai",
260
+ "resolved_did": "did:wba:..."
261
+ },
262
+ "security": {
263
+ "requested": "on",
264
+ "mode": "e2ee",
265
+ "session": "missing",
266
+ "will_init": true
267
+ },
268
+ "mutations": [
269
+ "remote:e2ee_init",
270
+ "remote:e2ee_msg"
271
+ ]
272
+ }
273
+ },
274
+ "summary": "预演完成:将先建立 E2EE 会话,再发送消息。",
275
+ "meta": {
276
+ "dry_run": true
277
+ }
278
+ }
279
+ ```
280
+
281
+ 这对 AI 特别重要,因为它可以先预览,再决定是否真的执行。
282
+
283
+ ---
284
+
285
+ ## `schema` 应该怎么配合返回
286
+
287
+ 如果你做 `awiki schema`,那命令返回就应该是**命令元数据本身**,而不是说明文字。
288
+
289
+ 示例:
290
+
291
+ ```json
292
+ {
293
+ "ok": true,
294
+ "data": {
295
+ "name": "awiki msg send",
296
+ "summary": "Send a direct or group message",
297
+ "side_effect": true,
298
+ "dry_run_supported": true,
299
+ "output_formats": ["json", "pretty", "table", "ndjson"],
300
+ "args": [...],
301
+ "returns": {
302
+ "success": {...},
303
+ "error": {...}
304
+ }
305
+ }
306
+ }
307
+ ```
308
+
309
+ 这样 assistant、MCP bridge、自动文档生成器都可以直接用。
310
+
311
+ ---
312
+
313
+ ## 要不要支持 `--jq`
314
+
315
+ 我建议**要**。
316
+ 飞书最新版本已经加了 `--jq`,这个非常值得直接抄思路。([GitHub][4])
317
+
318
+ 比如:
319
+
320
+ ```bash
321
+ awiki status --jq '.data.inbox.unread'
322
+ awiki msg inbox --jq '.data.messages[] | {from, text}'
323
+ awiki people search "agent" --jq '.data.items[0]'
324
+ ```
325
+
326
+ 这会极大提升:
327
+
328
+ * AI 调试效率
329
+ * shell 自动化能力
330
+ * 人类用户的 grep/jq 工作流体验
331
+
332
+ ---
333
+
334
+ ## exit code 也要一起设计
335
+
336
+ 不要只设计 stdout,不设计退出码。
337
+
338
+ 我建议:
339
+
340
+ * `0`:成功
341
+ * `1`:一般错误
342
+ * `2`:参数错误
343
+ * `3`:身份/认证缺失
344
+ * `4`:权限不足
345
+ * `5`:资源不存在
346
+ * `6`:部分成功
347
+ * `7`:需要确认但未提供 `--yes` / 非交互上下文不允许执行
348
+
349
+ 飞书现在也明显不是只靠文本判断,而是把 exit code 和结构化输出一起用。([GitHub][1])
350
+
351
+ ---
352
+
353
+ ## shortcut 要不要影响返回格式
354
+
355
+ 我建议可以,但要谨慎:
356
+
357
+ ### canonical command
358
+
359
+ 默认始终 JSON:
360
+
361
+ ```bash
362
+ awiki msg send ...
363
+ awiki status
364
+ awiki msg inbox
365
+ ```
366
+
367
+ ### shortcut
368
+
369
+ 可以偏人类友好,但最好仍支持显式切回 JSON:
370
+
371
+ ```bash
372
+ awiki inbox # 默认 pretty/table
373
+ awiki dm alice "hello" # 默认 pretty
374
+ awiki inbox --format json
375
+ awiki dm alice "hello" --json
376
+ ```
377
+
378
+ 也就是说:
379
+
380
+ * **canonical 命令**:面向机器和 AI,默认 JSON
381
+ * **shortcut**:面向人,默认 pretty/table
382
+
383
+ 这样既能借飞书 shortcut 的体验,又不会让协议层混乱。
384
+
385
+ ---
386
+
387
+ ## 最终建议
388
+
389
+ 如果你要一个最明确的结论,我建议你这样定:
390
+
391
+ **1. awiki CLI 的标准返回是 JSON。**
392
+ **2. 自然语言不是返回协议,只是 `summary/message` 字段。**
393
+ **3. `pretty/table/ndjson` 都是 JSON 的视图。**
394
+ **4. 所有有副作用命令必须支持 `--dry-run`,并返回 `plan`。**
395
+ **5. 所有命令都支持 `--jq`。**
396
+ **6. shortcut 可以默认 pretty,但 canonical command 必须默认 JSON。**
397
+
398
+ 一句话概括:
399
+
400
+ **飞书给你的最佳参考不是“返回自然语言”,而是“结构化结果对象 + 多种格式渲染 + dry-run + schema + jq”。awiki 最适合沿着这条路走。**
401
+
402
+ 你要的话,我下一条可以直接把 **awiki v2 输出协议规范** 单独起草出来,包括字段定义、错误码、不同命令的 `data` 结构,以及 human / pretty / table / ndjson 的渲染规则。
403
+
404
+ [1]: https://github.com/larksuite/cli/blob/main/README.md?utm_source=chatgpt.com "cli/README.md at main · larksuite/cli"
405
+ [2]: https://github.com/larksuite/cli/blob/main/skills/lark-shared/SKILL.md "cli/skills/lark-shared/SKILL.md at main · larksuite/cli · GitHub"
406
+ [3]: https://github.com/larksuite/cli/issues/127?utm_source=chatgpt.com "Bug: 飞书文档写入存在问题 docs +update/+create loses ..."
407
+ [4]: https://github.com/larksuite/cli/blob/main/CHANGELOG.md "cli/CHANGELOG.md at main · larksuite/cli · GitHub"