Ask mode: a real Ask page (5th tray mode) with conversation history #150

Closed
opened 2026-09-26 07:10:07 +00:00 by kayg · 20 comments
Owner

DESIGN §35 (grill round 2): Ask is the 5th tray mode (after Calendar/Files/Photos/Analytics; tray shows 3 and scrolls). Today there is no Ask index page, only /ai/turns (individual Ask conversations, merged in #60: Ask answers from your own data with citations, read-only agent scope). Build /ask: the conversation list (history, newest first, search via the one palette only — no inline search), a new-question composer surface reusing the shared palette capsule/composer primitives (no second overlay system), the answer view with citations that deep-link to the cited items (§33), Copy link, empty state, per-user; mode registered through the plugin catalog (AI plugin, #85: hidden when AI is off). ModeHeader row, primary-action pill = New question. Essentials only.

DESIGN §35 (grill round 2): Ask is the 5th tray mode (after Calendar/Files/Photos/Analytics; tray shows 3 and scrolls). Today there is no Ask index page, only /ai/turns (individual Ask conversations, merged in #60: Ask answers from your own data with citations, read-only agent scope). Build /ask: the conversation list (history, newest first, search via the one palette only — no inline search), a new-question composer surface reusing the shared palette capsule/composer primitives (no second overlay system), the answer view with citations that deep-link to the cited items (§33), Copy link, empty state, per-user; mode registered through the plugin catalog (AI plugin, #85: hidden when AI is off). ModeHeader row, primary-action pill = New question. Essentials only.
Author
Owner

Starting ask-page on branch job/ask-page, based on dev at 7c1d6c82ea.

Starting ask-page on branch job/ask-page, based on dev at 7c1d6c82ea98ac3772117a534fbb923825a60bab.
Author
Owner

Finding for #150: the server already exposes POST /api/v1/ai/ask (question + provider, read-only Ask turn), and the shared /ai/turns panel already renders citations. The shell has no AI mode in PLUGIN_NAVIGATION, and the source rows currently have no Copy link action. I will reuse the API, panel, and palette surface, add the AI mode registration and source Copy link controls, and use the existing AI e2e fixture database for the new page flow.

Finding for #150: the server already exposes POST /api/v1/ai/ask (question + provider, read-only Ask turn), and the shared /ai/turns panel already renders citations. The shell has no AI mode in PLUGIN_NAVIGATION, and the source rows currently have no Copy link action. I will reuse the API, panel, and palette surface, add the AI mode registration and source Copy link controls, and use the existing AI e2e fixture database for the new page flow.
Author
Owner

Finding for #150: this dev base has no Analytics mode in apps/web navigation or the server plugin catalog (the only matching server manifest is AI). I reserved Analytics before AI in the canonical mode order, so Ask sorts fifth once Analytics is registered. I am not adding an unbuilt Analytics route or placeholder mode to this Ask issue.

Finding for #150: this dev base has no Analytics mode in apps/web navigation or the server plugin catalog (the only matching server manifest is AI). I reserved Analytics before AI in the canonical mode order, so Ask sorts fifth once Analytics is registered. I am not adding an unbuilt Analytics route or placeholder mode to this Ask issue.
Author
Owner

Finding for #150: the existing AI e2e harness could not start because its locked Playwright package was not installed at tests/adversarial/node_modules/playwright/index.mjs. I am installing the pinned tests/adversarial dependency set; this does not change source or lockfiles.

Finding for #150: the existing AI e2e harness could not start because its locked Playwright package was not installed at tests/adversarial/node_modules/playwright/index.mjs. I am installing the pinned tests/adversarial dependency set; this does not change source or lockfiles.
Author
Owner

Finding for #150: the first real-server Ask e2e passed provider selection and Ask-only history, then timed out waiting for transcript text after opening the test fixture turn at /ai/turns/. I am comparing its event encoding with the existing AI fixture transcript and Turn view loader before adjusting the regression test.

Finding for #150: the first real-server Ask e2e passed provider selection and Ask-only history, then timed out waiting for transcript text after opening the test fixture turn at /ai/turns/<id>. I am comparing its event encoding with the existing AI fixture transcript and Turn view loader before adjusting the regression test.
Author
Owner

Finding for #150: the Ask transcript fixture emits both Claude assistant text and its final result event, so the shared Turn view correctly renders the final answer as ; the e2e expected . I changed the assertion to inspect transcript rows. The member invitation test also used a non-existent button: the real flow is Continue, then Open calternal to sign in. I am aligning it with the existing auth e2e helper.

Finding for #150: the Ask transcript fixture emits both Claude assistant text and its final result event, so the shared Turn view correctly renders the final answer as ; the e2e expected . I changed the assertion to inspect transcript rows. The member invitation test also used a non-existent button: the real flow is Continue, then Open calternal to sign in. I am aligning it with the existing auth e2e helper.
Author
Owner

Finding for #150: the Ask transcript fixture emits both Claude assistant text and its final result event, so the shared Turn view renders the final answer as b-result; the e2e initially expected b-text. The assertion now checks transcript rows. The member invitation test also looked for a missing Done button: the real flow is Continue, then Open calternal to sign in. I am aligning the test with the existing auth e2e helper.

Finding for #150: the Ask transcript fixture emits both Claude assistant text and its final result event, so the shared Turn view renders the final answer as b-result; the e2e initially expected b-text. The assertion now checks transcript rows. The member invitation test also looked for a missing Done button: the real flow is Continue, then Open calternal to sign in. I am aligning the test with the existing auth e2e helper.
Author
Owner

Finding for #150: member setup reached its final screen and signed in, but the e2e expected /today exactly. The app correctly canonicalizes that location to /calendar/today/; I am matching the existing auth e2e route assertion.

Finding for #150: member setup reached its final screen and signed in, but the e2e expected /today exactly. The app correctly canonicalizes that location to /calendar/today/<date>; I am matching the existing auth e2e route assertion.
Author
Owner

Finding for #150: disabling AI closed /ask for the owner, then the existing Today redirect canonicalized to /calendar/week/ from saved view state. The e2e waited for exactly /today and timed out after observing /calendar/week. I am asserting the shared calendar fallback route for both owner and member.

Finding for #150: disabling AI closed /ask for the owner, then the existing Today redirect canonicalized to /calendar/week/<date> from saved view state. The e2e waited for exactly /today and timed out after observing /calendar/week. I am asserting the shared calendar fallback route for both owner and member.
Author
Owner

Finding for #150: the layout sweep checked 168 screens and found a touch hit-target gap after Ask adds a fourth mode to the shared tray. The tray scrolls at 390 px and the hit-test corners for Files land on the page underneath. The same tray failure repeats on other routes, so its fix belongs in the shared UI TabBar rather than the Ask page. I am recording it for the owner instead of changing the shared UI package from this page job.

Exact Ask-related sweep output:

checked 168 screens
FAIL ask-mode 390 collapsed paper: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content)
FAIL header ask 390 scale 1: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content)
FAIL break-it ask 320 scale 1: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content)

Finding for #150: the layout sweep checked 168 screens and found a touch hit-target gap after Ask adds a fourth mode to the shared tray. The tray scrolls at 390 px and the hit-test corners for Files land on the page underneath. The same tray failure repeats on other routes, so its fix belongs in the shared UI TabBar rather than the Ask page. I am recording it for the owner instead of changing the shared UI package from this page job. Exact Ask-related sweep output: checked 168 screens FAIL ask-mode 390 collapsed paper: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content) FAIL header ask 390 scale 1: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content) FAIL break-it ask 320 scale 1: hit area button.seg-btn.island-segment "Files" is under 44×44 (50×44 painted; -21,-21 hits div.route-content)
Author
Owner

Finding for #150: the full web unit suite passed 48 of 49 files and 358 of 359 tests. Its sole failure was the unrelated rendered-theme contrast test timing out at 5 seconds (reported runtime 5.569 seconds); Vitest also reported 251.36 seconds of module transforms across workers. I am rerunning that test alone to check for a shared-host load timeout.

Finding for #150: the full web unit suite passed 48 of 49 files and 358 of 359 tests. Its sole failure was the unrelated rendered-theme contrast test timing out at 5 seconds (reported runtime 5.569 seconds); Vitest also reported 251.36 seconds of module transforms across workers. I am rerunning that test alone to check for a shared-host load timeout.
Author
Owner

Update: the isolated rendered-theme contrast test timed out again at 9.308 seconds against its 5-second limit. At 11:12 UTC the host load average was 58.14 / 64.44 / 85.48, with several Rust compiles and server processes active. This confirms the unit-suite failure is a shared-host slowdown; the test itself and theme files are outside this Ask change.

Update: the isolated rendered-theme contrast test timed out again at 9.308 seconds against its 5-second limit. At 11:12 UTC the host load average was 58.14 / 64.44 / 85.48, with several Rust compiles and server processes active. This confirms the unit-suite failure is a shared-host slowdown; the test itself and theme files are outside this Ask change.
Author
Owner

Correction: the load-average observation above was at 11:12 CEST (09:12 UTC), not 11:12 UTC.

Correction: the load-average observation above was at 11:12 CEST (09:12 UTC), not 11:12 UTC.
Author
Owner

Finding for #150: the existing Agent e2e reached Settings → AI but timed out because its empty-history assertion expects “No agent turns yet.” while the actual shared TurnHistory empty state says “No turns yet.” This assertion was already stale; I am aligning it with the rendered state before rerunning the Agent flow.

Finding for #150: the existing Agent e2e reached Settings → AI but timed out because its empty-history assertion expects “No agent turns yet.” while the actual shared TurnHistory empty state says “No turns yet.” This assertion was already stale; I am aligning it with the rendered state before rerunning the Agent flow.
Author
Owner

Finding for #150: after correcting the stale empty-state text, the existing Agent e2e advanced through setup and then timed out on another stale selector: it asks for “More note actions”, while the shared ModeHeader labels the overflow button “More actions”. I am updating that selector to the current shared component contract.

Finding for #150: after correcting the stale empty-state text, the existing Agent e2e advanced through setup and then timed out on another stale selector: it asks for “More note actions”, while the shared ModeHeader labels the overflow button “More actions”. I am updating that selector to the current shared component contract.
Author
Owner

Finding for #150: dev advanced to 82d4c25 while this job was running. I merged it before final gates; the merge brought in shared auth session changes and background CSS, with no conflicts. I am rerunning the final web checks and the affected server checks against the merged tree.

Finding for #150: dev advanced to 82d4c25 while this job was running. I merged it before final gates; the merge brought in shared auth session changes and background CSS, with no conflicts. I am rerunning the final web checks and the affected server checks against the merged tree.
Author
Owner

Post-merge full web tests still pass 48 of 49 files and 358 of 359 tests; the sole failure is the same 5-second rendered-theme test timeout (reported runtime 10.168 seconds). Vitest reported 228.69 seconds of module transforms. The failure is unchanged from the pre-merge run and is load-related on this shared host.

Post-merge full web tests still pass 48 of 49 files and 358 of 359 tests; the sole failure is the same 5-second rendered-theme test timeout (reported runtime 10.168 seconds). Vitest reported 228.69 seconds of module transforms. The failure is unchanged from the pre-merge run and is load-related on this shared host.
Author
Owner

Post-merge layout sweep completed on 2026-09-26: checked 168 screens.

Ask-specific failures:

  • ask-mode 390 collapsed paper, header ask 390 scale 1, and break-it ask 320 scale 1: the shared Files TabBar segment paints 50×44, but its tested corner hit at (-21, -21) lands on div.route-content.
  • header collapse ask 1440: the collapsed header did not blur, move, or shrink. At 390px the Ask header did not collapse on scroll.

The same TabBar corner-hit failure repeats across Calendar, Files, Photos, Notes, and other routes. Header-collapse failures also repeat across routes. These point to shared shell components, not Ask page code. They remain accessibility/layout defects and need a shared UI fix. The full output is in target/tmp/layout-final.log in this worktree.

Post-merge layout sweep completed on 2026-09-26: `checked 168 screens`. Ask-specific failures: - `ask-mode 390 collapsed paper`, `header ask 390 scale 1`, and `break-it ask 320 scale 1`: the shared Files TabBar segment paints 50×44, but its tested corner hit at (-21, -21) lands on `div.route-content`. - `header collapse ask 1440`: the collapsed header did not blur, move, or shrink. At 390px the Ask header did not collapse on scroll. The same TabBar corner-hit failure repeats across Calendar, Files, Photos, Notes, and other routes. Header-collapse failures also repeat across routes. These point to shared shell components, not Ask page code. They remain accessibility/layout defects and need a shared UI fix. The full output is in `target/tmp/layout-final.log` in this worktree.
Author
Owner

What was built

  • Added the Ask mode page with per-User conversation history, newest first, and the real empty state.
  • Reused the shared Ask endpoint and palette capsule for new questions and provider selection.
  • Reused the shared turn view for answers, stable citation links, citation Copy link actions, and turn deep links.
  • Gated Ask navigation and route access on the AI plugin catalog.

Files

apps/web/e2e/ai.mjs
apps/web/e2e/ask.mjs
apps/web/e2e/header-sweep.mjs
apps/web/e2e/layout-sweep.mjs
apps/web/package.json
apps/web/src/lib/ai/TurnPanel.svelte
apps/web/src/lib/ai/api.ts
apps/web/src/lib/ai/ask.ts
apps/web/src/lib/ai/commands.test.ts
apps/web/src/lib/ai/commands.ts
apps/web/src/lib/ai/mention.ts
apps/web/src/lib/components/search-dialog.svelte
apps/web/src/lib/navigation.test.ts
apps/web/src/lib/navigation.ts
apps/web/src/lib/search/SearchField.svelte
apps/web/src/lib/search/access.test.ts
apps/web/src/lib/search/providers.ts
apps/web/src/lib/search/registry.ts
apps/web/src/lib/search/window.svelte.ts
apps/web/src/routes/+layout.svelte
apps/web/src/routes/ask/+page.svelte
apps/web/src/routes/settings/ai/TurnHistory.svelte

Branch and gates

Head SHA: 32f9d1a9ff219b2f20fd215b33ed40babd82ac5a (after git merge dev; no conflicts).

cargo fmt --check exited 0 and emitted no output.

cargo clippy --all-targets -- -D warnings exited 0. Output:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 44s

cargo test exited 101 during compilation. The saved log ended with these lines and no compiler diagnostic or test summary:

   Compiling calternal-plugin-ai v0.0.1 (/home/kayg/Developer/calternal-wt/ask-page/crates/plugins/ai)
   Compiling calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/ask-page/crates/calternal-notes-core)

The user cgroup reported oom_kill 5; several other Cargo builds and tests were active. This supports host memory pressure, but it does not prove which process was killed.

bun run check exited 0. Output:

svelte-check found 0 errors and 0 warnings

bun run test exited 0. Output:

 Test Files  53 passed (53)
      Tests  420 passed (420)
   Start at  16:14:42
   Duration  74.84s (transform 76%, import 11%, environment 8%, tests 5%)

The real-server Ask Playwright flow exited 0:

PASS Ask composer uses the read-only Ask endpoint with keyboard provider selection
PASS Ask history lists only Ask turns, newest first
PASS long answer, 32 source links, citation Copy link and stable note deep link
PASS member without AI credentials sees an empty, isolated Ask history
PASS disabling the AI plugin hides Ask and closes the route for a member
ask e2e: ok

Browser plugin was not available; the repo Playwright flow ran against a fresh production web build embedded in the local server. It saved desktop and mobile history and answer screenshots in both themes at /home/kayg/Developer/calternal-wt/ask-page-review-150/.

Findings and gaps

  • bun e2e/layout-sweep.mjs --only ask checked 8 screens and exited 1. On the open 390 px Ask screen, Calendar, Files and Photos sidebar rows paint 355×43. On the collapsed Ask tray, the Files segment's tested corner hits route content. I filed this with the shared responsive findings in #168.
  • The broad post-merge 168-screen layout run was stopped after 20 minutes to limit shared-host load. Its interrupted output is not counted as a result.
  • The single post-merge adversarial run exited 1. Non-SLOW findings were added to existing issues: bookmark capture no-responses (#149), missing initial sync files (#166), empty shared Photos timeline (#173), and a 3.58 s write during Home purge against a 2 s target (#174). The remaining reported outliers were tagged SLOW with expected statuses. Hostile-byte checks reported 0 findings; restart probe reported 0 findings.
  • The cargo test gate did not complete, as described above.

Decisions

No extra product decision was needed. The page uses the shared Ask API, palette, and turn history as required by #150.

## What was built - Added the Ask mode page with per-User conversation history, newest first, and the real empty state. - Reused the shared Ask endpoint and palette capsule for new questions and provider selection. - Reused the shared turn view for answers, stable citation links, citation Copy link actions, and turn deep links. - Gated Ask navigation and route access on the AI plugin catalog. ## Files ```text apps/web/e2e/ai.mjs apps/web/e2e/ask.mjs apps/web/e2e/header-sweep.mjs apps/web/e2e/layout-sweep.mjs apps/web/package.json apps/web/src/lib/ai/TurnPanel.svelte apps/web/src/lib/ai/api.ts apps/web/src/lib/ai/ask.ts apps/web/src/lib/ai/commands.test.ts apps/web/src/lib/ai/commands.ts apps/web/src/lib/ai/mention.ts apps/web/src/lib/components/search-dialog.svelte apps/web/src/lib/navigation.test.ts apps/web/src/lib/navigation.ts apps/web/src/lib/search/SearchField.svelte apps/web/src/lib/search/access.test.ts apps/web/src/lib/search/providers.ts apps/web/src/lib/search/registry.ts apps/web/src/lib/search/window.svelte.ts apps/web/src/routes/+layout.svelte apps/web/src/routes/ask/+page.svelte apps/web/src/routes/settings/ai/TurnHistory.svelte ``` ## Branch and gates Head SHA: `32f9d1a9ff219b2f20fd215b33ed40babd82ac5a` (after `git merge dev`; no conflicts). `cargo fmt --check` exited 0 and emitted no output. `cargo clippy --all-targets -- -D warnings` exited 0. Output: ```text Finished `dev` profile [unoptimized + debuginfo] target(s) in 1m 44s ``` `cargo test` exited 101 during compilation. The saved log ended with these lines and no compiler diagnostic or test summary: ```text Compiling calternal-plugin-ai v0.0.1 (/home/kayg/Developer/calternal-wt/ask-page/crates/plugins/ai) Compiling calternal-notes-core v0.1.0 (/home/kayg/Developer/calternal-wt/ask-page/crates/calternal-notes-core) ``` The user cgroup reported `oom_kill 5`; several other Cargo builds and tests were active. This supports host memory pressure, but it does not prove which process was killed. `bun run check` exited 0. Output: ```text svelte-check found 0 errors and 0 warnings ``` `bun run test` exited 0. Output: ```text Test Files 53 passed (53) Tests 420 passed (420) Start at 16:14:42 Duration 74.84s (transform 76%, import 11%, environment 8%, tests 5%) ``` The real-server Ask Playwright flow exited 0: ```text PASS Ask composer uses the read-only Ask endpoint with keyboard provider selection PASS Ask history lists only Ask turns, newest first PASS long answer, 32 source links, citation Copy link and stable note deep link PASS member without AI credentials sees an empty, isolated Ask history PASS disabling the AI plugin hides Ask and closes the route for a member ask e2e: ok ``` Browser plugin was not available; the repo Playwright flow ran against a fresh production web build embedded in the local server. It saved desktop and mobile history and answer screenshots in both themes at `/home/kayg/Developer/calternal-wt/ask-page-review-150/`. ## Findings and gaps - `bun e2e/layout-sweep.mjs --only ask` checked 8 screens and exited 1. On the open 390 px Ask screen, Calendar, Files and Photos sidebar rows paint 355×43. On the collapsed Ask tray, the Files segment's tested corner hits route content. I filed this with the shared responsive findings in #168. - The broad post-merge 168-screen layout run was stopped after 20 minutes to limit shared-host load. Its interrupted output is not counted as a result. - The single post-merge adversarial run exited 1. Non-SLOW findings were added to existing issues: bookmark capture no-responses (#149), missing initial sync files (#166), empty shared Photos timeline (#173), and a 3.58 s write during Home purge against a 2 s target (#174). The remaining reported outliers were tagged SLOW with expected statuses. Hostile-byte checks reported 0 findings; restart probe reported 0 findings. - The `cargo test` gate did not complete, as described above. ## Decisions No extra product decision was needed. The page uses the shared Ask API, palette, and turn history as required by #150.
Author
Owner

Merged into dev at 116cd780 after Claude's screenshot review. Deploy status on #203.

Merged into dev at 116cd780 after Claude's screenshot review. Deploy status on #203.
kayg closed this issue 2026-09-26 16:42:16 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#150
No description provided.