Skip to content

Session launch bundle: atomic model/Plan Mode, workspace defaults, task priority (T-39/40/41/42/44/38) - #8

Merged
jaesbit merged 12 commits into
mainfrom
feat/t39-session-launch-bundle
Jul 2, 2026
Merged

Session launch bundle: atomic model/Plan Mode, workspace defaults, task priority (T-39/40/41/42/44/38)#8
jaesbit merged 12 commits into
mainfrom
feat/t39-session-launch-bundle

Conversation

@jaesbit

@jaesbit jaesbit commented Jul 2, 2026

Copy link
Copy Markdown
Owner

Summary

  • T-39POST /sessions accepts model + planMode atomically. Plan Mode is entered before the auto-start prompt queues. Rejects model/planMode combined with resumeFromPath (400). An explicit model is validated against the live ModelRegistry (unknown or unauthenticated → 400, no silent fallback).
  • T-42 — new workspace_preferences table: per-exact-cwd default model override. GET/PUT /workspace-preferences, surfaced as WorkspaceEntry.defaultModel. Session-creation precedence: explicit request model > workspace override > SDK/OMP_MODEL global default. Settings → Workspaces materializes the CRUD UI (previously a stub).
  • T-40 — new SessionLaunchModal (workspace + model + Plan Mode in one panel), backed by a shared useModelCatalog() hook extracted from ModelPickerModal. Wired into every "New session" entry point: SessionPicker, Sidebar, chat header switcher.
  • T-41 — Tasks' "Open in chat" and Inbox's "Open in chat" now go through SessionLaunchModal instead of silently creating a session against a default/task cwd. On create failure the modal stays open with the task/draft intact for retry.
  • T-44 — new "Send to agent" button next to "Open in chat" in TaskModal, using the same launch flow but a short Trabaja en T-<id>: <title> draft instead of the full title+body (the agent re-reads the task via GET /api/tasks).
  • T-38 — native Task.priority (P0P5) column. Migration backfills legacy [PN] title prefixes into the field and strips the redundant prefix from the title; unmarked cards default to P5. TaskModal/TaskCard get a priority selector + colored badge; the kanban header gets a priority filter and an optional priority sort. TaskModal now always shows T-<displayId> (previously only the unused TaskDrawer had it).

Testing

  • apps/server: bun test — 212 pass, 0 fail (new: db/workspace-preferences.test.ts, routes-sessions.test.ts, extended db/tasks.test.ts).
  • apps/web: bun test — 134 pass, 0 fail.
  • tsc --noEmit clean on both apps/server and apps/web.
  • apps/web production build succeeds.
  • Migration 006's backfill verified directly against a scratch SQLite db (legacy [P0] Titlepriority=P0, title stripped to Title; unprefixed rows default to P5).

Out of scope

  • T-43 (declarative chat profiles) — explicitly deferred per prior product decision, not part of this batch.

jaesbit added 12 commits July 3, 2026 00:15
…ults, task priority

- CreateSessionRequest.planMode (T-39)
- WorkspaceEntry.defaultModel + WorkspacePreference/SetWorkspacePreferenceRequest/ListWorkspacePreferencesResponse (T-42)
- Task.priority: TaskPriority + CreateTaskRequest/UpdateTaskRequest.priority (T-38)
…rkspace defaults (T-39, T-42)

T-39: CreateSessionOpts.planMode applied before the auto-start prompt queues;
POST /sessions rejects model/planMode combined with resumeFromPath; an
explicit model is validated against the live ModelRegistry catalog
(unknown/unauthenticated model -> 400 instead of a silent fallback).

T-42: new workspace_preferences table (per-cwd model override), CRUD at
GET/PUT /workspace-preferences (also model-validated), surfaced as
WorkspaceEntry.defaultModel on GET /workspaces. Session creation precedence:
explicit request model > workspace override > SDK/OMP_MODEL global default.

Tests: db/workspace-preferences.test.ts (CRUD unit tests) and
routes-sessions.test.ts (Hono in-memory router tests covering validation,
combo rejection, and precedence) using a hand-rolled AgentBridge stub.
…-40)

Extract model catalog fetch/filter/group logic out of ModelPickerModal into
a reusable useModelCatalog() hook (apps/web/src/lib/model-catalog.ts), then
build SessionLaunchModal on top of it: pick workspace (+ new-path/browse),
model (preselecting the workspace's default when T-42 has one configured),
and Plan Mode as one atomic POST /sessions request.

Wire it into every 'New session' entry point — SessionPicker, Sidebar, and
the chat header switcher — replacing the direct createSession({cwd}) calls
so all three produce equivalent requests for equivalent choices. store.ts's
createSession() action now threads model/planMode/suppressAutoStart through
to the API client.
Materializes the previously-stubbed Workspaces settings section: lists every
derived workspace, shows its effective default model (override vs global/SDK
fallback), and lets the user pick or clear a per-cwd override via
PUT/GET /workspace-preferences, reusing the same useModelCatalog() hook as
SessionLaunchModal.
…ing (T-38, T-41, T-44)

T-38: tasks.priority column (migration backfills legacy '[PN] title' prefixes
into the field and strips the now-redundant prefix from the title, defaulting
unmarked cards to P5), CreateTaskRequest/UpdateTaskRequest validation, a
priority selector + colored badge in TaskModal/TaskCard, and a board-header
priority filter + optional priority sort. TaskModal now also always shows
T-<displayId> next to the state selector (previously only TaskDrawer, which
is unused dead code, had it).

T-41/T-44: Tasks' 'Open in chat' and the new 'Send to agent' button, plus
Inbox's 'Open in chat', now open SessionLaunchModal (T-40) instead of
silently creating a session against a default/task cwd. 'Send to agent'
sends a short 'Trabaja en T-<id>: <title>' draft instead of the full
title+body — the agent re-reads the task itself via GET /api/tasks. On
create failure the modal stays open with the task/draft intact so the user
can retry without re-entering anything.
… rename

- TaskModal's T-<id> badge now matches the header buttons' height/weight
  instead of a barely-visible font-mono 2xs label.
- P4 and P5 priority badges had no background color at all (P3 downward
  faded to plain text) — every tier now gets a visible tone across a
  danger -> warn -> accent -> thinking -> success -> neutral gradient.
- 'Send to agent' -> 'Assign to agent' (button label + tooltip + modal title).
…mpt, Goal Mode sidebar pill

Previously, opening a session with a contextual draft (task attach, inbox
item) fired the server's configured OMP_DECK_AUTO_START command (e.g.
/start) as its own turn, then queued the draft as a second turn once the
user sent it: /start -> response -> attach. The SDK's own slash-command
expansion (`/command <rest>` -> rendered template + "\n\n" + rest, when the
template has no  placeholder) already supports combining these
into one turn — new apps/web/src/lib/first-prompt.ts exposes
getAutoStartCommand()/combineWithAutoStart() to do exactly that.

- Tasks/Inbox 'Open in chat' and 'Assign to agent' now pass
  suppressAutoStart:true and prefix the autostart command onto the draft
  instead of letting the server fire it separately.
- SessionLaunchModal gains an optional 'Initial prompt' textarea (hidden
  for Task/Inbox launches, which already build their own draft) so a plain
  New session can hand the agent an instruction up front without needing
  Plan Mode. Same combine-with-autostart treatment via the new shared
  launchSession() helper, wired into SessionPicker, Sidebar, and ChatHeader.
- Sidebar's session list had a 'plan' pill for Plan Mode but nothing for
  Goal Mode — added a matching 'goal'/'goal:<status>' pill.
- Also fixed a real bug found in passing: the Tasks board's Board-toggle
  button and StateConfig's own close (X) never closed the inspector panel
  it had opened, forcing a separate inspector-toggle click.
Opening a task/inbox conversation or entering a plain session initial prompt now deliberately auto-sends after the newly-created session's WS snapshot hydrates, rather than merely pre-filling the composer. Each pending launch prompt is bound to the created session id to avoid sending into a different active session during a switch.

Task/Inbox flows suppress server auto-start and send the configured /start command prefixed to their contextual message as one SDK-expanded turn. The optional plain-session initial prompt follows the same rule. Add focused combineWithAutoStart unit coverage.
Task Open in chat, Assign to agent, Inbox Open in chat, and the optional
New-session initial prompt now all suppress the server's separate auto-start
and auto-send one session-targeted message beginning with /start. This no
longer depends on OMP_DECK_AUTO_START being enabled: these actions explicitly
request the canonical initialization workflow.

Extend first-prompt unit tests to cover auto-send targeting and preserved
server auto-start for a blank initial prompt.
@jaesbit
jaesbit merged commit 67f5e0b into main Jul 2, 2026
@jaesbit
jaesbit deleted the feat/t39-session-launch-bundle branch July 2, 2026 23:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant