* feat(cli): add GitHub Copilot CLI agent support via ACP
Wrap `copilot --acp --stdio` for remote sessions and spawn the native TUI locally, with full hub/web integration for spawn, resume, and permissions.
Fixestiann/hapi#362
Co-Authored-By: HAPI <noreply@hapi.run>
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(copilot): agent modes, models, slash/file UX, local session sync
Add Interactive/Plan/Autopilot (fleet is slash-only), subscription-aware
model discovery, web StatusBar/permission UX, @ file mentions, and fix
local Safe Yolo plus session-id locator for handoff/resume.
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: re-trigger Codex PR review after auth outage
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: retry Codex PR review
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): preserve agent mode on resume and apply via ACP set_mode
Resume was dropping copilotAgentMode so Plan/Autopilot reset to interactive.
Also switch local/remote mode application to --mode / session set_mode instead of slash prompts.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): wake remote loop when agent mode changes
Empty isolated queue tick lets setMode apply without inventing a user prompt.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): confirm mode changes before persisting
Await Copilot mode changes and expose discovered models so session state reflects backend acceptance.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): guard mode discovery and slash updates
Keep model probes within runner roots and preserve active sessions when mode switching is unavailable or rejected.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): preserve resume and auto semantics
Deduplicate Copilot resume rows, apply Auto explicitly, and fail closed on denied permissions.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): close permission and model discovery gaps
Keep write-capable commands pending in read-only mode, extend model probe RPCs, and preserve explicit model validation before session creation.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): persist runtime model and agent mode
Fallback to ACP model options when direct model switching is unavailable and retain Copilot agent mode across hub restarts.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): normalize composer auto selection
Use the null session sentinel for Copilot Auto so the composer selects and resets default models consistently.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(copilot): reject local permission mode changes
* style(copilot): remove trailing blank line
* fix(copilot): secure local config handoffs
* fix(copilot): reject local agent mode slashes
* fix(copilot): reject mode changes during turns
* fix(copilot): consume rejected slash updates
* fix(copilot): preserve thinking across slash handling
* fix(copilot): stabilize async config changes
* fix(copilot): roll back rejected startup model
* fix(copilot): preserve cancellation and file mentions
* fix(copilot): hide local permission controls
* fix(deps): support clean workspace installs
* test(copilot): account for spawn mode argument
* fix(copilot): attribute usage to active model
---------
Co-authored-by: HAPI <noreply@hapi.run>
Co-authored-by: Cursor <cursoragent@cursor.com>
Restores directory glanceability by default after #1315. Settings → Display
adds a toggle next to Active sessions only that re-enables the pinned section.
Fixes#1347
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): re-subscribe push when VAPID key changes (stale hub subscriptions)
* fix(web): prune stale push endpoint from the hub after VAPID re-subscribe
* fix(web): record VAPID key only after hub registration succeeds
* fix(web): preserve push registration on unsubscribe failure
via [HAPI](https://hapi.run)\n\nCo-Authored-By: HAPI <noreply@hapi.run>
* feat: add cache-aware token usage dashboard
Track normalized Claude, Codex, and ACP usage with incremental SQLite backfill. Exclude imported transcript history, rebuild usage after history rewrites, and expose an owner-only dashboard with cache-aware totals and breakdowns.
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
* fix: preserve usage model and local dates
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
* fix: normalize cached usage and timezone buckets
via [HAPI](https://hapi.run)
Co-Authored-By: HAPI <noreply@hapi.run>
---------
Co-authored-by: HAPI <noreply@hapi.run>
ElevenLabs only passed bootstrap context through dynamicVariables without
a matching {{initialConversationContext}} prompt placeholder, so Brief me
connected with no session history. Stream deferred chunks then push bootstrap
on all backends; add the placeholder for newly created ConvAI agents.
Co-authored-by: Cursor <cursoragent@cursor.com>
Settings truncated read-only fixtures to 800 chars so scrolling never
revealed the rest. Default preview is now the full document; explicit
caps remain for tests.
Closes#1341
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(web): show hidden directories in workspace browser
Add optional includeHidden param to the machine list-directory RPC so the
WorkspaceBrowser can toggle hidden (dot-prefixed) entries. Default remains
filtered for backward compatibility; the toggle persists via localStorage.
* fix(web): disable show-hidden toggle while directory loading
Prevent overlapping list-directory requests with opposite includeHidden
values; the toggle is now disabled while a directory load is active.
* fix(web): migrate chat-path attachments on scratchlist park (#1226)
When an image is attached via the normal upload adapter before scratchlist
mode is enabled, toggling mode swapped adapters and send() dropped the
metadata — park stored text-only and cleared chips. Migrate pending
chat-path files into hub scratchlist storage on send, and fail closed if
non-hub paths still reach the park wrapper.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): defer chat-path cleanup until scratchlist park succeeds
send() migrates before scratchlist.add; deleting the original upload
there left retries pointing at a missing chat blob when park failed.
Stamp migratedFromPath and clean up only after the park attempt result.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): park scratchlist before composer.send clears chips
assistant-ui empties text/attachments before onNew, so return false from
park could not restore retryable state and rejected cleanup deleted the
migrated hub blob. Intercept park from a live snapshot; clear only after
accept; releaseWithoutDelete so clearAttachments keeps parked hubs.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): lock composer while scratchlist park is in flight
Disable input/send and hide chip remove during migrate+add so mid-flight
edits are not wiped on success and hub blobs are not deleted out from
under the accepted entry.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): do not clear composer if park snapshot changed mid-flight
Compare post-await composer state to the pre-park snapshot before
clearing; disable DragDropZone and scratchlist promote while parking
so parent paths cannot add chips the clear would silently drop.
Addresses Codex Major on #1227 (preserve post-snapshot composer changes).
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): defer migrated chat-path cleanup until park snapshot clears
Return ScratchlistParkResult.beforeClear from onParkScratchlist so
finalizeMigratedScratchlistParkCleanup runs only after HappyComposer
confirms the composer was unchanged mid-flight.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): flush rich mentions before scratchlist park snapshot
Park snapshots composer.text after flushSerializedText so session
@-mention chips serialize to markdown links before scratchlist add.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): validate park snapshot before scratchlist add
Split prepare/commit/abort so mid-flight composer edits abort orphan
hub blobs instead of parking a duplicate. Reuse restored hub paths in
prepareScratchlistParkAttachments so remounted chips do not re-upload.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(web): ignore scratchlist toggle hotkey while park is in flight
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat: add message-level conversation fork and rewind
Expose native Codex/Grok/Claude history controls through hub REST+RPC and web ConfirmDialog actions, without file rewind or composed forks. Also reconcile the duplicate hub V14→V15 migration so typecheck can pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: hydrate fork transcript and consume Claude --fork-session
Forked HAPI children now copy the source transcript prefix so navigation is not a blank thread, and Claude drops --fork-session after the first launch so relaunches do not branch again.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: harden fork/rewind concurrency and durable history points
Skip pending scheduled rows when hydrating fork transcripts, serialize fork/rewind per session, and persist conversation history points/indexes across existing-session bootstrap and Grok relaunches.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: close remaining fork/rewind races and UI anchoring
Block sends and scheduled maturation while history actions run, order fork prefixes by invocation time, inherit history locators into children, and only offer Fork current on the live tail boundary.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: address remaining fork/rewind bot findings
Materialize Claude --fork-session before the first child prompt, validate
HAPI history boundaries before native RPC, expose forkCurrent on a latest
user boundary, fully demote unsupported conversationHistory capabilities,
and fix the truncate test setup order.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: align fork-current ids and Claude fork bootstrap
Compare the latest fork boundary in assistant-ui threadMessageId space,
spawn Claude forks with the persisted session mode, and preserve
forkedFrom across existing-session bootstrap.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: close fork/rewind consistency holes at the contract layer
Hold the source history lock until Claude child binds a distinct native
id, persist Codex localId→turnId locators, and mark/block diverged
sessions when native rewind outruns HAPI truncate.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: use Codex stable lastTurnId for historical fork
Map HAPI's exclusive boundary to the previous turn's inclusive
lastTurnId so native fork context matches the hydrated transcript.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: require exact Grok native resume for fork children
Reject newSession fallback when forkedFrom is set, and keep the hub
history lock until the child binds the forked grokSessionId.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: kill active fork children before failed-fork cleanup
Bind/readiness failures can leave the child process running; deleteSession
rejects active rows, so terminate first then remove the HAPI session.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: close remaining fork lock, hydrate, and todos gaps
Reject mode switches during history actions, batch-copy fork
transcripts in one SQLite transaction, and rebuild todos after
fork hydrate / rewind truncate.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: allow Codex historical fork before the first turn
Use experimental beforeTurnId when there is no previous turn for the
stable inclusive lastTurnId boundary.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: mark Grok history busy immediately after dequeue
Hub idle checks clear once messages-consumed fires; hold the busy flag
across permission sync and rewind-points lookup before prompt starts.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: encode copied conversation history content
* fix(web): hide local conversation history actions
* style(codex): remove trailing whitespace
* fix(fork): preserve children when cleanup is unconfirmed
* fix(history): confirm cleanup and guard rewind divergence
* fix(history): probe capabilities before advertising
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(web): pin running sessions in an 'in progress' section with a live badge
* feat(web): show project name on pinned running session rows
* feat(web): make the pinned 'in progress' section collapsible
* fix(web): don't auto-expand directory groups when opening pinned running sessions
* fix(web): keep running section open while searching; clear auto-expand guard when selection leaves a group
* feat(web): show machine label on pinned running session rows
* fix(web): make running-section toggle keyboard-accessible with correct filtered state
* feat(web): split pinned running section into working/pending/idle groups with distinct badges
Keep touch and pen input eligible to cancel initial bottom settling when native panning dispatches pointercancel before scroll. Add interaction coverage for the mobile event sequence and unrelated global cancellations.