Commit Graph
9801 Commits
Author SHA1 Message Date
roboomp 527c68c72b fix(session): waited for persistence before compaction rearm
Move the dead-end rearm probe below the mid-run turn-persistence barrier so prepareCompaction sees the just-finished assistant and tool result.

Delay message-end persistence in the regression and require compaction at the second tool boundary, before another provider request can be sent.

Fixes #7151
2026-07-31 08:48:25 +00:00
roboomp f6878d3739 fix(session): re-arm mid-turn compaction after new cut points
The dead-end mark parked the live tool-loop context permanently, but the array keeps growing: a later smaller tool result can move the oversized turn to the summarizable side. Recheck prepareCompaction each boundary and re-attempt once a cut point appears, instead of suppressing until provider overflow.

Added a regression proving maintenance re-attempts once a cut point becomes available.

Fixes #7151
2026-07-31 08:37:56 +00:00
roboomp ae7038f9d3 fix(session): stopped repeated mid-turn compaction dead ends
Remember no-progress mid-turn compaction results for the live agent-loop context so later tool boundaries skip identical rescue work. The weak context key naturally resets for the next user turn.

Added a scripted regression covering one warning and one attempt per oversized tool-loop turn.

Fixes #7151
2026-07-31 08:25:00 +00:00
metaphorics 54bf138cab feat(keybindings): accept shift+up for the steering dequeue
macOS Terminal.app consumes Option for character composition, so Alt+Up
never reaches the app and the dequeue is unreachable there. Bind Shift+Up
alongside it -- Shift is not intercepted, and the key was unbound in the
input path.

The three overlay handlers that already use shift+up for fast scroll
(scroll-view, model-hub, log-viewer) match keys directly rather than
through the manager, so they never see this binding.

Both default tables move together: the registry in config/keybindings.ts
and DEFAULT_ACTION_KEYS in custom-editor.ts, which silently shadows the
registry when they disagree.
2026-07-31 16:53:11 +09:00
iacore fcf6d65140 fix(coding-agent): resolve the secret placeholder key lazily for builtin credential entries
Appending builtinCredentialSecretEntries() unconditionally made every
secrets.enabled session carry a regex obfuscate entry, so
secretEntriesNeedPlaceholderKey was always true and startup always
created secret-placeholder.key — nullifying the replace-only/no-secret
key-avoidance path and failing headless runs on an unwritable config
root for a feature they never use.

Only configured entries now force startup key creation. The built-in
credential pattern matches dynamically, so SecretObfuscator accepts a
key provider resolved once on the first actual credential match, via
the new getSecretPlaceholderKeySync (never throws: degrades to a
process-ephemeral key with a warning when the key file is unwritable).

Also moves both CHANGELOG entries from the released 17.1.7 sections to
[Unreleased].
2026-07-31 13:38:09 +08:00
Alex Jaden daa9b99aab fix(coding-agent): preserve scrollback on appearance changes 2026-07-31 10:34:43 +05:00
Dan Greco 9bb96b22e7 fix(bash): scope shell snapshots per uid so shared-/tmp accounts don't EACCES
- The snapshot dir was one fixed name under the shared `os.tmpdir()`,
  created 0700 because the script inlines env-var values referenced by
  captured functions (#3470). The first account to run omp owns it, so on
  a box where a second Unix account runs omp every bash tool call died
  with `EACCES: permission denied, open
  '/tmp/omp-shell-snapshots/snapshot-bash-<uuid>.sh'`.
- `recursive: true` swallows EEXIST and `mode` is ignored for an existing
  dir, and the defensive `chmodSync` fails EPERM on a foreign-owned dir
  and was already swallowed, so the code walked straight into a dir it
  could not write.
- `mkdirSync` and the pre-create `writeFileSync` both sat outside any
  try/catch, so the error escaped `getOrCreateSnapshot` into
  `executeBash`. Nothing is cached on failure, so it repeated for every
  command instead of degrading once.
- Scope the dir per uid (`omp-shell-snapshots-<uid>`) and guard both
  filesystem calls: an unusable dir now logs at debug and returns `null`,
  which callers already handle as "run without a snapshot".
2026-07-30 22:54:33 -04:00
roboomp 4119bc461e fix(agent): resolve xd:// notice after final prompt override
A before_agent_start extension can replace the base system prompt after the
mount notice was consumed. Catalog-backed additions were then marked
announced and suppressed even though the provider request no longer contained
the catalog.

Reserve the notice's pre-user message position, wait until the extension has
selected the final prompt, and suppress catalog-backed additions only when no
per-turn replacement dropped the base catalog. Explicit replacements retain
the mount notice as the device-discovery channel.

Fixes #7139
2026-07-31 02:45:21 +00:00
roboomp 0213f1c439 fix(agent): defer xd:// announce suppression to notice delivery
Marking rebuild-exposed devices announced (and deleting them from the pending
delta) at rebuild time broke add/remove coalescing: a device mounted by
deferred discovery then unmounted before the first user prompt would leave the
device marked announced with the add already gone, so the unmount produced a
spurious "No longer mounted" notice for a device the model never saw.

Record the catalog the current base prompt exposes in #basePromptXdevNames and
apply the suppression in takePendingXdevMountNotice at delivery instead. The
pending delta is left untouched by rebuilds, so #notifyXdevMountDelta still
cancels an undelivered add against a later remove.

Fixes #7139
2026-07-31 02:36:34 +00:00
roboomp d77dd10e5b fix(agent): suppress redundant xd:// mount notice after catalog rebuild
On a fresh session with deferred MCP discovery the post-discovery prompt
rebuild renders the full mounted xd:// device catalog, yet the pre-user
xdev-mount-notice re-listed the same names because announcement tracking was
never updated by the rebuild. This double-billed the entire mounted MCP
inventory into the first model request.

rebuildSystemPrompt now reports the catalog it rendered via
BuildSystemPromptResult.xdevCatalogNames, and applyActiveToolsByName folds
those devices into the announced-mount baseline (marking them announced and
dropping them from the pending delta). Notices for mount changes the rebuild
did not expose, and all unmount notices, remain intact.

Fixes #7139
2026-07-31 02:27:38 +00:00
Wolfgang Schoenberger dc292d4c84 fix(task): track deferred model refresh 2026-07-30 18:34:40 -07:00
roboomp bf1643483d fix(telemetry): merge OTEL_RESOURCE_ATTRIBUTES into export resource
Env-driven OTLP trace export built its resource from only service.name,
so OTEL_RESOURCE_ATTRIBUTES entries were silently dropped and backends
that attribute spans via resource attributes never received them.

Merge the vendored envDetector into the resource, which parses
OTEL_RESOURCE_ATTRIBUTES (percent-decoded, per spec) with OTEL_SERVICE_NAME
taking precedence for service.name.

Fixes #7134
2026-07-30 23:38:30 +00:00
Wolfgang Schoenberger 5f9558d17a fix(tools): keep truncation metadata when spilling read output
The artifact spill wrapper dropped the read truncation metadata, so a
spilled oversized read lost its next-offset pagination hint, and an
artifact:// read of an already-spilled result was spilled a second time.
Preserve the existing truncation metadata and skip re-spilling artifact
reads.
2026-07-30 16:25:48 -07:00
Alexander Kirilin bb76178f55 fix(omp): honor tree navigation order 2026-07-30 19:11:27 -04:00
Wolfie 3492f45ac1 fix(session): drain batches from flushSync 2026-07-30 16:09:32 -07:00
Wolfie b3ab92ce90 fix(session): expose synchronous batch drain 2026-07-30 16:09:30 -07:00
Alexander Kirilin 40a3c256b7 docs(omp): show tree paging aliases 2026-07-30 19:05:43 -04:00
Alexander Kirilin 5c9895c01e feat(omp): page through session tree 2026-07-30 18:57:45 -04:00
can1357 61c6e9a80f feat(coding-agent/modes): added file hyperlinks to path status line segments
- Wrap status line path segment labels and worktree names in file hyperlinks.
- Apply hyperlink generation using the project directory and rendered path text.
2026-07-31 00:40:27 +02:00
Wolfgang Schoenberger 070167dd4a perf(tui): batch persistence work off the render path 2026-07-30 15:35:38 -07:00
Alexander Kirilin 5289deb8a5 feat(omp): traverse conversation turns in tree 2026-07-30 18:33:11 -04:00
Alexander Kirilin dec2970994 feat(omp): jump to conversation turns in tree 2026-07-30 18:21:35 -04:00
can1357 652647770e feat(coding-agent): added app.live.toggle keybinding and map display reset to alt+l
- Add the `app.live.toggle` keybinding defaulted to `Ctrl+L` to start or stop live voice mode.
- Remap the default display-reset action (`app.display.reset`) from `Ctrl+L` to `Alt+L`.
- Update the live visualizer to listen for stop keys so the toggle chord terminates active sessions.
2026-07-31 00:20:04 +02:00
can1357 5ea583e413 feat: replaced legacy editing commands with unified put and cut syntax
- Replaced legacy `SWAP`, `INS`, and `PASTE` commands with unified `PUT` and `CUT` hunks across parser, grammar, tokenizer, and test suites.
- Added support for named registers and span paste operations in clipboard and block execution logic.
- Implemented indentation repair and enhanced gap locator formatting for improved patch resilience.
- Updated documentation, system prompts, and session analysis scripts to reflect the new syntax and header shapes.
2026-07-31 00:19:52 +02:00
Wolfgang Schoenberger 26e422a00a fix(coding-agent): suppress WIP advisor non-blockers 2026-07-30 15:18:06 -07:00
Wolfgang Schoenberger 37a4adfcea perf(task): defer subagent launch setup 2026-07-30 15:16:47 -07:00
roboomp 81e34d90ad fix(web-search): extract duckduckgo result timestamps for date bounds
DuckDuckGo does not parse after:/before: operators, so the provider relies
on the shared lenient post-filter to enforce them. But parseHtmlResults()
discarded the ISO timestamps DuckDuckGo now emits per result row, so every
source was undated and passed the date filter unconditionally.

Extract the timestamp span into publishedDate/ageSeconds so
applyQueryConstraints can honor the requested window.

Fixes #7115
2026-07-30 22:10:04 +00:00
roboomp a07d782058 fix(search): paginated duckduckgo results
Followed DuckDuckGo's returned continuation form until the requested result limit is satisfied, preserving deduplication across pages and the existing search deadline.

Added regression coverage for continuation field submission and 20-result collection.

Fixes #7116
2026-07-30 22:09:44 +00:00
Wolfgang Schoenberger 9a6a1b40be fix(coding-agent): spill oversized read results to artifacts 2026-07-30 15:04:52 -07:00
roboomp 942f856b29 fix(web-search): derived duckduckgo lang from raw query
callDuckDuckGoHtml now parses params.query once when parsedQuery is absent and uses that structured view for both q and kl. Direct searchDuckDuckGo/DuckDuckGoProvider.search calls no longer strip lang: from q while defaulting kl to us-en.

Fixes #7110
2026-07-30 21:55:47 +00:00
roboomp 8cf4e30a61 fix(web-search): validated duckduckgo locale codes
Replaced unrestricted locale component swapping with DuckDuckGo's documented kl allowlist and explicit aliases for provider-specific codes such as jp-jp, kr-kr, tw-tzh, and uk-en. Unsupported locale combinations now fall back to the existing us-en default instead of sending invalid kl values.

Expanded regression coverage for Japanese, Korean, Traditional Chinese, and unsupported region-language combinations.

Fixes #7110
2026-07-30 21:53:44 +00:00
roboomp 9cd42dd8f9 fix(web-search): honored lang: directive in duckduckgo kl param
callDuckDuckGoHtml hardcoded kl=us-en and never read parsedQuery.lang, so
the shared lang: directive was silently discarded — unlike the Perplexity
and SearXNG providers, which map it. Distinct locales collapsed to the same
request.

Added localeToKl mapping the parsed language-region locale onto DDG's
region-language kl code (swapping components, gb->uk alias), falling back to
us-en for language-only, malformed, or absent locales.

Fixes #7110
2026-07-30 21:47:03 +00:00
roboomp 18594e01d8 fix(coding-agent): keep terminal-failure tool cards; settle re-keyed completions
Address Codex review on #6881. Retraction of never-run tool cards no longer runs eagerly at message_end: only a TTSR rewind (known via isTtsrAbortPending) retracts there. A terminal error/abort lets agent-loop's synthetic tool_execution_end settle each card in place so the failure stays visible, and an auto-retry removes those synthetic-settled cards only when auto_retry_start actually supersedes the turn.

Also settle a held server-resolved (Cursor/todo) completion after a mid-stream tool-call id re-key, so the migrated card is not stranded pending.

Fixes #6879
2026-07-30 21:29:54 +00:00
Márton Danóczy 38f63b792a fix(acp): preserved whitespace-only editor prefill
editor's prefill is the actual document being edited, not a placeholder
like input's — the interactive (hook-editor.ts) and RPC implementations
set it verbatim on any truthy value. Trimming before the presence check
silently dropped whitespace/blank-line prefill content from the ACP
elicitation schema, so a client-side form opened empty and accepting it
could not reproduce the extension's supplied indentation.

Now only a genuinely empty string omits `default`; any other prefill,
including whitespace-only, passes through unchanged.
2026-07-30 22:53:54 +02:00
Márton Danóczy 490bdd3c4b docs(acp): fixed stale editor-stub note in createAcpExtensionUiContext JSDoc
The factory-level doc comment still listed editor among the non-elicitation
surface that 'remains stubbed', contradicting the elicitation bridge added
in ec3144860. Reflows the sentence without changing its meaning otherwise.
2026-07-30 22:53:54 +02:00
Márton Danóczy f62e528042 acp: wire ctx.ui.editor through elicitFromAcpClient
createAcpExtensionUiContext stubbed editor as a hardcoded no-op
(async () => undefined), so free-text elicitation requests from
/review's custom-instructions branch and the ask tool's custom-input
path never reached the client and silently resolved to undefined.

Wire editor through the existing elicitFromAcpClient bridge used by
select/confirm/input, using a {type: "string"} schema with default
set to the prefill text when non-blank.

Verified against a real stdio JSON-RPC transport via acp-probe: the
elicitation/create request now fires with the expected schema and
round-trips the accepted value back to the prompt without hanging.

Adds matching unit test coverage in acp-agent.test.ts mirroring the
existing select/confirm/input bridge tests (prefill->default mapping,
whitespace-prefill omits default, decline/cancel->undefined, no-form
fallback).
2026-07-30 22:53:54 +02:00
roboomp 8d0a193f19 fix(rpc): guarded IRC wake recovery by prompt generation
- Captured the prompt generation before an IRC wake and passed it to the post-prompt recovery wait.
- Stops the wait from following a successor turn once an abort supersedes the wake, so the wake monitor finalizes promptly instead of misattributing successor progress.

Fixes #7105
2026-07-30 20:16:20 +00:00
roboomp d686375b8c fix(rpc): monitored IRC wakes on cold-revived subagents
- Extracted the shared attachIrcWakeTurnMonitor from the executor reviver closure.
- Installed it in the persisted cold-revive path, forwarding the top-level event bus.
- Covered that a resumed process's parked subagent emits wake lifecycle frames.

Fixes #7105
2026-07-30 20:08:21 +00:00
roboomp 4670a34590 fix(rpc): waited for IRC wake session settlement
- Kept IRC run monitors attached through post-prompt retry and continuation recovery.
- Flushed the final deferred agent_end before terminal lifecycle emission.
- Covered empty-stop retry ordering for RPC event subscribers.

Fixes #7105
2026-07-30 19:53:39 +00:00
roboomp b2d18b6920 fix(rpc): restored frames for IRC-revived subagents
- Monitored autonomous IRC wake turns with the task executor lifecycle and progress channels.
- Preserved monitoring after idle-TTL parking and session revival.
- Covered RPC subscriptions for both idle and parked keep-alive agents.

Fixes #7105
2026-07-30 19:42:58 +00:00
David Andrews 7928353e02 fix(tui): preserve assistant code copy 2026-07-30 15:27:21 -04:00
Larry Gordon e8d9f15e9d fix(extensions): inherit the wrapper call's abort and progress channels
A bare ctx.invokeTool(params) passed undefined for both signal and onUpdate,
so a wrapper that simply delegates did not stop the native tool when the
outer call was aborted, and native progress updates were dropped unless every
wrapper forwarded them by hand.

createContext now takes the delegation wiring as one named object and binds
the wrapper's own signal and onUpdate as defaults for the delegated call, with
explicit invokeTool options still taking precedence. Grouping toolName, depth,
context, signal, and onUpdate together also keeps the signature readable now
that delegation carries five inputs.

Tests: the delegated native call receives the outer signal and onUpdate,
explicit options override them, invokeTool is absent when no native built-in
of that name exists, and recursion stays bounded per call chain.
2026-07-30 10:35:12 -07:00
Larry Gordon efaf4f5d49 fix(extensions): preserve the caller tool context when delegating via invokeTool
The delegated native call built a fresh AgentToolContext with no toolCall
metadata. Native tools read that: write/edit derive LSP batch flushing from
context.toolCall, and computer uses provider metadata plus
providerSafetyApproved for the required screenshot/safety acknowledgement, so
wrapping those tools lost batching and dropped provider result metadata.

Thread the caller's own context (the one the re-registered tool received)
through RegisteredToolAdapter.execute and createContext into invokeNativeTool,
and reuse it for the native call instead of a bare getContext(), falling back
to a fresh session context only when the caller had none.
2026-07-30 10:35:12 -07:00
Larry Gordon a50bcd5fed fix(extensions): wire invokeTool to the extension path as same-tool delegation
Addresses PR review. The initial version put invokeTool on AgentToolContext
via ToolContextStore, but the extension execute path (RegisteredToolAdapter)
builds its own ExtensionContext and never saw it, so the documented
registerTool wrapper use case did not work. It also allowed arbitrary
cross-tool targets (bypassing the target's approval policy), used a
session-global recursion counter that tripped on concurrent independent
delegations, and missed discoverable built-ins that xdev partitioning moves
out of the tool array.

Rework:
- Move invokeTool onto ExtensionContext, and bind it in RegisteredToolAdapter
  to the tool's own name, so a re-registered built-in actually receives it.
- Make delegation same-tool only: invokeTool takes just (params, options) and
  runs the native built-in of the caller's own name. It cannot reach an
  arbitrary target, so it cannot escalate past the approval already granted
  for the call, and the native call is not re-gated.
- Track recursion depth per call chain (threaded through invokeNativeTool and
  createContext) instead of session-global state, so concurrent delegations
  do not interfere.
- Seed the native resolver from the xdev registry when present (it retains
  discoverable built-ins like browser), else the built-in registry.

Replaces the ToolContextStore-level unit test with an end-to-end test that
registers a built-in wrapper through the extension/session path and asserts
the native tool runs the wrapper's delegated input.
2026-07-30 10:35:12 -07:00
Larry Gordon 6acf957dd8 feat(extensions): add ctx.invokeTool for native built-in delegation
A tool's execute context now carries invokeTool(name, params, options?),
which runs the native built-in of `name` and returns its result. A tool
that re-registers a built-in (e.g. wrapping write to add logging or a
policy check) can delegate to the original instead of reimplementing it.

The native implementation is captured before extension re-registration
replaces the registry entry and before the ExtensionToolWrapper pass, so
invokeTool reaches the unwrapped native execute: it does not recurse into
the caller's own wrapper, and it inherits the caller's already-granted
approval rather than re-running the gate. Delegation depth is guarded
against accidental self-recursion, and it resolves to undefined when no
native tool of that name exists.

Wired through ToolContextStore with a lazy native-tool resolver, so it is
coding-agent-only (no agent-loop change) and sees the fully-assembled
built-in set at call time.
2026-07-30 10:35:09 -07:00
Ant39140 af538a1387 Merge remote-tracking branch 'upstream/main' into fix/lsp-batch-stale-replay 2026-07-31 00:16:34 +08:00
roboomp 47044e060f fix(commit): loaded extension-provided models
- Bootstrapped extension providers before model selection in both commit pipelines.
- Loaded project-local settings consistently in the legacy pipeline.
- Added regression coverage for explicit and role-based extension models.

Fixes #7099
2026-07-30 15:50:49 +00:00
can1357 4c1793b9b7 fix(security): hardened cloud import attribution and comparison honesty
- Failed closed when cloud pulls could not verify the project origin.
- Re-verified configuration attribution on every cloud finding detail.
- Rejected non-repository-relative Codex bundle locations.
- Refused lineage comparisons against incomplete after-scans.
- Preserved diff and working-tree targets when adding path scopes.
- Logged post-publication output failures and recovered persisted status.
- Used Bun.SHA256 directly and reused pi-ai JWT decoding.
- Shortened exported paths in interactive output.
2026-07-30 17:24:07 +02:00
can1357 ab572106cd Merge PR #7048: feat(security): add OMP-native security scan subsystem (@kmccleary3301) 2026-07-30 17:11:06 +02:00
can1357 3803219716 Merge PR #7095: fix(coding-agent): add createEditTool/createWriteTool to legacy pi shim (@roboomp) 2026-07-30 17:05:16 +02:00