diff --git a/.trellis/.version b/.trellis/.version index 8b707c6..b976b13 100644 --- a/.trellis/.version +++ b/.trellis/.version @@ -1 +1 @@ -0.6.7 \ No newline at end of file +0.6.10 \ No newline at end of file diff --git a/.trellis/spec/frontend/api-and-state.md b/.trellis/spec/frontend/api-and-state.md index c9bc131..665426d 100644 --- a/.trellis/spec/frontend/api-and-state.md +++ b/.trellis/spec/frontend/api-and-state.md @@ -16,6 +16,79 @@ 勿为低价值资源建冻结所有权/结果未知协议的状态机(2026-07 IdP 图标精简教训)。 域相关异步前置设置未加载完成前禁用提交,后端仍是同一约束的权威校验。 - 可重入异步加载(分页、自动刷新、详情弹窗、依赖切换)不经 useAsync 时必须带**请求代次守卫**(`let seq = 0; const n = ++seq; … if (n !== seq) return`),晚到响应丢弃、loading 只由最新请求清;作用域标识(如 cfg/region/bucket)变更时同步重置从属状态(前缀/游标/选中/弹窗)。会创建远端会话的打开流程,过期响应要就地删除刚建的会话(SerialConsolePanel)。(2026-07-22 审查 #5/#6/#10/#17) -- 401 登出前比对**发出请求时快照的 token** 与当前 token:不一致说明会话已更新(如 OAuth 绑定回跳),旧令牌的迟到 401 不得登出新会话(request.ts `handleUnauthorized`)。含时间比较的登录态判定用普通函数,不用 computed(时间流逝不触发重算)。(#4/#15) +- 401 登出前比对**发出请求时快照的 token** 与当前 token:不一致说明会话已更新(如 OAuth 绑定回跳),旧令牌的迟到 401 不得登出新会话(request.ts `handleUnauthorized`)。敏感写操作还须遵守下方「会话换发与并发 401」契约。含时间比较的登录态判定用普通函数,不用 computed(时间流逝不触发重算)。(#4/#15) - 固定周期轮询用 `setTimeout` 自链(上一轮 finally 里排下一轮),不用 `setInterval`:慢响应会堆叠请求且可能永久饥饿。(#16) - `window.open` 只能在用户手势内同步调用,异步回调(如签发 PAR 后)现开会被弹窗策略拦截且返回 null:需要新窗口的异步流程在点击处理器里先 `window.open('', '_blank')` 预开、拿到结果后 `location.replace` 导航,失败关闭空白窗;任何 `window.open` 返回 null 都要如实报错并给重试(重试点击是新手势),不得标记成功。(2026-07-22 审查 #19,ObjectBrowser 下载) +- 写请求(非 GET)在 `request.ts` 层按 method+url+body 做 **in-flight 去重**(2026-07-23 起):前一发未返回时同 key 复用同一 Promise 不再发第二发,完成即移除;GET 不去重(useAsync seq 后发优先)。这是防连点的系统级兜底,组件级 busy/disabled 仍必须做(见 typescript-vue.md);合法的「连续两次相同写」(极少)需改变 body 或等待前次完成。 + +## 场景:会话换发与并发 401 + +### 1. Scope / Trigger + +后端成功后会令旧 JWT 失效并返回新会话的认证写接口(改密、登录策略、TOTP、 +身份/通行密钥变更、撤销全部会话及钱包绑定)必须使用本契约。它防止并发旧请求的 +401 先到时清空即将换发的新会话;不用于普通写接口,也不把所有写请求全局串行化。 + +### 2. Signatures + +```ts +interface RequestOptions { + refreshesSession?: boolean +} + +request(path, { + method: 'POST', + body, + refreshesSession: true, +}) +``` + +`SessionRefresh` 的成功响应必须包含字符串 `token` 与 `expiresAt`。 + +### 3. Contracts + +- 有旧 Token 的 `refreshesSession` 请求按“发出时 Token”登记在途换发。 +- 2xx 响应须在 Promise 返回、换发登记释放前由请求层先写入 Auth Store;组件可为 + mock 流程重复写同值。 +- 其他请求的 401 若发现同一旧 Token 仍有换发在途,须等待全部结束后再比较 Store; + Token 已变化则只抛业务错误,不登出。 +- 换发请求自身收到 401 时先幂等退出登记再处理 401,避免两个失败换发互相等待。 +- 公开登录没有旧 Token,不由请求层提前建立会话;页面仍负责登录后导航。 + +### 4. Validation & Error Matrix + +| 条件 | 行为 | +| --- | --- | +| 2xx 且 `token` / `expiresAt` 合法 | 先 `setSession`,再释放等待者 | +| 网络错误、畸形 JSON、非 2xx | 不写 Store,必须释放登记 | +| 并发 401 等待后 Token 已变化 | 保留新会话,不跳登录页 | +| 等待后仍是请求时 Token | 登出并带当前地址跳转登录页 | +| 多个换发请求均返回 401 | 全部拒绝,不死锁,只执行一次有效登出 | + +### 5. Good / Base / Bad Cases + +- Good:改密成功响应与旧列表请求 401 并发,成功响应先落 Store,旧 401 不登出。 +- Base:没有换发在途的当前 Token 收到 401,按原流程登出。 +- Bad:仅在组件 `await` 后写 Store;Promise `finally` 与组件 continuation 之间存在 + 微任务窗口,迟到 401 可抢先登出。 + +### 6. Tests Required + +- 401 先登记等待、换发随后成功:断言 Store 为新 Token 且不导航。 +- 换发 Promise 完成边界:断言返回调用方前 Store 已更新。 +- 两个换发请求同时 401:断言均结束、无死锁、仅一次导航。 +- 无旧 Token 的公开登录:断言请求层不提前写 Store。 + +### 7. Wrong vs Correct + +```ts +// Wrong:后端会换 Token,却没有加入协调 +return request('/auth/totp/activate', { method: 'POST', body }) + +// Correct:请求层在释放并发 401 前先落新会话 +return request('/auth/totp/activate', { + method: 'POST', + body, + refreshesSession: true, +}) +``` diff --git a/.trellis/spec/frontend/buttons.md b/.trellis/spec/frontend/buttons.md new file mode 100644 index 0000000..02c46ac --- /dev/null +++ b/.trellis/spec/frontend/buttons.md @@ -0,0 +1,24 @@ +# 按钮规范 + +设计稿:统一设计项目「组件-按钮规范.dc.html」;完整决策档案见 `.trellis/tasks/archive/**/07-24-button-spec-rollout/design.md`。 + +## 七个合法变体(新增按钮先对号入座,禁用 secondary / tertiary / dashed / warning) + +| 写法 | 用途 | +|---|---| +| `type="primary"` | 区块唯一主操作(保存/登录/新建);一个区块至多一个 | +| (无 type) | 并列次操作(取消/测试/上一步) | +| `quaternary` | 行内轻操作(修改/复制/分页);hover wash 底 | +| `quaternary type="primary"` | 行内肯定动作(绑定/启用);一行至多一个 | +| `quaternary type="error"` | 行内危险入口(删除/解绑);必接 ConfirmPop | +| `type="error"` | 危险最终确认;仅确认层/危险区收尾 | +| `ghost type="error"` | 详情页危险区入口(终止/删除资源) | + +## 规则 + +- 行内(卡片头/表格/列表行尾)一律文字按钮;危险两段式:入口文字红或描边红 → 确认层内才出 Error 实底。 +- 尺寸跟容器:页面级工具栏 medium;弹窗底部/筛选条/区块工具行/详情操作条 small;卡片行内/表格 tiny;登录页 large+block。同一容器不混档。 +- 图标按钮方形(quaternary 去 circle)且必带 title/tooltip;circle 仅浮层关闭与 VNC 媒体控制。 +- 异步必上 loading,宽度稳定、禁重复提交;成功后才关弹层。 +- 互斥单选用 `ChoiceChip`(components/ChoiceChip.vue),不用 NButton 动态 type 模拟。 +- pressed 色已入 token:accentPressed / errHover / errPressed(tokens.ts + main.css 双处同步)。 diff --git a/.trellis/spec/frontend/index.md b/.trellis/spec/frontend/index.md index 4d8e687..b7367e0 100644 --- a/.trellis/spec/frontend/index.md +++ b/.trellis/spec/frontend/index.md @@ -17,6 +17,7 @@ Vue 3 + Vite + TypeScript + Naive UI + Tailwind CSS v4 + ECharts + Pinia。Naive | [Directory Structure](./directory-structure.md) | src 分层、文件命名与全局作用域约定 | | [TypeScript & Vue](./typescript-vue.md) | TS 严格模式与组件写法 | | [Styling & Design Tokens](./styling-design-tokens.md) | Anthropic 风设计 token、字体与反模式清单 | +| [Buttons](./buttons.md) | 按钮七变体、尺寸档位与危险两段式守则 | | [API & State](./api-and-state.md) | 请求封装与 Pinia 使用边界 | --- @@ -28,7 +29,7 @@ Vue 3 + Vite + TypeScript + Naive UI + Tailwind CSS v4 + ECharts + Pinia。Naive - [ ] 读过 [Directory Structure](./directory-structure.md),文件放对层(views / components / composables / api / stores / types) - [ ] 涉及颜色、圆角、间距时先看 [Styling & Design Tokens](./styling-design-tokens.md),禁止硬编码 hex - [ ] 新增请求走 `api/` 统一封装,DTO 类型进 `types/`(与后端 swagger `oci-portal/docs/` 一一对应) -- [ ] 出 UI 设计稿前读 `../../guides/design-workflow.md` +- [ ] 出 UI 设计稿前读 `../guides/design-workflow.md` ## Quality Check diff --git a/.trellis/spec/frontend/styling-design-tokens.md b/.trellis/spec/frontend/styling-design-tokens.md index a989c37..589698e 100644 --- a/.trellis/spec/frontend/styling-design-tokens.md +++ b/.trellis/spec/frontend/styling-design-tokens.md @@ -71,6 +71,16 @@ - **浮层投影**:下拉/确认弹层/整页提示卡统一 `shadow-overlay`(@theme `--shadow-overlay`),圆角不超过 `rounded-lg`;禁止再写 `shadow-[0_18px…]` 一类逐处任意值。 - **恒暗页面**(网页 VNC 等):色值从 `@/theme/tokens` 的 `darkTokens` 取,不硬编码 hex;需要给组件 prop 传具体色时同样从 tokens/darkTokens 引。 +## 移动端形态约定(2026-07-21 移动端适配 B0-B4 固化) + +- **断点**:`md`(768px)为移动/桌面切换线,JS 层条件渲染一律 `useIsMobile()`(与 CSS 断点同源);`lg` 仅做网格降列。 +- **弹窗**:表单弹窗一律 `FormModal`(移动端自动全屏 + 页脚常驻);直接用原生 NModal 的(详情查看类)接 `useMobileModal(width)` 取 `:style` 与 `:class`,全屏布局规则 `.form-modal-mobile` 在 `main.css`(全局,teleport 与跨 chunk 都够得到)。组件 scoped 里给弹窗内容限高须包 `@media (min-width: 768px)`——main.css 先于组件样式加载,同特异性覆盖不可靠。 +- **表格**:所有 NDataTable 必配 `scroll-x`(内容合计宽);受控分页 reactive 对象加 `get simple() { return isMobile.value }`(移动端页码槽放不下);高频列表页(租户/实例式)另供 `MobileCardList` 卡片形态,表格 `v-if="!isMobile"`。 +- **筛选器**:多控件筛选一律包 `FilterBar`(桌面 wrap、移动横滚+右缘渐隐);面板头单控件筛选桌面放 `PanelHeader` 插槽、移动独立行(`v-if="isMobile"` 的 `border-b px-4.5 py-2.5` 全宽行)。 +- **详情页 hero**:panel 内「返回链接 → 标题行(page-title+徽标+flex-1+按钮组)→ 移动折叠 toggle → meta grid」四段式;操作按钮组包 `flex items-center gap-2 max-md:w-full`,移动端整组独立成行。 +- **导航**:顶级页面进 `layouts/navItems.ts`(侧栏/底栏/「更多」抽屉唯一来源);新增页面须归入 `mobileTabNames`(高频四项)或 `mobileMoreNames`。 +- **构建**:新增大体积三方库须在 `vite.config.ts` 的 `vendorChunk` 归入命名组(office 系深依赖靠 importer 链上溯),否则聚成匿名 index 块逃逸 PWA 预缓存排除(`globIgnores: office-*`)并可能触发 chunk 告警。 + ## Common Mistake: NModal 宽度不能用 Tailwind class **Symptom**:`` 弹窗实际渲染为全宽。 diff --git a/.trellis/spec/frontend/typescript-vue.md b/.trellis/spec/frontend/typescript-vue.md index 1772dc1..1da09c7 100644 --- a/.trellis/spec/frontend/typescript-vue.md +++ b/.trellis/spec/frontend/typescript-vue.md @@ -14,7 +14,8 @@ - `v-for` 必须带 `key`,且不与 `v-if` 写在同一元素上。 - 组件内样式一律 `scoped`;跨组件复用样式上提到全局 token 或工具类。 - 复用逻辑抽 composable(`useXxx` 命名,放 `composables/`);单文件组件函数遵循 ≤30 行的项目约定。 -- 二次确认一律用 `components/ConfirmPop.vue`(批次8 起替代裸 NPopconfirm):kind 分 danger/warn/plain 三态,`onConfirm` 返回 Promise 时确认按钮自动 loading 且弹层锁定;双按钮抉择场景(如终止实例选是否保留引导卷)仍用 `dialog.warning`。 +- 二次确认一律用 `components/ConfirmPop.vue`(批次8 起替代裸 NPopconfirm):kind 分 danger/warn/plain 三态,`onConfirm` 返回 Promise 时确认按钮自动 loading 且弹层锁定(onConfirm 内部必须自行 catch,不得向外抛)。`dialog.warning` 例外仅限两类:多分支抉择(如终止实例选是否保留引导卷)与下拉菜单项触发(popover 无锚点),此时 onPositiveClick 返回 Promise 让确认键自带 loading;NDialog 其余只用于结果展示。 +- 写操作触发器(按钮/开关)必须有 in-flight 防连点(按钮交互一致性任务 2026-07-23 起):单动作用 busy ref;列表行内用 `ref(new Set())` 按行 loading/disabled;同行多动作用 `Map` 区分,避免错按钮亮 loading。中断性电源操作(停止/重启)与改登录策略类操作必须 ConfirmPop(warn)确认。 - 文件类型图标用 `components/objectstorage/FileIcon.vue`(Catppuccin Icons):图标数据由 `node scripts/gen-file-icons.mjs` 从 devDependency `@iconify-json/catppuccin` 提取到 `fileIcons.ts`(生成文件勿手改);新增类型改脚本 PICK 列表后再生成,禁止整包 import iconify JSON 进 bundle。 - highlight.js 高亮输出的配色是全局 `.code-hl` 类(`assets/main.css`,引用设计 token 明暗自适应),给容器加该类即可,勿在组件 scoped 里重复定义;markdown 渲染必须 marked + DOMPurify 消毒后再 v-html,两库一律动态 import 保持独立 chunk。 - 对象内容数据面分两路(round11 起):预览/编辑走面板中转 `getObjectContent`/`putObjectContent`(GET ≤20MB / PUT ≤5MB,保存以 If-Match 防并发,412 走覆盖确认),**不签发 PAR**;分享/下载/上传仍走 PAR 直连,勿把大流量改经面板。对象查看统一入口是 `ObjectViewerModal`(预览编辑合一,左内容右信息),office/pdf 用 `@vue-office/*` 且必须 `defineAsyncComponent` 动态加载保持独立 chunk。 diff --git a/.trellis/workflow.md b/.trellis/workflow.md index 7775a93..bf3d1c1 100644 --- a/.trellis/workflow.md +++ b/.trellis/workflow.md @@ -183,7 +183,7 @@ Complex task: ask the user if you can create a Trellis task and enter the planni - 1.0 Create task `[required · once]` (only after task-creation consent) - 1.1 Requirement exploration `[required · repeatable]` (`prd.md`; complex tasks also need `design.md` + `implement.md`) - 1.2 Research `[optional · repeatable]` -- 1.3 Configure context `[required · once]` — Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix (sub-agent-dispatch platforms only; inline platforms skip) +- 1.3 Configure context `[required · once]` — Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Grok, Kimi Code (sub-agent-dispatch platforms only; inline platforms skip) - 1.4 Activate task `[required · once]` (review gate, then `task.py start`; status → in_progress) - 1.5 Completion criteria @@ -220,7 +220,7 @@ Inline mode: skip jsonl curation; Phase 2 reads artifacts/specs via `trellis-bef therefore must cover every required step from implementation through commit, including Phase 3.3 spec update and Phase 3.4 commit. --> -Sub-agent dispatch protocol applies to all platforms and all sub-agents, including class-2 Codex/Gemini/Qoder/Copilot/ZCode/Reasonix/Trae and `trellis-research`: every dispatch prompt starts with `Active task: ` before role-specific instructions. +Sub-agent dispatch protocol applies to all platforms and all sub-agents, including native Codex `SubagentStart` context injection with child-side pull fallback, class-2 Gemini/Qoder/Copilot/Reasonix/Trae/Grok/Kimi Code, hook-backed ZCode/Snow, and `trellis-research`: every dispatch prompt starts with `Active task: ` before role-specific instructions. On Grok Build, use `spawn_subagent` with `subagent_type` set to the Trellis agent name (e.g. `trellis-implement`). On Kimi Code, dispatch the built-in `coder` / `explore` sub-agent with the matching `.kimi-code/skills/trellis-/SKILL.md` instructions. [workflow-state:in_progress] Tools: `trellis-implement` / `trellis-research` are sub-agent types only (Task/Agent tool, NOT Skill; there is no skill by these names). `trellis-update-spec` is a skill. `trellis-check` exists as both; prefer the Agent form when verifying after code changes. @@ -272,13 +272,13 @@ Code committed. Run `/trellis:finish-work`; if dirty, return to Phase 3.4 first. When a user request matches one of these intents inside an active task, route first, then load the detailed phase step if needed. -[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] - Planning or unclear requirements -> `trellis-brainstorm`. - `in_progress` implementation/check -> dispatch `trellis-implement` / `trellis-check`. - Repeated debugging -> `trellis-break-loop`; spec updates -> `trellis-update-spec`. -[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] [codex-inline, Kilo, Antigravity, Devin] @@ -353,7 +353,7 @@ Return to this step whenever requirements change and revise the relevant artifac Research can happen at any time during requirement exploration. It isn't limited to local code — you can use any available tool (MCP servers, skills, web search, etc.) to look up external information, including third-party library docs, industry practices, API references, etc. -[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] Spawn the research sub-agent: @@ -361,11 +361,11 @@ Spawn the research sub-agent: - **Task description**: Research - **Key requirement**: Research output MUST be persisted to `{TASK_DIR}/research/` -[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] [codex-inline, Kilo, Antigravity, Devin] -Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. (For `codex-inline` this avoids the `fork_turns="none"` isolation that prevents `trellis-research` sub-agents from resolving the active task path.) +Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. `codex-inline` is the explicit mode that keeps work in the main session. [/codex-inline, Kilo, Antigravity, Devin] @@ -380,7 +380,7 @@ Brainstorm and research can interleave freely — pause to research a technical #### 1.3 Configure context `[required · once]` -[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the right spec/research context. These files were seeded on `task create` with a single self-describing `_example` line; your job here is to fill in real entries. @@ -425,7 +425,7 @@ Ready gate: both `implement.jsonl` and `check.jsonl` must contain at least one r Skip this step only when both files already have real curated entries. -[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] [codex-inline, Kilo, Antigravity, Devin] @@ -458,11 +458,11 @@ If `task.py start` errors with a session-identity message (no context key from h | `design.md` exists (complex tasks) | ✅ | | `implement.md` exists (complex tasks) | ✅ | -[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] | `implement.jsonl` and `check.jsonl` each contain at least one real curated entry (seed row does not count) | ✅ | -[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] --- @@ -472,21 +472,22 @@ Goal: turn reviewed planning artifacts into code that passes quality checks. #### 2.1 Implement `[required · repeatable]` -[Claude Code, Cursor, OpenCode, CodeBuddy, Droid, Pi, Oh My Pi] +[Claude Code, Cursor, OpenCode, codex-sub-agent, CodeBuddy, Droid, Pi, ZCode, Snow, Oh My Pi] Spawn the implement sub-agent: - **Agent type**: `trellis-implement` - **Task description**: Implement the reviewed task artifacts, consulting materials under `{TASK_DIR}/research/`; finish by running project lint and type-check -- **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`. +- **Dispatch prompt guard**: The prompt MUST start with `Active task: `, then tell the spawned agent it is already the `trellis-implement` sub-agent and must implement directly, not spawn another `trellis-implement` / `trellis-check`. The platform hook/plugin auto-handles: - Reads `implement.jsonl` and injects referenced spec/research files into the agent prompt - Injects `prd.md`, `design.md` if present, and `implement.md` if present +- For Codex, `SubagentStart` supplies native context injection; the agent profile keeps child-side loading as the fallback -[/Claude Code, Cursor, OpenCode, CodeBuddy, Droid, Pi, Oh My Pi] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, CodeBuddy, Droid, Pi, ZCode, Snow, Oh My Pi] -[codex-sub-agent, Gemini, Qoder, Copilot, ZCode, Reasonix, Trae] +[Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code] Spawn the implement sub-agent: @@ -498,7 +499,7 @@ The pull-based sub-agent definition auto-handles the context load requirement: - Resolves the active task with `task.py current --source`, then reads `prd.md`, `design.md` if present, and `implement.md` if present - Reads `implement.jsonl` and requires the agent to load each referenced spec/research file before coding -[/codex-sub-agent, Gemini, Qoder, Copilot, ZCode, Reasonix, Trae] +[/Gemini, Qoder, Copilot, Reasonix, Trae, Grok, Kimi Code] [Kiro] @@ -526,13 +527,13 @@ The platform prelude auto-handles the context load requirement: #### 2.2 Quality check `[required · repeatable]` -[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] Spawn the check sub-agent: - **Agent type**: `trellis-check` - **Task description**: Review all code changes against specs and task artifacts; fix any findings directly; ensure lint and type-check pass -- **Dispatch prompt guard**: Tell the spawned agent it is already the `trellis-check` sub-agent and must review/fix directly, not spawn another `trellis-check` / `trellis-implement`. +- **Dispatch prompt guard**: The prompt MUST start with `Active task: `, then tell the spawned agent it is already the `trellis-check` sub-agent and must review/fix directly, not spawn another `trellis-check` / `trellis-implement`. The check agent's job: - Review code changes against specs @@ -540,7 +541,7 @@ The check agent's job: - Auto-fix issues it finds - Run lint and typecheck to verify -[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Reasonix, Trae] +[/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi, Oh My Pi, ZCode, Snow, Reasonix, Trae, Grok, Kimi Code] [codex-inline, Kilo, Antigravity, Devin] diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cce023..9fec2fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,21 @@ 格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/)(版本段不记日期),版本号遵循语义化版本。 +## [0.8.3] + +### Added + +- 登录页新增通行密钥与 Web3 钱包免密登录;设置 · 安全重构为密码登录、免密登录、登录方式配置与活跃会话分区,支持管理通行密钥、绑定钱包,并查看及定点撤销其他设备会话 + +### Changed + +- 全面统一按钮变体与按下态,删除、停用、实例电源操作等写操作统一补齐二次确认、加载态和防重复触发;相同写请求在飞行期复用同一结果 +- IAM 用户新建 API Key 后均可切换为面板签名凭据,切换到其他用户时明确提示权限变化并同步刷新签名用户状态 + +### Fixed + +- 修复敏感操作换发新令牌后,迟到的旧请求 401 可能清除当前新会话;现在仅当失败请求使用的仍是当前令牌时才退出登录 + ## [0.8.2] ### Added diff --git a/package-lock.json b/package-lock.json index 72de8fc..0669ad0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "oci-portal-dash", - "version": "0.8.2", + "version": "0.8.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "oci-portal-dash", - "version": "0.8.2", + "version": "0.8.3", "dependencies": { "@codemirror/lang-css": "^6.3.1", "@codemirror/lang-go": "^6.0.1", diff --git a/package.json b/package.json index b9a17a9..ddd52f3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "oci-portal-dash", "private": true, - "version": "0.8.2", + "version": "0.8.3", "type": "module", "scripts": { "dev": "vite",