Skip to content

feat(mobile): fork a session from a message - #7440

Merged
iscekic merged 11 commits into
igor/fork-cut-ingestfrom
igor/fork-from-message-app
Oct 13, 2026
Merged

iscekic merged 11 commits into
igor/fork-cut-ingestfrom
igor/fork-from-message-app

Conversation

@iscekic

@iscekic iscekic commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator

bot: Adds "Fork from here" to the message details sheet in the mobile agent chat, for Cloud Agent and remote CLI sessions.

Summary

  • Long-press an assistant message and select "Fork from here". The fork keeps the transcript up to and including that message.
  • Long-press a user message and select "Fork from here". The fork cuts before that message and puts its text in the new composer. The action is not shown on the first user message, on queued or failed messages, or on a reply that is still streaming.
  • The action opens the existing Continue screen with the cut, so the user selects the destination and the model.
  • Cloud destination: cloneUpToMessageId goes through prepareSession (web and worker schemas), session registration, and the session-ingest clone. The cut is part of the retry fingerprint, so a retry with a different cut is a conflict.
  • Remote destination: create_session carries the cut. The relay forwards the new sessionCloneAtMessage heartbeat capability. Mobile refuses the fork on a CLI without it and shows "Update the Kilo CLI".
  • Files: a Cloud Agent source has no per-message diffs, so the Continue screen shows "Files start from the base branch." or "Files on this computer are not changed."
  • A cut message that is not saved yet shows "This message is not saved yet. Try again in a moment."
  • A Continue without a cut is unchanged.

Merge order

  1. feat(cli): fork a remote session from a message kilocode#15004 (CLI). Mobile hides remote forks until the CLI advertises support.
  2. The base PR, the session-ingest cut.
  3. This PR.

Verification

  • Ran on a VM:
    • mobile typecheck, lint, check:unused, check:i18n, and test: all pass.
    • Typechecks for cloud-agent-next, cloud-agent-sdk, web, and session-ingest: clean.
    • The session-ingest and cloud-agent-sdk test suites pass. The web jest tests for the changed routers pass with Postgres.
    • The cloud-agent-next suite passes except one file, managed-github-preparation-auth.test.ts, which this PR does not touch. It failed because real github.com returned HTTP 429 to the VM.
  • I generated the translations of the five new strings with a model. They need a translator review.
  • Not done yet: an end-to-end run on a device.

@kilo-code-bot

kilo-code-bot Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Incremental review of the fork-cut follow-up (commit baaf027): the mobile cloned-session first-page re-read, the cloned=1 route handoff, the stale clone-cut meta cleanup, and the widened clone-rollback match. I verified the re-read is bounded and clears its flag on first success, the rollback match still requires the stored source and destination to equal the requested pair, and the new meta delete preserves the "no cut key <=> full clone" invariant. Typecheck/test status is per the author's E2E notes; the disclosed lint failures are confined to mobile-session-manager.test.ts test-only as never casts and do not affect runtime behavior.

Files Reviewed (11 files)
  • apps/mobile/src/app/(app)/agent-chat/[session-id].tsx
  • apps/mobile/src/components/agents/mobile-session-manager.ts
  • apps/mobile/src/components/agents/mobile-session-manager.test.ts
  • apps/mobile/src/components/agents/session-detail-routes.ts
  • apps/mobile/src/components/agents/session-provider.tsx
  • apps/mobile/src/components/agents/use-remote-spawn-dispatch.ts
  • apps/mobile/src/components/agents/use-remote-spawn-dispatch.test.ts
  • services/session-ingest/src/dos/SessionIngestDO.ts
  • services/session-ingest/src/dos/SessionIngestDO.test.ts
  • services/session-ingest/src/session-ingest-rpc.ts
  • services/session-ingest/src/session-ingest-rpc.test.ts
Previous Review Summary (commit fb8952d)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit fb8952d)

Status: No Issues Found | Recommendation: Merge

The PR threads an inclusive clone cut (cloneUpToMessageId) from mobile "Fork from here" through the web/worker/session-ingest/SDK clone path, adds the sessionCloneAtMessage capability gate, and reuses the existing composer/share handoff. I verified the cut is forwarded and validated consistently across schemas, the retry fingerprint, metadata immutability, and the remote capability gate, and that the capability fail-closed logic, fork-cut resolution, and error-code mapping line up with their tests. The services/kilo-mcp/catalog.json refresh only extends the existing prepareSession clone mutation with the cut field; it does not newly expose credential/secret/authz/deploy/billing/delete operations.

Files Reviewed (129 files)
  • apps/mobile/src/components/agents/fork-cut.ts / fork-cut.test.ts
  • apps/mobile/src/components/agents/message-details-sheet.tsx
  • apps/mobile/src/components/agents/new-session-prefill.ts / new-session-prefill-continue.test.ts
  • apps/mobile/src/components/agents/new-session-screen-body.tsx
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.ts / .test.ts
  • apps/mobile/src/components/agents/use-remote-spawn-dispatch.ts / .test.ts
  • apps/mobile/src/lib/app-actions/prepare-agent-session.ts
  • apps/mobile/src/lib/hooks/remote-instance-spawn-classifier.ts / .test.ts
  • apps/mobile/src/lib/share-navigation.ts
  • apps/mobile/src/lib/use-new-session-share-remote.ts
  • apps/mobile/src/i18n/locales/*.json (86 catalogs)
  • apps/web/src/lib/cloud-agent-next/cloud-agent-client.ts
  • apps/web/src/routers/active-sessions-router.ts / .test.ts
  • apps/web/src/routers/cloud-agent-next-schemas.ts / .test.ts
  • apps/web/src/routers/cloud-agent-next-router.test.ts
  • packages/cloud-agent-sdk/src/create-session.ts / .test.ts
  • packages/cloud-agent-sdk/src/transport.ts
  • packages/session-ingest-contracts/src/rpc-contract.ts
  • services/cloud-agent-next/src/control-plane/session/session-do.ts
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts
  • services/cloud-agent-next/src/persistence/session-metadata.ts / .test.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.ts
  • services/cloud-agent-next/src/router/schemas.ts / schemas.test.ts
  • services/cloud-agent-next/src/session-service.ts / .test.ts
  • services/cloud-agent-next/src/session/session-registration.ts
  • services/cloud-agent-next/src/session/session-requests.ts
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/kilo-mcp/catalog.json
  • services/session-ingest/src/dos/UserConnectionDO.ts / .test.ts
  • services/session-ingest/src/types/user-connection-protocol.ts / .test.ts

Reviewed by deepseek-v4.1-flash · Input: 97.8K · Output: 25.5K · Cached: 1.3M

Review guidance: REVIEW.md from base branch igor/fork-cut-ingest

@iscekic

iscekic commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

bot: E2E on a VM: "Fork from here" on an assistant reply forked a remote CLI session into a second remote directory. The new session holds turns 1-2 only, the destination has only the turn 1-2 file edits, and the Continue screen showed no composer prefill. The session-ingest cut export returned the kept messages and an empty sessionDiff. The order bug in the forked transcript is fixed in the CLI (Kilo-Org/kilocode#15004).

Fork from here

Forked session

@iscekic

iscekic commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

bot: More E2E results. b: a fork from a user message cloned the turns before it and prefilled its text, unsent. The first view of the new session showed "No messages yet" until I reopened it from history; the transcript then showed turns 1-2. e: an older CLI without sessionCloneAtMessage gets the update hint, and Start session stays disabled.

b: Fork from here on a user message

b: first view shows no messages

b: after reopening

e: update hint

@iscekic

iscekic commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

bot: E2E for "Fork from here" with a Cloud Agent source (local stack on a VM, fake model, two turns writing a.txt then b.txt), forked from the turn 1 reply.

  • Cloud Agent → computer: pass. The Continue screen says "Files on this computer are not changed." The forked transcript holds only turn 1, and the destination folder is byte-identical before and after the fork.
  • Cloud Agent → Cloud Agent: pass on the backend, blocked in the app. The Continue screen says "Files start from the base branch.", but Start session stays disabled because the test account has no GitHub connection. I sent the same clone-with-cut request to prepareSession directly. The session-ingest export holds only turn 1 and an empty session diff. The new sandbox started and has only the base branch (no a.txt or b.txt), and a follow-up turn ran there.
  • Seen again: the first view of the session forked to the computer shows "No messages yet". After reopening it from the list, it shows turn 1.

Cloud Agent source, two turns

Continue to computer with note

First view after fork shows No messages yet

Forked computer session after reopening: turn 1 only

Continue to Cloud Agent with note

Cloud Agent fork: turn 1 plus a new turn

…remote CLI

The CLI answers create_session for a clone before its share bootstrap and
debounced full sync reach session ingest, so the route's one-time first page
read could find the row with no history and show "No messages yet" until
reopen. A clone spawn now navigates with cloned=1, and the manager re-reads an
empty first page at 1s for the spawned budget.
@iscekic

iscekic commented Oct 12, 2026

Copy link
Copy Markdown
Collaborator Author

bot: I re-tested the fix for the empty first view, with the app bundle served by Metro from this branch. I forked the Cloud Agent session from its turn 1 reply onto a computer again. The session opened straight away showing turn 1, with no "No messages yet" state and no need to reopen it. The destination CLI holds only the turn 1 messages, and its folder is unchanged.

The app checks on this branch: typecheck and tests pass, lint fails with 7 errors in mobile-session-manager.test.ts: non-null assertions on fetchSnapshotPage and an as never object-literal cast in the test setup.

First view after fork with the fix: turn 1 shown

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