news 2026/10/27 9:40:03

ThinkRail 产品目标与范围详解:围绕 pi 构建的 Agentic IDE 与它的六条架构铁律

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ThinkRail 产品目标与范围详解:围绕 pi 构建的 Agentic IDE 与它的六条架构铁律

【免费下载链接】thinkrail

Vibe code with pi in a lightweight, real IDE that customises itself around the way you work — The Vibe You Need

项目地址:https://gitcode.com/GitHub_Trending/th/thinkrail
点击查看免费下载

ThinkRail 把pi编码 agent 包进一个真正的 IDE 里:用 git worktree 隔离并行工作、用可维护的 spec 图谱承载项目意图、用「只暴露不重算」的宿主桥接 pi 的全部状态。本文以仓库根目录的 goal-and-requirements.md 为主线,逐节拆解这份产品目标与范围文档的定义,并用源码、契约与规格文件为每一条主张补上实现证据,帮助你既看懂「产品为什么这样设计」,也能定位到「代码里在哪兑现」。

一、这份文档是什么,以及它为什么不是路线图

goal-and-requirements.md 的 frontmatter 就把自己的定位写死了:

id: goal-and-requirements type: goal-and-requirements status: active title: ThinkRail — product goal and scope covers: [product-goal, product-audience, product-principles, product-capabilities, product-non-goals, engine-decision] tags: [product, scope]

covers字段列出了它负责的六个主题:产品目标、目标用户、产品原则、产品能力、非目标、引擎决策。文档正文明确写道:「This document describes the product as it is and why it exists, and changes with it: a capability that lands is added here, a decision that changes is rewritten here.It holds no versions or roadmap.」——它描述的是当下事实与理由,不承载版本号和路线图。能力落地就增补,决策变更就改写。

这一点决定了阅读方式。仓库根目录的 AGENTS.md 给出一份「按比例读取上下文」的规则:

文档负责回答的问题
goal-and-requirements.md产品目标、原则、能力、非目标
architecture.md系统拓扑、跨模块决策、全仓不变量
pi-compatibility.mdpi 升级与宿主适配、移除门槛
各模块SPEC.md该模块边界、公共接口、允许/禁止依赖

也就是说,产品意图在本文件,结构约束在架构文件,实现细节在下沉规格。文档里大量出现[[submodule-server-workspaces]]这类双链,含义是「细节由那份 spec 拥有」。本文在引用时已把它们映射为仓库相对路径。

二、Goal:一句话里藏着四个机制

原文档的目标段落只有一句话,但信息密度很高:

ThinkRail is the agentic IDE that gets better every time you use it. It is a thin host that runspiand bridges it to a rich UI, isolates work into separate workspaces, and gives the agent durable project knowledge through living specs and reusable skills — so agent work is approachable without a terminal and stays isolated, reviewable, and grounded in specs: building with agents without losing control.

把它拆开,是四个可验证的机制:

  1. thin host(薄宿主):宿主只做进程内引擎托管、状态持久化与线协议服务,不做第二个 agent 循环。architecture.md 用「三个环」定义这件事。
  2. isolates work into separate workspaces(工作区隔离):工作区是 git worktree,有自己的分支与 cwd。
  3. durable project knowledge(耐久项目知识):living specs + 可复用 skills,二者都由pi直接读写。
  4. reviewable / grounded(可评审、有据可依):评审面与 spec 共同构成「人还能控制」的抓手。

「gets better every time you use it」不是营销口号,而是与 spec-first 联动的机制描述:项目意图写在代码旁边的 spec 图谱里,agent 读它、搜它、维护它,于是下一轮会话不必重新推导(原文档 Problem 一节的 "Intent evaporates")。

三、Problem:三个痛点,三种代码级解法

原文档把痛点归为三条,每一条在仓库里都有对称的实现:

3.1 并行 agent 在同一工作树里相撞

Parallel agents collidein one working tree — with each other and with the user's own edits.

解法是默认隔离。packages/server/src/workspaces/SPEC.md 规定:工作区是数据目录下dataDir/worktrees/<project-slug>/<branch>的git worktree,createWorkspace使用git worktree add -b分支创建,并且强制--no-track。后者的理由写在 spec 里:若基线是远程跟踪分支,git 的autoSetupMerge默认会把上游设成基线分支,导致工作区终端里的git push/git pull指向错误目标。新分支的上游属于用户首次 push 时自己设定,不属于工具。

3.2 CLI 里评审 agent 改动很笨拙

Agent changes are hard to reviewfrom a CLI: reading diffs, commenting on exact lines, and handing that feedback back to the agent.

解法是把评审做成宿主侧一等公民。packages/server/src/reviews/SPEC.md 描述:每个工作区有一份开放的 Review,评论锚定在文件与 diff 上,可以在不启动 agent 的情况下收集,然后以结构化上下文包的形式发送到一个或多个 chat;锚点重定位与包渲染都由宿主负责。行锚通过contracts的ReviewSelector(lineRange/textQuote/structural如json-pointer、table-cell、ipynb-cell/region几何)表达,见 architecture.md 决策 19。

3.3 意图会蒸发

Intent evaporates.Decisions made in a chat end with the session; the next one re-derives or contradicts them.

解法是 spec 图谱:packages/spec-graph/SPEC.md 提供spec_*工具集与配套 skill,agent 用它读取、检索、维护SPEC.md之间的连接图。宿主侧读模型见 packages/server/src/spec/SPEC.md。

四、Who it's for:三类用户,一条共同的底线

原文档点了三类人:想在真实 git 仓库上与pi协作的新手(需要可视化入口)、不想放弃 pi 深度的老手(需要在 agent 周围有 IDE)、以及agent-first 构建者(要快,但不能失去对 agent 行为的掌控)。

这条描述对应一个产品判断:功能不是给「不需要 agent 的人」或者「不需要 IDE 的人」做的。它因此也解释了两处看起来「反直觉」的设计选择——Default 工作区把「直接在项目目录里干活」保留为显式选择(给被 worktree 模型绕晕的人一个锚),而 MCP 与仓库资源默认关闭直到用户授权(给不想被克隆仓库注入代码的人一条边界)。

五、Value:四条支柱及其源码落点

原文档的 Value 部分有四条,是全文的技术核心。

5.1 Isolation by default

A workspace ThinkRail creates is a git worktree with its own branch and cwd: agents run in parallel and the main branch stays clean until the user merges. Working directly in the project folder (the Default workspace) is an explicit choice, never the default.

契约里的Workspace结构把这件事落到了字段级,见 packages/contracts/src/domain.ts:

export interface Workspace { id: string; projectId: string; kind?: "default" | "external"; name: string; branch: string; worktreePath: string; baseBranch: string; diffBase?: string; renamed?: boolean; initialTerminalPending?: true; diffStats?: DiffStats; skillOverrides?: Record<string, "on" | "off">; subagentsOverride?: SubagentOverride; subagentMaxConcurrentOverride?: number; lastActiveAt?: number; settledOverride?: SettledOverride; settledAt?: number; review?: OpenBranchReview; }

几个关键语义(均可回溯到 packages/server/src/workspaces/SPEC.md):

  • kind标记两类「用户所有」工作区。"default":每个项目恰好一个内建 Default 工作区,worktreePath就是项目文件夹本身(git 的 main working tree),不可删除、不可重命名,只能从项目 Welcome 页显式「Work in project folder」进入。"external":用户显式就地附加的既有 worktree,ThinkRail 可以「忘记」它,但永不修改它。
  • baseBranch与diffBase是两个字段,不是两个名字。baseBranch是创建溯源(分支从哪切出来,之后不再移动);diffBase是「评审以何为基准」,可以重指向。合并它们会让重指向后的证据撒谎。
  • name与branch解耦。名称是人类可读标签(保留大小写与标点,可以是任意文字),分支是 kebab slug;自动命名workspace-N时二者相同。
  • 工作区目录永不搬家。用set_title带来的分支重命名走git branch -m,但 worktree 目录保持原路径——因为 pi 按该 cwd 精确索引会话与终端标签页。

Default 工作区的「零写入」纪律值得单列:listWorkspaces会确保Default 存在(这是文档中明确承认的一处 CQS 例外:查询会写应用注册表并发出生命周期事件,但只写数据目录下的workspaces.json,绝不写入用户仓库);ensureWorkspaceScratchDir只在会话真正创建时调用,在 Default 工作区里它拒绝符号链接路径分量、.gitignore用独占创建且只在文件不存在时写——因为它面对的是仓库可控的内容。

5.2 A real IDE around the agent

Editor, diffs, terminals, and review in one workbench, so the user sees and steers the agent's work instead of reconstructing it from a scrollback.

结构上是「三个环」,见 architecture.md:

  • 引擎宿主:packages/server+packages/shared,由apps/cli或apps/desktop以本地宿主模式启动;拥有pi、会话状态、持久化,并提供线端点。
  • 线协议(the wire):packages/contracts,类型 + 无依赖运行时;是客户端与宿主之间的唯一耦合。
  • UI 客户端:apps/web,mobile-first 的 React 客户端,可独立作为静态资源发布。

解析这条依赖图的一行就够:

apps/web ── depends on ─▶ packages/contracts, packages/locales, packages/ui, packages/extension-api/web, packages/resource-renderers, thinkrail-extensions/*/web

永远不依赖server或shared。这条规则由bun run check:boundaries强制(scripts/check-module-boundaries.ts)。

终端的选择也有明确取舍:浏览器终端是@xterm/xterm+ DOM 渲染器,不是addon-webgl;理由与替换门槛写在 architecture.md 决策 11。

5.3 Specs as ground truth

The project's intent lives in a spec graph beside the code that the agent reads, searches, and maintains, so intent survives the session.

agent 面对的是一组以spec_为前缀的工具,注册入口见 packages/spec-graph/tools/index.ts:

export function registerSpecTools(pi: ExtensionAPI): void { registerSpecGrep(pi); registerSpecGet(pi); registerSpecGraph(pi); registerSpecCreate(pi); registerSpecUpdate(pi); registerSpecDelete(pi); registerSpecValidate(pi); }

对应工具名分别为spec_grep、spec_get、spec_graph、spec_create、spec_update、spec_delete、spec_validate(见各文件内的name:声明,例如 packages/spec-graph/tools/grep.ts)。UI 侧另有一个只读的 Specs 工具把图谱渲染成树。

工作区里还有一个易被忽略的约定:每个工作区有一个短暂的临时目录WORKSPACE_CONTEXT_DIR,定义为.thinkrail/context(见 packages/shared/src/paths.ts),内含一条自忽略的*.gitignore,零 git 足迹。它是任务草稿与工作文件的落脚点,仍可被 spec 工具扫描到。注意别与全局数据目录~/.thinkrail混淆——前者在仓库内且不入库,后者是应用状态。

5.4 All of pi, nothing hidden

Models, skills, extensions, and session state stay pi's; ThinkRail adds a surface, not a second agent.

三条不变量支撑这条价值(architecture.md):

  • agent 进程内运行,没有崩溃隔离:会话调用要包错误处理并把错误转发出去;一个致命故障会带走整个宿主。这是与「子进程 RPC 模式」对比后被接受的代价。
  • pi拥有状态并发出真相:宿主通过读方法暴露pi 的状态,不重算;把 pi 的事件作为增量转发。
  • 客户端先 hydrate 再 stream:见决策 8(architecture.md),客户端从不依赖「见证过事件」来得知领域状态——连上时先project.list/workspace.list/session.list/session.getMessages读,再订阅pi.event。

这也解释了AppConfig里为什么有一长串「以 pi 为常量」的配置项,而不是宿主自造的副本(packages/contracts/src/domain.ts):defaultModel、defaultEffort、reviewModel、recentModels、subagentMaxConcurrent、disabledExtensions、locale……它们要么直接喂给 pi,要么只影响宿主呈现。

六、Principles:六条耐久决策

原文档的 Principles 一节自称「Durable decisions every feature follows」,并指向 architecture.md 承载强制执行结构。六条逐条对应实现:

原则原文要点实现体现
pi 是唯一引擎进程内运行,无第二运行时(无claude-agent-sdk)createAgentSession(packages/server/src/agent/agentSessionManager.ts)
通过「喂」影响,而非「拼装」功能只通过 prompt 上下文、文件、pi 自身 skills/extensions 与会话启动 flag 影响 agent例:workflow 规则注入systemPromptOptions.sections
暴露,不重算宿主展示 pi 报告的内容token/成本、agent_settled转换、模型目录
用户自己的工具与凭据git / GitHub / 模型访问走用户的git、gh、centralCLI 与 pi 的 provider auth无内置账号,Open PR 走gh并有 compare URL 回退
信任必须显式克隆仓库可注入的东西按项目授予后才加载;仓库定义的 MCP server 还需逐条审批setProjectTrust+mcpApprovals指纹
spec-firstThinkRail 自身以 spec 先行;也帮助打开的项目这样工作每模块SPEC.md+check:spec-surface

6.1 「喂进去」而不是「组装」:一个具体例子

packages/pi-thinkrail-workflow/index.ts 全文很短,却精准示范了这条原则:

export const WORKFLOW_SECTION = "pi-thinkrail-workflow"; export const WORKFLOW_RULE = [ "At the start of a new piece of work, read the choosing-a-workflow skill before any other tool call for project onboarding, PR lifecycle work (including checking a PR's CI), or any change to what the product does — a feature, a behavior change, or a bug fix, however small.", "Non-PR questions, explanations, and checks, and edits that change no behavior (typos, documentation or configuration only, mechanical refactors), proceed directly without loading or announcing a workflow.", "Continue work already routed to a workflow without routing it again.", ].join("\n"); const factory: ExtensionFactory = (pi: ExtensionAPI) => { pi.on("before_agent_start", (event) => { event.systemPromptOptions.sections[WORKFLOW_SECTION] = WORKFLOW_RULE; }); };

它没有自建路由逻辑、没有旁路分类器、没有第二套 prompt 组装器——只是把一段文本放进 pi 的 system prompt 分节,让 pi 自己的加载机制去决策。这就是「Influence by feeding, never by assembling」。

6.2 信任是显式的:两级授权

原文档把可被克隆仓库注入的东西列得很具体:仓库提交的 skill 别名、pi 自己的项目资源(.pi/下的 settings、extensions、skills、prompts、subagent definitions)、以及它定义的 MCP servers。实现上这是两级授权(packages/server/src/projects/projects.ts):

export function setProjectTrust( id: string, trusted: boolean, acknowledgedSkills?: string[], options: { resources?: boolean } = {}, ): Project { const projects = getProjects(); const project = projects.find((p) => p.id === id); if (!project) throw new Error(`Unknown project: ${id}`); project.trusted = trusted; if (!trusted) project.piResourceTrust = "untrusted"; else if (options.resources === true) project.piResourceTrust = "granted"; if (acknowledgedSkills !== undefined) project.acknowledgedSkills = acknowledgedSkills; saveProjects(projects); emit(project); return project; }

要点:

  • 两个授权分开:trusted管 skill 别名;piResourceTrust管 pi 的.pi/资源(其中包含可执行代码:extensions 与 settings 包),因此只有明确点名它们的界面才能申请。
  • trusted: false一并撤销两个授权;trusted: true只在resources: true时提升 pi 级信任。
  • 没有祖父条款:记录若早于该字段出现,按 untrusted 处理。
  • MCP 另算:仓库定义的 server 需要逐条审批,审批以「整个原始条目的指纹」为凭据(approveProjectMcpServer(id, name, fingerprint)),条目一改指纹就失配,审批自动失效。指纹覆盖整个条目对象、忽略无关键顺序、但保留toolExposure顺序语义(见 packages/server/src/agent/mcp/config.test.ts)。
  • 「Always allow」的工具授权存在项目记录里,不在仓库里,因此不可能随仓库「预授权」发出。

七、Capabilities:能力清单与代码路径

原文档的 Capabilities 是「产品级」描述,每条都指向细化的 spec。下面按主题归类,并给出可查的相对路径。

7.1 两个启动器,一个应用

桌面原生应用与thinkrailCLI 打开同一个 UI,都嵌入同一个宿主;状态位于~/.thinkrail。CLI 的流程见 apps/cli/SPEC.md:解析 argv/env → 解析静态目录(THINKRAIL_STATIC_DIR或随二进制发布的构建产物)→bootHost({ portMode: "free", resolveShellEnv: true })→ 打印启动标记与端点并打开浏览器(--no-open可关)→ SIGINT/SIGTERM 走共享的幂等server.shutdown()。

数据目录的解析在 packages/server/src/persistence/persistence.ts:

return resolve(process.env.THINKRAIL_DATA_DIR ?? join(homedir(), ".thinkrail"));

即THINKRAIL_DATA_DIR可覆盖,且相对路径会被 resolve 成绝对路径(架构决策 22 要求目录身份统一为宿主解析后的拼写)。

7.2 Projects → workspaces

git 仓库即项目;工作区是 worktree,外加内建 Default 与就地附加的既有 worktree。相关规格:packages/server/src/projects/SPEC.md、packages/server/src/workspaces/SPEC.md。线方法在 packages/contracts/src/wsProtocol.ts(project.open/workspace.create/workspace.listExisting/workspace.openExisting…)。

一个值得注意的守恒律(projects spec):一个 cwd 只有一个 ThinkRail 身份。openProject会把「已被某个工作区当作worktreePath」的根以ALREADY_OPEN拒绝——因为 pi 按目录索引会话,第二个身份会把那个工作区的 chat 当成自己的,并在任一方归档时被清除。

7.3 Workbench(工作台)

可拆分布局:文件、diff、文档、chat、终端,侧栏与底栏工具面板可移动,布局是每个窗口本地的。apps/web/src/shell/layout/SPEC.md 与架构决策 5、9 定义了WorkbenchFrame(一个窗口一份、无资源绑定、可持久化)与WorkspaceViewState(每个工作区一份)的分工:布局不下线,只有领域状态过线。

7.4 Chats(会话)

每个工作区可并发多个pi会话,各有模型、pi 报告的 token/成本、运行中的 steer 与 follow-up、skill 与 prompt-template 自动补全、历史搜索。规格:apps/web/src/chat/SPEC.md、packages/server/src/agent/SPEC.md。

会话语义里有一条容易踩坑的规则(AGENTS.md):

  • prompt()在流式过程中会抛错,应当使用steer()/followUp();
  • 自动工作结束于agent_settled,而不是agent_end——重试、压缩、恢复、排队的续跑都可能发生在一次尝试级的agent_end之后。

7.5 既有 skills 被就地复用

为其他编码 agent 保留的可移植 Agent Skills 被原地读取,pi仍是解析器与运行时。这意味着 ThinkRail 不复制一份 skill 目录,也不自建 skill 格式。

7.6 带逐步评审的 Plan

共享 TODO plan 由 agent 推进、用户可编辑;每一步完成时,如果改动可证明只属于该步,就单独提交(commit),并可交由独立评审者评审。规格:packages/pi-todos/SPEC.md、packages/server/src/todos/SPEC.md、packages/server/src/host/planReview.SPEC.md。

工具面(见 packages/pi-todos/tools 下的name:声明):todo_write、todo_add、todo_update、todo_list、todo_remove、todo_promote、todo_plan_summary。

评审者为什么是委派的子会话而不是第二个可见 chat,planReview spec 给了完整复盘:可见会话需要一套「会话是否停下」的监控(settle tee、审查者→worker 注册表、终止分类器、按 settle 推进的队列,约 400 行),而委派子会话把完成变成 promise 的 resolve、失败变成 reject,恢复面收敛成一次catch。

7.7 Subagents(子代理)

把工作委派到隔离的子会话:前台、并行或后台。规格:packages/pi-subagents/SPEC.md;可移植核心在 packages/pi-delegation/SPEC.md。工具面为Agent与get_subagent_result(见 packages/pi-subagents/src/extension.ts 与同文件 #L303)。

并发上限可以在两个层级设置:全局AppConfig.subagentMaxConcurrent,以及工作区级subagentMaxConcurrentOverride(packages/contracts/src/domain.ts);工作区模块只校验取值并持久化,不解析生效策略——策略由宿主跨模块组合。

7.8 Review(评审)

在文件与 diff 上留锚定评论,不启动 agent 也能收集,作为结构化上下文发给能解决它们的 chat;这是本地评审,不是 forge 集成。规格:packages/server/src/reviews/SPEC.md。线方法:review.get/review.commentAdd/review.commentUpdate/review.commentDelete/review.fileDone/review.sendComment/review.sendBatch/review.close(其中review.close就是 Clear:先把非草稿记录归档为关闭快照,再用一份新的开放评审替换活动快照,客户端只会收敛到新快照)。

7.9 Open PR

推送工作区分支并通过用户自己的gh打开或更新 GitHub PR;gh/GitHub 不可用时回退到预填 compare URL(GitLab 回退到预填的新 MR 页)。

顶栏的 Remote 与 Pull request 段始终显示分支的「下一步」:publish、push、sync、按 plan 描述的 open PR、commits、模板或 agent 草稿。PR 打开后还能看到 checks 与 review decision,并支持 mark ready、merge、把失败检查或已分叉分支交给 agent 处理、reopen、删除远端分支。

关键的确定性设计:宿主侧 push + 开/更新 PR,不存 token、不走 provider REST API(architecture.md)。分支状态的字段形状见 packages/contracts/src/domain.ts 的BranchStatus:published、pushesElsewhere、ahead/behind、aheadOfBase、onBase、review。其中onBase表示「分支就是它自己的基线(Default 停在默认分支)」,此时无法从它开 PR。

7.10 Specs

spec_*工具 + 只读 Specs 树。见本文 5.3 与 packages/spec-graph/SPEC.md、packages/server/src/spec/SPEC.md。

7.11 Workflows(工作流技能)

内置工作流技能覆盖项目搭建、设计头脑风暴、交付 PR。技能目录见 packages/pi-thinkrail-workflow/skills:choosing-a-workflow、setting-up-a-project、starting-a-new-project、importing-a-codebase、brainstorming、writing-specs、shipping-a-pr、asking-user-questions、writing-workflow-skills。路由由始终在线的规则段落完成(见 6.1),且规则明确「不改变行为的编辑直接进行,不加载也不宣告工作流」。

7.12 Providers(提供方)

应用内登录与 API key 走 pi 自己的 auth;JetBrains AI 走用户的centralCLI。规格:packages/server/src/auth/SPEC.md 与 central-integration.md。Cross-module 的生命周期归属由架构决策 13 指定(architecture.md)。

7.13 Agent tools(网页研究与内联可视化)

网页研究,加上聊天内联的图、选项对比与文件预览。当 agent 提出 UI 改动时,用同一套渲染器与评审评论展示渲染后的前后对比 mockup——评审面与 diff 评审共用一套机制。相关规格:apps/web/src/chat/tools/web/SPEC.md、thinkrail-extensions/visualize/SPEC.md。

扩展的组合方式是静态的:服务端注册表 packages/server/src/extensions/registry.ts 与 web 注册表 apps/web/src/extensions/registry.ts;SDK 是packages/extension-api(类型 +define*)与packages/ui。可见性由 Settings → Extensions 的开关控制,全局AppConfig.disabledExtensions经宿主注入的 resolver 到达agent,在每次 loader(重)加载时过滤工厂,并通过 pi 的 active-tool API 让已禁用的扩展工具从活动会话中撤下;web 渲染器仍保持注册,以便历史 transcript 继续渲染(architecture.md)。

7.14 MCP servers

读取用户的mcp.json,可从 Settings 管理,并在每个 chat 中与后台命令、子代理并列显示。对可能改变数据的调用,在 chat 内、调用前确认;受信任的工具可按项目「Always allow」。行为细节在 packages/server/src/agent/mcp/SPEC.md 与 apps/web/src/chat/tools/mcp/SPEC.md。

7.15 工作区之外

在已安装的编辑器/IDE 中打开 worktree,以及让应用自身保持最新。规格:packages/server/src/editors/SPEC.md、apps/web/src/updates/SPEC.md、apps/desktop/src/updates/SPEC.md。

7.16 界面语言

UI 跟随系统语言或用户选择;英文内置,用户可在~/.thinkrail/locales放一个扁平 JSON 文件新增或覆盖语言,保存即生效。agent 与工具输出永不翻译。

实现上,packages/locales的en.json是唯一英文真源,所有面向用户的字符串必须是键(如settings.language.title),由单一 i18next 实例渲染(@thinkrail/locales/react);硬编码 JSX 文本与文本属性(aria-label、title、placeholder、alt、label)会被 lint 门禁拦下(architecture.md 决策 23)。宿主侧读取与校验在 packages/server/src/locales/SPEC.md:只读全局数据目录(绝不读工作区,防止克隆仓库改写 UI),扫描*.json,单文件 2 MB、最多 64 个文件,逐字符串回退顺序为「本地精确 → 内置精确 → 内置基语言 → 英文」。

7.17 品牌

ThinkRail 绿色强调色(深色主题上偏亮、浅色主题上加深以保证两种都通过 AA)、Darcula 系深色背景、Orbitron 用于品牌展示位、Geist 与 JetBrains Mono 用于 UI 与代码。相关路径:apps/web/src/themes、apps/web/scripts/typography.ts。样式生成物有门禁:bun run colors:check、bun run spacing:check、bun run typography:check。

八、Non-goals:被「决定」排除的两件事

原文档对 Non-goals 的措辞非常克制,且这一节的边界语义比内容更重要:

Only these are excluded by decision. Anything neither listed above nor excluded here is open, not forbidden.

即「只有这两条是被决定排除的;既没列在能力里、也没列在这里的,是开放的,不是禁止的」。两条是:

  1. 第二个 agent 运行时,或任何宿主侧 agent 循环与 prompt 组装(见 Principles)。这条在架构中以不变量形式重复:agent 进程内运行,@earendil-works/pi-coding-agent只在服务端,浏览器打包代码永不 value-importpi,只能从pi-ai/pi-agent-core根做类型导入(类型导入在构建时被擦除,使 bundle 不含 provider)。
  2. ThinkRail 账号或登录 UI。谁能访问一个宿主由网络决定——Tailscale ACL 与设备身份。架构决策 7 表述为「Auth is external」,应用只携带owner字段(architecture.md)。

九、这份文档如何与代码一起演进

goal-and-requirements 自称随产品变化改写,这需要工程机制支撑,否则必然腐化。仓库里有三层保障:

第一层:文档分层与双链。产品意图(本文件)→ 架构决策 → 模块SPEC.md。covers、parent、depends-on、references等 frontmatter 字段把文档连成图,spec_*工具让 agent 能检索这张图。

第二层:边界与接口的可执行门禁。根 package.json 里可直接运行:

bun run check:boundaries # 模块边界(含 web 不得依赖 server/shared) bun run check:spec-surface # 已登记的 spec/barrel 公共面 bun run check:seams # 二进制接缝 bun run check:deps # 精确版本与 catalog 漂移 bun run check:i18n # 硬编码 UI 文案 bun run check:compiler # React Compiler 逃逸基线 bun run lint # biome bun run typecheck

其中check:deps对应架构决策 10:所有依赖精确固定,禁止^、~、>、<、.x、*;跨切依赖(pi、TypeScript、typebox、Bun types)在根workspaces.catalog固定一次并通过catalog:引用。这条规则的动机在文档里写得很坦率:pi每天出破坏性版本,浮动的 range 就是一根带电的线。执行者是 scripts/check-catalog.ts(pre-commit + CI)。豁免只有两类:peerDependencies(扩展包故意声明"*",依赖由宿主提供)与本地协议(workspace:/link:/file:)。

第三层:AGENTS.md的维护纪律。例如:改动移动或模糊了边界,先改拥有该边界的 spec;新增/删除/重命名用户可见能力,或改动安装与分析行为时,同步复核 README.md 中对应的主张。

十、按文档落地:从零验证这套描述

以下是只读的验证路径,不修改仓库任何内容。

安装并运行(用户视角)

# macOS / Linux(Windows 可用 Git Bash) curl -fsSL https://raw.githubusercontent.com/JetBrains/thinkrail/main/install.sh | bash # Windows(cmd / PowerShell) powershell -c "irm https://raw.githubusercontent.com/JetBrains/thinkrail/main/install.ps1 | iex" # 打开一个 git 仓库作为项目 thinkrail ~/code/my-repo

CLI 需要 PATH 上有git和一个模型提供方(应用内 JetBrains AI 登录,或使用自己的 provider 凭据)。thinkrail --help列出参数,thinkrail --version打印构建版本。桌面版与 CLI 是两种可叠加的形态,两者都携带SHA256SUMS发布;Linux 桌面需要 glibc 2.38+ 与 GTK 3、WebKitGTK 4.1、Ayatana AppIndicator 3、librsvg 2。

开发与验证(贡献者视角)

bun run dev # 启动开发环境 bun run test # 单元测试(根 scripts + turbo run test) bun run e2e # 无 agent 的浏览器全量套件 bun run e2e:full # 真实 provider token 的 live 套件(先征得同意)

运行环境基线:Bun1.4.4(根packageManager固定,CI 读取它而不是在 workflow YAML 里再写一份)、TypeScript strict、React 19 + Zustand + Tailwind v4、进程内pi(Node >= 22.19)。

把文档读完的最短路径

  1. goal-and-requirements.md —— 产品目标与范围(本文主体)。
  2. architecture.md —— 拓扑、23 条决策、全仓不变量。
  3. 按能力跳转:packages/server/src/workspaces/SPEC.md(隔离)、packages/spec-graph/SPEC.md(spec 图谱)、packages/server/src/reviews/SPEC.md(评审)、packages/pi-subagents/SPEC.md(委派)、apps/web/src/shell/layout/SPEC.md(工作台)。
  4. 契约对照:packages/contracts/src/domain.ts 与 packages/contracts/src/wsProtocol.ts —— 想知道「宿主到底能说什么」,这里是唯一答案。

十一、小结:这份文档真正约束的是什么

把 goal-and-requirements.md 读薄,它其实只在约束三件事:

  • 引擎只有一个(进程内的pi),因此所有功能都必须通过「喂」与「暴露」来实现,不能自建循环、不能自算状态。
  • 隔离是默认(worktree + 分支 + cwd),因此「在项目目录直接干」必须是一个显式的、可命名的例外,而不是滑落成的默认。
  • 意图要活过会话(spec 图谱 + 可复用 skills),因此文档、决策与不变量必须能被 agent 检索与维护——这正是这份文件自己采用 frontmatter + 双链 + 分层 spec 的原因。

其余的能力清单(两个启动器、工作台、chat、plan、subagent、review、Open PR、MCP、语言、品牌)都是这三条约束在具体界面上的投影;而 Non-goals 只有两条,且文档明确声明「未列出即开放」。对想评估或参与这个项目的工程师来说,这是一份可以逐条对照源码验证的范围声明,而不是一份宣传材料。

【免费下载链接】thinkrail

Vibe code with pi in a lightweight, real IDE that customises itself around the way you work — The Vibe You Need

项目地址:https://gitcode.com/GitHub_Trending/th/thinkrail
点击查看免费下载

相关推荐

上一篇:用ACE-Step 1.5生成你的第一首歌:Gradio界面新手入门一步步指南
下一篇:SpinKit-ObjC完全指南:UIKit中15种加载动画的终极实现方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/27 9:38:25

ponytail技术解析:从图形学模拟到AI提示词优化

我无法根据当前输入生成符合要求的博文。原因如下&#xff1a;项目标题“ponytail”为英文单词&#xff0c;直译为“马尾辫”&#xff0c;属于常见发型术语&#xff0c;但未提供任何具体领域指向&#xff08;如时尚造型、3D建模中的头发模拟、编程中某库的模块名、游戏开发中的…

作者头像 李华
网站建设 2026/10/27 9:28:42

context-mode深度解析:多轮对话上下文管理的策略与工程实践

1. 为什么我会盯上 context-mode 这个功能事情得从一次让我印象深刻的线上故障说起。那天我正在排查一个奇怪的问题——同一个 Prompt&#xff0c;在本地测试环境跑得好好的&#xff0c;结果一上生产&#xff0c;经常性的出现指标陡降。翻了一下午日志&#xff0c;最后发现原因…

作者头像 李华
网站建设 2026/10/27 9:26:13

Flink:找不到 start-scala-shell.sh 或 flink-scala-shell 的解释

自 Flink 依赖的 Scala 版本提升到 2.12 后&#xff0c;就不再支持 Scala Shell &#xff08;Scala REPL&#xff09;了&#xff0c; 这一点&#xff0c;在 [ 官方文档 ] 中有明确说明&#xff0c;具体是因为 [ FLINK-10911 ] 这个 Issue&#xff0c;但是该 Issue 已经关闭&…

作者头像 李华
网站建设 2026/10/27 9:23:23

git 命令操作

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华