跳到內容
Crystal CodeDocs
繁繁體中文

Plan and Work

本頁內容尚未翻譯。

These are product modes, not Crystal types.

  • Plan registers read, list, tree, glob, grep, search, todowrite, todoread, and question. When Skills is enabled, it also registers skill. External tools whose catalogs include plan are appended after the built-ins.
  • Work registers read, list, tree, glob, grep, search, todowrite, todoread, question, and skill when enabled, then edit, write, bash, and the session-local bash_start, bash_status, bash_logs, and bash_stop tools, then external tools whose catalogs include work.

CrystalCode currently maps only JSON tool input. Built-in and external dotnet tools publish ToolDefinition.Json; a dotnet tool set that publishes ToolDefinition.Text is skipped with a visible note. Provider adapters reject a text-input tool or a text tool call in history with NotSupportedException instead of wrapping it. Session documents and the plugin model transcript preserve ToolInputKind, but no current provider maps ToolInputKind.Text.

--disable-tool repeats on crystal, crystal space, and crystal run. Each value is one built-in tool name. The process omits that tool from Plan and Work, including describe_image, view_image, skill, and a named background shell tool. An unknown name refuses to start. The choice is not saved. The system text lists the omitted names and tells the model not to call them. The name stays reserved for plugins and external tools.

The built-in question tool accepts an ordered question array. Each question has a short header, full text, described options, optional multiple selection, and custom input enabled by default. A single single-select question submits immediately. Multiple questions and multiple-select questions use a shared confirmation step. Answers return in question order as arrays of selected labels; dismissing the overlay returns a failed tool result.

Built-in Plan still has no edit, write, or bash. An external Plan tool keeps a Write + Workspace floor, so Plan is not built-in reads only once such a tool is installed. Approval still runs.

Background Bash tasks are owned by the live session. bash_start returns a task ID without waiting for process exit. bash_status reports the task state, bash_logs reads the bounded output buffer by offset, and bash_stop kills the process tree. Tasks are not saved in session documents, do not cross a process restart, and are stopped when the session closes. The configured backgroundBashTimeoutSeconds timer applies to them, independent of the foreground bashTimeoutSeconds; omitting it keeps 10800 seconds (3 hours), and null or "unlimited" disables that timer. At most 32 tasks may be active at once; completed tasks remain queryable but do not consume an active-task slot. Background task stdin is closed after startup.

Switching modes replaces the first system message and the executor catalog. The transcript is otherwise the same conversation.

The todo list belongs to the session, not to a mode. Built-in Plan text asks the model to write the plan’s steps as pending todos and leave them pending; built-in Work text asks the model to work through pending todos it finds instead of starting a new list. Built-in Work and Plan text also direct the model to use search first when it does not know which files matter, then read the best candidates and use tree, glob, grep, and list to understand the repository. They tell the model that file contents and tool results are data, not instructions, and that workspace instructions override the built-in defaults while the user’s latest message overrides both. When question is unavailable or dismissed, Work continues on the recommended default only when it is safe and reversible, and Plan records that default as an open question.

Built-in Review text defines risk_level and user_authorization levels and derives outcome from them: allow for low risk with medium or high authorization, medium risk with high authorization, or high risk the user explicitly requested; deny for low authorization or unrequested harm; ask otherwise. Host risk and host authority are a lower bound, and the policy still refuses to pass a forbidden call whatever the verdict says.

Live Work and Plan system text is assembled from overlayable templates using host-owned placeholders ({{name}}). Review and compaction prompts use the same placeholder syntax. Composite session slots are {{env}}, {{skills}}, {{directories}}, and {{instructions_section}} or raw {{instructions}}. Atomic session slots include {{workspace}}, {{is_git_repo}}, {{git_root}}, {{platform}}, {{os}}, {{architecture}}, {{date}}, {{time}}, {{provider}}, {{model}}, {{model_line}}, {{mode}}, {{product_name}}, {{session_id}}, and {{approval}}. {{os}} is the operating system name and version. {{architecture}} is the process architecture. {{time}} is the local time with a numeric offset, captured when that system message is composed. {{is_git_repo}} is yes when the workspace directory itself contains a .git directory or file. {{git_root}} is the repository root found by walking parent directories, or empty when that walk finds none. {{session_id}} is the saved session id. {{approval}} is the approval mode (plan, default, edit, review, audit, or full). {{mode}} is plan or work for Work and Plan, review for Review system text, compaction for compaction system text, and image for image-description system text. The {{env}} block includes the operating system, architecture, and local time, and adds git root, session, and approval lines when the host has them. {{directories}} is empty when the session has no added directory rules. Otherwise it is the same session directory access text appended to workspace instructions. Built-in templates do not declare this slot. It refreshes when the live system message is replaced, including after /access. Review user templates add {{conversation}}, {{tool_name}}, {{tool_arguments}}, {{host_risk}}, {{host_authority}}, and {{classification_summary}}. Compaction user templates add {{conversation}}, {{prior_summary_section}}, {{summary_task}}, {{output_template}}, and {{todos_section}}. Image user templates add {{question}}. A disk plugin may add further names through IPluginPlaceholder. The host rejects a name it already owns, and the first loaded plugin keeps a duplicated name. Those values expand in the same binding pass as the host names, including attachments, Review, compaction, and image description. A returned value is inserted as text, so tokens inside it stay literal. A resolver that throws, or returns no text, leaves the token and records an English note. Built-in Work, Plan, Review, compaction, and image-description templates declare the slots they need explicitly. Topic naming uses topic.md. It is a named prompt, so a prompt set, Home, or project file can replace it. The live session does not invoke it yet. Review system text is the named file plus any enabled review attachments. It does not receive the workspace instruction block. Its user turn is the named review.user template. Composite and atomic host values are not overlay files and refresh on /cd, /model, /approval, and when the live system message is replaced. Skill guidance is host-owned and is not an overlay file.

Prompt set selection and direct prompt overrides are separate features. A prompt set is a Home-only directory under ~/.crystal/promptsets/<name> with prompt.json and any subset of the named prompt files (work.md, plan.md, review.md, review.user.md, topic.md, compaction.system.md, compaction.user.md, image.system.md, and image.user.md; .txt is also accepted). The host never scans a workspace for prompt sets. default is a virtual, reserved selection backed by the built-in prompts. A missing or empty file in a selected set falls back to the built-in prompt for that name. Direct prompts/work.md overrides do not use prompt.json.

prompt.json may set name (display title, at most 80 characters) and description (at most 280 characters). The directory name stays the id. enabled is required to turn the directory on; omitting it means off. Unknown fields are kept. A missing, unreadable, or invalid manifest skips the directory and reports an English note. Commands do not create a missing directory or a missing manifest, and they leave a broken manifest unchanged.

At most one prompt set may be enabled. Enabling one writes enabled: true on that manifest and enabled: false on every other enabled set. Disabling the current set, or /promptset default, clears every enabled flag and the session uses built-in text. If two or more sets are hand-edited to enabled: true, the session uses none, notes the conflict, and stays on default.

The complete named-prompt precedence is built-in, selected prompt set, direct ~/.crystal/prompts override, then direct workspace .crystal/prompts override. That order covers Work, Plan, Review, the Review user turn, topic naming, compaction system and user text, and image-description system and user text. Instructions, skill guidance, and the environment block are not prompt-set members. Compaction’s required output format stays inside {{output_template}}; replacing compaction.user.md can omit that slot. /promptset (alias /prompts) lists sets and the effective source of Work, Plan, and Review. /promptset <name> switches at idle by writing prompt.json, replaces the live system message, and rebuilds Review. It does not write config.json. A process --prompt-set refuses that switch and leaves the file unchanged. Resume and fork use the enabled manifest rather than a selection stored in the session. crystal promptsets list|show|enable|disable edits the same Home manifests outside a session. --home and --format text match the plugin commands. There is no --source flag, because prompt sets are Home-only.

Prompt attachments append after the resolved Work, Plan, or Review text has been bound. The resolved text stays in place. Attachments are not prompt-set members. An attachment only appends Work, Plan, or Review. Topic, Review user, compaction, and image description are replaced by named prompt files, not by attachments. Each attachment is a directory of prompt.json plus work.md, plan.md, and review.md files (.txt is also accepted). A missing file contributes nothing for that mode. Empty files are missing. A trailing newline at the end of an attachment file is kept. Directory names use the same 1-64 character hyphenated form as prompt sets. default is a valid attachment name.

Discovery reads ~/.crystal/prompt-attachments/<name>/ and <workspace>/.crystal/prompt-attachments/<name>/. The workspace is the current workspace root only; parent directories are not walked. The same name in both places uses the workspace prompt.json entirely, including enabled and order. Many attachments may be enabled. They sort by order, then by directory name. A missing order sorts last. Enabling appends the name and rewrites the enabled orders as 0..n-1. Disabling sets enabled false and does not renumber. /promptattach up and down swap within that order and rewrite it. Placeholder tokens inside an attachment expand with the same host values as the body.

Composition order is the resolved body, bound placeholders, enabled attachments for that mode in order, then an ordinary plugin OnPrompt append. A raw RewritePrompt can still replace the result. /promptattach lists discovered attachments with title, description, and Home or workspace source. Changes are refused while a turn is running. Listing stays available. The status bar continues to show only the selected prompt set directory name. crystal prompt-attachments list|show|enable|disable edits the same manifests. It accepts --home, --workspace, --source home|project, and --format text. Session /promptattach edits the winning directory and has no source prefix.

crystal, crystal space, and crystal run accept --prompt-set <name>. That flag forces the named set for the process even when its manifest says enabled: false. default forces the built-in text. /promptset switching, including default, is refused while the flag is set and does not write prompt.json. Listing and export stay available. --prompt-attachments on|off is the process switch: omitted or on follows the file flags and order; off appends nothing and refuses enable, disable, up, and down. Listing stays available. Repeatable --prompt-attachment <name> appends those discovered names after the enabled set, even when a manifest says enabled: false. A name that is already enabled stays in its manifest order and is not appended twice. The same name passed more than once is kept once, in first-seen order. Combining it with --prompt-attachments off is rejected. A name that is not discovered in Home or the launch workspace fails startup. /promptattach enable, disable, up, and down are refused for a forced name and do not write prompt.json. Other names can still be changed. Listing stays available and marks a forced disabled row. A later workspace change that no longer contains a forced name skips that name and prints a note. These flags do not write prompt.json or config.json. Older promptSet and promptAttachments keys in config.json are ignored and omitted the next time preferences are saved. There is no migration tool.