36 Commits

Author SHA1 Message Date
Fatih Al-Aziz 8a22872ece fix(tui): preserve mode submissions across async input 2026-08-11 16:46:45 +07:00
Fatih Al-Aziz de9ee6d412 fix(tui): preserve mode attachments across async paths 2026-08-11 16:25:20 +07:00
Fatih Al-Aziz d194f2d76c fix(tui): honor transformed mode attachments 2026-08-11 15:52:58 +07:00
Fatih Al-Aziz 276f1dd3b2 fix(tui): keep pasted images when a mode command submits the draft
`/goal <objective>`, `/plan <prompt>` and `/vibe <prompt>` promote the
composer draft into the first turn, but built their submission from the
draft *text* only:

    this.onInputCallback(this.startPendingSubmission({ text: objective }));

The editor-submit path in `InputController` passes
`editor.pendingImages`/`pendingImageLinks` alongside the text; these four
call sites did not. A draft holding pasted screenshots therefore reached
the model with its positional `[Image #N, WxH]` markers intact and every
image payload missing, so the agent saw markers pointing at nothing and
`read "Image #1"` resolved against an empty list.

The payload was not only dropped, it also outlived the draft: the mode
commands cleared the composer with `editor.setText("")`, which leaves
`pendingImages` attached. The orphans then rode along with whatever the
user typed next, one index off, which is how a later message can attach a
screenshot the user never re-pasted.

Measured on 259 image-bearing user messages across 10 local session logs
(v17.2.x): 36 of 37 messages submitted as a goal objective lost every
image, against 190 of 198 preserved on the ordinary submit path.

Fix:
- `#takeDraftImages()` detaches the composer's pending images and links,
  and all four mode-command submissions spread it into
  `startPendingSubmission` (`cancelPendingSubmission` already restores
  them when a submission is cancelled).
- `/goal`, `/guided-goal`, `/plan` and `/vibe` clear the draft with
  `editor.clearDraft()` instead of `editor.setText("")`, so images can
  never outlive the text they were pasted into (the streaming branch of
  `/goal` never submits, so its draft must die whole).

Tests: two regression cases in `goal-mode-integration.test.ts` assert the
objective submission carries the image and empties the composer; both
fail on the previous behaviour with `images: undefined`. The `/plan`,
`/goal` and `/guided-goal` slash stubs now model `clearDraft`.
2026-08-09 08:38:09 +07:00
can1357 a872d77068 chore: cleanup dumb tests 2026-08-02 20:39:23 +02:00
can1357 169a1b81c7 feat(coding-agent/goals): replaced guided goal modal workflow with interview brief
- Reworked the `/guided-goal` command to send a hidden interview brief instead of a modal popup flow.
- Removed the deprecated `guided-setup.ts` module and system prompt template.
- Updated goal tool availability and activation logic to support goal creation during the interview.
- Replaced existing tests and added new verification for the updated guided-goal workflow.
2026-07-28 08:55:49 +02:00
can1357 5ff277349c refactor(coding-agent): consolidated tool surface onto xd:// devices and hub
- Added the `xd://` virtual device protocol (`internal-urls/xd-protocol.ts`, `tools/xdev.ts`): tools declaring `loadMode: "discoverable"` are unmounted from the request tools array and driven via `read xd://` (list/docs+schema) and `write xd://<tool>` (execute), gated by the `tools.xdev` setting (default on) and inlined into the system prompt.
- Merged the `irc`, `job`, and `launch` tools into a single `hub` tool (`tools/hub/`, `async/job-manager.ts`): messaging keeps `send`/`inbox`/`list`, job control maps to `wait`/`cancel`/`jobs`, process supervision keeps `start`/`logs`/`stop`/`restart`/`describe` with `ps`, and the unified `wait` races background jobs against peer messages; SDK `IrcTool`/`JobTool`/`LaunchTool` are replaced by `HubTool`.
- Removed the hidden `resolve` tool in favor of the `xd://resolve`/`xd://reject`/`xd://propose` resolution devices, auto-including `write` whenever a deferrable tool or plan mode is present.
- Removed the BM25 tool-discovery system: the `search_tool_bm25` tool, the `tool-discovery` module, the `tools.discoveryMode`/`mcp.discoveryMode`/`mcp.discoveryDefaultServers`/`tools.essentialOverride` settings, per-tool MCP selection, and the `mcp_tool_selection` message type.
- Unified tool presentation on `ToolLoadMode` (`essential`|`discoverable`), replacing the custom-tool `xdev?: boolean` opt-out; custom, extension, MCP, RPC host, image-generation, and TTS tools now default to `discoverable`, and added a `satisfies` predicate to `SoftToolRequirement`.
- Removed the standalone `ssh` command tool and `ssh/ssh-executor` (the `ssh://` read/write/search protocol stays), and made `--tools` address hidden built-ins.
- Updated collab-web to render `xd://` dispatches and `hub` op families, dropped the `search_tool_bm25`/`ssh`/`report-finding` renderers, refreshed tool docs and prompts, and migrated the affected tests and changelogs.
2026-07-15 15:16:29 +02:00
roboomp 9b8ec997b2 fix(coding-agent): reused one codex side session per guided-goal interview
- Minted the guided-goal Codex side session id once per interview in handleGuidedGoalCommand and threaded it through every turn via GuidedGoalTurnOptions.sideSessionId, so a multi-question interview shares a single websocket-only Codex socket instead of opening a fresh one each turn (which could trip websocket_connection_limit_reached and fall back to the rejected SSE path).
- Exported newGuidedGoalSessionId; runGuidedGoalTurn mints its own id only when no side session id is supplied (one-shot callers, tests).
- Added regression coverage asserting the supplied side session id is reused across turns.

Fixes #5304
2026-07-14 20:25:16 +00:00
roboomp 8b179ffc3b fix(coding-agent): routed guided-goal oneshot through codex websocket transport
- Passed the session provider transport (providerSessionState + preferWebsockets) and an isolated session id to the /guided-goal interview completion so websocket-only Codex models (gpt-5.6-luna/sol/terra) get a websocket session instead of an SSE fallback the Codex /responses endpoint rejects with "Model not found".
- Added regression coverage asserting the guided-goal request inherits the session transport with an isolated session id.

Fixes #5304
2026-07-14 18:09:59 +00:00
roboomp 8da17ba3b5 fix(session): handled malformed custom messages
Normalized extension custom-message payloads before session state or persistence, including bare string sendMessage shorthands. Skipped legacy bare custom_message entries during context rebuilds and dropped malformed custom/hook messages before LLM conversion. Added regression coverage for the poisoned-session resume crash.\n\nFixes #4345
2026-07-02 20:34:15 +00:00
Jeff Scott Ward ac4d624495 fix: address todo follow-up review 2026-06-29 11:58:40 -04:00
Jeff Scott Ward a4601d2893 fix: gate goal todo activation hint 2026-06-29 11:58:40 -04:00
Jeff Scott Ward f1dc0773a5 fix: preserve discoverable goal todos 2026-06-29 11:58:40 -04:00
Jeff Scott Ward 45086d280e fix: address todo reminder review feedback 2026-06-29 11:58:40 -04:00
Jeff Scott Ward 9a9dc88f43 fix: address todo HUD review feedback 2026-06-28 11:16:30 -04:00
Jeff Scott Ward 44ca363be0 fix: keep goal todos in context 2026-06-28 11:09:17 -04:00
can1357 8351536641 refactor(coding-agent): consolidated and prioritize perplexity authentication
- Moved authentication logic to `perplexity-auth.ts` to share logic between search providers and CLI commands.
- Updated authentication priority to prefer browser cookies over OAuth tokens during search operations.
- Modified the `token` CLI command to display active OAuth tokens when both an OAuth token and an API key are configured.
- Added comprehensive unit tests in `perplexity.test.ts` to verify authentication priority and precedence.
2026-06-19 17:44:59 +02:00
can1357 9478e3cc5c refactor: replaced ReturnType<typeof setTimeout> with Timer type
- Replaced usage of `ReturnType<typeof setTimeout>` and `ReturnType<typeof setInterval>` with the explicit `Timer` type across the codebase.
- Updated several type definitions and function signatures to use concrete types instead of inferred return types for improved clarity and maintainability.
2026-06-19 17:38:07 +02:00
usr_bin_roygbiv c16a41fd95 fix(session): prevent goal mode pause during compaction/switch 2026-06-18 14:44:39 -05:00
can1357 76dc05da65 fix(coding-agent): guided goal fallback model resolution (#2889) 2026-06-18 02:46:48 +02:00
can1357 a050474af7 feat: migrated validation schemas and tool definitions from Zod to ArkType
- Migrated all wire protocol, schema definitions, and tools validation from Zod to ArkType across multiple packages.
- Updated extension runtimes, custom tools loader, and TypeBox compatibility shim to expose and use ArkType instances.
- Added a comprehensive ArkType migration guide, validation parity tests, and helper utilities.
- Removed redundant PDF asset routing and parsing implementations from the read tool.
2026-06-18 00:59:53 +02:00
KamijoToma 4286b36e0e fix(coding-agent): fallback guided goal model 2026-06-18 00:00:12 +08:00
can1357 5bce7ed6df feat: added advisory transcript formatting and one-shot benchmark metrics
- Introduced advisory note output as `<advisory>` tags with optional severity and guidance.
- Updated session transcript formatting to `### Session update` and inline watched role labels.
- Added shared `escapeXmlText` utility and escaped XML-sensitive text in advisor outputs.
- Added one-shot success run token metrics and one-shot statistics reporting.
2026-06-16 18:34:50 +02:00
can1357 6385afdfb7 test(coding-agent): replaced Bun.sleep and wall-clock timing
- Replaced Bun.sleep and wall-clock timing with fake timers (vi.useFakeTimers), release gates, and deterministic polling across 15+ test files to eliminate flakiness and improve speed.
- Consolidated per-test fixture setup into beforeAll/afterAll lifecycle hooks across 20+ test files, reducing redundant initialization and improving test performance by reusing shared immutable fixtures.
- Stubbed network calls in ModelRegistry and test discovery to prevent unintended outbound requests during test execution.
- Replaced subprocess-based test coordination (file markers, Bun.sleep polling) with in-memory fakes (FakeWebSocket, FakeLspServer, VirtualClock) for deterministic, fast test execution.
2026-06-15 11:48:55 +02:00
usr_bin_roygbiv 2474e1a6d8 fix(goals): avoid deactivating goal mode on wall-clock-only updates 2026-06-14 16:19:17 -05:00
can1357 c9adcd5da5 Merge remote-tracking branch 'origin/farm/17ca1d16/defer-goal-objective-while-streaming' 2026-06-14 17:10:18 +02:00
roboomp 207caa3621 fix(coding-agent): drop stale goal continuation tick while streaming
Reviewer flagged a race left open by the streaming guard added in #2455:
getUserInput() arms onInputCallback and schedules an 800 ms goal
continuation timer; when /goal set takes the streaming branch (or any
extension/hook starts a turn inside that window), the timer fired
unchecked. The downstream onInputCallback resolved the main waiter with
a goal-continuation submission, submitInteractiveInput called
session.promptCustomMessage without a streamingBehavior, and the same
AgentBusyError the PR set out to fix resurfaced.

Make the continuation timer streaming-aware: at fire time, bail out
when session.isStreaming || isCompacting || hasPostPromptWork is true.
Reuses the auto-submit busy check loop mode already relies on (renamed
#isLoopAutoSubmitBlocked -> #isAutoSubmitBlocked since both flows have
the same notion of 'agent is busy, do not submit'). The next agent_end
in #handleGoalSessionEvent reschedules normally.

Fixes #2454
2026-06-14 07:22:42 +00:00
metaphorics 219fa0765c fix(coding-agent): obfuscate guided-goal transcript before provider calls
runGuidedGoalTurn sent the rendered interview transcript to the plan/slow
provider as raw text, so a secret typed into the rough goal or an answer
bypassed the session's redaction contract. Route the transcript through the
session obfuscator before the request and deobfuscate the echoed question /
objective before it is displayed or the goal starts (no-op when no secrets
are configured).
2026-06-14 08:51:59 +09:00
metaphorics 06528f9d0d feat(coding-agent): add guided-goal setup interview 2026-06-14 06:43:54 +09:00
roboomp 34a5362adf style: bun run fix 2026-06-13 15:07:00 +00:00
roboomp 1292bd5fd6 fix(cli): deferred goal objective while streaming
Stopped goal objective commands from resolving the interactive input waiter while the agent is already streaming. The goal context still uses steer immediately, and the next idle goal continuation submits the objective work without AgentBusyError spam.

Added goal-mode integration coverage for both initial and replacement objective commands during streaming.

Fixes #2454
2026-06-13 15:06:51 +00:00
can1357 20d19e8002 test: replaced blind sleeps with shared fixtures and condition polling
- Shared immutable model registries and auth storage via beforeAll/afterAll.
- Swapped fixed-delay settle sleeps for predicate polling and signals.
- Stubbed network/timers to drop wall-clock waits in registry and history tests.
- Added resetDisplay invalidation tests and startup-timing breakdown lines.
2026-06-06 22:09:04 +02:00
roboomp ccba77c5c7 fix(cli): allowed goal set to replace active goals
Allowed /goal set to replace the current active goal instead of rejecting and discarding the command input.

Added goal runtime and interactive-mode regression coverage for active replacements.

Fixes #1293
2026-05-22 13:23:06 +00:00
roboomp 83475cf7a4 fix(goals): repair goal state machine after interrupts and reloads
- get op now returns paused goals (was returning null when enabled=false)
- complete op now works on paused goals; previously required enabled=true
  which always failed after an interrupt set enabled=false
- create op now allowed after previous goal status is 'complete'; was
  incorrectly blocked by the same guard as 'dropped' check
- goal tool is re-added to the active tool set on session reload when a
  paused/active goal is persisted to disk; sdk.ts:1599 excludes 'goal'
  from initial active tools unconditionally, so restoreModeFromSession
  now re-adds it and saves #goalModePreviousTools for later cleanup
- goal_updated event for 'dropped' status now triggers #exitGoalMode
  before clearing goalModeEnabled, ensuring the previous tool set is
  restored when the agent drops a goal via the tool
- added 'resume' and 'drop' ops to goal tool schema and execute path
- updated goal.md prompt to document new ops and the paused-goal workflow

Fixes #1249
2026-05-21 05:39:06 +00:00
can1357 b9b2c381f0 fix(coding-agent/goals): skipped goal accounting operations when accounting state was absent
- Added an internal accounting-state guard and used it to skip goal usage flushing when accounting was inactive.
- Updated goal abort handling to return early unless accounting or pause logic was required, then paused only a cloned active goal state before committing.
- Aligned related tests/types by tightening OpenAI helper typing and using Tool typings for the goal tool registry.
2026-05-14 06:53:21 +02:00
can1357 933058a241 feat(goals): added per-session goal mode with token budget tracking
- Added GoalRuntime with wall-clock and token accounting, budget steering, and lifecycle operations (create, pause, resume, drop, complete).
- Exposed goal tool as a hidden agent tool, activated only when goal mode is enabled.
- Integrated goal continuation loop in InteractiveMode with auto-submit between turns.
- Added status line segment and theme icons for goal mode state.
2026-05-14 06:40:41 +02:00