- Added `supportsMultipleSystemMessages?: boolean` to `OpenAICompat` for configurable multi-system handling.
- Added OpenAI-compat host detection, allowing per-host multiple-system defaults and explicit override control.
- Updated `convertMessages` to merge system prompts when disabled, while preserving separate system messages when enabled.
- Added tests for merged-vs-split system prompts, MiniMax/Qwen strict-template behavior, and override defaults.
- Added a new `scrubProcessEnv` helper in `procmgr` to remove macOS malloc logging variables from `process.env` before spawning.
- Invoked the helper at coding-agent CLI startup so bun sub-processes no longer inherit the problematic environment.
- This prevented the recurring `MallocStackLogging` warning from appearing in child process stderr output.
- Added optional `/loop` `count|duration` command arguments and wired `command.args` into loop handling.
- Implemented `loop-limit` parsing and runtime types/helpers for iteration and duration budget limits with validation.
- Updated interactive mode to enforce loop limits per iteration, check duration expiry, and clear budget state on disable.
- Added loop-limit parse/runtime tests and fixed `/loop` arg errors plus macOS `MallocStackLogging` environment leakage.
- Rendered diff content before the truncation notice instead of after.
- Updated hidden lines label to show count with "+" prefix.
- Added fallback label when no lines are hidden.
- Removed the read CLI argument and tool schema field so read requests no longer accept custom timeouts.
- Updated URL read handling to stop forwarding timeout values and execute URL reads without a timeout parameter.
- Standardized URL read fetching to a fixed 30-second timeout and dropped timeout metadata from URL call rendering.
- Removed [blocked]-focused instructions from failure handling and pre-yield checks in the system prompt.
- Eliminated the separate completion-honesty block and folded stronger end-to-end-completion language into the contract sections.
- Reworded output and critical-response guidance to focus on continuous progress and completion-only yielding.
- Added a readonly intent property to the write tool implementation.
- The intent now returned a contextual message using `args.path` when available, otherwise a generic "writing" label.
- Exported hashline section interfaces and helpers, including a new section-diff API for external callers.
- Refactored `computeHashlineDiff` to split input sections, propagate split errors, and delegate each section via helper.
- Added context-highlight caching and batched highlighting for unchanged lines, with `replaceTabs` fallback on unknown files.
- Fixed hashline streaming preview so completed sections stay visible when a new `@PATH` header appears mid-stream.
- Added hashline streaming tests for section persistence, malformed trailing `+ 7`, and dual sections.
- Adjusted streaming preview formatting to render the tail section using a computed start index and hidden-line count.
- Passed language into streaming formatting to syntax-highlight visible lines and include aligned line-number gutters.
- Updated the hidden-lines notice to handle singular vs plural earlier-line counts correctly.
- Added a new `orchestrate.md` prompt under `src/prompts/commands` defining an orchestrator workflow, verification gates, and anti-patterns.
- Imported and rendered the prompt in `src/task/commands.ts` as `orchestrateMd`.
- Appended the new prompt to `EMBEDDED_COMMANDS` so it is registered with existing embedded command templates.
- Updated the hashline prompt to require replacement ranges to cover entire statements or expressions, preventing broken syntax when applying changes.
- This clarified how replacement anchors should be chosen for function calls, literals, blocks, and control-flow branches.
- Updated the write tool preview renderer to syntax-highlight visible lines and annotate them with line-number gutters.
- Changed the file metadata output to an inline line-count suffix on the header and removed the separate metadata row.
- Adjusted preview truncation to show the first lines first while preserving hidden-line hints for collapsed output.
- Added a new completion-honesty section to the coding-agent system prompt with stricter delivery constraints.
- The prompt now requires all acceptance criteria to be met before completion, prohibits scope reduction without approval, and forbids delivering stubs, placeholders, or fake implementations as finished work.
- Verification language was tightened so completion claims must reflect actual verification and not be inflated by partial checks.
- Added `.ipynb` detection and editable-cell conversion utilities, including merge/serialize helpers in `edit/notebook`.
- Rerouted hashline, patch, and replace edit flows, plus read/write paths, through notebook-aware helpers before persistence.
- Removed the dedicated `notebook` tool, its schema flags, renderer, and built-in registration/settings checks.
- Updated notebook read behavior, docs, and tests so `.ipynb` reads return editable `# %%` cells and edits reserialize to JSON.
- Removed persona preambles ("You are an expert...") in favor of direct imperatives.
- Stripped redundant MUST/SHOULD modals where plain prose suffices.
- Condensed multi-sentence instructions into tighter single-line equivalents.
- Updated the `init` operation to require a `list: [{phase, items: string[]}]` payload and to replace any existing list.
- Updated the `append` operation description to state tasks are appended to a given `phase` and that the phase is lazily created.
- Added optional `loadMode` and `summary` fields to `AgentTool` and related type declarations.
- Added `loadMode` and `summary` metadata to built-in tool classes for discoverable/essential behavior.
- Replaced `BUILTIN_TOOL_METADATA` with per-tool fields in discovery code paths.
- Updated `search_tool_bm25` and discovery indexing to use each tool's `summary` text.
- Updated discovery tests to validate tool `loadMode` and summary completeness.
Restore BUILTIN_TOOLS to Record<string, ToolFactory> so external SDK callers can
still invoke BUILTIN_TOOLS.read(session) directly, and move per-tool discovery
metadata (loadMode, summary) into a dedicated BUILTIN_TOOL_METADATA map. All
internal callers (computeEssentialBuiltinNames, getBuiltinDiscoverableEntries,
createTools, sdk.ts initial-tool filter, agent-session built-in collection) now
read metadata through the new map.
Restore the legacy MCP discovery API on AgentSession: getDiscoverableMCPTools()
returns DiscoverableMCPTool[] with description, and getDiscoverableMCPSearchIndex()
returns the legacy DiscoverableMCPSearchIndex whose documents expose
tool.description while remaining usable by searchDiscoverableTools (summary is
populated from description so the BM25 corpus still scores correctly). Generic
discovery via getDiscoverableTools / getDiscoverableToolSearchIndex is unchanged.
Centralize discovery cache invalidation in #invalidateDiscoveryCaches and call it
from #applyActiveToolsByName, refreshMCPTools, and refreshRpcHostTools so the
generic search index can no longer return tools that have already been activated
or registry entries that have been replaced.
Restrict #collectDiscoverableBuiltinTools to entries whose
BUILTIN_TOOL_METADATA[name].loadMode === "discoverable", which keeps hidden
tools (resolve, yield, exit_plan_mode, report_finding, report_tool_issue) and
unknown extension/custom registry entries out of the discovery corpus.
Tests: add coverage for callable BUILTIN_TOOLS factories, legacy MCP description
shape on getDiscoverableMCPTools / getDiscoverableMCPSearchIndex, stale-index
invalidation on setActiveToolsByName, and hidden-tool exclusion from
getDiscoverableTools({ source: "builtin" }).
Wired the generic discovery methods on AgentSession into the tool
factory session, resolved the effective discovery mode (tools.discovery
Mode wins; mcp.discoveryMode as back-compat alias for "mcp-only"),
and threaded the resulting flag into rebuildSystemPrompt so the prompt
template fires the discovery hint for both legacy and new modes.
Added the load-bearing filter in createAgentSession: when the
effective mode is "all", drop any built-in tool whose loadMode is
"discoverable" from the initial tool set unless it is essential per
computeEssentialBuiltinNames, was explicitly listed via
options.toolNames, or was restored from persistence. The model finds
hidden tools via search_tool_bm25 and activates them on demand.
Built-in activation persistence is intentionally limited to the
existing MCP persistence store for this PR; full discovered-tool
persistence is a follow-up.
The internal class is now SearchToolsTool but the wire name stays
"search_tool_bm25" so persisted MCP selections in user session files
continue to resolve correctly.
The BM25 corpus is now drawn from the generic DiscoverableTool list
(built-ins, MCP, extension, custom) rather than only MCP tools.
createIf fires when either tools.discoveryMode !== "off" or the
legacy mcp.discoveryMode is true.
AgentSession gains generic discovery methods (isToolDiscoveryEnabled,
getDiscoverableTools, getDiscoverableToolSearchIndex,
getSelectedDiscoveredToolNames, activateDiscoveredTools). The existing
MCP-named methods are kept as thin shims that filter by
source === "mcp" so existing callers continue to work.
Updated the tool's prompt copy to advertise discovery across all
sources rather than MCP only. Tests extended for the new shape.
Added two settings:
- tools.discoveryMode ("off" | "mcp-only" | "all", default "off")
- tools.essentialOverride (string[], default empty)
Converted BUILTIN_TOOLS from Record<string, ToolFactory> to
Record<string, BuiltinEntry> with a per-tool loadMode ("essential"
or "discoverable") and an optional summary used as the BM25 corpus
entry when discovery hides the tool.
Marked read, bash, edit as essential. Marked the remaining 24 built-in
tools as discoverable with hand-written summaries. search_tool_bm25
stays essential (always loaded when discovery is on; gated separately
by isToolAllowed).
Added DEFAULT_ESSENTIAL_TOOL_NAMES, computeEssentialBuiltinNames
(reads tools.essentialOverride with a default fallback), and
getBuiltinDiscoverableEntries (used by the search tool to build the
BM25 corpus).
mcp.discoveryMode is preserved as a back-compat alias for "mcp-only".