Commit Graph

3994 Commits

Author SHA1 Message Date
roboomp 1f32b8aaf9 fix(github): compared run_watch repo guard case-insensitively
GitHub owner/repo slugs are case-insensitive; `gh repo view` returns
the canonical casing while callers may pass any casing. The new guard
used strict equality, so a caller in the correct repo who typed
`owner/repo` while the canonical form was `Owner/Repo` was forced to
pass a redundant `branch`/`run` selector. Normalize both sides via
toLowerCase() before deciding the cwd is a different repository.

Regression test covers the casing-only match.

Refs #1949 #1951
2026-06-05 18:06:39 +00:00
roboomp 31950067f1 fix(github): honored explicit repo in run_watch instead of falling back to cwd
executeRunWatch passed undefined for the explicit `repo` to
resolveGitHubRepo, so a call like
`{op: "run_watch", repo: "owner/cxf", branch: "main"}` from a nested
or umbrella workspace silently fell through to `gh repo view` in cwd
and streamed `watching <sha> on <cwd-repo>` against the wrong
repository.

Route params.repo through resolveGitHubRepo so the explicit owner/repo
wins over both cwd inference and run-URL inference. When no `branch`
or `run` selector is given, refuse to derive the watched commit from
`git HEAD` unless the cwd actually points at the resolved repo —
otherwise raise a ToolError telling the caller to pass `branch` or
`run` instead of silently rebinding to an unrelated commit.

Also deduped resolveSearchRepoScope's best-effort cwd resolution into a
shared tryResolveCurrentRepo helper used by the new guard.

Fixes #1949
2026-06-05 18:02:45 +00:00
can1357 61f11a6ce0 fix(tui): blocked destructive scrollback replay on unknown terminal viewports
- Blocked checkpoint scrollback replay unless native viewport-at-bottom proof succeeded.
- Expanded ED3-risk terminal detection to include SSH, multiplexer, WT-like, and unknown profiles.
- Added sync-output defaults with PI_TUI_SYNC_OUTPUT and PI_FORCE_SYNC_OUTPUT overrides.
- Deferred transcript thawing until native scrollback refresh returned true.
- Adjusted non-escape parsing to emit one Unicode scalar and raised timeout to 75ms.
2026-06-05 17:47:47 +02:00
can1357 492b454141 fix(archive): read zip central directory without inflating members
- Parsed zip metadata via central directory and lazy ranged reads.
- Inflated member contents only when a specific entry is read.
- Prevented large or corrupt zips from freezing directory reads.
2026-06-05 17:38:24 +02:00
can1357 1002ba0242 feat(search): accepted internal URL selectors as line filters
- Added selectorLineRanges to extract ranges from raw/conflicts selectors.
- Routed internal URLs through URL-aware splitter in content search.
- Treated display-mode selectors as whole-resource searches instead of rejecting.
2026-06-05 16:29:58 +02:00
can1357 da18b51e21 docs(rules): added exception for named non-obvious formulas
- Allowed tiny functions that name a magic-constant computation the inlined expression wouldn't explain.
2026-06-05 15:52:11 +02:00
can1357 8943fb8084 refactor(file-mentions): removed fuzzy and prefix resolution for @-mentions
- Resolved @-mentions to exact existing paths only.
- Relied on the TUI @-selector to insert complete real paths.
- Dropped candidate scanning to avoid dragging in same-named files.
2026-06-05 15:51:37 +02:00
can1357 1dfab0a883 fix(file-mentions): resolved trailing-slash mentions to directories only
- Made `@`-mention resolution directory-aware so a mention ending in `/` or `\` matches only directory candidates.
- Stopped stripping the trailing separator and fuzzy-matching an arbitrary same-named file (e.g. npm scopes like `@scope/`).
- Left non-slash mentions unchanged.
2026-06-05 15:47:53 +02:00
can1357 2f9645c40d Merge remote-tracking branch 'origin/farm/b818bb5f/allow-opting-out-of-max-output-tokens-per-model' 2026-06-05 11:45:32 +02:00
can1357 c130fde15e Merge remote-tracking branch 'origin/farm/b86bd90c/log-session-title-failures' 2026-06-05 11:44:54 +02:00
can1357 a1ef5d62ec Merge remote-tracking branch 'origin/farm/f2c1d17f/fix-github-skills-discovery' 2026-06-05 11:44:46 +02:00
can1357 26ea8202ec Merge remote-tracking branch 'origin/farm/6449817e/package-omp-docs' 2026-06-05 11:44:34 +02:00
can1357 59b6c14887 Merge remote-tracking branch 'origin/farm/0ad2d1fd/mcp-oauth-clear-stale-credentials' 2026-06-05 11:44:17 +02:00
can1357 29c91250fc Merge remote-tracking branch 'origin/farm/d4f04d82/tree-not-list-sessions' 2026-06-05 11:44:08 +02:00
can1357 d63f8a1665 Merge remote-tracking branch 'origin/farm/cec7b559/fix-pi-permission-plugin-load' 2026-06-05 11:44:01 +02:00
can1357 7f06ef86fa Merge remote-tracking branch 'origin/farm/a8a41944/login-url-cut-off-ellipsis' 2026-06-05 11:43:49 +02:00
can1357 a23c5841b5 Merge remote-tracking branch 'origin/farm/fa262623/fix-hindsight-bankid-reactivity' 2026-06-05 11:43:36 +02:00
can1357 9151ce9623 Merge remote-tracking branch 'origin/farm/9e76efd7/task-fallback-sync-no-async-manager' 2026-06-05 11:43:28 +02:00
can1357 c39350d598 fix(dry-balance): decoupled bench mode from sampling flags
- Skipped count/concurrency normalization when --bench is set.
- Errored when no OAuth accounts resolve for the provider.
- Updated flag docs to run one request per OAuth account.
2026-06-05 11:43:17 +02:00
can1357 0340604f64 Merge remote-tracking branch 'origin/farm/9c8b047b/fix-async-job-manager-singleton-overwrite' 2026-06-05 11:41:15 +02:00
can1357 88703a4ebb feat(dry-balance): added live bench mode for OAuth accounts
- Added `getOAuthAccesses` to resolve each stored credential once.
- Sent one live request per account, reporting TTFT and TPS.
- Streamed per-account progress with interactive status lines.
2026-06-05 11:41:07 +02:00
can1357 eb8e4f7657 feat(task): added read-summarize override for subagents
- Parsed `read-summarize` frontmatter into `readSummarize` field.
- Applied `read.summarize.enabled: false` override on isolated subagent settings.
- Disabled summarization for `explore` and `librarian` agents.
2026-06-05 11:36:13 +02:00
roboomp be9e5218ed fix(sdk): cleared async singleton after startup failures
If createAgentSession failed after installing a newly created AsyncJobManager but before AgentSession took ownership, the process-global singleton stayed installed. The new singleton guard then caused the next top-level session to skip constructing a scoped manager, disabling async bash/task support.

The startup-error cleanup now clears the singleton only when it still points at the newly created manager, disposes that manager, and then continues the existing registry/kernel cleanup. The regression test forces a startup failure after singleton installation and verifies the next top-level session can create and use its own async manager.
2026-06-05 09:34:10 +00:00
roboomp ac304eacdc fix(sdk): scoped async job snapshots to sessions
AgentSession now stores the same scoped AsyncJobManager reference that tools receive: owning top-level sessions use their constructed manager, subagents inherit the parent's manager, and secondary in-process top-level sessions get no manager when a singleton is already live.

getAsyncJobSnapshot and ACP delivery drains now use that scoped manager instead of AsyncJobManager.instance(), so secondary sessions cannot report or drain the primary session's background jobs. The regression test covers a secondary session created while the primary has a Main-owned running job.
2026-06-05 09:29:30 +00:00
can1357 2dab082a68 fix(tui): restored live block boundary reporting to TUI
- Appended newly sealed transcript blocks to native scrollback once.
- Deferred only the active live block during ED3-risk streaming.
- Hardened snapshot TTL parsing to handle whitespace-only env values.
2026-06-05 11:29:27 +02:00
can1357 1e3a8d5cdf fix(tui): pinned native scrollback to commit sealed live-region rows
- Added `NativeScrollbackLiveRegion` seam so components report the live suffix start.
- Stopped ED3-risk streaming from dropping sealed transcript rows above the live block.
- Appended newly sealed rows once while keeping the active tail deferred to checkpoint.
2026-06-05 11:29:18 +02:00
roboomp 5d4bba80c2 style: bun run fix 2026-06-05 09:22:23 +00:00
roboomp eda5eebe71 fix(sdk): route bash/task/job through ToolSession.asyncJobManager to keep secondary sessions isolated
Per PR review on #1926: a secondary in-process top-level createAgentSession() that exposes bash/task/job tools would still call AsyncJobManager.instance() at execute time, register on the primary's manager, and have the primary's onJobComplete enqueue results into the primary's yieldQueue — corrupting the owning session's conversation.

ToolSession now carries an asyncJobManager reference scoped to its session: the constructed manager for top-level sessions, the inherited singleton for subagents (so their bash/task completions still flow into the spawning conversation as before), and undefined for secondary in-process top-level sessions that found a singleton already installed. bash, task, and job tools resolve the manager through ToolSession instead of the process-global singleton, so a secondary session whose tools attempt async work fails fast with the standard "Async job manager unavailable" error instead of contaminating the primary.
2026-06-05 09:22:18 +00:00
can1357 b8a602ac2a test(auth): switched OAuth ranking tests to weighted selection
- Replaced top-rank assertions with weighted-preference distribution checks.
- Added cases for equal-priority balancing and 2x best-bucket cap.
- Added coding-agent snapshot-cache boot and seed tests.
2026-06-05 11:15:32 +02:00
can1357 5004ba057f feat(auth-broker): added encrypted local snapshot cache
- Added AES-GCM cache for at-rest broker snapshots keyed on token, with URL as additional data.
- Added `onSnapshot` hook to RemoteAuthCredentialStore for persisting applied snapshots.
- Exposed cache read/write and TTL defaults through the coding-agent re-exports.
- Added `getAuthBrokerSnapshotCachePath` with `OMP_AUTH_BROKER_SNAPSHOT_CACHE` override.
2026-06-05 11:09:47 +02:00
roboomp 36db2530a9 fix(sdk): keep primary AsyncJobManager when secondary top-level session disposes
Any in-process secondary createAgentSession() (e.g. the Agent Control Center's create flow in agent-dashboard.ts) was constructing its own AsyncJobManager, overwriting the process-global singleton, and then clearing it on its own dispose. The primary session still held its #ownedAsyncJobManager reference, but AsyncJobManager.instance() was undefined for the rest of the process — the task async path hard-failed with "Async execution is enabled but no async job manager is available" and only a full restart cleared it.

- sdk.ts: skip constructing/installing a second AsyncJobManager when a singleton is already live, so secondary top-level sessions share the owning session's manager instead of clobbering it.\n- agent-session.ts: scope #cancelOwnAsyncJobs so a secondary session inheriting the singleton with the default MAIN_AGENT_ID can no longer cancel the primary session's running bash/task jobs at dispose time. Subagents still reach the inherited singleton via their unique agent ids; the owning session still cancels its own jobs through #ownedAsyncJobManager.

Fixes #1923
2026-06-05 09:06:53 +00:00
can1357 a0ff234500 feat(coding-agent/cli): added dry-balance CLI dry-run check for OAuth account balancing
- Added `omp dry-balance` command with model, count, concurrency, and JSON flags.
- Implemented random session-id sampling with bounded concurrency for OAuth access dry-run checks.
- Added success/failure summary generation with account and reason stats and optional JSON output.
- Set CLI exit status to 1 when any dry-balance attempt fails.
- Added the new dry-balance capability to the unreleased changelog notes.
2026-06-05 10:59:38 +02:00
roboomp de21a28e43 fix(task): fallback to sync when AsyncJobManager is unavailable
When `async.enabled` is true but `AsyncJobManager.instance()` returns
`undefined` (orphaned-session state, host that never wired one up, etc.),
the `task` tool was returning a hard error and was unusable for the rest
of the session — even though the existing sync codepath (`#executeSync`,
which still parallelizes via `mapWithConcurrencyLimit`) was right there.

Fall back to `#executeSync` instead and emit a `logger.warn` so the
missing-manager state stays diagnosable. Background/job-poll semantics
are lost in this degraded mode, but the tool keeps working.

Fixes #1922
2026-06-05 08:54:49 +00:00
can1357 0f83efdf78 fix(coding-agent): relativized rule path in TTSR injections
- Stopped leaking absolute home directory to the model in ttsr-interrupt and ttsr-tool-reminder blocks.
- Rendered rule paths as cwd-relative in-project, `~`-relative under home, else raw.
2026-06-05 10:53:01 +02:00
roboomp 2ef758f5e3 fix(coding-agent): kept setup login url row visible
Reserved the first wrapped plain-text login URL rows above the manual-code prompt, while rendering the complete wrapped URL again below the prompt for terminals without OSC 8 support.

Fixes #1919
2026-06-05 08:12:43 +00:00
roboomp b896007e75 fix(coding-agent): pinned setup login link above prompt
Hoisted an always-visible OSC8 'Browser login' row in the setup sign-in tab so wizard body clipping never hides both the clickable link and the focused manual-code prompt. The wrappable URL text still renders below for terminals without OSC 8 support.

Fixes #1919
2026-06-05 08:07:43 +00:00
roboomp 9333fccc03 fix(coding-agent): kept setup login prompts visible
Rendered manual-code prompts before wrapped OAuth status lines so wizard body clipping cannot hide the focused input behind a long login URL.

Fixes #1919
2026-06-05 08:00:16 +00:00
roboomp c4fa93e460 fix(plugins): preserved null package import exclusions
Kept explicit null package imports as exclusions so exact entries and active conditions do not fall through to wildcard or fallback targets.\n\nFixes #1889
2026-06-05 07:59:28 +00:00
roboomp 510a2b8596 fix(coding-agent): preserved setup login urls
Wrapped setup sign-in OAuth status lines instead of truncating them, and added a full OSC8 login link so narrow terminals still expose the complete URL.

Fixes #1919
2026-06-05 07:54:37 +00:00
roboomp 01677a0c1f style: bun run fix 2026-06-05 05:58:04 +00:00
roboomp ccc3533c45 fix(tui): differentiate /tree empty-state for fresh sessions
The session-tree selector collapsed to "No entries found" whenever the
default filter rejected every entry. On a fresh session that is the
normal case: `sdk.ts` writes `model_change` + `thinking_level_change`
at startup so model + thinking state survive resumes, and the default
filter treats both as bookkeeping. `selector-controller.showTreeSelector`
guards on `tree.length === 0` so the selector still opens, and the user
sees an unexplained empty panel with `(0/0)` next to a "Recent sessions"
list that does contain data.

Split the empty-state branch into three shapes:
- `flatNodes.length === 0` → unchanged "No entries found".
- `searchQuery` non-empty → "No entries match search \"…\"" plus a
  Backspace hint, with the real total in `(0/N)`.
- otherwise → "N entries hidden by the current filter [mode]" plus
  "Press Alt+A to show all, Alt+D for default", with the real total in
  `(0/N)`.

So the fresh-session case now explains why the panel is empty and how
to widen it instead of reading as "/tree is broken".

Fixes #1909
2026-06-05 05:57:47 +00:00
roboomp 95f64b6142 fix(mcp): clear stale OAuth credential on definitive refresh failure
When an HTTP MCP server returns invalid_grant (or invalid_token / revoked /
plain 401 from the token endpoint) during OAuth refresh, MCPManager
previously logged "MCP OAuth refresh failed, using existing token" and
re-attached the stale access token as Authorization: Bearer on every
subsequent request. The next tool-load 401'd with invalid_token, future
sessions repeated the loop, and the only recovery was to hand-clear the
credential row in agent.db. Reported with Logfire as the trigger; any
remote HTTP MCP that rotates / revokes refresh tokens is affected.

#resolveAuthConfig now reuses pi-ai's isDefinitiveOAuthFailure classifier
(same one auth-broker and AuthStorage use for first-party providers): on
a definitive failure it calls AuthStorage.remove(credentialId), drops the
Bearer entirely, and the next request surfaces a clean auth error so the
user can /mcp reauth <server> (or /mcp unauth) to recover. Transient
failures (network/fetch failed/ECONNREFUSED) still fall back to the
existing token to ride out blips.

Verified with new mcp-manager-oauth-refresh.test.ts (invalid_grant, 401,
transient fallback, happy-path rotation). The full mcp-* test set
(45 tests across 5 files) still passes.

Fixes #1908
2026-06-05 05:47:09 +00:00
roboomp a4be51f08c fix(discovery): scan .github/skills via the github provider
The github provider registered context-files (.github/copilot-instructions.md)
and instructions (.github/instructions/*.instructions.md), but no skills
capability — so .github/skills/<name>/SKILL.md, the layout GitHub documents
for Copilot Agent Skills, was silently never discovered. The skill://
URL resolved to 'Available: none' and nothing surfaced in the system prompt.

Register a skill capability on the github provider (priority 30, project-only)
pointing at .github/skills/ and reuse scanSkillsFromDir with
requireDescription: true to match the Agent Skills spec and the sibling
native/omp-plugins providers. Pin the wiring with a discovery test that
loads the skills capability scoped to the github provider against a temp
cwd containing a SKILL.md, and a negative case that drops a skill missing
a description.

Fixes #1906
2026-06-05 05:36:05 +00:00
roboomp a8b3aeaeaa fix(coding-agent/hindsight): serialized live scope rebuilds
Coalesced synchronous Hindsight routing setting hooks into one serialized
session rebuild so cwd reloads and multi-setting updates cannot have
multiple continuations capture the same old state and leak fresh
session listeners.

Also re-read the current state after awaiting the previous queue flush
before installing the replacement state, so an unexpected concurrent
owner cannot leave the actual current state undisposed.

Fixes #1902
2026-06-05 05:35:09 +00:00
roboomp 34005e6656 fix(coding-agent/hindsight): reacted to live bank scope changes and flushed before dispose
Mid-session edits to hindsight.bankId / bankIdPrefix / scoping kept the
active HindsightSessionState pinned to the bank selected at session
start, so retain/recall/reflect calls landed in the stale bank. Settings
hooks now fire onHindsightScopeChanged; the backend rebuilds the
primary state against the recomputed scope, disposing the previous one
after flushing its queue so queued tool-initiated retains still land in
the bank they were enqueued for.

Also:
- Renamed ensureBankMission to ensureBankExists. The old version
  skipped creation entirely when bankMission was blank, so the first
  mental-model POST (auto-seed) could land against a never-PUT bank.
  Bank creation is now idempotent and unconditional, and runs before
  mental-model bootstrap.
- Fixed AgentSession.dispose to flush the retain queue BEFORE clearing
  the session state pointer. Reversed, HindsightRetainQueue.#doFlush's
  identity guard would see the cleared pointer and drop the spliced
  batch with a 'session vanished' warning.
- Snapshotted hindsightScopeCallbacks before iterating because each
  rebuild subscribes a fresh callback inside the same fire; iterating
  the live Set would spin.

Fixes #1902
2026-06-05 05:25:45 +00:00
can1357 4e54836f94 chore(tui): adopt #1895 streaming-scrollback-defer; drop live-region pin 2026-06-05 06:42:05 +02:00
roboomp 61c26af62a fix(coding-agent): expanded omp docs search alias
Handled omp://docs as an embedded documentation search root alongside omp://.

Added regression coverage for searching embedded docs through the docs alias.

Fixes #1898
2026-06-05 03:44:50 +00:00
roboomp 124e5593e9 fix(coding-agent): resolved omp docs urls
Accepted omp://docs as the embedded documentation root and mapped docs-prefixed paths to the generated documentation index.

Added regression coverage for omp://docs and omp://docs/tools/read.md resolution.

Fixes #1898
2026-06-05 03:41:51 +00:00
can1357 7447086186 fix(tui): pinned live region to stop scrollback dup on ED3 streams
- Added NativeScrollbackLiveRegion seam reporting where a component's transient suffix begins.
- Pinned the live block and chrome below it out of native history during foreground streams on ED3-risk terminals.
- Consumed pending forced scrollback wipes while pinned to avoid yanking a scrolled-up reader (#1682).
2026-06-05 00:53:39 +02:00
roboomp 356db2b845 fix(coding-agent): surfaced title generation failures
Logged structured session-title generation skip and failure outcomes with session/model context, and prevented credential lookup errors from escaping into the caller's swallowed promise path.

Added regression coverage for missing and failing title credentials.

Fixes #1892
2026-06-04 22:27:23 +00:00