@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,903 @@
|
|
|
1
|
+
# awiki-cli v2 落地实施规划
|
|
2
|
+
|
|
3
|
+
**文档状态**:Draft v1.0
|
|
4
|
+
**文档用途**:把架构设计转成可执行的工程实施计划,作为后续拆解里程碑、Issue、子任务和验收的基线。
|
|
5
|
+
**适用范围**:`awiki-cli` Go 重写、命令面收敛、SQLite/凭证迁移、runtime/listener、skills/docs/schema、发布切换。
|
|
6
|
+
**最后更新**:2026-04-07
|
|
7
|
+
|
|
8
|
+
> **Phase 0 冻结结果说明**:`docs/plan/phase-0/` 下的冻结文档是后续实现的直接约束。当本文与 Phase 0 冻结文档冲突时,以 Phase 0 冻结文档为准。
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## 1. 目标与输入基线
|
|
13
|
+
|
|
14
|
+
本文档不再讨论“是否要重写”或“是否继续 Python”。这些决策已经在架构文档中冻结。本文档只回答一个问题:
|
|
15
|
+
|
|
16
|
+
**如何把 awiki v2 的目标架构按可交付、可验收、可迁移的方式实现出来。**
|
|
17
|
+
|
|
18
|
+
### 1.1 实施目标
|
|
19
|
+
|
|
20
|
+
awiki-cli v2 的实施目标是:
|
|
21
|
+
|
|
22
|
+
1. 把当前脚本集合收敛成统一的 `awiki-cli` 产品面。
|
|
23
|
+
2. 把 `id / msg / group / runtime` 做成首批可用的稳定域。
|
|
24
|
+
3. 保留 awiki 的差异化能力:DID、多身份、本地状态、E2EE、显式 runtime mode、group/relationship 沉淀。
|
|
25
|
+
4. 让 CLI、docs、schema、doctor、skills 不再分裂,转成单一元数据驱动的产品体系。
|
|
26
|
+
5. 提供从 `../awiki-agent-id-message/` 到 v2 的凭证、SQLite、本地 runtime 配置迁移路径。
|
|
27
|
+
|
|
28
|
+
### 1.2 本次规划的输入文档与代码基线
|
|
29
|
+
|
|
30
|
+
| 类别 | 路径 | 用途 |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| 总体架构 | `docs/architecture/awiki-v2-architecture.md` | v2 总体分层、域模型、runtime、安全、发布 |
|
|
33
|
+
| 命令与执行方案 | `docs/architecture/awiki-command-v2.md` | 最终命令树、参数、输出、目录、阶段划分 |
|
|
34
|
+
| 输出契约 | `docs/architecture/output-format.md` | JSON envelope、dry-run、schema、exit code |
|
|
35
|
+
| 飞书 CLI 参考 | `../cli/` | Cobra 命令组织、schema/doctor/completion、skills、shortcuts、发布 |
|
|
36
|
+
| awiki v1 Python CLI 参考 | `../awiki-agent-id-message/` | 能力映射、listener/runtime、本地 SQLite、凭证布局、迁移逻辑 |
|
|
37
|
+
| 用户服务 API | `../user-service/docs/api/` | 身份、handle、profile、relationships、group |
|
|
38
|
+
| 消息服务 API | `../message-service/docs/api/` | direct/group/attachment、local view、WS 通知 |
|
|
39
|
+
|
|
40
|
+
### 1.3 发生冲突时的优先级
|
|
41
|
+
|
|
42
|
+
实现时按照下面的优先级裁决:
|
|
43
|
+
|
|
44
|
+
1. `docs/architecture/awiki-command-v2.md`
|
|
45
|
+
2. `docs/architecture/awiki-v2-architecture.md`
|
|
46
|
+
3. `docs/architecture/output-format.md`
|
|
47
|
+
4. `../user-service/docs/api/` 与 `../message-service/docs/api/`
|
|
48
|
+
5. `../awiki-agent-id-message/`
|
|
49
|
+
6. `../cli/`
|
|
50
|
+
|
|
51
|
+
> 说明:`../awiki-agent-id-message/` 是实现参考与迁移基线,不是 v2 命令契约的最终真相。
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 2. 规划前先冻结的决定
|
|
56
|
+
|
|
57
|
+
本节是实施前必须明确、不允许实现阶段再反复摇摆的决定。
|
|
58
|
+
|
|
59
|
+
### 2.1 产品与命令冻结
|
|
60
|
+
|
|
61
|
+
- 主二进制名固定为:`awiki-cli`
|
|
62
|
+
- canonical 顶级命令固定为:
|
|
63
|
+
- `status`
|
|
64
|
+
- `docs`
|
|
65
|
+
- `schema`
|
|
66
|
+
- `doctor`
|
|
67
|
+
- `version`
|
|
68
|
+
- `completion`
|
|
69
|
+
- `config`
|
|
70
|
+
- `id`
|
|
71
|
+
- `msg`
|
|
72
|
+
- `group`
|
|
73
|
+
- `runtime`
|
|
74
|
+
- `people`
|
|
75
|
+
- `page`
|
|
76
|
+
- `debug`
|
|
77
|
+
- 发消息唯一 canonical 入口固定为:`awiki-cli msg send`
|
|
78
|
+
- transport 只允许出现在 `runtime` 域,不允许泄漏到 `msg` / `group` 命令参数面。
|
|
79
|
+
|
|
80
|
+
### 2.2 术语冻结
|
|
81
|
+
|
|
82
|
+
- 用户层主术语使用 **identity**。
|
|
83
|
+
- `credential` 仅作为兼容 v1 的内部实现术语或 alias,不再作为 v2 主文案。
|
|
84
|
+
- 本地数据隔离主键继续使用 `owner_did`。
|
|
85
|
+
|
|
86
|
+
### 2.3 User 生命周期冻结
|
|
87
|
+
|
|
88
|
+
- **handle 是对外用户主流程的必填项。**
|
|
89
|
+
- **v2 首版不支持 pure DID 作为对外用户完成态。**
|
|
90
|
+
- **对外公共身份标识只使用 handle;`did` 仅在协议级定位需要时出现;`user_id` 为内部字段,不对 CLI / docs / schema / 输出透出。**
|
|
91
|
+
- `id create` 只保留为本地 bootstrap / 迁移辅助能力,不作为消息、runtime、群组主链路的前置完成态;默认从公开 help 中隐藏。
|
|
92
|
+
- 用户完成态固定定义为:**本地 DID 材料已生成 + 远端 user 已创建 + handle 已创建或恢复 + 本地凭证已记录**。
|
|
93
|
+
- `id register` / `id recover` 是进入可用用户态的 canonical 入口;`msg` 与 `runtime listener` 默认要求当前 identity 已完成该用户态。
|
|
94
|
+
|
|
95
|
+
### 2.4 输出与全局参数冻结
|
|
96
|
+
|
|
97
|
+
- 全局格式参数统一为:`--format`
|
|
98
|
+
- 结构化输出以 JSON envelope 为准。
|
|
99
|
+
- 更新提示字段统一为:`_notice`
|
|
100
|
+
- 所有有副作用的命令必须支持:`--dry-run`
|
|
101
|
+
- 支持:`--jq`
|
|
102
|
+
- exit code 与错误码统一收敛到 v2 新协议。
|
|
103
|
+
|
|
104
|
+
### 2.5 环境变量冻结
|
|
105
|
+
|
|
106
|
+
存在一个已发现冲突:
|
|
107
|
+
|
|
108
|
+
- v2 命令文档当前使用 `AVIKI_*`
|
|
109
|
+
- v1 Python CLI 当前使用 `AWIKI_*`
|
|
110
|
+
- 旧环境还有 `E2E_*`
|
|
111
|
+
|
|
112
|
+
实现规划采用以下冻结规则:
|
|
113
|
+
|
|
114
|
+
- **v2 新变量 canonical 名称使用 `AVIKI_*`**(遵循当前 v2 命令文档)
|
|
115
|
+
- **兼容读取旧变量**:`AWIKI_*` 与 `E2E_*`
|
|
116
|
+
- doctor 需要显式提示当前命中的来源与优先级,避免隐式混用
|
|
117
|
+
|
|
118
|
+
### 2.6 参考基线冻结
|
|
119
|
+
|
|
120
|
+
- **SQLite 表设计以 `../awiki-agent-id-message/scripts/local_store.py` 与 `../awiki-agent-id-message/references/local-store-schema.md` 为基线参考。**
|
|
121
|
+
- **凭证文件设计以 `../awiki-agent-id-message/scripts/credential_layout.py` 与 `../awiki-agent-id-message/scripts/credential_store.py` 为基线参考。**
|
|
122
|
+
- 首版实现优先保证“稳定迁移”和“兼容导入”,不主动重构这些数据模型。
|
|
123
|
+
|
|
124
|
+
### 2.7 已知审计项
|
|
125
|
+
|
|
126
|
+
这些问题不阻塞规划,但必须在 Phase 0 记录为审计任务:
|
|
127
|
+
|
|
128
|
+
1. `local-store-schema.md` 当前未列出 `e2ee_outbox`,但 `local_store.py` 中该表是权威存在的。
|
|
129
|
+
2. v2 文档使用 `AVIKI_*`,v1 实际环境使用 `AWIKI_*`,需要在实现层做兼容。
|
|
130
|
+
3. E2EE 协议文档存在历史冲突,v2 必须先冻结具体协议再编码实现。
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 3. 目标工程结构
|
|
135
|
+
|
|
136
|
+
建议把本仓库直接落成单仓 Go CLI,目录结构如下:
|
|
137
|
+
|
|
138
|
+
```text
|
|
139
|
+
.
|
|
140
|
+
├── cmd/
|
|
141
|
+
│ └── awiki-cli/
|
|
142
|
+
├── internal/
|
|
143
|
+
│ ├── app/
|
|
144
|
+
│ ├── cli/
|
|
145
|
+
│ ├── cmdmeta/
|
|
146
|
+
│ ├── config/
|
|
147
|
+
│ ├── output/
|
|
148
|
+
│ ├── schema/
|
|
149
|
+
│ ├── doctor/
|
|
150
|
+
│ ├── identity/
|
|
151
|
+
│ ├── messaging/
|
|
152
|
+
│ ├── group/
|
|
153
|
+
│ ├── people/
|
|
154
|
+
│ ├── page/
|
|
155
|
+
│ ├── runtime/
|
|
156
|
+
│ ├── transport/
|
|
157
|
+
│ │ ├── http/
|
|
158
|
+
│ │ ├── websocket/
|
|
159
|
+
│ │ └── ipc/
|
|
160
|
+
│ ├── secure/
|
|
161
|
+
│ ├── store/
|
|
162
|
+
│ ├── serviceapi/
|
|
163
|
+
│ ├── migrate/
|
|
164
|
+
│ └── buildinfo/
|
|
165
|
+
├── schemas/
|
|
166
|
+
├── skills/
|
|
167
|
+
│ ├── awiki-shared/
|
|
168
|
+
│ ├── awiki-id/
|
|
169
|
+
│ ├── awiki-msg/
|
|
170
|
+
│ ├── awiki-runtime/
|
|
171
|
+
│ ├── awiki-people/
|
|
172
|
+
│ ├── awiki-page/
|
|
173
|
+
│ └── awiki-debug/
|
|
174
|
+
├── docs/
|
|
175
|
+
│ ├── architecture/
|
|
176
|
+
│ └── plan/
|
|
177
|
+
├── testdata/
|
|
178
|
+
│ ├── credentials/
|
|
179
|
+
│ ├── sqlite/
|
|
180
|
+
│ ├── rpc/
|
|
181
|
+
│ └── golden/
|
|
182
|
+
└── .goreleaser.yaml
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### 3.1 模块职责
|
|
186
|
+
|
|
187
|
+
| 模块 | 职责 |
|
|
188
|
+
|---|---|
|
|
189
|
+
| `internal/cli` | Cobra 命令树、flag 绑定、命令执行入口 |
|
|
190
|
+
| `internal/cmdmeta` | 命令元数据、schema/help/docs 生成的单一事实来源 |
|
|
191
|
+
| `internal/output` | JSON envelope、pretty/table/ndjson、错误输出、_notice |
|
|
192
|
+
| `internal/config` | XDG 路径、env 兼容、配置加载、默认 identity 选择 |
|
|
193
|
+
| `internal/identity` | DID、注册、绑定、恢复、profile、多 identity 管理 |
|
|
194
|
+
| `internal/messaging` | direct/group 消息收发、history、mark-read |
|
|
195
|
+
| `internal/group` | group 生命周期与本地快照管理 |
|
|
196
|
+
| `internal/secure` | E2EE session、secure send、outbox、repair/retry/drop |
|
|
197
|
+
| `internal/runtime` | mode、listener、heartbeat、service lifecycle |
|
|
198
|
+
| `internal/transport/*` | HTTP、WSS、IPC 抽象与实现 |
|
|
199
|
+
| `internal/store` | SQLite DAO、migrations、identity store、runtime state |
|
|
200
|
+
| `internal/serviceapi` | user-service / message-service 客户端与请求映射 |
|
|
201
|
+
| `internal/migrate` | 从 v1 导入 credentials / SQLite / runtime state |
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 4. 参考基线:SQLite 与凭证文件
|
|
206
|
+
|
|
207
|
+
这是本规划里必须明确记录的项目约束。
|
|
208
|
+
|
|
209
|
+
### 4.1 凭证文件设计基线
|
|
210
|
+
|
|
211
|
+
v2 的 identity 存储设计,参考以下实现:
|
|
212
|
+
|
|
213
|
+
- `../awiki-agent-id-message/scripts/credential_layout.py`
|
|
214
|
+
- `../awiki-agent-id-message/scripts/credential_store.py`
|
|
215
|
+
- `../awiki-agent-id-message/scripts/credential_migration.py`
|
|
216
|
+
|
|
217
|
+
#### 4.1.1 目录布局基线
|
|
218
|
+
|
|
219
|
+
v2 采用 XDG 目录,但 identity 内部文件布局继续参考 v1 的 indexed multi-credential layout:
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
~/.config/awiki-cli/config.yaml
|
|
223
|
+
~/.config/awiki-cli/identities/index.json
|
|
224
|
+
~/.config/awiki-cli/identities/<identity-dir>/identity.json
|
|
225
|
+
~/.config/awiki-cli/identities/<identity-dir>/auth.json
|
|
226
|
+
~/.config/awiki-cli/identities/<identity-dir>/did_document.json
|
|
227
|
+
~/.config/awiki-cli/identities/<identity-dir>/key-1-private.pem
|
|
228
|
+
~/.config/awiki-cli/identities/<identity-dir>/key-1-public.pem
|
|
229
|
+
~/.config/awiki-cli/identities/<identity-dir>/e2ee-signing-private.pem
|
|
230
|
+
~/.config/awiki-cli/identities/<identity-dir>/e2ee-agreement-private.pem
|
|
231
|
+
~/.config/awiki-cli/identities/<identity-dir>/e2ee-state.json
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
#### 4.1.2 index.json 基线
|
|
235
|
+
|
|
236
|
+
首版实现遵循以下约束:
|
|
237
|
+
|
|
238
|
+
- `schema_version` 与 v1 索引版本兼容读取
|
|
239
|
+
- `default_identity_name` 语义等价于 v1 的 `default_credential_name`
|
|
240
|
+
- index 中保存 identity 元信息,不保存私钥原文
|
|
241
|
+
- `default` 作为 alias 时优先解析显式 `default`,再 fallback 到当前默认 identity
|
|
242
|
+
|
|
243
|
+
#### 4.1.3 文件权限基线
|
|
244
|
+
|
|
245
|
+
- identity 目录:`0700`
|
|
246
|
+
- 私钥 / token / json 凭证:`0600`
|
|
247
|
+
- 文档与日志中不得打印私钥、JWT、E2EE 私钥
|
|
248
|
+
|
|
249
|
+
#### 4.1.4 迁移基线
|
|
250
|
+
|
|
251
|
+
需要兼容识别 v1 flat legacy layout:
|
|
252
|
+
|
|
253
|
+
- `<credential>.json`
|
|
254
|
+
- `e2ee_<credential>.json`
|
|
255
|
+
- `<credential>_did_document.json`
|
|
256
|
+
- `<credential>_private_key.pem`
|
|
257
|
+
|
|
258
|
+
并提供统一入口:
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
awiki-cli migrate from-v1
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### 4.2 SQLite 表设计基线
|
|
265
|
+
|
|
266
|
+
v2 本地 SQLite 设计参考以下来源:
|
|
267
|
+
|
|
268
|
+
- `../awiki-agent-id-message/scripts/local_store.py`
|
|
269
|
+
- `../awiki-agent-id-message/references/local-store-schema.md`
|
|
270
|
+
- `../awiki-agent-id-message/scripts/database_migration.py`
|
|
271
|
+
- `../awiki-agent-id-message/scripts/e2ee_session_store.py`
|
|
272
|
+
- `../awiki-agent-id-message/scripts/e2ee_outbox.py`
|
|
273
|
+
|
|
274
|
+
#### 4.2.1 首版必须保留的表
|
|
275
|
+
|
|
276
|
+
| 表名 | 用途 | 基线来源 |
|
|
277
|
+
|---|---|---|
|
|
278
|
+
| `contacts` | 联系人、沉淀关系、follow-up 信息 | `local_store.py` / `local-store-schema.md` |
|
|
279
|
+
| `messages` | direct/group 收发消息本地缓存 | `local_store.py` / `local-store-schema.md` |
|
|
280
|
+
| `e2ee_outbox` | secure 失败重试 / drop / resend | `local_store.py` / `e2ee_outbox.py` |
|
|
281
|
+
| `groups` | group 快照、本地 membership 状态 | `local_store.py` / `local-store-schema.md` |
|
|
282
|
+
| `group_members` | group 成员快照 | `local_store.py` / `local-store-schema.md` |
|
|
283
|
+
| `relationship_events` | 关系沉淀事件流 | `local_store.py` / `local-store-schema.md` |
|
|
284
|
+
| `e2ee_sessions` | 私聊 E2EE session 持久化 | `local_store.py` / `e2ee_session_store.py` |
|
|
285
|
+
|
|
286
|
+
#### 4.2.2 首版必须保留的视图
|
|
287
|
+
|
|
288
|
+
| 视图 | 用途 |
|
|
289
|
+
|---|---|
|
|
290
|
+
| `threads` | 聚合线程摘要 |
|
|
291
|
+
| `inbox` | 所有 incoming message 视图 |
|
|
292
|
+
| `outbox` | 所有 outgoing message 视图 |
|
|
293
|
+
|
|
294
|
+
#### 4.2.3 首版必须保留的关键设计原则
|
|
295
|
+
|
|
296
|
+
- 本地快照隔离维度必须继续使用 `owner_did`
|
|
297
|
+
- `credential_name` / `identity_name` 字段继续保留,用于诊断、迁移与兼容
|
|
298
|
+
- thread id 规则保持对称:
|
|
299
|
+
- 私聊:`dm:{min_did}:{max_did}`
|
|
300
|
+
- 群聊:`group:{group_id}`
|
|
301
|
+
- schema version 继续使用 `PRAGMA user_version`
|
|
302
|
+
- 首版 migration 优先保证与 v1 数据可导入,不主动做大规模重构
|
|
303
|
+
|
|
304
|
+
#### 4.2.4 规划中的文档补齐任务
|
|
305
|
+
|
|
306
|
+
需要在后续实现中补齐以下差异:
|
|
307
|
+
|
|
308
|
+
- `local-store-schema.md` 需补充 `e2ee_outbox` 的正式表说明,避免文档与实现脱节
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
## 5. 外部接口与命令映射基线
|
|
313
|
+
|
|
314
|
+
### 5.1 user-service 相关命令映射
|
|
315
|
+
|
|
316
|
+
| CLI 命令 | 服务/API 文档 | 说明 |
|
|
317
|
+
|---|---|---|
|
|
318
|
+
| `id create` | `../user-service/docs/api/did-auth.md`(仅 bootstrap 背景) | 本地 DID 材料生成;不是对外用户完成态 |
|
|
319
|
+
| `id register` | `../user-service/docs/api/did-auth.md` + `authentication.md` + `handle.md` | 创建远端 user、注册 handle、写回凭证 |
|
|
320
|
+
| `id bind` | `../user-service/docs/api/authentication.md` | 手机/邮箱绑定 |
|
|
321
|
+
| `id resolve` | `../user-service/docs/api/did-profile.md` + `handle.md` + `users.md` | DID/Handle 解析与用户摘要查询 |
|
|
322
|
+
| `id recover` | `../user-service/docs/api/did-auth.md` + `handle.md` | 通过手机验证码恢复 handle DID 绑定 |
|
|
323
|
+
| `id profile get/set` | `../user-service/docs/api/profile.md` + `did-profile.md` + `users.md` | 自己/公开 profile 与当前用户查询 |
|
|
324
|
+
| `people follow/unfollow/status` | `../user-service/docs/api/relationships.md` | follow/unfollow/status |
|
|
325
|
+
| `group *` 生命周期 | `../user-service/docs/api/group.md` | create/get/update/join/leave/kick/list members 等 |
|
|
326
|
+
|
|
327
|
+
### 5.2 message-service 相关命令映射
|
|
328
|
+
|
|
329
|
+
| CLI 命令 | 服务/API 文档 | 说明 |
|
|
330
|
+
|---|---|---|
|
|
331
|
+
| `msg send --to` | `../message-service/docs/api/ANP-client-server-api-direct.md` | `direct.send` |
|
|
332
|
+
| `msg send --group` | `../message-service/docs/api/ANP-client-server-api-group.md` | `group.send` |
|
|
333
|
+
| `msg inbox` | `ANP-client-server-api-direct.md` | `inbox.get` local-view 方法 |
|
|
334
|
+
| `msg mark-read` | `ANP-client-server-api-direct.md` | `inbox.mark_read` |
|
|
335
|
+
| `msg history --with` | `ANP-client-server-api-direct.md` | `direct.get_history` |
|
|
336
|
+
| `group messages` | `ANP-client-server-api-group.md` | `group.list_messages` |
|
|
337
|
+
| `msg secure *` | `ANP-client-server-api-direct.md` | prekey/session/init/ack/e2ee_msg |
|
|
338
|
+
| 附件增强 | `ANP-client-server-api-attachment.md` | `attachment.create_slot` / `commit_object` / download ticket |
|
|
339
|
+
|
|
340
|
+
### 5.3 飞书 CLI 中需要借鉴的部分
|
|
341
|
+
|
|
342
|
+
`../cli/` 只作为产品结构和工程组织参考,不直接复制业务体量。需要借鉴的点包括:
|
|
343
|
+
|
|
344
|
+
1. `cmd/root.go` 的 Cobra 根命令组织方式
|
|
345
|
+
2. `schema` / `doctor` / `completion` 作为一级产品命令
|
|
346
|
+
3. `internal/output` 式的统一输出与错误 envelope
|
|
347
|
+
4. `shortcuts` 与 domain service commands 分离
|
|
348
|
+
5. `skills/lark-shared` + domain skill 的分层方式
|
|
349
|
+
6. update notice 的 `_notice` 注入策略
|
|
350
|
+
7. GoReleaser + GitHub Releases + npm wrapper 的发布链路
|
|
351
|
+
|
|
352
|
+
---
|
|
353
|
+
|
|
354
|
+
## 6. 分阶段实施计划
|
|
355
|
+
|
|
356
|
+
本节是本规划的核心。每个阶段都以“可交付物”和“验收标准”为中心,而不是只写方向。
|
|
357
|
+
|
|
358
|
+
### Phase 0:冻结与审计
|
|
359
|
+
|
|
360
|
+
**目标**:把会影响后续所有实现的契约问题全部冻结。
|
|
361
|
+
|
|
362
|
+
**主要任务**:
|
|
363
|
+
|
|
364
|
+
1. 把最终命令树、全局 flags、输出 envelope、错误码写成一份实现约束表。
|
|
365
|
+
2. 对照 `awiki-command-v2.md` 与 `awiki-v2-architecture.md`,标出所有实现需要遵守的冻结项。
|
|
366
|
+
3. 完成三类差异审计:
|
|
367
|
+
- v2 文档内部冲突
|
|
368
|
+
- v2 文档与 v1 Python 行为差异
|
|
369
|
+
- v2 文档与 API 文档差异
|
|
370
|
+
4. 明确 E2EE 协议冻结结果。
|
|
371
|
+
5. 明确环境变量兼容顺序与 XDG 目录规则。
|
|
372
|
+
|
|
373
|
+
**交付物**:
|
|
374
|
+
|
|
375
|
+
- 一份实现约束表(可并入本规划附录)
|
|
376
|
+
- 一份 API/命令/脚本能力对照表
|
|
377
|
+
- 一份风险清单与 ADR 列表
|
|
378
|
+
|
|
379
|
+
**验收标准**:
|
|
380
|
+
|
|
381
|
+
- 后续阶段不再允许更改主命令树与主输出协议
|
|
382
|
+
- 后续阶段不再允许更改 identity/credential 命名策略
|
|
383
|
+
- 已列出所有阻塞实现的协议冲突项并给出裁决
|
|
384
|
+
|
|
385
|
+
### Phase 1:CLI 产品壳
|
|
386
|
+
|
|
387
|
+
**目标**:搭起可运行的 v2 CLI 外壳,先稳定产品面,再做业务实现。
|
|
388
|
+
|
|
389
|
+
**主要任务**:
|
|
390
|
+
|
|
391
|
+
1. 初始化 Go 模块与 `cobra` 根命令。
|
|
392
|
+
2. 建立顶级命令骨架:
|
|
393
|
+
- `status`
|
|
394
|
+
- `docs`
|
|
395
|
+
- `schema`
|
|
396
|
+
- `doctor`
|
|
397
|
+
- `version`
|
|
398
|
+
- `completion`
|
|
399
|
+
- `config`
|
|
400
|
+
- `id`
|
|
401
|
+
- `msg`
|
|
402
|
+
- `group`
|
|
403
|
+
- `runtime`
|
|
404
|
+
- `people`
|
|
405
|
+
- `page`
|
|
406
|
+
- `debug`
|
|
407
|
+
3. 建立全局 flags:
|
|
408
|
+
- `--format`
|
|
409
|
+
- `--jq`
|
|
410
|
+
- `--dry-run`
|
|
411
|
+
- `--identity`
|
|
412
|
+
- `--verbose`
|
|
413
|
+
4. 实现统一 JSON success/error envelope。
|
|
414
|
+
5. 实现 update notice 注入 `_notice`。
|
|
415
|
+
6. 实现 `schema` 基础框架,哪怕最开始只输出静态元数据。
|
|
416
|
+
7. 实现 `doctor` 基础检查框架,先检查路径、配置、identity store、SQLite 可达性。
|
|
417
|
+
|
|
418
|
+
**交付物**:
|
|
419
|
+
|
|
420
|
+
- 可编译的 `awiki-cli`
|
|
421
|
+
- 完整 help 树
|
|
422
|
+
- 统一输出层
|
|
423
|
+
- schema/doctor 基础命令
|
|
424
|
+
|
|
425
|
+
**验收标准**:
|
|
426
|
+
|
|
427
|
+
- `awiki-cli --help` 展示最终顶级命令树
|
|
428
|
+
- `awiki-cli schema` 能输出结构化命令元数据
|
|
429
|
+
- `awiki-cli doctor` 能输出基础诊断结果
|
|
430
|
+
- 所有命令在失败时都遵循统一错误 envelope
|
|
431
|
+
|
|
432
|
+
### Phase 2:配置、Identity 与凭证存储
|
|
433
|
+
|
|
434
|
+
**目标**:先落地本地 identity 基础设施,为后续 User 完成态做准备。
|
|
435
|
+
|
|
436
|
+
**主要任务**:
|
|
437
|
+
|
|
438
|
+
1. 落地 XDG 目录解析:
|
|
439
|
+
- config
|
|
440
|
+
- data
|
|
441
|
+
- state
|
|
442
|
+
- cache
|
|
443
|
+
2. 落地 env 兼容读取:
|
|
444
|
+
- `AVIKI_*`
|
|
445
|
+
- fallback `AWIKI_*`
|
|
446
|
+
- fallback `E2E_*`
|
|
447
|
+
3. 实现 identity index store。
|
|
448
|
+
4. 实现 identity create/list/use/current。
|
|
449
|
+
5. 明确 `id create` 只负责本地 DID / 密钥 / did_document 生成,不作为对外用户完成态。
|
|
450
|
+
6. 完成 v1 credential import。
|
|
451
|
+
7. 完成旧 flat legacy credential 扫描与导入提示。
|
|
452
|
+
8. 设计 token / daemon token 与 keychain 的接口层,但首版可先用受权限保护的文件存储。
|
|
453
|
+
|
|
454
|
+
**交付物**:
|
|
455
|
+
|
|
456
|
+
- identity store
|
|
457
|
+
- v2 index.json + per-identity dir
|
|
458
|
+
- 本地 bootstrap 命令
|
|
459
|
+
- migrate from-v1(credential 部分)
|
|
460
|
+
|
|
461
|
+
**验收标准**:
|
|
462
|
+
|
|
463
|
+
- `id create/list/use/current` 可用
|
|
464
|
+
- 旧 `.credentials` 能被识别、提示、导入
|
|
465
|
+
- 文件权限符合最小权限要求
|
|
466
|
+
|
|
467
|
+
### Phase 3:User、Handle 与 Credential 完整化
|
|
468
|
+
|
|
469
|
+
**目标**:跑通“可用用户态”主链路:创建远端 user、注册 handle、绑定联系方式、记录本地凭证。
|
|
470
|
+
|
|
471
|
+
> 说明:旧版本规划把这部分隐含在 identity 阶段里,导致“本地 DID bootstrap”和“远端 user 完成态”混在一起。本阶段将两者显式拆开,并冻结 handle-first 约束。
|
|
472
|
+
|
|
473
|
+
**主要任务**:
|
|
474
|
+
|
|
475
|
+
1. 明确主流程为 handle-first:
|
|
476
|
+
- `id register` 是 canonical 用户创建入口
|
|
477
|
+
- `handle` 为必填
|
|
478
|
+
- 不支持 pure DID 作为对外用户完成态
|
|
479
|
+
2. 对接 user-service API:
|
|
480
|
+
- `POST /did-auth/rpc` `register`
|
|
481
|
+
- `POST /handle/rpc` `send_otp`
|
|
482
|
+
- `POST /did-auth/rpc` `recover_handle`
|
|
483
|
+
- `POST /auth/phone-bind-send`
|
|
484
|
+
- `POST /auth/phone-bind-verify`
|
|
485
|
+
- `POST /auth/email-send`
|
|
486
|
+
- `GET /auth/email-status`
|
|
487
|
+
- `POST /did/profile/rpc` `get_me` / `update_me` / `get_public_profile`
|
|
488
|
+
- `POST /users/rpc` `get_me` / `get_by_did` / `get_by_handle`
|
|
489
|
+
3. 参考 Python 版本补齐非交互 CLI 流程:
|
|
490
|
+
- `register_handle.py`
|
|
491
|
+
- `bind_contact.py`
|
|
492
|
+
- `recover_handle.py`
|
|
493
|
+
- `get_profile.py`
|
|
494
|
+
- `update_profile.py`
|
|
495
|
+
- `credential_store.py`
|
|
496
|
+
4. 本地凭证落盘与索引补齐:
|
|
497
|
+
- `identity.json` 内部记录 `did / user_id / handle / created_at`
|
|
498
|
+
- `auth.json` 记录 token
|
|
499
|
+
- `did_document.json` 记录当前 DID 文档
|
|
500
|
+
- index 中内部同步 `user_id`、`handle` 与默认 identity 解析
|
|
501
|
+
- `user_id` 只作为内部映射字段保存,不进入公共 CLI 输出
|
|
502
|
+
5. 建立当前 identity 的“用户完成态”判断:
|
|
503
|
+
- local-only identity
|
|
504
|
+
- registered user
|
|
505
|
+
- partial user / incomplete user
|
|
506
|
+
6. 对 `doctor`、`msg`、`runtime listener` 增加 gating:
|
|
507
|
+
- 未完成 handle 注册的 identity 不能进入消息和 realtime 主链路
|
|
508
|
+
- CLI 需要明确提示先完成 `id register` 或 `id recover`
|
|
509
|
+
|
|
510
|
+
**交付物**:
|
|
511
|
+
|
|
512
|
+
- handle-backed user lifecycle 命令
|
|
513
|
+
- OTP / email verification / bind / recover 流程
|
|
514
|
+
- 完整 credential 持久化
|
|
515
|
+
- 用户完成态检查与 gating
|
|
516
|
+
|
|
517
|
+
**验收标准**:
|
|
518
|
+
|
|
519
|
+
- `id register` 能完成:
|
|
520
|
+
- 创建远端 user
|
|
521
|
+
- 创建或恢复 handle
|
|
522
|
+
- 保存本地凭证
|
|
523
|
+
- 形成可复用 identity
|
|
524
|
+
- `id bind`、`id recover`、`id profile get/set` 能与 user-service 跑通
|
|
525
|
+
- `id current` 与 `doctor` 能识别 local-only identity 与 registered user
|
|
526
|
+
- 未完成 handle 注册的 identity 不能直接执行 `msg *` 与 `runtime listener *`
|
|
527
|
+
|
|
528
|
+
### Phase 4:SQLite 本地状态与迁移
|
|
529
|
+
|
|
530
|
+
**目标**:把 v1 的本地状态模型迁到 v2,同时保留 owner_did 隔离和 v1 可导入能力。
|
|
531
|
+
|
|
532
|
+
**主要任务**:
|
|
533
|
+
|
|
534
|
+
1. 建立 SQLite 连接层、WAL 模式、schema version 管理。
|
|
535
|
+
2. 落地首版表:
|
|
536
|
+
- `contacts`
|
|
537
|
+
- `messages`
|
|
538
|
+
- `e2ee_outbox`
|
|
539
|
+
- `groups`
|
|
540
|
+
- `group_members`
|
|
541
|
+
- `relationship_events`
|
|
542
|
+
- `e2ee_sessions`
|
|
543
|
+
3. 落地首版视图:
|
|
544
|
+
- `threads`
|
|
545
|
+
- `inbox`
|
|
546
|
+
- `outbox`
|
|
547
|
+
4. 建立 DAO 层与查询接口。
|
|
548
|
+
5. 建立从 v1 SQLite 导入的 migration。
|
|
549
|
+
6. 支持 DID 恢复后的 owner rebind。
|
|
550
|
+
7. 建立 test fixtures:
|
|
551
|
+
- v1 DB 样本
|
|
552
|
+
- 多 identity 样本
|
|
553
|
+
- 含 secure outbox / group / relationship 的样本
|
|
554
|
+
|
|
555
|
+
**交付物**:
|
|
556
|
+
|
|
557
|
+
- SQLite schema
|
|
558
|
+
- migration runner
|
|
559
|
+
- DAO 层
|
|
560
|
+
- v1 DB 导入能力
|
|
561
|
+
|
|
562
|
+
**验收标准**:
|
|
563
|
+
|
|
564
|
+
- 本地 SQLite 可初始化、升级、查询
|
|
565
|
+
- v1 DB 可导入到 v2 schema
|
|
566
|
+
- owner_did 隔离语义不丢失
|
|
567
|
+
- `threads/inbox/outbox` 查询结果符合预期
|
|
568
|
+
|
|
569
|
+
### Phase 5:Messaging 与 Group 基础域
|
|
570
|
+
|
|
571
|
+
**目标**:先跑通 plain direct / plain group 的主链路。
|
|
572
|
+
|
|
573
|
+
**主要任务**:
|
|
574
|
+
|
|
575
|
+
1. 实现 message-service 客户端:
|
|
576
|
+
- `direct.send`
|
|
577
|
+
- `inbox.get`
|
|
578
|
+
- `inbox.mark_read`
|
|
579
|
+
- `direct.get_history`
|
|
580
|
+
2. 实现 user-service group 客户端:
|
|
581
|
+
- `create`
|
|
582
|
+
- `get`
|
|
583
|
+
- `update`
|
|
584
|
+
- `refresh_join_code`
|
|
585
|
+
- `get_join_code`
|
|
586
|
+
- `set_join_enabled`
|
|
587
|
+
- `join`
|
|
588
|
+
- `leave`
|
|
589
|
+
- `kick_member`
|
|
590
|
+
- `list_members`
|
|
591
|
+
- `post_message`
|
|
592
|
+
- `list_messages`
|
|
593
|
+
3. 落地 CLI 命令:
|
|
594
|
+
- `msg send`
|
|
595
|
+
- `msg inbox`
|
|
596
|
+
- `msg history`
|
|
597
|
+
- `msg mark-read`
|
|
598
|
+
- `group create/show/update/join/leave/kick/members/messages/code*`
|
|
599
|
+
4. 本地消息与群组快照持久化。
|
|
600
|
+
5. group 命令与消息命令的边界收敛:
|
|
601
|
+
- 群生命周期在 `group`
|
|
602
|
+
- 群发消息仍从 `msg send --group` 进入
|
|
603
|
+
6. 把 Phase 3 的 user gating 作为消息主链路前置条件,默认拒绝 local-only identity。
|
|
604
|
+
|
|
605
|
+
**交付物**:
|
|
606
|
+
|
|
607
|
+
- plain direct/group 全链路
|
|
608
|
+
- 本地缓存与历史
|
|
609
|
+
- group 本地快照
|
|
610
|
+
|
|
611
|
+
**验收标准**:
|
|
612
|
+
|
|
613
|
+
- 可以完成 direct 发消息、收件箱、历史、标记已读
|
|
614
|
+
- 可以完成 group 创建、入群、看成员、看消息、更新、离开、踢人
|
|
615
|
+
- 相关数据能稳定写入 SQLite
|
|
616
|
+
|
|
617
|
+
### Phase 6:Secure / E2EE 域
|
|
618
|
+
|
|
619
|
+
**目标**:补齐 awiki 的 secure messaging 差异化能力。
|
|
620
|
+
|
|
621
|
+
**主要任务**:
|
|
622
|
+
|
|
623
|
+
1. 根据冻结后的协议实现 secure session store。
|
|
624
|
+
2. 完成以下命令:
|
|
625
|
+
- `msg secure status`
|
|
626
|
+
- `msg secure init`
|
|
627
|
+
- `msg secure repair`
|
|
628
|
+
- `msg secure failed`
|
|
629
|
+
- `msg secure retry`
|
|
630
|
+
- `msg secure drop`
|
|
631
|
+
3. 保留 v1 的关键行为:
|
|
632
|
+
- auto-init
|
|
633
|
+
- inbox auto-processing
|
|
634
|
+
- session persistence
|
|
635
|
+
- outbox resend/drop
|
|
636
|
+
- peer failure feedback
|
|
637
|
+
4. 将 secure 状态与本地消息表、本地 outbox 表关联。
|
|
638
|
+
5. 处理 listener 与 secure auto-processing 的边界。
|
|
639
|
+
|
|
640
|
+
**交付物**:
|
|
641
|
+
|
|
642
|
+
- secure 命令面
|
|
643
|
+
- session store
|
|
644
|
+
- outbox retry/drop 机制
|
|
645
|
+
- E2EE 收发主路径
|
|
646
|
+
|
|
647
|
+
**验收标准**:
|
|
648
|
+
|
|
649
|
+
- direct E2EE 可以建立 session、发送、处理 incoming、重试失败项
|
|
650
|
+
- secure 状态能通过 CLI 与 doctor 观察
|
|
651
|
+
- secure 失败不会污染 plain message 主路径
|
|
652
|
+
|
|
653
|
+
> 默认假设:group E2EE 不作为首发阻塞项,待 direct E2EE 稳定后再进入后续里程碑。
|
|
654
|
+
|
|
655
|
+
### Phase 7:Runtime、Listener、Heartbeat 与 IPC
|
|
656
|
+
|
|
657
|
+
**目标**:把 v1 的 realtime/runtime 机制收敛成 v2 独立 runtime 域。
|
|
658
|
+
|
|
659
|
+
**主要任务**:
|
|
660
|
+
|
|
661
|
+
1. 实现 runtime mode:
|
|
662
|
+
- `http`
|
|
663
|
+
- `websocket`
|
|
664
|
+
2. websocket 模式下实现:
|
|
665
|
+
- listener 持有唯一远端连接
|
|
666
|
+
- 本地 IPC / daemon 转发 CLI RPC
|
|
667
|
+
- 后台服务 install/start/stop/restart/status
|
|
668
|
+
3. http 模式下实现:
|
|
669
|
+
- 业务命令直接走服务端 RPC
|
|
670
|
+
- listener 可选关闭
|
|
671
|
+
4. 实现 heartbeat 任务。
|
|
672
|
+
5. 实现 runtime setup/status/doctor 深度检查。
|
|
673
|
+
6. 兼容导入 v1 listener/settings 相关配置。
|
|
674
|
+
7. listener 启动前校验当前 identity 已完成 User 阶段,拒绝 local-only identity。
|
|
675
|
+
|
|
676
|
+
**交付物**:
|
|
677
|
+
|
|
678
|
+
- runtime mode 管理
|
|
679
|
+
- listener 服务管理
|
|
680
|
+
- IPC / local daemon
|
|
681
|
+
- heartbeat
|
|
682
|
+
|
|
683
|
+
**验收标准**:
|
|
684
|
+
|
|
685
|
+
- `runtime status/setup/mode/listener/heartbeat` 命令可用
|
|
686
|
+
- websocket 模式下所有消息命令能通过本地 daemon 工作
|
|
687
|
+
- http 模式下无需 listener 也可执行业务命令
|
|
688
|
+
- doctor 能报告 runtime 当前状态和异常原因
|
|
689
|
+
|
|
690
|
+
### Phase 8:扩展域、skills、docs、schema 生成
|
|
691
|
+
|
|
692
|
+
**目标**:建立“命令元数据驱动产品文档”的闭环。
|
|
693
|
+
|
|
694
|
+
**主要任务**:
|
|
695
|
+
|
|
696
|
+
1. 实现扩展域:
|
|
697
|
+
- `people`
|
|
698
|
+
- `page`
|
|
699
|
+
- `debug`
|
|
700
|
+
- `discovery`(如果保留在扩展域)
|
|
701
|
+
2. 构建 `cmdmeta` 元数据层,作为以下输出的单一事实来源:
|
|
702
|
+
- CLI help
|
|
703
|
+
- `schema`
|
|
704
|
+
- `docs` 生成
|
|
705
|
+
- skills 命令引用
|
|
706
|
+
3. 拆分 skills:
|
|
707
|
+
- `awiki-shared`
|
|
708
|
+
- `awiki-id`
|
|
709
|
+
- `awiki-msg`
|
|
710
|
+
- `awiki-runtime`
|
|
711
|
+
- `awiki-people`
|
|
712
|
+
- `awiki-page`
|
|
713
|
+
- `awiki-debug`
|
|
714
|
+
4. 建立 docs / schema / skills 引用校验。
|
|
715
|
+
5. 生成:
|
|
716
|
+
- `schemas/cli.json`
|
|
717
|
+
- `schemas/commands/*.json`
|
|
718
|
+
- shell completion
|
|
719
|
+
- man page
|
|
720
|
+
|
|
721
|
+
**交付物**:
|
|
722
|
+
|
|
723
|
+
- 扩展域命令
|
|
724
|
+
- skills 分层目录
|
|
725
|
+
- schema/docs/help 生成链路
|
|
726
|
+
|
|
727
|
+
**验收标准**:
|
|
728
|
+
|
|
729
|
+
- 命令帮助、schema、docs、skills 不再相互漂移
|
|
730
|
+
- 新增命令只需要更新一处元数据即可生成多处产物
|
|
731
|
+
- AI 不依赖外部 skill 也能理解核心 CLI 行为
|
|
732
|
+
|
|
733
|
+
### Phase 9:发布、切换与收尾
|
|
734
|
+
|
|
735
|
+
**目标**:把 v2 从“开发完成”转成“可发布、可切换、可回滚”的产品。
|
|
736
|
+
|
|
737
|
+
**主要任务**:
|
|
738
|
+
|
|
739
|
+
1. 接入 GoReleaser。
|
|
740
|
+
2. 产出多平台二进制与 checksums。
|
|
741
|
+
3. 可选接入 npm wrapper。
|
|
742
|
+
4. 生成安装说明、升级说明、迁移指南。
|
|
743
|
+
5. 落地 `migrate from-v1` 的完整入口。
|
|
744
|
+
6. 建立 shadow / verify / cutover 策略:
|
|
745
|
+
- 影子校验
|
|
746
|
+
- 双跑对比
|
|
747
|
+
- 切默认
|
|
748
|
+
- 回滚策略
|
|
749
|
+
|
|
750
|
+
**交付物**:
|
|
751
|
+
|
|
752
|
+
- release pipeline
|
|
753
|
+
- migration guide
|
|
754
|
+
- cutover checklist
|
|
755
|
+
|
|
756
|
+
**验收标准**:
|
|
757
|
+
|
|
758
|
+
- release 可生成 macOS / Linux / Windows 包
|
|
759
|
+
- 用户可从 v1 导入 credentials 和 SQLite 数据
|
|
760
|
+
- 文档明确说明切换、回滚和兼容边界
|
|
761
|
+
|
|
762
|
+
---
|
|
763
|
+
|
|
764
|
+
## 7. 里程碑与建议拆包
|
|
765
|
+
|
|
766
|
+
为了便于拆成 Epic/Issue,建议按下列工作包推进。
|
|
767
|
+
|
|
768
|
+
| 编号 | 工作包 | 对应阶段 | 完成定义 |
|
|
769
|
+
|---|---|---|---|
|
|
770
|
+
| EPIC-01 | 命令壳与输出协议 | Phase 0-1 | 根命令、输出 envelope、schema/doctor 骨架完成 |
|
|
771
|
+
| EPIC-02 | 配置与路径体系 | Phase 2 | XDG、env 兼容、default identity 解析完成 |
|
|
772
|
+
| EPIC-03 | identity store 与迁移 | Phase 2 | index.json、identity dir、v1 credential import 完成 |
|
|
773
|
+
| EPIC-04 | user + handle lifecycle | Phase 3 | register/bind/recover/profile/current + user gating 完成 |
|
|
774
|
+
| EPIC-05 | SQLite schema 与 DAO | Phase 4 | 表/视图/migration/fixtures 完成 |
|
|
775
|
+
| EPIC-06 | direct messaging | Phase 5 | send/inbox/history/mark-read 全链路完成 |
|
|
776
|
+
| EPIC-07 | group lifecycle | Phase 5 | create/join/show/members/messages/update/leave/kick 完成 |
|
|
777
|
+
| EPIC-08 | secure direct messaging | Phase 6 | session/outbox/retry/drop/auto-process 完成 |
|
|
778
|
+
| EPIC-09 | runtime 与 listener | Phase 7 | http/websocket、listener、IPC、heartbeat 完成 |
|
|
779
|
+
| EPIC-10 | docs/schema/skills 生成 | Phase 8 | cmdmeta 驱动链路闭环完成 |
|
|
780
|
+
| EPIC-11 | 发布与切换 | Phase 9 | goreleaser、迁移指南、cutover checklist 完成 |
|
|
781
|
+
|
|
782
|
+
---
|
|
783
|
+
|
|
784
|
+
## 8. 测试计划
|
|
785
|
+
|
|
786
|
+
### 8.1 单元测试
|
|
787
|
+
|
|
788
|
+
覆盖:
|
|
789
|
+
|
|
790
|
+
- config merge 与 env fallback
|
|
791
|
+
- identity index 解析与默认 identity 选择
|
|
792
|
+
- local-only identity vs registered user 状态判断
|
|
793
|
+
- output envelope / error mapping / exit code
|
|
794
|
+
- schema 生成与 help 生成
|
|
795
|
+
- thread id 生成
|
|
796
|
+
- SQLite DAO 与 view 查询
|
|
797
|
+
- secure session / outbox 状态机
|
|
798
|
+
|
|
799
|
+
### 8.2 迁移测试
|
|
800
|
+
|
|
801
|
+
覆盖:
|
|
802
|
+
|
|
803
|
+
- 从 `../awiki-agent-id-message/.credentials/` 样本导入
|
|
804
|
+
- 从 v1 SQLite 样本导入
|
|
805
|
+
- legacy flat file 检测与修复
|
|
806
|
+
- owner_did rebind
|
|
807
|
+
- secure session / outbox 导入
|
|
808
|
+
|
|
809
|
+
### 8.3 API 集成测试
|
|
810
|
+
|
|
811
|
+
覆盖:
|
|
812
|
+
|
|
813
|
+
- `authentication.md`
|
|
814
|
+
- `did-auth.md`
|
|
815
|
+
- `handle.md`
|
|
816
|
+
- `profile.md`
|
|
817
|
+
- `did-profile.md`
|
|
818
|
+
- `users.md`
|
|
819
|
+
- `relationships.md`
|
|
820
|
+
- `group.md`
|
|
821
|
+
- `ANP-client-server-api-direct.md`
|
|
822
|
+
- `ANP-client-server-api-group.md`
|
|
823
|
+
- `ANP-client-server-api-attachment.md`(若首版纳入附件)
|
|
824
|
+
|
|
825
|
+
### 8.4 runtime 测试
|
|
826
|
+
|
|
827
|
+
覆盖:
|
|
828
|
+
|
|
829
|
+
- http mode
|
|
830
|
+
- websocket mode
|
|
831
|
+
- listener install/start/stop/status
|
|
832
|
+
- 本地 IPC / daemon
|
|
833
|
+
- heartbeat run/status
|
|
834
|
+
- runtime doctor 检查
|
|
835
|
+
|
|
836
|
+
### 8.5 系统测试
|
|
837
|
+
|
|
838
|
+
建议通过同级服务仓完成端到端联调,主链路至少覆盖:
|
|
839
|
+
|
|
840
|
+
1. `id create`(仅验证本地 bootstrap)
|
|
841
|
+
2. `id register --handle ...`
|
|
842
|
+
3. `id bind`
|
|
843
|
+
4. `id current` / `doctor`
|
|
844
|
+
5. `msg send --to`
|
|
845
|
+
6. `msg inbox`
|
|
846
|
+
7. `msg history`
|
|
847
|
+
8. `group create` / `join` / `members` / `messages`
|
|
848
|
+
9. `msg secure init` / `msg secure retry`
|
|
849
|
+
10. `runtime mode set websocket` + listener
|
|
850
|
+
|
|
851
|
+
### 8.6 文档与生成校验
|
|
852
|
+
|
|
853
|
+
覆盖:
|
|
854
|
+
|
|
855
|
+
- 每个命令都有 schema
|
|
856
|
+
- 每个命令 help 可生成
|
|
857
|
+
- skills 中引用的命令必须存在
|
|
858
|
+
- docs / schema / help / generated reference 不允许漂移
|
|
859
|
+
|
|
860
|
+
---
|
|
861
|
+
|
|
862
|
+
## 9. 最终验收标准
|
|
863
|
+
|
|
864
|
+
以下条件全部满足时,才认为 v2 首版达到“可发布”标准:
|
|
865
|
+
|
|
866
|
+
1. 所有核心能力都通过 `awiki-cli` 统一入口暴露。
|
|
867
|
+
2. `id / msg / group / runtime` 的主链路可实际执行,不仅有命令壳。
|
|
868
|
+
3. handle-backed user 阶段是显式能力:可以区分 local-only identity 与 registered user。
|
|
869
|
+
4. `msg` 与 `runtime listener` 默认拒绝未完成 handle 注册的 identity。
|
|
870
|
+
5. `schema`、`doctor`、`docs` 是 CLI 本体能力,而不是外部补丁。
|
|
871
|
+
6. 所有副作用命令支持 `--dry-run`。
|
|
872
|
+
7. 所有命令遵循统一输出协议和错误协议。
|
|
873
|
+
8. direct plain、group plain、direct secure 三条主路径可用。
|
|
874
|
+
9. websocket runtime + listener + IPC 可用。
|
|
875
|
+
10. SQLite 本地状态可创建、升级、迁移、诊断。
|
|
876
|
+
11. 凭证目录布局支持 v2 新格式,并兼容从 v1 导入。
|
|
877
|
+
12. docs / schema / skills / help 由统一元数据驱动,避免文档漂移。
|
|
878
|
+
13. 发布链路可生成多平台包,并有明确迁移与回滚说明。
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## 10. 默认实现假设
|
|
883
|
+
|
|
884
|
+
除非后续明确调整,本规划默认采用以下实现假设:
|
|
885
|
+
|
|
886
|
+
1. 首版语言固定为 Go。
|
|
887
|
+
2. CLI 框架固定为 Cobra。
|
|
888
|
+
3. 首版采用 handle-first 用户流程;handle 为必填,不支持 pure DID 作为对外用户完成态。
|
|
889
|
+
4. `id create` 仅作为本地 bootstrap / 迁移辅助能力,不作为 `msg`、`group`、`runtime listener` 的前置完成态。
|
|
890
|
+
5. 首版优先实现 direct E2EE,不把 group E2EE 作为首发阻塞项。
|
|
891
|
+
6. 首版不强制接入系统 keychain,可先采用受权限保护的文件存储;但接口层需要预留 keychain 扩展点。
|
|
892
|
+
7. 首版必须兼容导入 `../awiki-agent-id-message/` 的凭证与 SQLite 数据。
|
|
893
|
+
8. 首版不追求覆盖 v1 所有边角脚本,而是先覆盖架构文档定义的 canonical 命令面。
|
|
894
|
+
9. 首版发布主渠道为 GitHub Releases;npm wrapper 为可选增强项。
|
|
895
|
+
10. Go 核心实现固定使用 Go 1.22,并保持 pure Go,禁止依赖 CGO;如果后续需要做系统兼容性壳层,可放在 TypeScript/Node 的薄壳中实现。
|
|
896
|
+
|
|
897
|
+
---
|
|
898
|
+
|
|
899
|
+
## 11. 本文档维护规则
|
|
900
|
+
|
|
901
|
+
- 当 `docs/architecture/awiki-v2-architecture.md` 或 `docs/architecture/awiki-command-v2.md` 发生影响实施范围的变化时,必须同步更新本文档。
|
|
902
|
+
- 当 v1 SQLite schema 或凭证布局的参考基线发生变化时,需要同步更新“参考基线”章节。
|
|
903
|
+
- 当新增一级命令或调整 canonical contract 时,必须同步更新 Phase、工作包、验收标准与测试计划。
|