跳转至

2026-04-26 周报

自然周:2026-04-20 至 2026-04-26

本周主线

这一周的第一条主线是“公开客户端如何安全接入身份与后端能力”。Vite 环境变量、Supabase anon/publishable key、OAuth Device Flow、OAuth 回跳、外部身份映射与 GitHub Actions OIDC 都在拆同一个问题:哪些凭据可以公开,哪些身份断言真正用于授权,浏览器、CLI、数据库和云厂商之间靠什么锚点建立信任。

第二条主线继续深入 Claude Code 与 agent harness 的运行机制:配置来源、权限模式、推理 effort、模型别名、hooks 注册、skill 参数解析、SKILL.md 拼接与 @ 附件解析。这些素材把“命令行参数、配置文件、环境变量、skill 文本、hook 脚本”都放回同一个上下文注入和执行控制系统里理解。

第三条主线是前端工程的“声明式表面与运行时真实行为”分离。Tailwind v4 的 @theme、TypeScript shim、micro-app CSS 隔离、React Context/Fiber、Vercel AI SDK 都说明:配置、类型、CSS、JSX 和流式消息只是描述层,真正决定行为的是构建器、运行时代码、Fiber 工作循环、DOM 注入位置和 SDK 的工具循环。

第四条主线是工具链与本机环境的工程化细节:MCP 配置管理、Superpowers 的 specs/plans 分层、iTerm2 Hotkey Window 和目录继承、jenv、Keychain、IntelliJ 插件 CI/CD、飞书画板 DSL。这些不是孤立技巧,而是在处理“配置从哪里来、状态由谁持有、自动化边界在哪里”。

主题一:公开客户端、OAuth 与身份锚点

核心脉络

  • 问题起点:最初从 Vite 环境变量与 Supabase OAuth 接入切入,问题集中在前端能看到哪些变量、anon key 是否安全、OAuth 回跳和外部身份怎样最终落到数据库权限判断上。
  • 推进关系:随后把 GitHub OAuth Device Flow 与 GitHub Actions OIDC 放进同一视角:CLI 和 CI 都不能依赖长期 secret,而是通过用户确认、短期 code、短期 JWT、Discovery 和公钥验签建立信任。
  • 最终判断:公开客户端不是没有安全模型,而是安全边界不在“隐藏客户端字符串”。前端/CLI 可持有公开标识或低权限 key,真正的授权依赖用户登录后的 token、RLS policy、state 关联、短期凭据和服务端/云厂商验签。

沉淀认知

  • Vite envDirenvDir 会改变 Vite .env 文件查找目录,并影响 import.meta.env 与运行时注入;单独 loadEnv(mode, dir) 只让 vite.config.ts 读到变量,不会让整个 Vite 运行时改用同一目录。
  • 前端变量:浏览器侧应使用 import.meta.env,并且只有 VITE_ 前缀变量会被可靠暴露;把服务端 secret 放进 Vite 前端变量,本质上等于公开。
  • Supabase key:Supabase anon/publishable key 是公开客户端的项目访问凭证,不是用户认证凭证;数据安全边界在用户 JWT 与数据库 RLS policy,RLS 不正确时 anon key 本身无法提供实质保护。
  • Supabase 身份映射:外部 IdP 的身份通常先进入 auth.identities,再关联到 auth.users;数据库里的 auth.uid() 对应 Supabase 内部 user id,而不是外部 IdP token 的原始 sub
  • OAuth 回跳redirect_uri 是外部 IdP 回到 Supabase callback 的协议层地址,redirect_to 是 Supabase 最后送回前端的目标;稳定关联锚点是 state,不是回跳 URL 字符串本身。
  • SPA session:纯前端 SPA 不靠 Supabase callback 域名给业务站点跨域种 cookie,而是在浏览器回到业务站点后由 supabase-js 读取授权结果并恢复 session,默认持久化到当前站点的 localStorage。
  • Device Flow:GitHub OAuth Device Flow 适合 CLI/终端这类无法可靠承接浏览器 callback 的 public client;安全锚点是 GitHub 官方页面上的用户登录与手动授权,而不是客户端持有 secret。
  • OIDC for CI:GitHub Actions OIDC 通过短期 JWT、OIDC Discovery、JWKS 公钥验签和云厂商临时凭据替代长期 secret;iss 在 OIDC 中既是发行者标识,也是 Discovery 端点的 base URL。

适用边界

这组认知适合设计 SPA 登录、Supabase RLS、CLI 授权和 CI 云厂商认证。不要把“客户端可见”直接等同于“不安全”,也不要把公开 key 当成权限边界;真正需要检查的是 token 的签发方、受众、有效期、state 绑定、RLS policy 和服务端是否错误信任前端可伪造输入。

来源

  • 2026-04-20:Vite envDir 与 loadEnv 的关系
  • 2026-04-20:GitHub OAuth Device Flow
  • 2026-04-20:Supabase OAuth 与前端环境变量
  • 2026-04-20:Supabase anon key
  • 2026-04-20:Supabase 外部身份映射与 OAuth 回跳
  • 2026-04-25:GitHub Actions OIDC 认证机制

主题二:Claude Code 配置、Skill 与执行控制

核心脉络

  • 问题起点:这一组问题围绕 Claude Code 的启动参数、权限跳过、推理关键词、模型选择、hooks 注册和 skill 执行,核心是搞清楚用户输入和配置如何进入运行时。
  • 推进关系:先从 --settings--setting-sources、权限模式和 alias 这些 CLI 层切入,再深入到 model alias、1M context、small fast model、hook stdin JSON、skill 参数替换、SKILL.md 二次解析与 newMessages 注入。
  • 最终判断:Claude Code 的行为由多层配置合并和多条上下文注入通道共同决定。排查时不能只看某个文件或某个命令行参数,而要按优先级、来源、是否实际非空、是否被强制保留、最终注入到 API 的消息形态逐层确认。

沉淀认知

  • 配置层级--settings 不会替换默认 ~/.claude/settings.json,而是作为 flagSettings 加入合并链,优先级高于 user/project/local;--setting-sources 只控制 user、project、local 文件来源,不能移除 flagSettingspolicySettings
  • 来源显示:状态页里的 Setting sources 显示的是实际读取到且内容非空的来源,不是命令行允许来源列表;project.claude/settings.json.claude/settings.local.json 属于 local
  • 权限模式--dangerously-skip-permissions 适合受信任沙箱里的高速迭代;更细粒度的 --permission-mode 可在 acceptEdits、auto、bypassPermissions、default、dontAsk、plan 等模式间选择。
  • 推理 effort:Claude Code 客户端硬编码识别 ultrathink,触发后注入高推理 effort 的系统消息并设置 effort 参数;其他“think harder”类提示更多依赖模型关联,不是客户端机制。
  • 模型抽象:Claude Code 把模型选择拆成“能力别名映射”和“使用场景覆盖”。ANTHROPIC_MODEL 控制主对话,CLAUDE_CODE_SUBAGENT_MODEL 覆盖子 Agent,ANTHROPIC_SMALL_FAST_MODEL 服务后台轻任务。
  • 1M context:1M context 通过模型名后缀 [1m] 触发,发 API 前再剥离后缀;它不是独立 model ID,可由 CLAUDE_CODE_DISABLE_1M_CONTEXT=true 禁用。
  • Hooks 注册:hook 脚本放在 hooks 目录并不会自动生效,必须在 settings 的 hooks 字段声明触发时机、matcher 和 command;脚本通过 stdin 接收完整工具调用 JSON。
  • Skill 参数/skill-name args 只按第一个空格切出原始 args;参数替换按命名、索引、简写、全量、兜底追加逐级处理,确保 SKILL.md 不写占位符时参数也不会丢。
  • SKILL.md 注入:SKILL.md 会先经过参数替换、变量展开、内联 shell 执行和 @ 附件解析,再以 isMeta:true 消息或 SkillTool newMessages 进入对话;UI 隐藏不等于模型不可见。

适用边界

这组认知适合排查 Claude Code 行为漂移、配置不生效、skill 参数丢失、模型选择异常和 hook 未触发。涉及 --dangerously-skip-permissions 时只应在受信任沙箱里使用;涉及模型别名和版本支持时要回到当前源码或官方配置确认,因为默认模型和可用别名会随版本变化。

来源

  • 2026-04-21:Claude Code 配置来源与启动参数
  • 2026-04-22:Claude CLI 权限跳过与别名技巧
  • 2026-04-22:Claude Code 推理关键词机制
  • 2026-04-23:Claude Code Skill 参数解析与提交流程
  • 2026-04-24:Claude Code 模型环境变量设计
  • 2026-04-24:Claude Code 模型配置体系
  • 2026-04-24:Claude Code Hooks 注册机制
  • 2026-04-26:Skill 工具 SKILL.md 拼接与 @ 引用机制

主题三:前端声明、类型与运行时机制

核心脉络

  • 问题起点:前端相关素材分别来自 TypeScript 类型错配、Tailwind v4 主题机制、micro-app CSS 隔离、React Context/Fiber 和 Vercel AI SDK Agent,看似横跨构建、样式、运行时和 AI UI。
  • 推进关系:这些问题都要求先区分“声明层看到什么”和“运行时实际发生什么”:.d.ts 不等于组件真实行为,@theme 是 token 注册而不是普通 CSS,CSS 注入位置影响 micro-app 能否补前缀,JSX 只是描述对象,AI SDK 的 ReAct 循环由 SDK 驱动。
  • 最终判断:前端工程排障不能只看表面语法。要确认类型声明、构建器、CSS 作用域、DOM 注入、Fiber 工作循环和 SDK 回调边界各自在哪一层生效。

沉淀认知

  • 类型 shim:当三方组件运行时实际接受 string,但 .d.ts 声明成对象类型时,本地 shim 是在修正错误声明;前提是先核对运行时代码,确认不是业务模型传错。
  • Tailwind v4 入口@import "tailwindcss"; 是 Tailwind v4 的框架入口;没有它,@theme@layer@apply 和工具类生成都不会正常生效。
  • @theme 语义@theme 是设计 token 注册区,不是普通样式块;只有 --color-*--spacing-*--breakpoint-* 等命名空间变量会转成可用工具类或变体。
  • v3 到 v4 映射:Tailwind v3 的 theme.extend.colors.background = "var(--background)" 对应 v4 的 --color-background: var(--background);迁移的是设计 token,不是整个 tailwind.config.js
  • micro-app CSS:micro-app 的前缀隔离主要处理可感知的静态或容器内样式;antd 5 CSS-in-JS 直接向 document.head 动态注入时会绕过隔离,需要把 StyleProvider container 指到子应用容器,让 MutationObserver 有机会补前缀并随卸载清理。
  • CSS 作用域<style> 放在 <head><body> 不会天然改变 CSS 作用域;关键是插入位置是否被隔离框架拦截和改写。
  • Context 读取:React Context 的 Provider 是 reconciler 识别的特殊对象,Provider fiber 在 beginWork 时 push 新值、completeWork 时 pop 旧值;useContext 读取当前 _currentValue,不是每次沿组件树向上查找。
  • Fiber 遍历:Fiber 用 return/child/sibling 指针构成可中断遍历结构,beginWork/completeWork 的循环替代了 React 15 递归渲染,为时间切片和优先级调度提供基础。
  • AI SDK Agent:Vercel AI SDK 通过 maxSteps 内置 ReAct 循环,工具调用、结果回传和流式输出由 SDK 串联;落库和审计放在 onStepFinish/onFinish,前端按 message.parts 的 type 渲染结构化流。

适用边界

这组认知适合前端类型兼容、Tailwind v4 迁移、微前端样式隔离、React Context 性能理解和 AI SDK 单 Agent 应用。不要用 shim 掩盖未经核验的运行时问题;也不要把 AI SDK 当作完整多 Agent 编排框架,它主要覆盖单 Agent、工具调用和流式 UI。

来源

  • 2026-04-21:TypeScript shim 与三方组件类型错配
  • 2026-04-21:Tailwind v4 的 @theme 机制
  • 2026-04-21:Tailwind v3 与 v4 的主题配置映射
  • 2026-04-22:micro-app CSS 隔离机制
  • 2026-04-22:React Context 与 Fiber 原理
  • 2026-04-22:React Context 入栈出栈机制
  • 2026-04-24:Vercel AI SDK Agent 架构

主题四:工具链配置、工作流与本机自动化边界

核心脉络

  • 问题起点:这一组素材集中在 MCP 管理、Superpowers 的 specs/plans、iTerm2 行为、jenv、IntelliJ 插件 CI/CD、Keychain 和飞书画板 DSL,都是工具链在本机或 CI 中如何可靠运行的问题。
  • 推进关系:MCP 和 Superpowers 解决“多工具配置与执行文档如何组织”;iTerm2 和 jenv 解决“本机会话状态如何继承”;CI/CD、Keychain 和 OIDC 解决“自动化凭据和版本事实源怎么处理”;飞书画板 DSL 则展示“声明式布局如何转成平台 OpenAPI”。
  • 最终判断:工程工具链的稳定性来自单一事实源、显式配置、受控状态继承和边界清楚的自动化。越是看起来像小技巧,越需要确认它依赖的是文件、环境变量、系统服务、CI 事件还是外部 OpenAPI。

沉淀认知

  • MCP 管理:Claude Code 的 MCP 配置在 ~/.claude.json 或项目 .mcp.json,Codex 的 MCP 配置在 codex-settings.toml[mcp_servers.*];跨工具管理的难点正是 JSON/TOML 与作用域差异。
  • Skill 管理差异:Claude Code 的 skills 没有独立 CLI,主要通过 ~/.claude/skills/ 文件系统和会话内交互使用;这与 MCP 已有 add-mcp、mcpm、AI Orbiter 等管理工具形成对比。
  • Specs 与 Plans:Superpowers 的 specs/ 是“做什么+为什么”的设计文档,plans/ 是“怎么做”的 checkbox 执行清单;两者把 brainstorming、planning 和 execution 的产物分层,减少设计讨论与执行任务互相污染。
  • iTerm2 Space:Hotkey Window 跳 Space 往往是 macOS 绑定最后使用 Space 导致;Floating Window、All Spaces、Screen with Cursor 和避免 Native Full Screen 可降低切换问题。
  • iTerm2 目录继承:新 Tab 是独立会话,不自动继承当前 Window 的起始目录;需要 Profile 的 Working Directory 设为 Reuse previous session's directory。
  • jenv 作用域:jenv 版本优先级应理解为 shell 会话、用户级和项目级的叠加;在 Makefile 中用 $(shell jenv javahome) 可在解析阶段读取当前项目 .java-version,绕过 JAVA_HOME 未刷新问题。
  • 插件 CI/CD:JetBrains 插件签名 DSL 字段以 Gradle task 源码为准;tag 驱动版本时让 CI 从 tag 注入 PLUGIN_VERSION,本地回退 dev 版本,避免多处维护版本号。
  • Keychain 边界:Keychain 能防跨用户访问和未授权进程静默读取,但同用户恶意进程可调用已授权二进制如 git-credential-osxkeychain 间接取凭据;这是本地凭据存储的现实权衡。
  • 飞书画板 DSL:飞书画板 DSL 是声明式布局,whiteboard-cli 用 Yoga 做布局计算并转成带精确坐标的 OpenAPI JSON;服务端接收的是算好坐标的节点,不负责理解 DSL。

适用边界

这组认知适合整理多 AI 工具配置、本机终端工作流、Java 版本管理、插件发布和飞书画板自动化。不要把工具 UI 上的状态当作唯一事实源;需要追到配置文件、CI event、系统 ACL、OpenAPI payload 或 CLI 编译产物。

来源

  • 2026-04-21:飞书画板 DSL + OpenAPI + Yoga 引擎原理
  • 2026-04-23:MCP 生态管理工具
  • 2026-04-23:iTerm2 Hotkey Window 跨 Space 行为
  • 2026-04-23:Superpowers 工作流:specs 与 plans 的语义分层
  • 2026-04-23:iTerm2 标签页目录继承
  • 2026-04-25:jenv 版本管理机制
  • 2026-04-25:IntelliJ 插件 CI/CD 工程实践
  • 2026-04-25:macOS Keychain 安全模型

其他杂项

修正报告

  • 污染日志清洗2026-04-21 的“Claude Code 配置来源与启动参数”中混入了大量 shell 环境变量和 zsh 参数输出,属于记录过程污染,不是有效 insight。周报只保留其中可恢复的 4 条结论:--settings 作为 flagSettings 加入合并链、--setting-sources 只控制 user/project/local、状态页只显示实际读取且非空的 source、projectlocal 分别对应 .claude/settings.json.claude/settings.local.json。涉及来源:2026-04-21:Claude Code 配置来源与启动参数。
  • jenv 优先级表述:日报写成“项目级 > 用户级 > Shell 级”容易误导。修正后应理解为:当前 shell 会话显式选择通常优先于目录/项目文件,项目 .java-version 又优先于用户级默认;但在 Makefile 或非交互环境中,实际生效结果取决于 jenv 初始化、当前目录和环境变量是否刷新。涉及来源:2026-04-25:jenv 版本管理机制。