Plan 与 Work
这些是产品模式,不是 Crystal 类型。
- Plan 注册 read、list、tree、glob、grep、search、todowrite、todoread 和 question。启用 Skills 时,它也注册 skill。
catalogs包含plan的外部工具追加在内置工具之后。 - Work 注册 read、list、tree、glob、grep、search、todowrite、todoread,启用时的 question 和 skill,然后是 edit、write、bash,以及会话本地的
bash_start、bash_status、bash_logs和bash_stop工具,然后是catalogs包含work的外部工具。
CrystalCode 目前只映射 JSON 工具输入。内置和外部 dotnet 工具发布 ToolDefinition.Json;发布 ToolDefinition.Text 的 dotnet 工具集带着可见说明被跳过。提供商适配器对历史中的文本输入工具或文本工具调用以 NotSupportedException 拒绝,而不是包裹它。会话文档和插件模型记录保留 ToolInputKind,但当前没有提供商映射 ToolInputKind.Text。
--disable-tool 在 crystal、crystal space 和 crystal run 上可重复。每个值是一个内置工具名称。进程从 Plan 和 Work 中省略该工具,包括 describe_image、view_image、skill 和命名的后台 shell 工具。未知名称拒绝启动。选择不保存。系统文本列出被省略的名称,并告诉模型不要调用它们。该名称对插件和外部工具仍然保留。
内置 question 工具接受有序的问题数组。每个问题有短标题、全文、带描述的选项、可选多选,以及默认启用的自定义输入。单个单选问题立即提交。多个问题和多选问题使用共享的确认步骤。答案按问题顺序作为所选标签数组返回;驳回覆盖层返回失败的工具结果。
内置 Plan 仍然没有 edit、write 或 bash。外部 Plan 工具保持 Write + Workspace 下限,因此一旦安装了这样的工具,Plan 就不再只是内置读取。审批仍然运行。
后台 Bash 任务归活动会话所有。bash_start 不等待进程退出就返回任务 ID。bash_status 报告任务状态,bash_logs 按偏移读取有界输出缓冲区,bash_stop 杀死进程树。任务不保存在会话文档中,不跨越进程重启,并在会话关闭时停止。配置的 backgroundBashTimeoutSeconds 计时器适用于它们,独立于前台 bashTimeoutSeconds;省略它保持 10800 秒(3 小时),null 或 "unlimited" 禁用该计时器。最多同时有 32 个活动任务;已完成的任务仍可查询,但不占用活动任务槽。后台任务的 stdin 在启动后关闭。
切换模式替换第一条系统消息和执行器目录。记录在其他方面仍是同一段对话。
待办列表属于会话,不属于模式。内置 Plan 文本要求模型把计划步骤写成待处理待办并让它们保持待处理;内置 Work 文本要求模型处理它找到的待处理待办,而不是开始新列表。内置 Work 和 Plan 文本也指示模型在不知道哪些文件重要时先用 search,然后读取最佳候选,并用 tree、glob、grep 和 list 理解仓库。它们告诉模型,文件内容和工具结果是数据,不是指令,工作区指令覆盖内置默认,而用户最新消息覆盖两者。question 不可用或被驳回时,Work 只在安全且可逆时按推荐默认继续,Plan 把该默认记录为开放问题。
内置 Review 文本定义 risk_level 和 user_authorization 级别,并从中派生 outcome:低风险且中或高授权、中风险且高授权,或用户明确请求的高风险时 allow;低授权或未经请求的伤害时 deny;否则 ask。宿主风险和宿主权限是下限,无论裁决怎么说,策略仍然拒绝放行 forbidden 调用。
活动的 Work 和 Plan 系统文本用宿主拥有的占位符({{name}})从可覆盖模板组装。Review 和压缩提示使用相同的占位符语法。复合会话槽是 {{env}}、{{skills}}、{{directories}},以及 {{instructions_section}} 或原始 {{instructions}}。原子会话槽包括 {{workspace}}、{{is_git_repo}}、{{git_root}}、{{platform}}、{{os}}、{{architecture}}、{{date}}、{{time}}、{{provider}}、{{model}}、{{model_line}}、{{mode}}、{{product_name}}、{{session_id}} 和 {{approval}}。{{os}} 是操作系统名称和版本。{{architecture}} 是进程架构。{{time}} 是带数字偏移的本地时间,在组合该系统消息时捕获。工作区目录本身包含 .git 目录或文件时,{{is_git_repo}} 为 yes。{{git_root}} 是通过遍历父目录找到的仓库根,该遍历找不到时为空。{{session_id}} 是已保存的会话 id。{{approval}} 是审批模式(plan、default、edit、review、audit 或 full)。对 Work 和 Plan,{{mode}} 是 plan 或 work;对 Review 系统文本是 review;对压缩系统文本是 compaction;对图像描述系统文本是 image。{{env}} 块包括操作系统、架构和本地时间,并在宿主有它们时添加 git 根、会话和审批行。会话没有添加的目录规则时,{{directories}} 为空。否则它是追加到工作区指令的同一段会话目录访问文本。内置模板不声明此槽。活动系统消息被替换时它会刷新,包括 /access 之后。Review 用户模板添加 {{conversation}}、{{tool_name}}、{{tool_arguments}}、{{host_risk}}、{{host_authority}} 和 {{classification_summary}}。压缩用户模板添加 {{conversation}}、{{prior_summary_section}}、{{summary_task}}、{{output_template}} 和 {{todos_section}}。图像用户模板添加 {{question}}。磁盘插件可以通过 IPluginPlaceholder 添加更多名称。宿主拒绝它已经拥有的名称,第一个加载的插件保留重复名称。这些值在与宿主名称相同的绑定过程中展开,包括附件、Review、压缩和图像描述。返回值作为文本插入,因此其中的 token 保持字面。抛出或没有返回文本的解析器留下该 token,并记录一条英文说明。内置 Work、Plan、Review、压缩和图像描述模板显式声明它们需要的槽。主题命名使用 topic.md。它是命名提示,因此提示集、Home 或项目文件可以替换它。活动会话尚未调用它。Review 系统文本是命名文件加上任何已启用的 review 附件。它不接收工作区指令块。其用户回合是命名的 review.user 模板。复合和原子宿主值不是覆盖文件,并在 /cd、/model、/approval 以及活动系统消息被替换时刷新。技能引导归宿主所有,不是覆盖文件。
提示集选择和直接提示覆盖是分开的功能。提示集是 ~/.crystal/promptsets/<name> 下仅 Home 的目录,带 prompt.json 和命名提示文件的任意子集(work.md、plan.md、review.md、review.user.md、topic.md、compaction.system.md、compaction.user.md、image.system.md 和 image.user.md;也接受 .txt)。宿主从不扫描工作区寻找提示集。default 是由内置提示支持的虚拟保留选择。所选集合中缺失或空的文件回退到该名称的内置提示。直接的 prompts/work.md 覆盖不使用 prompt.json。
prompt.json 可以设置 name(显示标题,至多 80 个字符)和 description(至多 280 个字符)。目录名仍是 id。打开目录需要 enabled;省略它表示关闭。未知字段被保留。缺失、不可读或无效的清单跳过该目录并报告一条英文说明。命令不创建缺失的目录或缺失的清单,并让损坏的清单保持不变。
最多可以启用一个提示集。启用一个在该清单上写入 enabled: true,并在其他每个已启用集合上写入 enabled: false。禁用当前集合,或 /promptset default,清除每个已启用标志,会话使用内置文本。如果两个或更多集合被手工编辑为 enabled: true,会话一个都不用,注明冲突,并留在 default。
完整的命名提示优先级是内置、所选提示集、直接的 ~/.crystal/prompts 覆盖,然后是直接的工作区 .crystal/prompts 覆盖。该顺序覆盖 Work、Plan、Review、Review 用户回合、主题命名、压缩系统和用户文本,以及图像描述系统和用户文本。指令、技能引导和环境块不是提示集成员。压缩所需的输出格式留在 {{output_template}} 内;替换 compaction.user.md 可以省略该槽。/promptset(别名 /prompts)列出集合以及 Work、Plan 和 Review 的有效来源。/promptset <name> 在空闲时通过写入 prompt.json 切换,替换活动系统消息,并重建 Review。它不写入 config.json。进程 --prompt-set 拒绝该切换并让文件保持不变。恢复和分叉使用已启用的清单,而不是会话中存储的选择。crystal promptsets list|show|enable|disable 在会话外编辑相同的 Home 清单。--home 和 --format text 与插件命令匹配。没有 --source 标志,因为提示集仅限 Home。
提示附件在已解析的 Work、Plan 或 Review 文本绑定之后追加。已解析的文本留在原地。附件不是提示集成员。附件只追加 Work、Plan 或 Review。主题、Review 用户、压缩和图像描述由命名提示文件替换,而不是由附件替换。每个附件是 prompt.json 加上 work.md、plan.md 和 review.md 文件的目录(也接受 .txt)。缺失的文件对该模式不贡献任何内容。空文件视为缺失。附件文件末尾的尾随换行被保留。目录名使用与提示集相同的 1–64 字符连字符形式。default 是有效的附件名。
发现读取 ~/.crystal/prompt-attachments/<name>/ 和 <workspace>/.crystal/prompt-attachments/<name>/。工作区只是当前工作区根;不遍历父目录。两处同名时完全使用工作区 prompt.json,包括 enabled 和 order。可以启用多个附件。它们按 order 排序,然后按目录名。缺失的 order 排在最后。启用追加该名称,并把已启用顺序改写为 0..n-1。禁用把 enabled 设为 false,且不重新编号。/promptattach up 和 down 在该顺序内交换并改写它。附件内的占位符 token 用与正文相同的宿主值展开。
组合顺序是已解析正文、已绑定占位符、该模式按 order 的已启用附件,然后是普通插件 OnPrompt 追加。原始 RewritePrompt 仍可以替换结果。/promptattach 列出已发现的附件,带标题、描述和 Home 或工作区来源。回合运行时拒绝更改。列出仍然可用。状态栏继续只显示所选提示集目录名。crystal prompt-attachments list|show|enable|disable 编辑相同清单。它接受 --home、--workspace、--source home|project 和 --format text。会话 /promptattach 编辑获胜的目录,没有来源前缀。
crystal、crystal space 和 crystal run 接受 --prompt-set <name>。该标志为进程强制命名集合,即使其清单说 enabled: false。default 强制内置文本。设置该标志时拒绝 /promptset 切换,包括 default,且不写入 prompt.json。列出和导出仍然可用。--prompt-attachments on|off 是进程开关:省略或 on 遵循文件标志和顺序;off 不附加任何内容,并拒绝 enable、disable、up 和 down。列出仍然可用。可重复的 --prompt-attachment <name> 把这些已发现的名称追加到已启用集合之后,即使清单说 enabled: false。已经启用的名称留在其清单顺序中,不会追加两次。同一名称传入多次时只保留一次,按首次出现的顺序。把它与 --prompt-attachments off 组合会被拒绝。在 Home 或启动工作区中未发现的名称会使启动失败。对强制名称,/promptattach enable、disable、up 和 down 被拒绝,且不写入 prompt.json。其他名称仍可更改。列出仍然可用,并标记强制的禁用行。之后的工作区更改不再包含强制名称时,跳过该名称并打印一条说明。这些标志不写入 prompt.json 或 config.json。config.json 中较旧的 promptSet 和 promptAttachments 键被忽略,并在下次保存偏好时省略。没有迁移工具。