mirror of
https://github.com/stablyai/orca.git
synced 2026-11-04 19:17:28 +00:00
* feat(mobile): Resume in New CLI from a phone chat tab A chat tab on the phone had only Close in its long-press menu, so a chat that would not load left no way to reach its conversation. The phone now offers Resume in New CLI, like the desktop tab menu: the chat's host prepares the conversation and the phone opens a copy in a new terminal tab. The resume and fork startup builders move to src/shared so the desktop and the phone build the same command. * test(mobile): type the fake terminal create instead of casting its calls * fix(mobile): pass the host's fork source as is; match the quoted args in the test * test(mobile): give the fake host client the untyped mock the other client fakes use * style: format the shared resume builder and phone fork files * Fix mobile chat CLI fork creation on owning host * Fix mobile chat fork lint and split create owner helpers * Keep chat fork beside phone anchor across tab groups * Combine mobile terminal runtime type imports * Repair mobile create CI contracts after chat fork extraction * Classify chat fork preflight refusals and preserve mobile create recordings * Keep route-owned create cleanup quiet after unmount * Preserve typed runtime repair refusal in chat fork preflight * Preserve checked store through mobile chat fork preflight * Register mobile chat fork runtime fixture before test setup * Remove unused mobile create recording value * style(mobile): format the chat fork create files; move fork reply messages into the fork feedback module Formatting pushed the create hook past its line limit, so the fork-only reply message, partial-success warning and host capability check now live beside the other fork messages. Same order and copy as before. * Keep quick command mutation aligned with formatted request * Keep mobile chat CLI forks in terminal view * Pass mobile chat resolution its existing controller arguments * Match the mobile create fixture mock layout * Keep mobile chat CLI forks open when placement is unavailable * Brace placement contract fixture checks * test(mobile): keep the prompt controller mock under its line limit after the main merge * Expose pane admission in the runtime test fixture type * Complete the chat fork contract controller fixture
47 lines
2.3 KiB
TypeScript
47 lines
2.3 KiB
TypeScript
import { z } from 'zod'
|
|
import { salvagedOptional } from '../../../src/shared/zod-salvage'
|
|
|
|
// The session screen's writes: terminal input from native chat and the image surfaces, the tab
|
|
// strip's rename/close/activate, the New Tab terminal create, the terminal menu's display-mode
|
|
// toggle, the markdown tab save and the worktree review-notes write.
|
|
// Checked against the terminal-send envelope src/main/runtime/rpc/methods/terminal.ts answers with
|
|
// and RuntimeMarkdownSaveTabResult in src/shared/mobile-markdown-document.ts.
|
|
|
|
/**
|
|
* The six writes whose reply body no call site reads.
|
|
*
|
|
* Rename, close, tab-close, focus, tab-activate and the review-notes write are all decided by the
|
|
* acceptance verdict alone — use-mobile-session-close-actions.ts:50/76/113 read `accepted` and
|
|
* nothing else, the two activation sends are never interpreted at all, and
|
|
* use-mobile-session-diff-comments.ts:53 discards the interpretation. Declaring a member on any of
|
|
* them would be a requirement with no reader behind it.
|
|
*/
|
|
export const sessionWriteUnreadReplySchema = z.unknown()
|
|
|
|
/**
|
|
* The terminal tab a New Tab create answers with.
|
|
*
|
|
* `id` is required and non-empty: use-mobile-session-terminal-create-actions.ts reads it unguarded
|
|
* three times — the pending-active ref, `setActiveSessionTabId` and the strip's dedupe — so a reply
|
|
* without one seated a tab the strip could never address again. `type` is a literal because the
|
|
* whole tab is spread into the strip, where `type` picks the arm: a create answering a markdown or
|
|
* browser tab must be refused, not rendered as a terminal with no handle. `terminal`, `title` and
|
|
* `terminalTheme` stay optional and keep main's own guards (`typeof === 'string'`, `||`, `??`)
|
|
* behind them, and unknown members pass through so the strip keeps what a newer host sends.
|
|
*/
|
|
export const sessionCreatedTerminalTabSchema = z
|
|
.looseObject({
|
|
tab: z.looseObject({
|
|
type: z.literal('terminal'),
|
|
id: z.string().min(1),
|
|
terminal: salvagedOptional('terminal', z.string().nullable()),
|
|
title: salvagedOptional('title', z.string()),
|
|
terminalTheme: salvagedOptional('terminalTheme', z.unknown())
|
|
})
|
|
})
|
|
.transform((reply) => reply.tab)
|
|
|
|
export function createdTerminalDesktopWarning(raw: unknown): boolean {
|
|
return z.looseObject({ warning: z.literal('desktop-tab-not-shown') }).safeParse(raw).success
|
|
}
|