Skip to content

Native iOS app: Library and Ask with streaming answers - #127

Merged
Programcode merged 5 commits into
feat/native-iosfrom
native-ios/03c-library-ask
Oct 9, 2026
Merged

Programcode merged 5 commits into
feat/native-iosfrom
native-ios/03c-library-ask

Conversation

@Programcode

Copy link
Copy Markdown
Owner

Last piece of milestone 1 from plans/2026-10-08-native-ios-app.md: the Library tab to mock 04 and Ask to mock 07, with streaming answers. Stacked on #125. GitHub retargets this PR to feat/native-ios when #125 merges.

What the app now does:

  • Library. It lists the Current Debate's sources, with search and the All, Files, Links and Notes filters. The plus menu can paste a link, which goes through the import-source Edge Function, or write a note. Both are saved with the website's columns and folder. Tapping a row opens the source read-only, and its page opens in the in-app browser. Swiping a row left deletes it after a confirmation. "Choose a file" and "Scan pages" are left out of this PR.
  • Practice and Ask. Practice lists the website's practice tools. Ask opens full screen; the other tools say they are on their way.
    • Ask sends the same request as the website. A plain question streams from ai-stream through expo/fetch. With Citations, Web search, Pros/Cons or Argument map turned on, the full answer comes from ai, because ai-stream doesn't accept those options.
    • The model, settings and Current Debate context, pins included, are chosen the way the website chooses them. The Pro check and default model settings come from @debatelab/core, the same code Add the Debate tab, debate switcher and You tab to the app #125 uses.
    • Finished exchanges are saved to chats and messages. Past chats reopen from the history sheet. Leaving mid-answer cancels the request and saves nothing partial.
    • Answers render as Markdown, with citation chips that open the Library source or the cited page.
  • Shared code. The SSE parser moved from src/lib/ai/streaming.ts to packages/core/src/ai/sse.ts. The website imports it back, so its behaviour and tests are unchanged. That is the only website file this PR touches.
  • Ownership. Every read of a user-owned table also filters on user_id, as Add the Debate tab, debate switcher and You tab to the app #125 does. RLS still enforces ownership.

Checks, run locally on Node 22 at 685f4fb, because GitHub Actions on this account starts no jobs (billing):

  • At a6830d0, the same code rebased onto Add the Debate tab, debate switcher and You tab to the app #125's previous head: npm run verify exit 0 (286 Vitest tests, collaboration, Deno edge tests, build, service worker, 30 Chromium smoke), plus docs:check, the web export and 152 screenshots of the web export signed in to staging. At 685f4fb: typecheck, lint and all 286 tests pass.

  • Live on staging with throwaway 3c-test- data:

    • A link and a note added, then deleted.
    • Three real Ask requests. A plain question streamed from ai-stream, with the first token at 6.5 s. A Citations request came back from ai with 6 citation buttons. A request stopped mid-stream saved nothing partial.
    • The chat was saved and reopened from history.

    All test sources, chats and messages were deleted afterwards (0 left).

  • Every native module is in the App Store build of Expo Go.

Not proven: native rendering on an iPhone (sheets, swipe-to-delete, keyboard, the in-app browser). Those are for the milestone 1 check on Adam's phone.

🤖 Generated with Claude Code

Programcode and others added 4 commits October 9, 2026 11:36
The app needs the website's parser for ai-stream responses. streaming.ts
imports it back and re-exports it, so its behaviour and tests are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Library lists the Current Debate's sources with search and type
filters. The plus menu pastes a link through the import-source Edge
Function or writes a note, saved with the website's columns and folder.
A row opens the source read-only, with its page in the in-app browser,
and swiping it left deletes it after a confirmation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Practice lists the website's practice tools; Ask opens full screen and
the rest say they are on their way. Ask sends the website's request:
plain questions stream from ai-stream through expo/fetch, and with
Citations, Web search, Pros/Cons or Argument map on the whole answer
comes from the ai function, because ai-stream refuses those options.
The model, settings and Current Debate context are picked the way the
website picks them, including pins. Finished exchanges are saved to
chats and messages, past chats reopen from the history sheet, and
leaving mid-answer cancels it without saving half a message.

Answers render through a small Markdown reader with citation chips that
open the Library source or the cited page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The screenshot script now captures the Library's plus menu, link and
note sheets and a source, and Ask empty, mid-answer and answered with
citations. Ask runs on a fake stream inside the page and a fixed answer,
so screenshots never call a model or save a chat.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
debate-navigator Ready Ready Preview Oct 9, 2026 11:59am UTC
debatelab-staging Ready Ready Preview Oct 9, 2026 11:59am UTC

Copilot AI balanced review requested due to automatic review settings October 9, 2026 11:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@Programcode

Copy link
Copy Markdown
Owner Author

Mocks against the app's web export, then real Ask on staging (a cited answer, and the saved chat reopened from history):

Library: mock 04 vs app

Ask: mock 07 vs app

Live Ask with Citations on staging

Saved chat reopened from history

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository YAML (base), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Free
  • Run ID: ac4abf41-a529-4a4d-b835-29e16e02b268

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Note

🎁 Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.


Comment @coderabbitai help to get the list of available commands.

- Ask listens for cancellation before it reads the session, so leaving Ask
  during a token refresh no longer sends the question.
- When a new chat is created but its messages fail to save, Ask keeps the
  chat, so the next save adds to it instead of creating a second chat.
- A failed link import shows only translated text and logs the raw error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Programcode

Copy link
Copy Markdown
Owner Author

Codex review (gpt-6.1-sol)

  • r1 at 685f4fb
    • Medium. Leaving Ask while the session token was refreshing still sent the request, which used up quota. Fixed in 41a0b68: the abort is wired up before the session read and checked again after it. apps/mobile/src/lib/ask.test.ts fails on the old code.
    • Medium. If the messages insert failed, the new chat id was dropped, so the next save created a duplicate chat. Fixed in 41a0b68: ChatSaveError carries the record, and Ask keeps it.
    • Low. The app showed the raw backend import error in translated UI. Fixed in 41a0b68: it now shows only translated text and logs the raw message. The website's LibraryPage.tsx does the same thing and is tracked separately; this PR leaves it alone.
    • r1 also found SSE extraction matches the original across 16,997 chunk-boundary cases.
  • r2 at 41a0b68: no findings. A control probe confirmed the old abort bug.

Local checks at 41a0b68. GitHub Actions starts no jobs on this account because of billing, so these ran locally:

  • npm run verify exit 0, including 30 Chromium smoke tests.
  • Lint, typecheck, npm test (287), docs:check, build, the web export, and 152 screenshots against staging.

Merging into feat/native-ios.

🤖 Generated with Claude Code

@Programcode
Programcode merged commit c222ed4 into feat/native-ios Oct 9, 2026
8 of 18 checks passed
@Programcode
Programcode deleted the native-ios/03c-library-ask branch October 9, 2026 12:07

This branch was successfully deployed

2 active deployments
Preview – debate-navigator — 41a0b68c Deployed Oct 9, 2026 by vercel[bot]
Preview – debatelab-staging — 41a0b68c Deployed Oct 9, 2026 by vercel[bot]
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.

2 participants