@csntgao/uni-base 0.1.2 → 0.1.4

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.
@@ -1,215 +1,275 @@
1
- # Uni-Base 项目交接说明
1
+ # Uni-Base → Claude 交接文档
2
2
 
3
- ## 1. 当前仓库状态
3
+ > 更新时间:2026-09-02(Asia/Shanghai)
4
+ >
5
+ > 仓库:`/Users/gaostudio/uni-base`
6
+ >
7
+ > 分支:`main`
8
+ >
9
+ > 交接基线提交:`7d2f9bb docs(docs): 修正失效的原型与接口说明文档路径`
4
10
 
5
- - 仓库:`/Users/gaostudio/uni-base`
6
- - 分支:`main`
7
- - 交接时分支:`main`,客服、通知中心、发布说明等提交已通过完整验证并随本次交接推送。
8
- - 根目录历次 `pnpm pack` 生成的 `.tgz` 是本地发布产物,已由 `.gitignore` 忽略;不要提交或覆盖调用方正在使用的包。
9
- - 当前版本:
10
- - Core:`@uniplat/ai-employee-client@0.12.0`
11
- - Web Components:`@uniplat/ai-employee-web-components@0.19.0`
12
- - 本地 runtime manifest:`0.19.0`
13
- - `https://10.10.10.131:8787` 在本次交接时已启动,`current.json` 与 `releases/0.19.0/index.js` 可匿名读取。
14
- - npm registry 是 `https://registry.npmmirror.com`,当前机器未登录,npm 发布受认证条件阻塞。
11
+ ## 1. Claude 接手后的第一步
15
12
 
16
- 下一位 Agent 开始前必须完整阅读仓库根目录的 `AGENTS.md`,它替代所有旧版规则。
13
+ 先完整阅读根目录 `AGENTS.md`。它是本仓库当前唯一权威的 Agent 工作规则;本文件只记录状态快照、近期变更和接手顺序,若两者冲突,以 `AGENTS.md` 为准。
17
14
 
18
- ## 2. 当前公开 Web Components
15
+ 开始工作前执行:
16
+
17
+ ```bash
18
+ cd /Users/gaostudio/uni-base
19
+ git status --short --branch
20
+ git log -5 --oneline --decorate
21
+ ```
22
+
23
+ 交接文档更新前的 Git 状态为:
24
+
25
+ ```text
26
+ main 领先 origin/main 4 个提交(未推送)
27
+ 工作树无代码改动
28
+ HEAD = 7d2f9bb
29
+ ```
30
+
31
+ 不要清理、覆盖或提交根目录已有的 `.tgz`。它们是历史及当前本地发布产物,已由 `.gitignore` 忽略。
32
+
33
+ ## 2. 项目和包
34
+
35
+ `uni-base` 是 TypeScript 浏览器 SDK workspace,提供原生 HTML、Vue、Nuxt 等 Host 可使用的 Uniplat 数字员工与账户能力。
36
+
37
+ 当前包:
38
+
39
+ | 位置 | npm 名称 | 当前本地版本 | 说明 |
40
+ | ------------------------- | -------------------------------------- | -----------: | --------------------------------------- |
41
+ | 根目录 | `@csntgao/uni-base` | `0.1.4` | 当前公开发布入口;npmjs 尚未发布此版本 |
42
+ | `packages/core` | `@uniplat/ai-employee-client` | `0.14.0` | UI 无关的 HTTP/WebSocket/Core 状态机 |
43
+ | `packages/web-components` | `@uniplat/ai-employee-web-components` | `0.24.0` | Lit Web Components 与独立浏览器 runtime |
44
+ | `examples/vanilla` | `@uniplat/ai-employee-vanilla-example` | 私有示例 | 必须消费 workspace 包的构建产物 |
45
+
46
+ 注意:根包改名为 `@csntgao/uni-base` 不代表两个 workspace 包、已有 Web Component 标签或公开类型可以随之改名。`@uniplat/*` 名称和 `uniplat-*` 标签仍是公开契约。
47
+
48
+ ## 3. 当前公开 Web Components
19
49
 
20
50
  ```html
21
51
  <uniplat-ai-employee-chat></uniplat-ai-employee-chat>
22
52
  <uniplat-customer-support-chat></uniplat-customer-support-chat>
23
53
  <uniplat-user-login></uniplat-user-login>
24
54
  <uniplat-organization-selector></uniplat-organization-selector>
55
+ <uniplat-organization-multi-employee-selector></uniplat-organization-multi-employee-selector>
56
+ <uniplat-organization-single-employee-selector></uniplat-organization-single-employee-selector>
25
57
  <uniplat-account-context></uniplat-account-context>
26
58
  <uniplat-user-menu></uniplat-user-menu>
27
59
  <uniplat-notification-center></uniplat-notification-center>
60
+ <uniplat-notification-popover></uniplat-notification-popover>
28
61
  ```
29
62
 
30
- 以下标签不再公开或注册:
63
+ 不要注册或公开:
31
64
 
32
65
  ```html
33
66
  <uniplat-application-switcher></uniplat-application-switcher>
34
67
  <uniplat-organization-onboarding></uniplat-organization-onboarding>
35
68
  ```
36
69
 
37
- 工作台应用面板和组织入驻流程均内置于 `<uniplat-account-context>`。
70
+ 应用工作台与组织入驻是 `<uniplat-account-context>` 的内部能力。
38
71
 
39
- ## 3. 数字员工聊天
72
+ ## 4. 近期完成的改动
40
73
 
41
- `<uniplat-ai-employee-chat>` 渲染完整右侧抽屉,Host 只负责 `configure()` `open()`,不能再在外部拼装标题、消息区或输入区。
74
+ ### 4.0 多归属组织选择改为 S.0 / S.1
42
75
 
43
- 关键规则:
76
+ 最新提交:
44
77
 
45
- - 支持登录用户和匿名用户。
46
- - WebSocket 使用 `/api/user-realtime/ws` 的 `ai_employee` channel。
47
- - 同一连接只订阅当前 AI 会话,切换会话时取消旧订阅。
48
- - 打开抽屉或点击新对话只建立本地草稿。
49
- - 首条消息通过 `createSessionWithFirstMessage()` 原子创建会话。
50
- - 不允许先创建空 Session 再发送首条消息。
51
- - 当前会话始终视为已读,不显示角标,也不计入总未读。
52
- - “转人工”直接在同一抽屉切换到 `<uniplat-customer-support-chat>`。
78
+ ```text
79
+ 67d8d83 feat(web-components): S.0/S.1 设计重做多归属组织选择
80
+ ```
53
81
 
54
- ## 4. 人工客服组件
82
+ `<uniplat-organization-selector>` 现在覆盖 40.1 原型 S.1 默认态:脱敏账户摘要、名称与统一社会
83
+ 信用代码搜索、全部/企业/团队筛选、「最近进入 / 全部组织」分组、`+ 创建 / 加入`、`退出登录` 与
84
+ 带目标名称的主按钮。
55
85
 
56
- 主要实现:
86
+ 新增两个公开点:
57
87
 
58
- - `packages/core/src/customer-support-client.ts`
59
- - `packages/web-components/src/customer-support-chat.ts`
60
- - `packages/web-components/src/customer-support-transport.ts`
88
+ ```ts
89
+ configure({ presentation: 'inline' | 'modal', displayName, maskedMobile, ... })
90
+ resolveOrganizationEntryDecision({ organizations, rememberedOrganizationId })
91
+ ```
61
92
 
62
- 配置方式:
93
+ `presentation` 默认 `inline`(原卡片形态,遮罩归 Host);`modal` 为强制态,组件自渲染固定遮罩、
94
+ 无关闭按钮,遮罩点击与 `Escape` 都不关闭,`Escape` 也不冒泡到 Host。`resolveOrganizationEntryDecision()`
95
+ 是纯函数,返回 `personal | auto-enter | prompt`,不读写宿主存储。
63
96
 
64
- ```ts
65
- customerSupportChat.configure({
66
- realtimeUrl,
67
- transport,
68
- sessionId,
69
- })
97
+ 主要文件:
70
98
 
71
- customerSupportChat.open()
99
+ ```text
100
+ packages/web-components/src/organization-selector.ts
101
+ packages/web-components/tests/organization-selector.test.ts
102
+ packages/web-components/scripts/verify-runtime-build.mjs
103
+ examples/vanilla/main.js
72
104
  ```
73
105
 
74
- ### 4.1 实时连接规则
106
+ 官网需要配合的改动(删除自有遮罩与关闭按钮、按 helper 路由、持久化记住偏好)以及 UniplatBase
107
+ 组织条目 `credit_code` 的可选扩展,记录在
108
+ `/Users/gaostudio/.vibe-requirements/UniBase_QQXBWebsite_多归属组织选择S0S1接入需求_v0_1.md`。
109
+ 未扩展该字段前,搜索只按组织名称匹配。
75
110
 
76
- 人工客服使用同一个 `/api/user-realtime/ws`,但申请:
111
+ ### 4.1 企业员工头像回退
77
112
 
78
- ```json
79
- {
80
- "requested_channels": ["customer_support"]
81
- }
82
- ```
83
-
84
- 服务端按当前认证身份推送该用户所有客服会话的事件,而不是只推送当前会话。
85
-
86
- 最新完成的处理逻辑:
87
-
88
- - 任意客服会话事件都会重新请求会话列表。
89
- - 其他会话产生消息:
90
- - 更新会话标题、最后消息、状态和未读数。
91
- - 不刷新当前聊天历史。
92
- - 更新顶部聚合红点及会话列表红点。
93
- - 当前会话产生消息:
94
- - 刷新会话列表。
95
- - 刷新当前历史消息。
96
- - 自动同步已读。
97
- - `support_read_state_changed`:
98
- - 只刷新会话列表和未读投影。
99
- - 不刷新历史。
100
- - 不再次触发已读写入,避免反馈循环。
101
- - 当前正在查看的会话:
102
- - 不显示未读红点。
103
- - 不计入顶部聚合未读数量。
113
+ 最新提交:
114
+
115
+ ```text
116
+ df54bcc fix(account-context): 回退使用个人头像
117
+ ```
118
+
119
+ 当前规则:
120
+
121
+ 1. 当前组织存在员工头像时使用员工头像;
122
+ 2. 员工有企业内姓名、但没有企业内头像时,使用用户个人头像;
123
+ 3. 个人头像也没有或图片加载失败时,才显示姓名首字占位。
124
+
125
+ 主要文件:
126
+
127
+ ```text
128
+ packages/web-components/src/account-context.ts
129
+ packages/web-components/tests/account-context.test.ts
130
+ ```
131
+
132
+ 测试覆盖账户胶囊及展开后的 User Menu,不能只修其中一处。
133
+
134
+ ### 4.2 登录页当前开关和链接
104
135
 
105
136
  相关提交:
106
137
 
107
138
  ```text
108
- 2b5d5b9 fix(customer-support): 实时刷新全部客服会话与未读提示
109
- b65dcb9 fix(customer-support): 阻断客服已读事件反馈环并实现游标幂等
139
+ 9aea56c fix(user-login): 设置默认协议链接
140
+ 5813128 feat(user-login): 暂时隐藏扫码登录
141
+ f5464a1 fix(user-login): 居中安全提示锁图标
142
+ ```
143
+
144
+ 当前扫码登录由以下常量暂时关闭:
145
+
146
+ ```ts
147
+ export const USER_LOGIN_QR_LOGIN_ENABLED = false
148
+ ```
149
+
150
+ 位置:`packages/web-components/src/user-login.ts`。关闭时扫码页签不渲染;扫码 transport、状态机和跳过条件测试仍保留,恢复功能应只切换此常量并重新跑完整流程。
151
+
152
+ 默认协议链接:
153
+
154
+ ```text
155
+ 用户服务协议:https://website.hrs100.com/agreement/user-service-agreement.html
156
+ 隐私政策:https://website.hrs100.com/agreement/qqxb-user-privacy.html
110
157
  ```
111
158
 
112
- ### 4.2 客服 UI 状态
159
+ Host 显式传入 `userAgreementUrl` `privacyAgreementUrl` 时仍可覆盖默认值。
113
160
 
114
- 标题:`企业客服人工顾问`
161
+ ### 4.3 登录后账户信息刷新注意事项
115
162
 
116
- 状态由“会话状态 + 实时连接状态”组合:
163
+ `<uniplat-user-login>` `<uniplat-account-context>` 是解耦组件。登录 transport 会先等待 Host 的 `setAccessToken()` 完成,再派发不含 JWT 的 `login-success`;但 Account Context 不监听该事件,也不会监听 localStorage 变化。
117
164
 
118
- - 尚无会话、连接正常:`客服通道已连接`
119
- - 尚无会话、连接中:`正在连接客服通道`
120
- - `waiting`:`等待客服接入`
121
- - `active` 且实时正常:`人工客服在线`
122
- - `active` 但实时断开:`正在恢复实时连接`
123
- - `closed`:`会话已结束`
165
+ 如果 Account Context 在未登录时已经连接并加载失败,Host 必须在登录成功后主动刷新或重新挂载:
166
+
167
+ ```js
168
+ userLogin.addEventListener('login-success', async () => {
169
+ closeLoginModal()
170
+ await document.querySelector('uniplat-account-context')?.refresh()
171
+ })
172
+ ```
173
+
174
+ 账户投影会并行请求:
175
+
176
+ ```text
177
+ application.identity/list_available_applications
178
+ application.identity/list_available_organizations
179
+ ```
124
180
 
125
- 提交 `cca4db1` 修复了连接恢复后仍残留“鉴权服务暂不可用”横幅的问题:连接状态恢复为 `connected` 时清空可恢复错误提示。
181
+ 第二个请求体必须包含准确的应用名,例如:
126
182
 
127
- ## 5. 通知中心组件
183
+ ```json
184
+ { "application_name": "OfficialWebsite" }
185
+ ```
128
186
 
129
- `<uniplat-notification-center>` 是通知收件箱 Web Component,提供分类目录、通知列表与详情、未读状态、全部已读、关联资源和附件下载。
187
+ Open Application 的个人态允许 `xid/oid/eid/mid = 0`。无当前组织不是错误;服务端仍需返回满足契约的 `current_identity`、非空 `available_applications`、顶层用户资料和 `organizations` 数组。
130
188
 
131
- 关键边界:
189
+ Account Context 对外只派发净化后的 `LOAD_FAILED`,精确排错应看浏览器 Network 中上述两个请求的状态和安全错误码,禁止记录 Authorization header、JWT 或原始敏感响应。
132
190
 
133
- - 组件和 Core 不建立 WebSocket。
134
- - Host 复用自己的 `/api/user-realtime/ws`,订阅 `notification` channel,并通过 `applyRealtimeEvent(rawEvent)` 把事件交给组件。
135
- - 分类目录随 `listInbox({ includeTypeFacets: true })` 一并加载,不额外请求接口。
136
- - 分类显示名称来自后端 `notification_type_name`,SDK 不维护中文名映射。
137
- - 真实 HTTP transport 使用 `createUniplatBaseNotificationCenterTransport()`;JWT 只进入 transport 内部的 Authorization header。
138
- - 当前版本 Core `0.12.0`、Web Components `0.19.0` 已包含通知中心实现、测试与独立浏览器运行时。
191
+ ## 5. 核心架构边界
139
192
 
140
- ## 6. 登录、账户和工作台
193
+ 这里只列最容易被误改的边界,完整约束见 `AGENTS.md`。
141
194
 
142
- ### 6.1 User Login
195
+ ### 5.1 数字员工聊天
143
196
 
144
- 必须严格复刻 40.1 原型:
197
+ - `<uniplat-ai-employee-chat>` 自己渲染完整右侧抽屉;Host 只配置并调用 `open()`。
198
+ - 打开抽屉或点击新对话只创建本地草稿,不创建后端空 Session。
199
+ - 首条消息必须走 `createSessionWithFirstMessage()`,原子提交创建会话与首条消息。
200
+ - 实时连接使用 `/api/user-realtime/ws` 的 `ai_employee` channel。
201
+ - 当前会话始终视为已读;其他会话的实时消息仍累计未读。
202
+ - Assistant 消息使用共享的安全 Markdown 渲染器;用户、系统和错误消息保持纯文本。
203
+ - “转人工”释放数字员工连接,在同一抽屉切换客服组件。
145
204
 
146
- - 密码登录。
147
- - 短信验证码登录。
148
- - 扫码登录。
149
- - 不显示图形验证码。
150
- - 发送短信按钮始终可见,仅在手机号不完整或倒计时时禁用。
151
- - 登录结果先交给 Host `setAccessToken()`,再派发无凭据事件。
152
- - 登录设备信息包括稳定浏览器设备指纹,不得每次随机生成 `device_id`。
205
+ ### 5.2 人工客服
153
206
 
154
- ### 6.2 Account Context
207
+ - 使用同一个 realtime URL,但单独申请 `customer_support` channel。
208
+ - 首条消息通过客服会话创建接口的 `initial_message` 原子提交。
209
+ - 其他会话事件只刷新列表/未读投影;当前会话事件才刷新当前历史。
210
+ - `support_read_state_changed` 不得再次触发已读写入,避免反馈环。
155
211
 
156
- `<uniplat-account-context>` 负责:
212
+ ### 5.3 通知中心与小浮层
157
213
 
158
- - 用户姓名、头像、脱敏手机号。
159
- - 当前组织和可选组织。
160
- - 企业认证状态。
161
- - 员工信息弹窗。
162
- - 创建企业/团队流程。
163
- - 内嵌工作台应用面板。
164
- - 应用 ticket 跳转。
214
+ - Core 和两个通知组件都不建立 WebSocket。
215
+ - Host 保留唯一实时连接,订阅 `notification` channel,再调用组件的 `applyRealtimeEvent(rawEvent)`。
216
+ - Popover 固定加载最近 4 条未读,但总未读数必须调用 `getUnreadCount()`。
217
+ - 空 `applicationName` 表示当前用户和组织下的全应用聚合;transport 必须省略 `application_name`。
218
+ - 分类展示名来自后端 `notification_type_name`,SDK 不保存 code 到中文名映射。
165
219
 
166
- 必须传入 `applicationName`。账户资料从 `list_available_organizations` 顶层读取:
220
+ ### 5.4 Account Context 和工作台
167
221
 
168
- - `display_name`
169
- - `avatar_url`
170
- - `mobile_masked`
222
+ - 用户资料来自 `list_available_organizations` 顶层的 `display_name/avatar_url/mobile_masked`。
223
+ - 不再请求 `profile_summary_v2`,也不让 Host 手工组装服务端账户投影。
224
+ - 当前组织显示员工姓名和头像;缺少员工头像时按第 4.1 节回退。
225
+ - 应用工作台只加载应用,不在面板里重复组织选择器。
226
+ - 所有应用在新窗口打开;异步签发 ticket 时同步预开无凭据空白窗口。
227
+ - Ticket 只进入目标 URL Fragment,不进入 DOM、状态、事件、日志或异常。
171
228
 
172
- 不得再调用 `profile_summary_v2`。
229
+ ### 5.5 员工选择器
173
230
 
174
- 工作台只请求应用列表,不请求组织列表;组织上下文由 Account Context 管理。
231
+ - 多选与单选是两个独立公开组件,不暴露 `selectionMode`。
232
+ - 只使用当前 JWT 所属组织;公开参数不能接收 `org_id/oid/xid/eid` 等身份字段。
233
+ - 只展示在职且启用员工,接口失败不能用 Mock 或 Host 名单回退。
234
+ - 单选确认只返回 `{ employeeId, employee }`,不接收多选数组或 `maxSelection`。
175
235
 
176
- 应用跳转流程:
236
+ ## 6. 安全红线
177
237
 
178
- 1. 先构造完整目标 URL。
179
- 2. 使用当前 JWT `POST {}` 调用 `issue_ticket`。
180
- 3. 从签发响应取得 Ticket15 秒有效期和权威 `source_system`。
181
- 4. 新窗口打开目标页面。
182
- 5. Ticket 放入 `#uniplat_identity_ticket=<ticket>&source_system=<source_system>`。
183
- 6. 目标页先清除 Ticket Fragment,再以项目初始化的 `applicationName` 调用 `login_with_ticket`。
184
- 7. JWT 交给目标 Host 的 `setAccessToken()`。
238
+ - SDK 不读取、保存或刷新长期 JWT;Host 通过 `getAccessToken()`/`setAccessToken()` 管理。
239
+ - JWT 只能短暂进入规定的 Authorization header、WebSocket authenticate 首帧或 Host token 保存回调。
240
+ - JWTticket、challenge ID、密码、验证码不得进入 URL(ticket 规定的 Fragment 除外)、DOM、CustomEvent、日志、快照或构建配置。
241
+ - 不要把真实 JWT 粘贴到终端命令、Issue、文档或聊天中;若发生泄露,应要求后端撤销对应会话并重新登录。
242
+ - 不得在浏览器包中加入 HR-SaaS/Kanban HMAC 密钥或内部签名逻辑。
243
+ - 后端文本只能通过稳定白名单错误码映射,不能直接透传 `msg`、堆栈或原始响应。
185
244
 
186
- ## 7. 关联项目与资料
245
+ ## 7. 当前构建和验证状态
187
246
 
188
- 跨项目工作前先读取:
247
+ 在 `67d8d83` 上最近一次完整检查结果:
189
248
 
190
249
  ```text
191
- /Users/gaostudio/.vibe-requirements/projects.md
250
+ pnpm format:check 通过
251
+ pnpm lint 通过
252
+ pnpm typecheck 通过
253
+ pnpm test 25 个测试文件通过;275 passed,2 skipped
254
+ pnpm build core、web-components、runtime、vanilla 全部通过
192
255
  ```
193
256
 
194
- 主要关联项目:
257
+ 两个 SDK 已重新打包:
195
258
 
196
- - Kanban 后端:`/Users/gaostudio/ae_design/实现/uniplat-kanban/backend`
197
- - HR-SaaS:`/Users/gaostudio/ae_design/实现/hr_saas`
198
- - UniplatBase:`/Users/gaostudio/ae_design/实现/uniplat_base`
199
- - 官网:`/Users/gaostudio/qqxbwebsite`
200
- - Enterprise Admin:`/Users/gaostudio/ae_design/实现/ae-enterprise-admin`
259
+ ```text
260
+ /Users/gaostudio/uni-base/uniplat-ai-employee-client-0.14.0.tgz
261
+ /Users/gaostudio/uni-base/uniplat-ai-employee-web-components-0.24.0.tgz
262
+ ```
201
263
 
202
- 40.1 总原型:
264
+ 根包本地产物:
203
265
 
204
266
  ```text
205
- /Users/gaostudio/qqxbwebsite/原型/40.1、注册登录与企业入驻流程-standalone.html
267
+ /Users/gaostudio/uni-base/csntgao-uni-base-0.1.4.tgz
206
268
  ```
207
269
 
208
- 跨项目只允许查阅。未经用户明确授权,不得直接修改其他项目;如需后端或 Host 配合,应在 `.vibe-requirements` 编写独立联合需求。
270
+ 这些 tarball 都是本地交付物,不应提交 Git。
209
271
 
210
- ## 8. 验证与发布要求
211
-
212
- 任何代码修改后必须执行:
272
+ 任何后续代码改动都必须重新执行:
213
273
 
214
274
  ```bash
215
275
  pnpm format:check
@@ -221,34 +281,114 @@ pnpm --filter @uniplat/ai-employee-client pack
221
281
  pnpm --filter @uniplat/ai-employee-web-components pack
222
282
  ```
223
283
 
224
- 确认修法后直接完成:
284
+ 代码再次修改后,旧 runtime 与 tarball 立即过期。纯文档修改不需要版本递增、构建、打包或发布。
285
+
286
+ ## 8. 当前发布状态
287
+
288
+ ### 8.1 独立浏览器 runtime
289
+
290
+ 已发布并从远端验证:
291
+
292
+ ```text
293
+ Manifest: https://10.10.10.131:8787/current.json
294
+ Version: 0.24.0
295
+ Module: https://10.10.10.131:8787/releases/0.24.0/index.js
296
+ SHA-256: 2cc1ba9ab48eb20e23cd1f95e68ca9d70413c602aa5f400828147020d4cc0341
297
+ ```
298
+
299
+ 最后验证结果:
300
+
301
+ - `current.json`:HTTP 200、`Cache-Control: no-store`;
302
+ - 版本模块:HTTP 200、CORS `*`、`immutable`;
303
+ - 远端模块 hash 与本地一致;
304
+ - `current.json` 指向 `./releases/0.24.0/index.js`。
305
+
306
+ 静态服务未启动时可执行:
307
+
308
+ ```bash
309
+ node /Users/gaostudio/.uni-base-runtime/serve.mjs
310
+ ```
311
+
312
+ 该服务目录直接使用 `/Users/gaostudio/uni-base/dist/runtime`。证书和私钥在仓库外,禁止复制进仓库。
313
+
314
+ ### 8.2 npm
315
+
316
+ 当前 registry:
317
+
318
+ ```text
319
+ https://registry.npmjs.org/
320
+ ```
321
+
322
+ 当前远端状态:
323
+
324
+ ```text
325
+ @csntgao/uni-base 最新公开版本:0.1.3
326
+ 本地待发布版本:0.1.4
327
+ npm whoami:E401 Unauthorized
328
+ ```
329
+
330
+ 因此 `@csntgao/uni-base@0.1.4` 尚未发布,不能声称 npm 发布成功。用户完成以下登录后再继续:
331
+
332
+ ```bash
333
+ npm login --registry=https://registry.npmjs.org/
334
+ npm whoami
335
+ ```
336
+
337
+ 登录成功后必须重新查询远端版本;确认 `0.1.4` 不存在,再从已提交且干净的工作树发布并回读:
338
+
339
+ ```bash
340
+ npm view @csntgao/uni-base version
341
+ npm publish --access public
342
+ npm view @csntgao/uni-base@0.1.4 version
343
+ ```
344
+
345
+ 两个 `@uniplat/*` 包当前在 npmjs 不存在或对当前账号不可见。发布它们需要 `@uniplat` 组织管理员把账号 `csntgao` 加入组织,并授予创建、发布 public package 的权限;不要通过重命名内部包规避公开契约。
346
+
347
+ ## 9. 发布流程
348
+
349
+ 代码修改确认后,不要停在“建议修法”或本地测试阶段。按 `AGENTS.md` 完成:
225
350
 
226
351
  ```text
227
- 实现 → 测试构建打包 版本递增提交 → 发布
352
+ 实现 → 完整验证重建两个 SDK 重新打包查询远端版本
353
+ → SemVer 递增 → 再验证/构建/打包 → 提交 → 推送 → 发布 → 远端回读
228
354
  ```
229
355
 
230
- 不要在提出修法后停下来等待重复确认。
356
+ Runtime 必须:
357
+
358
+ 1. 先生成 `dist/runtime/releases/<version>/`;
359
+ 2. 匿名读取并核对版本模块内容;
360
+ 3. 再原子切换 `current.json`;
361
+ 4. 从远端重新读取 manifest 和模块验证。
362
+
363
+ npm 或静态目标缺凭据、权限、服务时,保留已验证产物,报告明确的一次性配置项;不能谎称发布成功。
231
364
 
232
- 发布时:
365
+ ## 10. 关联资料和跨项目边界
233
366
 
234
- - 先发布并验证版本化 runtime 目录。
235
- - 再原子切换 `current.json`。
236
- - 发布后重新读取远端 manifest 和模块校验。
237
- - npm 未认证时明确报告外部阻塞,不得声称 npm 发布成功。
238
- - 不要提交根目录历史 tarball。
367
+ 跨项目排查前先读:
239
368
 
240
- ## 9. 下一步建议
369
+ ```text
370
+ /Users/gaostudio/.vibe-requirements/projects.md
371
+ ```
241
372
 
242
- 下一位 Agent 应优先确认当前远端与发布状态:
373
+ 关联项目:
374
+
375
+ ```text
376
+ Kanban 后端: /Users/gaostudio/ae_design/实现/uniplat-kanban/backend
377
+ HR-SaaS: /Users/gaostudio/ae_design/实现/hr_saas
378
+ UniplatBase: /Users/gaostudio/ae_design/实现/uniplat_base
379
+ 官网 Host: /Users/gaostudio/qqxbwebsite
380
+ Enterprise Admin:/Users/gaostudio/ae_design/实现/ae-enterprise-admin
381
+ 40.1 原型: /Users/gaostudio/ae_design/1-新平台底座搭建/1-亲亲企服平台(基础能力+企服客户端)/3-需求及UI设计/官网及企服客户端设计/40.1_注册登录与企业入驻流程.html
382
+ ```
243
383
 
244
- 1. 核对 `main` 已推送到 `origin/main`。
245
- 2. 运行完整验证,确认 Core `0.12.0`、Web Components `0.19.0`。
246
- 3. 确认 HTTPS runtime 服务仍在运行;未运行时执行 `node /Users/gaostudio/.uni-base-runtime/serve.mjs`。
247
- 4. 验证:
384
+ 默认只能查阅其他项目。未经用户明确授权,不得修改其他仓库;需要联合变更时,在 `.vibe-requirements` 写独立需求并说明责任边界。
248
385
 
249
- ```text
250
- https://10.10.10.131:8787/current.json
251
- https://10.10.10.131:8787/releases/0.19.0/index.js
252
- ```
386
+ ## 11. 推荐接手顺序
253
387
 
254
- 5. npm 发布仍需用户先为配置的 registry 完成登录。
388
+ 1. 完整阅读 `AGENTS.md`;
389
+ 2. 确认 Git 分支、工作树和最新提交;
390
+ 3. 根据用户当前任务定位对应组件及测试,不要顺手改公开契约;
391
+ 4. 若继续 npm 发布,先让用户恢复 npmjs 登录,再核对远端版本;
392
+ 5. 若继续官网登录联调,重点确认 `setAccessToken()` 完成后是否调用 Account Context `refresh()`;
393
+ 6. 所有认证问题排查只查看安全状态码和白名单错误码,不复制 JWT;
394
+ 7. 代码修改完成后走完整验证、打包、版本、提交、发布和远端回读流程。