> For the complete documentation index, see [llms.txt](https://faction-os.gitbook.io/faction-os-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase18-session10-quest-actions-and-keyboard-shortcuts/spec.md).

# Session Specification

**Session ID**: `phase18-session10-quest-actions-and-keyboard-shortcuts` **Phase**: 18 - Quest Board Suggestion Parity **Status**: Complete **Created**: 2026-06-10 **Completed**: 2026-06-10 **Package**: apps/web **Package Stack**: TypeScript

***

## 1. Session Overview

This session makes the typed Quest Board from Session 09 actionable in the web cockpit. Sessions 01-08 already shipped the server-owned suggestion manager, accept and dismiss routes, codebase scan orchestration, on-demand analysis, project scan engines, and status routes. Session 09 consumed those snapshots as typed cards, but intentionally left the panel read-only.

The implementation stays in `apps/web`. It adds a small local-server action client, action-capability metadata on Quest Board cards, store-level pending and feedback state, interactive card controls, manual engine trigger buttons, and the historical shortcuts `1`, `2`, `3`, `Alt+X`, and `Alt+R`. It must consume existing backend contracts only and keep legacy text-only suggestions as a compatibility fallback.

The session should preserve the current dense cockpit layout and local-first trust boundary. Every state-mutating action needs duplicate-trigger prevention, clear in-flight feedback, compact failure messages, optimistic UI that reconciles against the next `suggestion_update` snapshot, and accessible keyboard-reachable controls.

***

## 2. Objectives

1. Wire accept, dismiss, bulk dismiss, and assign-to-idle-hero interactions to the shipped Quest Board routes in the web package.
2. Add manual codebase scan, on-demand analysis, and project scan triggers with visible in-progress, conflict, success, and failure feedback.
3. Extend global shortcut routing for `1`, `2`, `3`, `Alt+X`, and `Alt+R` without breaking typing guards or existing shortcut behavior.
4. Add focused web tests for action clients, store action state, component controls, shortcut routing, help copy, and failure paths.

***

## 3. Prerequisites

### Required Sessions

* [x] `phase18-session01-protocol-suggestion-contract-parity` - provides shared suggestion action and status response contracts.
* [x] `phase18-session03-suggestion-routes-and-websocket-parity` - provides accept, dismiss, summary, and WebSocket snapshot routes.
* [x] `phase18-session07-scan-orchestration-and-quest-ignore-patterns` - provides codebase scan trigger/status routes and Settings ignore patterns.
* [x] `phase18-session08-on-demand-analysis-and-project-scan-engines` - provides analysis and project scan trigger/status routes.
* [x] `phase18-session09-web-quest-board-typed-cards` - provides typed web cards, snapshot normalization, summary display, and component tests.

### Required Tools/Knowledge

* Node 26.2.0 or newer with npm workspaces.
* React 19, Vite, TypeScript, Zustand, and Vitest in `apps/web`.
* Existing `@factionos/protocol` suggestion action response types.
* Existing local auth helper in `apps/web/src/lib/localAuth.ts`.
* Existing `useKeyboardShortcuts` routing and typing-target guards.
* Existing `useSettingsStore` scan root and quest ignore pattern state.

### Environment Requirements

* Work from the repository root.
* Use package-relative monorepo paths from the repo root.
* Keep all generated and edited files ASCII-only with Unix LF line endings.
* Do not add server routes, hosted telemetry, entitlement gates, real executors, or analytics events.

***

## 4. Scope

### In Scope (MVP)

* Operators can accept a server-backed idle suggestion from a Quest Board card and see whether the server returned `send_prompt` for a hero or `prompt_sent` broadcast fallback.
* Operators can assign an idle suggestion to a selected idle hero, with clear feedback when no idle hero is available or the explicit target cannot be honored.
* Operators can dismiss individual idle suggestions and codebase issues with optimistic removal, in-flight guards, rollback on failure, and reconciliation against the next snapshot.
* Operators can bulk dismiss idle suggestions with `Alt+X`, including partial-failure feedback when one of several server-backed dismissals fails.
* Operators can trigger codebase scan, on-demand analysis, and project scan from the Quest Board, using Settings scan root and quest ignore patterns where applicable.
* Operators can accept the top three actionable suggestions with `1`, `2`, and `3`; focus the Quest Board reply/composer target with `Alt+R`; and see those bindings in the shortcut help overlay.
* Quest cards and action controls remain keyboard-reachable, screen-reader named, and stable while actions are pending.
* Focused tests cover action request helpers, store action state, component interactions, shortcut routing, shortcut help copy, and failure feedback.

### Out of Scope (Deferred)

* New server routes - *Reason: Sessions 03, 07, and 08 already shipped the required route family.*
* Accepting codebase issues as quests - *Reason: Phase 18 explicitly excludes that latent historical path; codebase issues are dismiss-only in parity scope.*
* Real execution of accepted prompts in a terminal or CLI - *Reason: real executors remain separately gated by the project threat model.*
* Hosted analytics or suggestion telemetry - *Reason: historical telemetry is excluded under local-first hosted-service guardrails.*
* Moving the Quest Board into a new side panel - *Reason: this session can add controls inside the existing panel; larger placement changes are not needed for parity.*

***

## 5. Technical Approach

### Architecture

Create `apps/web/src/lib/questBoardActions.ts` as the web action boundary for Quest Board route calls. It should use local auth headers, construct URLs from the current local server port, validate safe IDs before route construction, apply `AbortController` timeouts, parse bounded JSON responses, and map HTTP, offline, conflict, validation, not-found, and malformed-response failures into compact typed results.

Extend `apps/web/src/lib/questBoardModel.ts` with action capability metadata. Idle suggestion cards should retain the canonical suggestion ID and optional default hero ID for accept/dismiss/assign behavior. Codebase issue cards should retain the issue ID for dismiss-only behavior. Legacy idle, analysis, project scan, and session follow-up cards should expose explicit disabled or informational capability state rather than pretending unsupported routes exist.

Upgrade `apps/web/src/store/useGameStore.ts` with Quest Board action state and methods. The store should track pending action IDs, trigger scope state, last feedback, and optimistic removals. Component and shortcut callers should share the same store methods so pointer and keyboard paths cannot drift. Snapshot reducers must continue to treat `suggestion_update` as canonical and clear resolved optimistic state when the server confirms mutations.

Update `apps/web/src/components/QuestBoard.tsx` to render action controls on capable cards, an assign-to-idle-hero selector or menu, manual trigger buttons in the panel header/action bar, a small reply/composer focus target for `Alt+R`, and compact success/error feedback. Controls must be disabled while their matching action is pending and must not resize or overlap card content.

Extend `apps/web/src/lib/useKeyboardShortcuts.ts` so the pure `routeKey` function admits the specific Alt-key combinations required by this session while continuing to reject unrelated modifier chords. Numeric Quest Board accept bindings must stay inert while the user is typing in input, textarea, select, or contenteditable targets.

### Design Patterns

* Shared action boundary: route calls and error mapping live in one tested helper instead of being embedded in React components.
* Capability-driven UI: cards show actions only when the current card source has a supported route.
* Store-owned mutation state: card buttons and shortcuts use the same duplicate-trigger prevention, optimistic updates, rollback, and feedback.
* Snapshot reconciliation: local optimistic state is temporary; the next canonical `suggestion_update` snapshot is the source of truth.
* Local-first privacy: prompt bodies, raw responses, tokens, absolute paths, and command output are not surfaced in toast or panel feedback.
* Input-aware shortcuts: global bindings never steal normal typing.

### Technology Stack

* TypeScript in `apps/web`.
* React 19 component rendering.
* Zustand store actions in `useGameStore`.
* Existing `@factionos/protocol` suggestion contracts.
* Existing local auth headers from `apps/web/src/lib/localAuth.ts`.
* Existing Settings scan root and quest ignore patterns from `useSettingsStore`.
* Vitest with happy-dom and Testing Library.

***

## 6. Deliverables

### Files to Create

| File                                       | Purpose                                                                                                                                          | Est. Lines |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- |
| `apps/web/src/lib/questBoardActions.ts`    | Quest Board HTTP client for accept, dismiss, issue dismiss, scan, analysis, project scan, status, timeout, validation, and compact error mapping | \~320      |
| `apps/web/tests/questBoardActions.test.ts` | Unit tests for request building, local auth, response parsing, conflicts, offline failures, malformed responses, and timeout handling            | \~260      |

### Files to Modify

| File                                                 | Changes                                                                                                                         | Est. Lines |
| ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| `apps/web/src/lib/questBoardModel.ts`                | Add card action capability metadata and preserve server suggestion/issue IDs for supported actions                              | \~120      |
| `apps/web/src/lib/questBoard.ts`                     | Export action-capable card metadata through existing normalization boundaries                                                   | \~40       |
| `apps/web/src/store/useGameStore.ts`                 | Add action pending state, feedback state, optimistic removals, accept/dismiss/bulk/trigger methods, and snapshot reconciliation | \~260      |
| `apps/web/src/components/QuestBoard.tsx`             | Render action controls, assignment selector, manual trigger buttons, reply/composer focus target, and feedback states           | \~280      |
| `apps/web/src/lib/useKeyboardShortcuts.ts`           | Add numeric and Alt Quest Board shortcut routing, DOM focus helper, and store dispatch wiring                                   | \~160      |
| `apps/web/src/components/KeyboardShortcutsModal.tsx` | Keep shortcut grouping compatible with the new Quest Board help entries if needed                                               | \~20       |
| `apps/web/tests/questBoard.test.ts`                  | Extend normalization tests for action capabilities and unsupported-card states                                                  | \~80       |
| `apps/web/tests/questBoardStore.test.ts`             | Add store tests for optimistic mutation, rollback, trigger state, and snapshot reconciliation                                   | \~220      |
| `apps/web/tests/QuestBoard.test.tsx`                 | Add component interaction tests for accept, dismiss, assign, triggers, disabled states, and feedback                            | \~260      |
| `apps/web/tests/keyboardShortcuts.test.ts`           | Add route and hook tests for `1`, `2`, `3`, `Alt+X`, `Alt+R`, and typing guards                                                 | \~180      |
| `apps/web/tests/KeyboardShortcutsModal.test.tsx`     | Assert Quest Board shortcut help rows are surfaced                                                                              | \~40       |

***

## 7. Success Criteria

### Functional Requirements

* [ ] Accepting an actionable idle card calls the accept route exactly once while pending and reports `send_prompt` or `prompt_sent` semantics.
* [ ] Assigning an idle suggestion to an idle hero sends the selected hero ID and reports a warning when the server cannot honor that target.
* [ ] Dismissing an idle suggestion or codebase issue optimistically removes it, rolls back on failure, and reconciles on the next snapshot.
* [ ] `Alt+X` bulk dismisses idle suggestions with duplicate-trigger prevention and visible partial-failure feedback.
* [ ] Quest Board trigger buttons start codebase scan, analysis, and project scan requests, disable while pending, and surface success/conflict/error feedback.
* [ ] `1`, `2`, and `3` accept the top three actionable suggestions; `Alt+R` focuses the Quest Board reply/composer target.
* [ ] New shortcuts remain inert while typing and do not break existing shortcuts such as `?`, `/`, `g r`, `g l`, `g t`, `g x`, `r`, `s`, and `Cmd K`.

### Testing Requirements

* [ ] Action client unit tests written and passing.
* [ ] Store mutation and reconciliation tests written and passing.
* [ ] Quest Board component interaction tests written and passing.
* [ ] Keyboard shortcut routing, hook, and help overlay tests written and passing.
* [ ] `npm --workspace apps/web run typecheck` passes.
* [ ] Focused web tests for Quest Board and keyboard shortcuts pass.

### Non-Functional Requirements

* [ ] No raw prompts, tokens, absolute local paths, command output, or raw response bodies are surfaced in UI feedback.
* [ ] No hosted telemetry, analytics, entitlement, executor, auth, or server route claims are added.
* [ ] Controls remain accessible, keyboard-reachable, and stable at supported desktop and mobile widths.

### Quality Gates

* [ ] All files ASCII-encoded.
* [ ] Unix LF line endings.
* [ ] Code follows project conventions.
* [ ] Local action failures have deterministic, compact user feedback.

***

## 8. Implementation Notes

### Key Considerations

* The server accept route operates on suggestion IDs, so only cards with a canonical server suggestion ID should expose accept and assign controls.
* Codebase issue accept is deliberately excluded; issue cards expose dismiss only.
* Legacy idle cards do not have server IDs. They can remain informational or be cleared locally during bulk dismissal, but they must not call fake server routes.
* `suggestion_update` snapshots remain authoritative. Optimistic client state is only a temporary UI affordance.
* Settings already owns scan root and quest ignore pattern state. Quest Board triggers should reuse that state rather than introducing a second config source.

### Potential Challenges

* Mapping card IDs back to server IDs: add explicit action metadata instead of parsing display IDs.
* Shortcut collisions with browser or existing app chords: allow only the specified Alt chords and keep unrelated modifier guards unchanged.
* Partial bulk dismiss failures: report compact counts and roll back only the cards the server did not confirm.
* Assign-to-hero mismatch: if the server returns `prompt_sent` after an explicit hero was selected, surface a warning and keep the route result visible without leaking prompt content.

### Relevant Considerations

* \[P17-apps/web] **Pure normalization before store mutation**: action metadata should be derived by pure helpers before Zustand state changes.
* \[P03-apps/server] **Local server boundary must stay conservative**: route callers must send validated IDs, local auth headers, bounded bodies, and compact error handling.
* \[P07] **Redaction is boundary-specific**: action feedback must not display raw prompt text, absolute paths, tokens, raw responses, or command output.
* \[P03] **Real executors remain unimplemented by design**: accepting a suggestion routes the server-defined prompt intent only; it does not add a real executor.
* \[P07] **Hosted services ship as disabled-default guardrails only**: historical suggestion telemetry and entitlement flows remain excluded.
* \[P17-apps/web] **Pure normalization before store mutation**: snapshot reconciliation should remain deterministic and easy to test.

### Behavioral Quality Focus

Checklist active: Yes Top behavioral risks for this session:

* Duplicate accept or dismiss requests from rapid pointer clicks and shortcut repeats.
* Optimistic card removal diverging from canonical snapshots after failures or reconnects.
* Global shortcuts stealing focus from text inputs or contenteditable surfaces.
* Trigger buttons hiding conflict, timeout, offline, or malformed-response failures.

***

## 9. Testing Strategy

### Unit Tests

* Test `questBoardActions.ts` request URLs, payloads, local auth headers, response parsing, timeout handling, conflicts, offline failures, and compact error mapping.
* Test card action capability metadata for idle, codebase issue, legacy idle, analysis, project scan, and follow-up cards.
* Test `routeKey` for numeric accept, `Alt+X`, `Alt+R`, modifier guards, and typing-target behavior.

### Integration Tests

* Test store accept, dismiss, issue dismiss, bulk dismiss, trigger methods, pending-state guards, optimistic rollback, toast/feedback state, and snapshot reconciliation with mocked action clients.
* Test `useKeyboardShortcuts` dispatch through the real store methods where practical.

### Manual Testing

* In the local cockpit, seed a mixed Quest Board snapshot, accept the top actionable card, dismiss an idle card, dismiss a codebase issue, run each trigger button, verify disabled states while pending, and confirm feedback remains compact.
* Verify `1`, `2`, `3`, `Alt+X`, and `Alt+R` from the main cockpit and verify they do nothing while focus is inside an input or textarea.

### Edge Cases

* Local server offline.
* HTTP 400 validation error.
* HTTP 404 stale suggestion or issue ID.
* HTTP 409 action already in flight.
* Response body is malformed or missing required fields.
* No idle heroes are available for assignment.
* Explicit assigned hero disappears before the server responds.
* Legacy idle cards exist without canonical server IDs.
* Multiple rapid clicks or key repeats target the same card.

***

## 10. Dependencies

### External Libraries

* None new.

### Internal Dependencies

* `@factionos/protocol` suggestion action and status contracts.
* `apps/web/src/lib/localAuth.ts` for local bearer headers.
* `apps/web/src/lib/questBoard.ts` and `apps/web/src/lib/questBoardModel.ts` for typed card normalization.
* `apps/web/src/store/useGameStore.ts` for cockpit state and WebSocket snapshot handling.
* `apps/web/src/store/useSettingsStore.ts` for scan root and quest ignore patterns.
* `apps/web/src/lib/useKeyboardShortcuts.ts` for global shortcut routing.

### Other Sessions

* **Depends on**: `phase18-session09-web-quest-board-typed-cards`
* **Depended by**: `phase18-session11-validation-documentation-and-handoff`

***

## Next Steps

Run the implement workflow step to begin AI-led implementation.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://faction-os.gitbook.io/faction-os-docs/.spec_system/archive/sessions/phase18-session10-quest-actions-and-keyboard-shortcuts/spec.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
