Repository navigation
Releases: YELANDAOKONG/CrystalCode
Release list
Beta v0.8.8
What's Changed
🚀 New Features
- Returning an unstarted message to the composer with
Ctrl+C(243eb7b, 42a4912, b82bf94) — Before the model shows text, reasoning, a tool call, or a retry, with an empty composer and follow-up queue,Ctrl+Cnow stops the turn, removes the message from the transcript, and puts it back in the composer. Text typed while the turn stops is kept after the returned message, notes and errors in the transcript survive, a note, error, or slash command during the turn keeps the message instead, andcrystal rundoes not return messages this way.
🐛 Fixes
- Provider error payloads reported as faults (7766026, ff31269, 3de6d78) — Stream and response error payloads from Chat Completions, Responses, Anthropic, Gemini, and Ollama now become provider faults with the provider code and message instead of a truncated stream or a silent retry. This includes a JSON error body returned where an event stream was expected, even with HTTP 200, and only transient stream codes such as rate limits are retried.
- Closed-upload retry and clean composer input (3cc5302) — A request whose connection closes while its body is still being written is retried once and then reported with the transport cause instead of spending the rest of the retry budget. Stray mouse, mode, and cursor reports from the terminal no longer appear as text in the composer, and Windows echo is disabled so the console cannot print them there.
- Windows clipboard paste (48c9c6d) —
Ctrl+Vis now recognized on Windows even when the console reports the key without modifier metadata, so paste works in terminals that omit it. Clipboard image reads retry briefly when another process is holding the clipboard, so an image paste is less likely to fail on the first try.
⚡ Performance
- Skipping repaints of unchanged terminal rows (b251c1e) — Repaints now skip rows whose content did not change, including the composer, so idle frames and terminal mode updates write less to the terminal. The frame stays visually identical while the product does less work per paint.
Full Changelog: B0.8.7...B0.8.8
Beta v0.8.7
What's Changed
🚀 New Features
- Service tier and speed selection (
ddd9e4e) — Models can declareserviceTiersandspeedsinproviders.json, while/tierand/speed(alias/fast) cycle or select them, and--tier,--speed, and--fastoverride them for one launch. Slash-command choices persist intierSelectionsandspeedSelections, appear in session chrome and status output, and are visible to plugins. - Per-process built-in tool omission (
36d5e68) —--disable-tool <NAME>is repeatable oncrystal,crystal space, andcrystal runto omit a built-in tool, and an unknown name refuses to start. The omitted name stays reserved, so plugins and external tools cannot claim it. - Commented provider catalog (
7899078) —providers.jsonnow accepts//and/* */comments and trailing commas, and comments survive because the host never rewrites the file. - Underscores in catalog tokens (
aa8beab) —thinkingEfforts,serviceTiers, andspeedsinproviders.jsonnow accept underscores after the first letter, and/thinking,/tier, and/speedaccept them in token arguments.
🐛 Fixes
- JSON-only tool input with persisted input kinds (
97b34c6,a6c3798) — Sessions, forks, exports, and plugin model calls now preserveToolInputKind, and provider adapters reject text tool input withNotSupportedExceptioninstead of wrapping it. This is a breaking change for .NET native plugins and external tool sets: rebuild them againstToolDefinition.JsonandToolCall.InputKind, and note that a tool set publishing text input is skipped with a visible note. - Tier and speed changes applied consistently (
4843ba5) — Unsupported tier and speed selections are rejected when provider clients are created, before/tieror/speedsaves the choice, and compaction, approval, review, and image clients that use the changed model are rebuilt. Plugin client requests now receive both slots. - Verbatim thinking effort tokens (
698e47f) —/thinkingandthinkingEffortsnow forward endpoint tokens unchanged, somaxandmaximumremain distinct and values such asxhighare no longer rewritten for OpenAI-compatible gateways. Gemini 2.5 continues to accept onlyminimal,low,medium, andhigh. - Clearer model option failures (
010959c) — Tier and speed switches now report side-client refresh errors instead of falling back silently, and aliased provider names resolve correctly when side clients are matched. Compaction activity is set before its notice, andcrystal runprints unsupported option errors and exits 1 instead of failing unexpectedly.
Full Changelog: B0.8.6...B0.8.7
Beta v0.8.6
What's Changed
🚀 New Features
- Session directory access for built-in file tools (c750343) —
/accesslists the session's directory rules,add <path> read|writeadds or replaces one, andremove <path>drops it, with repeatable--allow-readand--allow-writeflags seeding the launched session. Covered directories are treated like workspace paths for read and write approval, areadrule refuses file writes before classification and path resolution, and the rules persist in the session document. - Per-workspace default directory access (647e88f) —
/access defaultlists the defaults saved in~/.crystal/access.json, anddefault add <path> read|write/default remove <path>change that file and the current session. New sessions,/clear,/fork, and a successful/cdor/spacecopy the destination workspace's defaults, while/resumekeeps the saved session rules. - F6 quick prompts (3dc6b96) — Pressing
F6opens a picker over direct.mdtemplates in~/.crystal/shortcuts, searching names and bodies with Fill and Send modes, and every open starts in Fill. Fill inserts at the composer cursor without replacing the draft; Send submits the template alone, keeps the draft and its images, and queues while a turn is running without interrupting it. - Compaction model and forced prompt attachments (7ab2d24) —
compactionModelinconfig.jsongives summaries their ownprovider,model, andthinkingEffort, shown and changed with/compact modeland/compact thinkingand reported by/statuswhile it is on. The launch flags--compaction-model,--compaction-provider,--compaction-model-id,--compaction-thinking, and repeatable--prompt-attachment <name>apply to one process without writingconfig.json, and a forced attachment cannot be changed with/promptattach. - Microcompaction and larger compaction budgets (2b692a6) — With
microCompactionenabled, old successful tool results are replaced with the omitted-result note before each model call, keeping the latestprotectTurnsuser turns andprotectTokensof newer results and rewriting only when the removed text is larger thanminimumTokens./compact microtoggles the switch,/statusshows a Microcompaction row while it is on, and compaction reserves up to 16384 tokens for the summary, keeps a verbatim tail of at most 32000 tokens, and discards a summary that stops at its output limit. - Slash commands queued during a turn (1ac7418) — Slash commands typed while a turn is running are held out of the message queue and run as commands when the turn finishes, so
/forkor/statusno longer reach the model as prompt text. A queued command that stops a busy turn still interrupts it. - Slash commands typed during compaction (f0d0ee3) — Commands that only report state or adjust the display run immediately while compaction is in progress, commands that would change the session are refused with the busy-turn message, and
/quitcancels compaction and exits. - Verbose switches for results, review cards, and tool cards (4eb843c, 1f07d9b, a0c2e90) —
/verbose resultsis a new parent switch for success result panels (verboseResultsinconfig.json), andverboseTools/verboseCommandsnow only act while it is on./verbose reviewandverboseReviewcontrol review allow cards independently ofverboseApprovals, and/verbose callsandverboseCallshide the Tool cards themselves without touching results. - Rule file switches (7ea48a2) —
/rulesshows the OpenCode-compatible global and project rule files and acceptson/offfor both orglobal/projectpluson/offfor one side, storing the choice inruleFileswithinconfig.json.--rules on|offorglobal=on|off/project=on|offapplies to one process without writing the file, and neither form affectsinstructions.mdor.crystal.md. - Plugin-registered status line fields (e7c0bc1) — Disk plugins can register named status fields, and the operator adds the lowercase name to
statusLineor through/statuslineto show text the plugin pushes./statuslinelists each loaded plugin field with its directory and description, keeps a saved name when the plugin is not loaded, and marks it unavailable. - Bounded
treetool (4e68aff, 08e8843) — The built-intreetool lists a workspace directory depth-first with a depth bound, a per-directory file cap, and a total-entry cap, lists a directory link once under its resolved path, and skips ignored directories, links that leave the workspace, and credential paths. Cap notes now name the workspace root instead of.. - GFM tables in the transcript (75f822e) — Assistant markdown now renders GitHub-flavored tables, aligned by display columns, wrapped inside a column, or stacked when the terminal cannot give every column its minimum. A table that cannot be parsed or laid out is shown as its original lines.
- Compaction summary switches (c635881, 6657748) —
/compact summarytoggles the manual summary panel and/compact autotoggles the same panel after automatic compaction, each acceptingonoroffand writingconfig.jsonwithout summarizing. Automatic compaction printsCompacted contextand, with the newshowAutomaticCompactionSummaryswitch on, the full summary panel. - Context budget launch override (cb118b7) —
--context <budget>selects one of the chosen model's declared local context budgets for that process, using the same272k/1m/ exact-token syntax as/context. The choice is not written tocontextSelections, and a model with one budget or one that does not declare the value is rejected. {{directories}}prompt placeholder (21d43c2) — Prompt templates gain{{directories}}, which prints the session's directory access text or nothing when there are no rules and refreshes when the live system message is replaced, including after/access.
🐛 Fixes
- Deferred stop commands (f6bbd06, f5cf4a4, 2160f58) —
/quit,/clear,/resume, and/forknow stop a busy turn even when other session work is still on the stack, stay in the Queued panel, and run in the order they were typed./clear,/resume, and/forkdrop follow-up text still waiting in the queue, and the panel reflects that. - Responses stream parsing for gateway variants (7f448ff) — Responses SSE streams that omit or reshape fields no longer throw: items without a type are skipped, a function call missing an identifier or name is rejected with a clear message, and missing usage counts are treated as absent usage. Chat Completions token names are accepted on Responses usage objects, and error events report the provider message and code from flat, nested, and
response.failedshapes. - Session access entry paths and saved rule validation (bbf7133) — Each rule records the path it was added with, so
/access remove <path>still revokes it after the entry symlink is deleted or retargeted, and invalid saved rules report a visible error instead of failing startup or replacing the current session. Theglob,grep, andsearchdescriptions now state that roots may be workspace-relative or absolute and that only the requested root is searched. - Directory access across links (2173f4c, fb3399f) — Saved directory access rules and prompt history now match a workspace by its canonical path, so defaults and history apply to workspaces reached through an ancestor link, and
--allow-readand--allow-writeresolve relative paths against the operator's workspace path rather than the resolved target. - Transcript and summary budget after microcompaction (9171dd8) — The transcript is no longer lost after a microcompacted round, and the review conversation keeps messages added later in the turn. The summary reserve is capped at half the summary window so a small context window can still send the conversation.
- Forked reasoning state (7594716) —
/forknow copies reasoning segments and the opaque reasoning state, so a forked session keeps its summaries and provider signatures instead of sharing or losing them. - Recalled slash commands in prompt history (7ce4931) — Up and Down keep walking recalled entries that start with
/without the slash picker taking over, and editing such an entry leaves history and opens the picker again. - Plugin status field ordering (40a3f43) — Plugin status snapshots are published in the order they were taken, so an in-flight update can no longer reorder text or swallow a
Clearfrom a plugin reload or close. The status sink attaches once per loaded catalog, and a failed sink's text is dropped. - Background bash output as command output (a980699) —
bash_start,bash_status,bash_logs, andbash_stopresults now count as command output, so they followverboseCommandsand command formatting in the run log instead of riding with generic results. - Markdown table width sharing (27d407d) — Table overflow is spread across the widest columns instead of one column absorbing the whole cut, so wide tables wrap into readable cells rather than a tall ribbon.
- CTX percentages (506ea17) — Used and left context percentages now show one decimal place, round to the nearest tenth, and always sum to 100.0.
- Cancellation after
bash_stop(4fb7059) — Cancellation requested while a background bash task is being stopped is now honored, so a cancelled turn or session exit completes instead of continuing.
Full Changelog: B0.8.5...B0.8.6
Beta v0.8.5
What's Changed
🚀 New Features
- Session-local background shell tasks (bf23b10) —
bash_startstarts a command in the workspace root and returns a task ID without waiting, andbash_status,bash_logs, andbash_stopobserve, read, and stop it. Tasks areWorkonly, capped at 32 active at once, keep bounded logs with stdin closed, are not persisted, and are stopped when the session closes. - Selectable per-model context windows with
/context(6196fc1) —/contextcycles the budgets declared for the active model or sets one by value, such as/context 272k, with Tab completion from that model's choices. The choice is saved per provider and model inconfig.json.contextSelectionsand drives compaction,/status, and CTX percentages. - Ranked
searchtool for file discovery (910fe71, 16e51e0) —searchmatches a .NET regular expression against workspace-relative paths and file contents and returns one ranked line per file with matching-line previews and optionalpath,glob,caseSensitive,offset, andlimitarguments. TheWorkandPlanprompts now direct the model to start withsearchwhen it does not know which files matter. - Configurable retry policies (a8a3012) —
retryandapprovalRetryinconfig.jsonsetenabled,maximumRetries,initialDelaySeconds,backoffFactor,jitterFactor, andmaximumDelaySecondsfor work turns, compaction, and the approval reviewer. A transient reviewer request failure is now retried instead of falling straight through to your approval prompt. - Host approval classifier for external tools (13e6e05, fa47d7b) — external dotnet tools can implement
IHostToolApprovalClassifier.ClassifyApprovalAsyncto classify their own calls before invocation, and the host bounds the call with a two-second budget, merges the result so it can only raise risk or authority, and fails closed on timeout, cancellation, or invalid values, disabling that classifier until the catalog reloads./toolslists a Pre-classifier column, and calls markedRequirePromptoffer only Once or Deny and cannot pass through a policy, a grant, or a reviewer Allow. - Reasoning replay across model switches (7ad11d6) — reasoning that a newly selected endpoint cannot consume as native state is replayed as assistant text, so switching models keeps the conversation instead of failing the turn.
- Endpoint-defined thinking effort tokens (f9b302c) — a model entry's
thinkingEffortsnow accepts a custom token that starts with a letter and then uses only letters, digits, and hyphens, and the host forwards it to the endpoint without interpreting it;/thinkingand--thinkingaccept the same tokens. - Unavailable thinking effort reporting (c8e7540) —
crystal runprints a note on its error stream when the requested thinking effort is unavailable for the model and continues with the provider default, and Gemini maps the portablemaximumeffort tohighbecause neither Gemini generation has a maximum level. - Anthropic
thinkingDisplayendpoint option (fb8ba48) — an Anthropic provider entry inproviders.jsoncan setthinkingDisplayin itsoptionsobject toomittedto leave the display field off a turned-on thinking block, whilesummarized(the default) asks for summarized thinking text; unknown or protocol-inapplicable options fail loading. - Declared audio and video input on model entries (2b23896) —
audioInputandvideoInputare accepted on a model entry and published to plugins, but they are declarations only: the host stores them without sending or accepting audio or video, andimageInputremains the only flag that allows media input. - Split bash timeouts with a 3-hour background default (8582c48, 87337fd) — the foreground
bashtimer now defaults to 600 seconds, backgroundbash_starttasks use their ownbackgroundBashTimeoutSecondssetting independent of the foreground timer, and that setting defaults to 10,800 seconds (3 hours). - Nested
contextSelectionsstorage (90b59a5) — saved context budgets inconfig.jsonare written as a nested{"provider": {"model": tokens}}map, and the older flat{"provider/model": tokens}form is still read and is rewritten nested on the next save. - Effective retry policies in
/status full(809e138) —/status fulland the full status overlay now report the retry and approval-retry policies in effect, including the retry count, base delay, factor, jitter, and cap. - Question tool answers as review authorization evidence (fd56a55) — answers you give to the
questiontool are marked as user evidence in the review transcript and count as user authorization, and the reviewer's transcript budgets grow to 8,000 message tokens and 4,000 tool tokens. - Approval review prompt hardening (3357034) — the reviewer now judges authorization by what your words materially permit rather than by exact phrasing, and an explicit approval of a concrete action after you were told its risk scores high even after an earlier refusal. It ignores untrusted text that tries to redefine the rules or demand approval and no longer claims to have inspected anything itself.
- Tighter compaction summaries (9739203) — compaction summaries now keep your authorized scope exact, record errors and dead ends with how they were resolved, keep unresolved failures under Blocked, and base Next Move on your most recent request.
🐛 Fixes
- Tool calls lost on Responses streams (d985841) — GPT streams that send complete arguments in
response.function_call_arguments.doneorresponse.output_item.donewithout argument deltas now produce the tool call payload, and object or array argument values are accepted as raw JSON. - Null and blank tool arguments (7625f0e) — a JSON
nulloptional string is now read as absent, blank strings pass through so each tool applies its own default, path tools fall back to the workspace root, and approval classifiers agree on the same value. - Reasoning and message items on Responses streams (8dcfddf) — each provider
output_indexand item kind pair now maps to a distinct Crystal item index, so reasoning and the following message no longer collide or share an index, and a stale reasoning state event attaches to the item that was streamed. - Background shell task limits, logs, and display (81a61a8) — background tasks now close stdin, count only active tasks toward the 32-task limit, keep the newest output when the log buffer overflows, and await the process stop in
bash_stop;Planrejects background bash side effects, and the bash tools show progress and summary text. - Context window in the header and chrome (027f0fd) — the renderer's context window now follows the selected local budget from the session status, so the header and context-window field stay in sync with
/context. - Multiple reasoning blocks in one assistant turn (d24c670) — reasoning blocks now merge in order instead of failing the request: readable text joins the assistant content in arrival order, and Ollama concatenates
thinkingtext. - Cancellation while stopping a background task (651e33b) — cancelling a turn while
bash_stopwaits for the process to stop now cancels that wait instead of ignoring the cancellation. - Non-finite retry settings and backoff overflow (d05dbb4) —
retryandapprovalRetryvalues that are NaN or infinite are rejected when settings load, and the exponential delay is clamped to the configured cap before it can overflow. - Spurious thinking-off note for models without thinking (6fedd08) — a model that does not think already omits reasoning hints, so an explicit
offselection no longer prints a fallback note fromcrystal run; named efforts on such models still report the provider default.
📝 Documentation
- Plugin-extensible status bar in planned capabilities (7af5eef) —
README.md,docs/user-guide.md, andBUSINESS.mdnow list a plugin-extensible status bar among the planned capabilities that are not yet implemented. - Open question on configurable built-in tool limits (158b018) —
BUSINESS.mdrecords that whether built-in tool limits become operator configuration is under consideration and not decided, with the current host-owned constants standing.
💬 If you run into any issues, please report them via GitHub Issues: https://github.com/YELANDAOKONG/CrystalCode/issues
Full Changelog: B0.8.4...B0.8.5
Beta v0.8.4
What's Changed
🚀 New Features
- Runtime data directories for operator plugins and external tool sets (57251b0) — Every plugin and tool set now receives a global data directory (
{home}/data/plugins/<directory>or{home}/data/tools/<directory>, shared across workspaces) and a project data directory (<workspace>/.crystal/data/plugins/<directory>or<workspace>/.crystal/data/tools/<directory>), created when the extension first receives them. Exec tools read them asCRYSTAL_TOOL_DATAandCRYSTAL_PROJECT_DATA, dotnet host tools readToolHostContext.GlobalDataDirectoryandToolHostContext.ProjectDataDirectory, and plugins receive them throughIPluginDataDirectory.
🐛 Fixes
-
Repeated usage snapshots in OpenAI-compatible chat streams (476794b) — Some vendors, such as SiliconFlow, attach usage to several chunks of one stream, which the parser treated as an error and failed the turn. The last snapshot is now kept and reported once after every candidate completes, so token usage is reported once, with the stream's final totals.
-
UTF-8 console output on Windows (4274f6f) — Switching the console code page to UTF-8 replaces
Console.Out, but Spectre's profile kept the previous writer, so the braille progress spinner and CJK text were encoded with the old OEM code page. The profile is now rebound to the liveConsole.Outwriter, so the spinner and CJK text render correctly. -
Extension data directory name validation (9cae9c5) — Data directory names must now be 1-64 characters, start with an ASCII letter, and contain only letters, digits,
.,_, or-, matching the rule that plugin and tool-set discovery already enforces. Names that start with a digit or contain spaces are rejected instead of being resolved into the home or workspace data tree.
⚡ Performance
- Anthropic prompt caching (2387fd4) — Anthropic Messages requests now mark the last system block and the last message content block with an ephemeral
cache_controlbreakpoint, so tool definitions, the system prompt, and the previous round's conversation prefix are served from the provider prompt cache instead of being reprocessed. Cached reads lower per-turn latency and token cost, including multimodal turns, where image expansion keeps the message breakpoint on the split block.
Full Changelog: B0.8.3...B0.8.4
Beta v0.8.3
What's Changed
🚀 New Features
- Named-prompt overrides and prompt-set members for every model-bound prompt (c5c912b) — Operators can now replace the Review user turn, topic naming, compaction system and user text, and image-description system and user text with
review.user.md,topic.md,compaction.system.md,compaction.user.md,image.system.md, andimage.user.mdfrom~/.crystal/prompts, a selected~/.crystal/promptsets/<name>/set, or<workspace>/.crystal/prompts. Image user templates accept the{{question}}placeholder, and/prompts exportwritesimage.system.mdandimage.user.mdalongside the existing templates.
Full Changelog: B0.8.2...B0.8.3
If you run into any problems, please report them via GitHub Issues. 🐛
Beta v0.8.2
What's Changed
🚀 New Features
- Prompt sets and prompt attachments driven by
prompt.json(7005fb7, 39ab044) — Operators can enable one Home prompt set with/promptsetorcrystal promptsets, and list, enable, disable, or reorder prompt attachments with/promptattach,crystal prompt-attachments, or--prompt-attachments. Each directory uses aprompt.jsonmanifest withenabled,order,name, anddescription, the workspace copy replaces the Home copy, and the oldconfig.jsonkeys are ignored. - Image tools through a configured image model (11e9a52) — Setting
imageModelinconfig.jsongivesPlanandWorkadescribe_imagetool that returns the vision model's text description of an image, and an image-capable session model also getsview_imageto load the file into the next round. Both follow thereadpath fence, so files outside the workspace still need approval. - Session launch overrides on the interactive commands (99aa491) —
crystalandcrystal spacenow accept the same per-process flags ascrystal run, including--approval,--plan,--work,--thinking,--prompt-set,--skills,--plugins,--model-calls, and--tool-calls. The flags shape that process only and are not written at startup. listtool for directory contents (685f161) —PlanandWorkcan list a directory's immediate entries withlist, using the optionalpath, 1-basedoffset, andlimitarguments to page through up to 1,000 entries. Directories end with a slash, and ignored build directories are skipped.- Paging for the
globtool (28cb546) —globnow takes optional 1-basedoffsetandlimitarguments and reports how many files remain, andgrepreturns up to 1,000 matches per call. - Thinking gear for the approval model (e20adfa) —
/approval thinking [effort]cycles or sets the reviewer's thinking effort and stores it inapprovalModel.thinkingEffort,--approval-thinking <effort>sets it for one process, and/statusshows it with the model. - Tab completion for approval-model arguments (5361100, 4cffb97) — Tab after
/approval modelofferson,off, and the catalog models, and Tab after/approval thinkingoffers the selected model's thinking gears. - Prompt placeholders and catalog snapshots for plugins (0ad6fae) — Plugins can add prompt placeholders and receive a read-only snapshot of the loaded plugins, external tool sets, external tools, and skills, with placeholder values resolved on every prompt bind.
- Session and review model access for plugins (3414910) — Plugins can read live session and review model facts and, when they implement
IPluginModelClient, receive side-channel clients for calling those models without entering the transcript, approval path, or turn budget. - Build and host sections in
crystal version(4219288) — The command now printsConfigurationwith the build lines and then, after a blank line,Runtimeand anOSline that includes the architecture. - Highlighted-row following in question panels (596c24c) — Moving the selection, or the cursor while editing a custom answer, scrolls the panel so that row is visible, and a manual scroll stays until the highlight or cursor moves.
- Pinned frame for scrolling overlay cards (20324b0) — A tall
/btwanswer now scrolls its rows under a fixed title and border, and PageUp, PageDown, and Ctrl+Up/Down move by the rows inside the frame. - Refined built-in Work, Plan, Review, and compaction prompts (dec9e17) — The defaults now explain the review risk levels and authorization scale, state the precedence of workspace instructions and the latest user message, keep Plan todos pending for Work, and record what was verified and how in compaction summaries.
🐛 Fixes
- Newline input with Ctrl+J and backslash-Enter in the composer (3d187fc) — Ctrl+J now inserts a newline on terminals that report it as Enter with LF, and a backslash before Enter works with the cursor anywhere in the text, not only at the end.
- Console input-mode re-arming and UTF-8 output (779ad68) — The session repeats bracketed paste and mouse reporting while it is open and turns off Windows quick edit, so the wheel keeps scrolling the transcript, and console output is UTF-8 so the braille spinner no longer shows a question mark on Windows.
- Launch overrides kept out of saved settings (9aca8a3) — A later preference save no longer writes this process's launch overrides to
config.json, and/promptsetswitching or/promptattachenable, disable, up, and down are refused while the matching--prompt-setor--prompt-attachments offflag is set. - Scrolling inside tall question panels (59f35df) — The mouse wheel, PageUp, PageDown, and Ctrl+Up/Down scroll a question panel that is taller than its slot, and only a scroll past either end or a panel that fits moves the transcript.
- Ctrl+J handling on question choice lists (bec0657) — The
J,K,H, andLshortcuts on question panels now apply only to plain keys, so Ctrl+J stays a newline. - Approval thinking gear kept out of
config.json(a675eb3) —--approval-thinkingapplies to one process only,/approval modelkeeps the saved gear, and only/approval thinkingwrites a new one. - LF line endings in model-visible tool output (69c75a0) —
read,list,glob,grep, and command output now use LF on every platform, so provider text and session files no longer vary with the host's newline convention. - Paging past the first
globmaximum (c04b426) —offsetandlimitnow page through the full match set instead of only the first 1,000 files, and only the requested page is kept in memory. - Duplicate
globmatch skipping (6fd7ee1) — A path reached more than once is reported once, so the match total and the paging offsets stay consistent. - Symlinked file entries kept distinct in workspace walks (2e56b49) — Directory enumeration yields the entry path instead of the resolved target, so two links to one file appear separately and a search rooted below the target reports the path it found.
- Prompt-attachment enable on the winning copy (c60be8d) — Enabling an attachment from
crystal prompt-attachmentsor/promptattachnow writes the Home or workspace manifest that discovery actually uses. - Trailing newlines in prompt attachments (807a5ca) — Attachment text keeps its trailing newline, so appended sections no longer run together.
- Two blank lines between appended prompt parts (0932a04) — The resolved prompt and each attachment are now separated by two blank lines.
📝 Documentation
- Git for Windows requirement for the
bashtool (a9da62e) — The README and user guide now tell Windows operators to install Git for Windows so Git Bash providesbash. - Workspace-level configuration documented as unread (6ab56fd) — The documents now state that operator preferences load only from
~/.crystal/config.jsonand that reading<workspace>/.crystal/config.jsonis deferred. Workmode tool order documented (0fc5732) — The architecture and user guide now list the built-inWorktools in registration order.- Deferred custom modes and the Plan
bashquestion documented (c254b1e) — The product document now records that modes beyondPlanandWorkare deferred and that whetherPlanmay includebashis undecided. - Multi-directory sessions on the unimplemented list (e85393e) — The product document now lists multiple accessible directories in one session as unimplemented.
Full Changelog: B0.8.1...B0.8.2
Beta v0.8.1
What's Changed
🚀 New Features
-
Manual compaction that always runs and shows its summary in an
Earlier contextpanel (309e171, 59b5fb5) —/compact(alias/summarize) now forces a summary even when the history still fits the retained tail, keeping only the latest user turn verbatim, and prints the result in a roundedEarlier contextpanel under the transcript. SetshowCompactionSummarytofalseinconfig.jsonto hide it; automatic compaction keeps printing onlyCompacted context, and a session with nothing earlier printsNothing earlier to compact. -
Sending the queued follow-up with an empty
enterwhile a turn runs (e0a7575, fbcd82f) — pressing Enter on an empty composer now sends the queued follow-up immediately by interrupting the running turn or the in-progress compaction. Pressing empty Enter with nothing queued still does nothing. -
Host context for plugin tools (becce01) — operator plugins can implement
IHostToolandIHostMultimodalToolso their tools receive the live session context, such as the workspace, on each call. -
A
{{git_root}}prompt placeholder (99ac7ae) — prompt templates can use{{git_root}}to resolve the repository root when the workspace is inside a git repository, and the environment block printsGit rootwhen one is set.
🐛 Fixes
-
Correct provider usage, tool calls, and error bodies (ba9dfec) — Gemini now reports usage once from the cumulative totals when the response completes, Ollama holds tool calls until the finish reason confirms them so non-tool finishes no longer emit phantom calls, and OpenAI-compatible errors whose body is a plain string now surface that message.
-
Plugin sessions that follow a replaced conversation or workspace (f1c34c1) —
/clear,/fork,/resume, and a workspace change now end and reopen the plugin session around the switch, so hooks and plugin tools stay bound to the live conversation and workspace. -
Skill discovery order and frontmatter validation (9ce65ce) — project OpenCode skills now override home OpenCode skills, nested
SKILL.mdfiles below a skill directory are ignored in favor of the immediate file, and whitespace-only quoted names or descriptions are rejected. -
Compaction failure handling (3d7f097) — a summarizer exception is contained to the summary round and reported as exhausted instead of escaping, and an empty candidate list now yields no summary instead of a blank one.
-
Unreadable instruction files during discovery (5cc8bcb) — instruction discovery now skips files it cannot open instead of failing the scan.
-
Reserved prompt set handling (1b95a94) — a prompt set directory named
defaultis now rejected as reserved with a clear note, anddefaultis no longer accepted as a valid set name. -
Empty side-question announcement (0436137) — the
/btwside-question view no longer announces an empty snapshot before content is available.
📝 Documentation
-
README command-line, provider, and roadmap documentation (4162f5a) — the README now documents the
crystal run,crystal space,crystal version,crystal plugins, andcrystal toolscommands, the built-in provider catalog, and a roadmap section. -
Anthropic provider setup documentation (e5cc53e) — the user guide now shows how to add a
~/.crystal/providers.jsonentry for Anthropic Messages (Claude) and setANTHROPIC_API_KEY. -
Installer alias and command section clarifications (3735744) — the README now explains the
crystalalias on Linux and macOS versusCrystalCodeon Windows, and separates everyday slash commands from shell commands. -
README badges, emoji headings, and terminal screenshot (326ee8f, d56fefa) — the README now shows status badges, emoji section headings, and a captured terminal session image.
-
Deferred model-list fetching in the roadmap (f3650b3) — the README and user guide now list automatic provider model-list fetching as planned but not implemented, and the README screenshot moved below the navigation links.
Full Changelog: B0.8.0...B0.8.1
Beta v0.8.0
What's Changed
⚠️ Heads up: This release contains a large number of changes. Please back up your data, including~/.crystaland your saved sessions, before upgrading.🐞 Found a problem? Please report it on GitHub Issues: https://github.com/YELANDAOKONG/CrystalCode/issues
🚀 New Features
- Operator space at
{home}/space(68ab0ee, 8349152, 371b4a7) —crystal spaceopens the terminal there,/spaceswitches a running session to it, andcrystal run --spaceruns one headless task there. The directory is trusted without a prompt or atrusted.jsonentry and is created when missing, and--spacecannot be combined with--workspace. - Session resume by id, directory, or all workspaces (a586451) —
crystal --resume [id]and/resumechoose a saved session: omit the value to list the current workspace, pass a directory to list it and enter it, passallto list every workspace and enter the chosen session's directory, and pass an id to load that file in place. - Workspace trust for directories (776201e, ca3aaeb) — The first interactive launch in a directory asks whether to trust it when
workspaceTrustis on, remembering a yes in~/.crystal/trusted.json;/trust on|off|forgetmanages the current root and/cdinto an untrusted root asks again.crystal runrefuses an untrusted directory unless--workspace-trust offis passed, and the prompt is framed in a bordered panel. - Per-directory plugin and tool-set switches (4c9f34f) —
/plugins enable|disable|show <directory>and/tools enable|disable|show <directory>change or show one manifest, andcrystal pluginsandcrystal toolsdo the same outside a session with--source home|projectand--format text. - Expanded plugin hooks (51a8a5c, 4c3b2dd, 229c9bc, 117ead8) — Hooks now cover user messages, outbound model requests, and completed model responses, and raw hooks can rebuild one model request or replace the composed prompt, compaction, and approval text.
- Full conversation archive (659f405) — A session keeps the full conversation for resume, fork replay, and export while compaction rewrites only the model context, so earlier turns are no longer lost from the screen or saved history.
- Turn stops on unusual finish reasons (37b751d) — A turn stops before tools when the model does not finish normally; truncated output and a content filter keep the text and end the turn, and unsupported requests are rejected instead of fabricated. Gemini 3 models disable
/thinking offand showThink Defaultfor a stored Off. - Side-question reasoning and Ctrl+C (8e27eda) — The
/btwpanel showsThinkingonce reasoning starts, and Ctrl+C closes the panel or cancels an in-flight side question while the main turn keeps running. crystal versioncommand (072f13c) —crystal versionandcrystal --versionprint the product commit, the Crystal library commit, the SDK, and the runtime, then exit without opening the terminal.- Terminal-safe rendering and transcript scrolling (e746d54, 76a3d29, 45c73cf) — Displayed text is stripped of terminal control sequences and every frame row stays within the terminal width while the transcript scroll stays anchored. The mouse wheel scrolls the transcript,
Up/Downstay with the composer, and text selection needsShift. - Local development install scripts (a121b38) —
sh scripts/install-local.shandscripts/install-local.ps1publish the current checkout as a self-contained single-file Release and replace~/.crystal/binaries/code/while leaving configuration, credentials, and prompts in place. - Verbose thinking panel toggle (6303a32) — The
verboseThinkingsetting and/verbose thinkingshow or hide Thinking cards, including cards restored with a saved session, and are surfaced in/statusand the status widget. - Verbose approval card toggle (fd2f577) — The
verboseApprovalssetting and/verbose approvalsshow or hide auto-pass approval cards, including cards already in the transcript, while the ask overlay always appears. [Assistant]label for replies when thinking is shown (fb04a8b) —crystal run --show-thinkingprints each assistant reply under an[Assistant]heading so a blank line in the thinking block cannot make it ambiguous.
🐛 Fixes
- Refuse workspace changes while a turn is running (4a7ee18) —
/cdand/spaceare refused while a turn is running instead of switching the workspace mid-turn. - Base tool calls on the finish reason and the tool budget (0f974fd) — Streaming turns keep the assistant text and reasoning and drop tool calls when a batch exceeds the tool-call budget, and Gemini emits function calls only for a tool-request finish reason.
- Count stats tools from the archive when context is compacted (2004557) —
/statstool counts and the tool share now read the conversation archive, so a compacted session still reports its tools. - Base side questions on the live turn with reconciled tool calls (1723d7c) —
/btwuses the in-progress transcript during a turn and appends synthetic failure results for tool calls that have no result. - Keep the terminal usable when Ctrl+C cancels a prompt (aee5a78) — Cancelling a prompt with Ctrl+C restores the terminal instead of leaving the alternate screen in a broken state.
- Keep markdown inline styles intact across wrapped rows (231b0f3) — Bold, italic, and code spans survive a row break, and underscores inside identifiers such as
__init__stay literal. - Ignore empty Enter while a turn is running (6a3b44b) — Submitting an empty composer during a turn is a no-op instead of cancelling the turn and firing the queue; Ctrl+C still interrupts.
- Keep trailing-enter and edit-key bursts as composer keys (37f8264) — A printable burst ending in one newline, or containing
BackspaceorDelete, stays in the composer instead of submitting as paste. - Honor verbose switches in inline output (8b123a6) — The verbose thinking, tool, command, and approval switches now also hide their categories in the inline fallback used when the alternate screen is unavailable.
- Flatten displayed line breaks and anchor the scroll on one row (9c92eaa) — Carriage returns, line breaks, and tabs are flattened to spaces so no chrome row keeps a bare control character, and the scroll anchor resolves to the row the operator is reading.
- Keep a split carriage return as a single line break (a6a7253) — A carriage return at the end of a stream chunk waits for the next chunk so a following line feed folds into one break instead of leaving a blank row.
- Undo every enabled mode when alternate screen setup fails (20759cb) — A failed alternate-screen setup restores the title, alternate scroll, and bracketed paste, then leaves the alternate buffer.
- Leave the alternate screen when setup fails (d29df31) — The main screen is restored when enabling the alternate screen throws after the escape was written.
- Label the first running tool call and drop overflow keys (27864e1) — The running-tool activity label uses the first call name, and drained keys are discarded instead of attaching an unfinished escape to the next key.
- Replace the install directory atomically with rollback (b5e250d) — The install scripts move the live tree aside and restore it on failure or interrupt, so a failed replace no longer leaves the install missing.
- Accept the .NET 11 SDK in local install tooling (f9b23c9) —
scripts/install-local.shandscripts/install-local.ps1accept the .NET 10.x and 11.x SDKs.
⚡ Performance
- Snapshot the session archive once when writing state (2477c05) — Session writes take a single archive snapshot and compute referenced image markers in one pass, retrying once if the archive changes underneath.
📝 Documentation
- Deferred TUI provider editing documented (5323b89) — The guide now states that editing providers from the TUI is deferred.
- Hook projection and dependency scope clarified (9e71696) — The plugin docs explain future hook methods and the plugin dependency scope.
- Model hook projection and one-hook registration documented (e092f19) — The plugin docs describe model hook projection and how a plugin registers one hook.
- C# Code Organization skill points to the sibling Clean Code skill (6f46cf7) — The skill now references the sibling C# Clean Code skill.
commit.shmaintenance helper documented (7525498) — The README documents thecommit.shmaintenance helper.- Test portability requirements noted (a13a470) —
STANDARDS.mdnow notes the portability requirements for tests.
Full Changelog: B0.7.0...B0.8.0
Beta v0.7.0
What's Changed
🚀 New Features
- Native Gemini and Ollama protocols (68d4933) —
geminiandollamasit beside DeepSeek, OpenAI, Responses, and Anthropic. Gemini usesx-goog-api-keyand generateContent SSE. Ollama uses/api/chatand can run without an API key - External tool timeouts (db31f73) —
timeoutSecondsstops a dotnet or exec call and kills its process tree.unlimiteddisables only that timer. stdout and stderr drain together, and only the model-visible prefix is kept - Write and edit outside the workspace (4462a60) — an absolute path is outside-workspace work and goes through approval. Edit and Full ask the operator. Review and Audit send it to the reviewer. Credential paths stay forbidden, including a symlink that leaves the workspace
- Headless
crystal run(4466ca7, cf665b5, aeb6df8, 61e9e6b) — one unattended turn. Overrides stay in that process, and slash commands are rejected. Exit codes are 0 through 5.--format jsonprints JSON Lines with the full tool output.--format defaultprints a shortened trace, with host markers kept apart from tool text - Host placeholders (979e088) —
{{os}},{{architecture}},{{time}},{{session_id}}, and{{approval}}bind into the system message,{{env}}, and the prompt template export - Image results from exec tools (ea886ae, af2d59b) —
"output": "content"reads one JSON object from stdout, with text and up to eight images. Gemini and Ollama attach those images on the tool result. A text-only model rejects them - Host context for dotnet tools (d4b2902) —
IHostToolandIHostMultimodalToolreceive the workspace, session id, and approval mode throughToolHostContext. Credentials and the home path are left out - Independent tool calls in one response (c68b540) — Work and Plan prompts tell the model to send every call it can already specify together, and to wait only when the next step depends on a result
- Separate approval model (60e76ee) — Review and Audit can use
approvalModelinconfig.json, with that provider's credentials./approval modelshows or sets it.crystal runcan override it for one process /effortas an alias for/thinking(09b22e4)/stats(5b3336c, 6715da3, 8871775, c1314de) — token totals, averages, median, and a per-tool share bar, includingall,<Nd>, andtools <count>. The page replaces the session frame. Esc,q, or Ctrl+C closes it and keeps the composer draft/btwside questions (3a4741d, b9823ad, bb2ce51) —/btwor/sideasks from the committed transcript plus the newest 20 side exchanges. The answer stays in a panel and is not saved. Until text arrives, the panel shows the progress spinner. Esc, Enter, or Space closes it. Left and Right step.xclears. Ctrl+C cancels only the side question- Reasoning kept in the session (bd16ed2) — reasoning text and provider state survive save, export, replay, and compaction. A provider error that survives retry closes the turn as failed and saves the transcript
- Front-end-neutral engine (2587a56) — session execution lives in
CrystalCode.Engine. The terminal host only draws. Built-inbashusesbashTimeoutSeconds, default 120 seconds.nullorunlimiteddisables that timer
🐛 Fixes
- Windows x64 install without the runtime architecture API (3a2134d) — the installer reads
PROCESSOR_ARCHITEW6432, thenPROCESSOR_ARCHITECTURE, and treats AMD64 as supported - Wheel scroll stays distinct from arrow keys (3f7087f) — the alternate screen enables SGR mouse reporting, and the previous Windows console input mode is restored on exit
- Tabs and one size snapshot per frame (ab4e012) — tabs are four columns in the composer and painted rows, one column stays free for the cursor, and overlays reproject the composer from that same size
- Workspace path checks follow the real target (bd16ed2) — symbolic links resolve to their final target. Workspace-relative
.ssh,.gnupg, and.crystal/credentials.jsonstay forbidden for write, edit, glob, and grep. Prompt history is trimmed per workspace - Side-question panel after a pause (bb2ce51) — a tab no longer clips the panel border, the card lines up with the other cards, and an open
/btwpanel returns after an approval or question. A dismissed panel stays closed
⚡ Performance
- Live transcript cards reflow only the open tail (dce8a4a) — finished rows stay wrapped. Scrolling and typing reuse those rows
📝 Documentation
- A future Avalonia front end must use C# markup, with no XAML or AXAML files (d4d9821)
Full Changelog: B0.6.0...B0.7.0