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
catalogsincludeplanare 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, andbash_stoptools, then external tools whosecatalogsincludework.
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.