@dashup/connector
v0.1.37
Published
Run beside the editor on each computer, including the PC whose Zed window connects to a development machine over SSH. Dashup retains that saved SSH relationship; it does not start a replacement SSH session.
Readme
Desktop connector
Run beside the editor on each computer, including the PC whose Zed window connects to a development machine over SSH. Dashup retains that saved SSH relationship; it does not start a replacement SSH session.
With Node 24:
npx @dashup/connector pairTo keep dashup as a command, install it with npm install -g @dashup/connector. The package bundles the workspace code.
dashup pair walks through pairing in the terminal: it shows a QR code that expires in five minutes, waits for a phone to scan it under Pair a computer, and offers to keep Dashup running in the background. The first phone adds the computer to its account, so the walkthrough names that account and shares nothing until you confirm it. Later codes pair more phones on the same account without asking, including through a connector that is already running. A phone that scans an expired code gets a pairing the computer revokes, because it never kept that key. To pair without the prompt, as an agent can, name the account with --account [email protected]; a phone signed in to any other account is refused. Without a terminal, the code opens in a browser on this computer instead of printing, because it carries the pairing's encryption key and an agent's output leaves the computer. Pairing then exits, and dashup install keeps Dashup running. Where no browser can open, pairing needs a terminal. It uses https://api.dashup.com; for a local API, add --api http://localhost:3000. A physical phone needs a reachable HTTPS API. To run a paired connector in the foreground, use dashup watch.
Existing projects and alerts
dashup doctor
dashup projects
dashup alert --project PROJECT_ID --title "Dashup is connected"The connector automatically reads existing Claude Code, Codex, Kimi, and OpenCode conversations alongside Zed workspaces and VS Code chat history. It honors the harness's existing data directory, authentication, and native session IDs. Native stores are opened read-only; discovery never launches an agent, creates or resumes a conversation, or changes editor settings. Only a session the phone starts runs an agent (see below). Opening the same supported harness session through Zed and its native history uses one Dashup thread when their actual session identities match. Matching directory names alone never merges local and SSH projects. An agent in a Zed SSH project runs on that machine, whose connector lists its conversations.
A thread's title is the agent's own (a rename, Codex's stored title, Claude's title), else the first message the person typed: Codex's injected AGENTS.md and environment messages and Claude Code's slash commands are skipped, and a Codex subagent is named for its task. In the conversation, Codex's injected messages and Claude Code's own meta rows stay out, and a Claude Code slash command reads as typed, followed by its output. A thread's time is its last conversation message in the agent's own history; editor bookkeeping such as Zed's sidebar restamps never moves it. Subagent sessions (OpenCode children, Codex spawned agents) carry their parent thread. Tool calls are joined with their results into one step with status, duration and, for file edits, a unified diff. Saved history has unknown live status unless an exact native Codex writer still owns it: its persisted turn start, completion and abort events then supply working or idle status. File timestamps alone never imply activity. The phone can answer an unowned saved session by resuming it (see Starting sessions from the phone). File changes publish project metadata; only an approval, a question, an error or a finished turn sends an alert. A workspace becomes a project once it has a conversation. The connector keeps one encrypted current dashboard per paired phone: bounded project cards, active/recent session summaries and usage. The phone can show that cached dashboard while the computer reconnects. Project session lists and conversation details come directly from the paired computer over the live encrypted session socket. Opening a chat reads only that native conversation and returns at most thirty whole messages, 16 KiB of text and 40 KiB of JSON. Signed cursors fetch older whole messages. Large messages have one opening preview with complete content available on demand. Live changes replace that bounded latest window; reading older messages stays put until the person returns to latest. No chat transcript, command journal or history generation is stored in the Dashup database. Native live interfaces provide actual status and pending choices. Tool integrations can also queue explicit encrypted alerts with alert.
The overview also carries this computer's agent logins, each with its email, its plan and what its windows have spent, and a working thread names the step it took last. At most every five minutes while sessions change, the connector asks Anthropic's usage meter about Claude Code's login, as Claude's /usage does. It reads that login from .credentials.json in Claude's config directory, or from the macOS Keychain, and sends the token only to Anthropic. It never refreshes the token, because a refresh would rotate the login Claude Code holds, so an expired one waits for Claude Code to renew it. A login whose usage can't be read still names its email, from .claude.json, and its plan, from the login itself. Codex usage is the rate limits Codex last wrote into a session's rollout, and its email and plan come from the identity token in Codex's auth.json.
Project paths, SSH details, thread content, approvals and alerts are encrypted separately for every paired phone. The server stores one replaceable dashboard ciphertext and routes opaque live session packets. Pairing and device changes use account-scoped state events; the connector does not subscribe to database model queries. Revoking a pairing discards its key, pending reminders and local request receipts, and closes its terminals.
Commands execute only through a connected live session. Read-only requests do not write connector receipts. Native mutations save a small request receipt before handoff, so a duplicate request cannot send an agent prompt twice; an unconfirmed handoff asks the person to inspect the native session. Native Codex queue receipts still track queued, delivered and unknown outcomes. Conversation messages and live packets are never added to a durable outbox.
Notification preferences
Settings on the phone configures each paired computer separately. Decisions only is the default: approvals, questions and problems. Completion notifications can be immediate or grouped into 15-, 30- or 60-minute digests. Projects can be muted or snoozed for one or eight hours. Quiet hours use the phone's selected time zone, including daylight-saving changes. The connector receives these preferences encrypted and applies them before the API sends a generic push. Muted events do not send a push; session status remains available on the dashboard.
Decisions wait briefly so an approval resolved automatically does not interrupt the person. Snoozed and quiet-hour requests are checked again before their reminder. Pending reminders survive connector restart encrypted under their pairing key. Completion means a live conversation became idle, with no known child still working or awaiting attention; it does not certify that the task succeeded. A digest opens its most recent conversation. Adapters without a reliable live state can still deliver explicit input alerts, but cannot establish completion. Desktop focus is not available from the current adapters, so using the computer does not suppress phone alerts.
Usage-reset alerts are enabled by default and can be disabled per computer in Settings → Attention preferences → Usage resets. They follow the reset timestamps already reported by the native provider meters (currently Codex and Claude Code), for windows with nonzero usage. Simultaneous windows for one provider/account produce one reminder. Quiet hours postpone a still-relevant reset; expired reminders, sign-outs and superseded reset times are discarded. Pending reminders stay encrypted locally, and small hashed receipts prevent repeat alerts after restart. An unavailable meter for the same login preserves its previously advertised deadline; stale history never invents another recurring reset. The computer must be running to deliver the alert. Push text says only that a usage allowance reset; tapping opens that computer’s Usage section.
Existing live sessions
Dashup discovers existing local OpenCode listeners, Codex control sockets, and VS Code Agent Host endpoints. These connections remain local; their tokens are never sent to Parcae or the phone. Native endpoints are checked for local ownership or loopback access, and redirects and remote endpoint URLs are rejected.
- OpenCode: the existing TUI/server supplies conversations, live events, prompts, native tool permissions, and questions, which the phone answers or skips. A reply targets the original session ID and preserves its latest native agent, model, and variant. For an existing session, Dashup does not run
opencode serveor create another one. OpenCode 2's background service is found from the record it keeps (~/.local/state/opencode/service.json, with the password every request takes) and reached through its/api, and its conversations are read from OpenCode's database (session_v2andsession_message). Active sessions outside the newest history page are fetched by their native IDs. When several OpenCode servers list the same saved conversation, the server reporting current work or a pending choice supplies its status and controls; an idle history view cannot hide it. - Codex: the existing control socket supplies already-loaded threads. Status and controls are read independently of conversation history, including paginated histories. Replies require a recognized native server and a thread that is still loaded and accepts direct input immediately before sending. Codex 0.165 and newer can take replies during a running turn; earlier supported servers require an idle thread. For an existing thread, Dashup never calls
thread/start,thread/resume, orsession/load. Approval controls appear only for native requests routed to this connection; approvals owned by another client may remain available only in the original UI. - VS Code: Microsoft's official AHP client subscribes to existing host sessions and chats. Native choices are retained, and delivery is acknowledged by the host. Older extension-host chats without an accessible Agent Host remain saved history. AHP chat IDs are namespaced rather than guessed to equal CLI thread IDs. Non-file remote AHP workspace URIs are not presented as local execution environments.
- Claude Code: existing transcripts are readable without starting Claude.
dashup installadds Dashup's plugin to Claude Code (dashup@dashup, read in place from this package'sclaude/folder), anddashup uninstallremoves it. A session that starts with the plugin holds a stream open to~/.dashup/claude.sockthroughcurl, and takes each reply as the person's own words; a reply that starts with/runs that command. The plugin also puts each permission request the session waits on to the phone: a tool to allow once or under the rule Claude Code suggests, questions, or a plan. The dialog on the computer, or the editor hosting the session, stays open, and the first answer wins. Claude Code lets only the person there or its host approve a plan, so the phone can only send a running session's plan back with what to change. Claude Code's inbox socket is not used, because Claude presents anything posted there as another session's message, without the person's authority. Sessions opened before the plugin was installed, and sessions on Windows, stay read-only.
Native listener discovery supports the host's available process/socket interfaces. File and socket formats are versioned implementation boundaries; unavailable or unfamiliar interfaces leave history readable and controls disabled. Existing editor and agent processes continue independently when the Dashup connector disconnects. The PC's saved SSH relationship is retained; reading it does not grant access to a remote machine's CLI store.
The existing Zed/Codex session proof records native queued-reply delivery and both observer and connector restarts against an unchanged original process. A separate product Queue reply adapter supports local Linux Codex 0.153.4, 0.160.1, 0.164.0 and 0.165.0, including desktop bundles, npm packages and private-stdio owners. The version comes from the exact running binary, not its package layout. It requires the exact native thread's owned writer lock, rollout file, queue database, process start time and executable version. A matching directory or copied transcript does not grant queue access. Isolated native checks verified queue acceptance and client-message identity on the installed 0.153.4, 0.164.0 and 0.165.0 binaries; connector regression tests cover ownership and receipt handling. End-to-end phone delivery on those versions remains unverified.
Only an explicit Queue reply starts a temporary official app-server helper to initialize and call thread/queue/add in that same native home. It does not start, resume or load an agent thread. A durable local intent records the caller-supplied native client-message ID before dispatch. Interrupted acknowledgement leaves the request unconfirmed and prevents automatic resubmission, including after connector restart. Known acceptance is retained if the item leaves the queue; disappearance is not delivery.
Delivery requires that exact typed client-message ID in the original thread's native history database. A response receipt requires a later native assistant item in the same turn; it does not mean the agent finished. Receipts travel through the encrypted live session socket. Opening a thread reads a bounded latest page; selected native changes update that window without polling database history. Writer ownership also enables lifecycle status without granting queue access on unknown versions, and prevents the connector from resuming a conversation another process holds. Native approvals owned by the private-stdio process remain unsupported and require its original UI. Queue text never substitutes for a native approval.
Each thread shows what its agent's own record says it last ran with. A Claude Code session shows the model of its newest reply and, where that model takes them, fast mode and ultracode; the choices and their names are the models the session's own Claude Code binary offers hosts in its initialize answer, or claude's where the system does not name the binary. A Codex thread shows the model and reasoning effort of its newest turn and, where the model has the priority tier, fast mode, named from Codex's own models_cache.json. An OpenCode session shows the model and agent OpenCode keeps on the session (/api/session), among the person's favourite and recent models as OpenCode's TUI keeps them (model.json), named by its catalog, and the primary agents it lists for the folder. Kimi records only a session's plan mode, so a session the phone runs shows the model and thinking it starts with, among the models Kimi's config.toml names. A setting an agent records only when it changes, such as ultracode or Codex's tier, is searched for however far back it lies. A saved thread carries these, without choices, only in its own published state, never in the dashboard.
The phone changes a running session's settings: through the Claude plugin with Claude Code's own /model, /fast and /effort ultracode commands; in a Claude session the phone started, with control requests at the start of each turn; in a Codex thread the connector holds, with the next turn/start it sends; in an OpenCode session, on the session itself, so the phone's messages go in what it runs with; and in a Kimi session the phone runs, as its next turn starts, with plan mode at once. An agent records a change when its next turn starts, so it shows from the next reply. Changes require the live connection and are never queued for an offline computer.
Stop interrupts the running turn through each live interface: OpenCode's session abort, Codex turn/interrupt, the AHP client's turn cancellation, ACP session/cancel, and the Claude Code plugin's turn abort. It refuses when nothing is running and is sent only through the connected live session.
Live discovery is bounded to 100 recent sessions per endpoint; OpenCode 2 additionally includes up to 100 active sessions outside that page. OpenCode supplies the latest 200 messages; the VS Code host supplies its current chat snapshot. Paged history prefers the native saved store when available and otherwise uses the existing live snapshot. Approvals whose actual commands or file contents cannot be previewed are approved on the computer; rejection remains available when the native protocol supports it.
Cline, Pi, Kilo Code and Junie
These integrations use local interfaces. Conversations and commands enter the existing paired-device encryption path; their local tokens never go to the relay.
| Agent | Connects to | Phone controls | | --------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | Cline | An existing authenticated local SDK/CLI hub | Reply, queue/steer, interrupt and native allow-once/reject decisions | | Pi | The Dashup package inside the existing interactive Pi process | Reply, follow-up queue, steer and interrupt; extension questions stay on the computer | | Kilo Code | Its existing local daemon | Read, reply, queue/steer, interrupt, permissions and questions; start a session explicitly | | Junie | ACP sessions started by Dashup; saved native histories | Reply, interrupt and native permissions in phone-started sessions; read imported histories |
Cline: start Cline normally with a version that exposes its local hub. Dashup reads Cline's private discovery records under ~/.cline/data/locks/hub/owners (or Cline's CLINE_DATA_DIR / CLINE_HUB_DISCOVERY_PATH). Discovery never creates or resumes a Cline session. This does not attach to older Cline editor extensions without a hub.
Pi: dashup install installs the bundled package using pi install <connector-install>/pi. Run /reload in an already-open Pi session. For a checkout, pi install /absolute/path/to/apps/connector/pi does the same. dashup uninstall removes the installed package through Pi's CLI. The package runs inside the existing TUI and publishes a private, authenticated loopback bridge; its registry contains connection credentials, not conversation text. Dashup does not launch Pi or turn an extension question into an ordinary prompt.
Kilo Code: run kilo daemon start and use that daemon's sessions. Dashup reads its private daemon.json, including Kilo's retained data/kilo/state fallback, then uses the native authenticated API. A standalone TUI/server outside this daemon is not attached by this integration. Dashup never starts a daemon while discovering sessions. Edit permissions without a complete diff stay on the computer; a displayed persistent permission includes its saved rule scope. Kilo already has its own mobile app; Dashup adds the shared agent inbox and paired-device transport.
Junie: install Junie and authenticate it normally before starting a Junie session from the phone. Dashup reads the native session index and committed user/final-answer events under ~/.junie/sessions; internal state blobs are not conversation messages. It runs junie --acp true for an explicit phone start. Imported histories stay read-only because Junie's index and terminal-process registry cannot prove that another ACP process has released the session. It does not attach to a running IDEA or terminal session. Editor-owned ACP sessions can use the optional wrapper below. Junie's own permission options and credential errors are preserved.
Transport checks use the published Cline core 0.2.0 hub, Pi 0.80.10, Kilo 7.8.18 and Junie 3110.7.0. Pi's interactive proof uses a local mock model with the same original process and session. Cline's proof uses the production hub with a resident test runtime; Kilo's native proof admits an input and answers permissions without invoking a model or tool. Junie's local mock-model proof starts a session and reads its native saved history. Its explicit native-load test verifies same-ID restoration after closing the original process; that does not establish ownership for imported product histories. These checks do not establish every editor integration or provider configuration.
Starting sessions from the phone
The phone starts a session in a local project, or in a new folder inside one of the folders that already hold this computer's projects, with Claude Code, Codex, Kimi or OpenCode: whichever of claude, codex, kimi and opencode runs here, and the Kimi Zed's agent registry installed when kimi is not on the PATH. The agent works with its own settings and permission rules, and asks the phone before anything they don't allow. Claude Code runs headless (claude -p) for each turn and resumes the session for the next; Codex threads start in Codex's own app-server daemon (codex app-server daemon start) and outlive the connector; OpenCode sessions run in OpenCode 2's background service where it runs, else on an opencode serve the connector starts for that folder; Kimi runs its wire mode (kimi --wire) for each turn under a session id the connector chooses, and the phone answers its approvals and questions. Claude Code's permission requests arrive with the command, or the diff an edit or write would make, and the rule that would stop it asking again; the phone answers its questions and plans as Claude Code's host.
A saved conversation is answered the same way when its agent runs here, its project is local, and nothing else has it open: Claude Code resumes it (claude -p --resume), Codex loads it in its daemon (thread/resume), Kimi resumes it (kimi --wire --session), and OpenCode serves its folder. One a native Codex process owns takes queued messages instead. A start requires a connected computer.
Kilo Code is offered when its local daemon is available; Junie is offered when its command is installed. Both keep their native session IDs. Cline and Pi appear through their existing live connections and are not offered as agents Dashup can launch.
For a Git project with an existing commit, New session offers the current checkout, a new worktree, or an existing worktree registered with that repository. A new worktree creates the chosen branch from the selected branch or commit in a sibling <project>.worktrees directory. It leaves the original checkout and its uncommitted changes alone. Existing-worktree selection accepts only paths Git lists for that repository. A project inside a repository subdirectory starts in the same subdirectory of the selected worktree; a branch without that folder is refused. Dashup does not automatically commit, move changes, remove worktrees, or retry a failed agent launch by replacing a branch. A worktree created before an agent fails to launch remains available to reuse.
Terminal conversations
New terminal starts a fresh shell in the selected local project and opens it in the same conversation list and composer as the agents. Its conversation shows a live terminal screen, including colors, cursor position and alternate screens used by terminal applications. The composer and keyboard controls write to the real PTY; the composer can submit a line or send text without Enter. Stop sends Ctrl-C to the foreground process. Close terminal ends the shell. A shell retains its working directory and environment, runs with the connector's operating-system permissions, and stays on the paired computer. For an SSH project, pair the execution host itself before starting its terminal.
A terminal belongs to the phone that created it. Other paired phones cannot see its instance or send it input. Input and raw terminal output use a live encrypted WebSocket pipe, shared with other live session traffic. The server routes ciphertext without storing terminal input or output. Only the terminal currently attached by that phone streams output; leaving it or disconnecting stops that stream. Input is sent only while connected and is never queued for later execution. Terminal attachments are not accepted as commands.
Up to eight shells can run at once. Private files under terminals/ beside connector.json retain only instance metadata, including ownership, project and exit status. There are no terminal chat messages or saved transcripts. An in-memory terminal emulator restores the current screen when the phone reconnects. Closing the app leaves the shell running; closing the shell, revoking its pairing, or stopping the connector ends it. After connector restart, saved instances are closed and New terminal starts a new shell.
An open agent conversation attaches to the same encrypted session transport. Its latest bounded message page arrives before detailed thread state, without waiting for a dashboard write or scanning other projects. Background source discovery remains independent of the selected conversation. Closing the conversation detaches its stream; the native agent keeps running.
Reviewing project changes
Review changes compares the current local checkout against HEAD or a chosen branch or commit. It includes staged, unstaged and untracked files, with a bounded text diff and binary-file markers. The screen labels these as current project changes because several agents and editors can share a checkout. It does not infer which session authored a change. Tap a diff line to add a comment; opening review from a conversation with a live reply connection lets the phone send the comments back to that session. Deleted-line comments retain their old-side line numbers.
Run check executes the command the person enters in that project's repository root, with the connector's operating-system permissions. It records the actual command, exit status, output and times. Checks stop after two minutes, their output is bounded, and stopping the connector stops its active checks. Only one check runs per checkout at a time. The latest three check results remain in connector memory until restart. A content fingerprint, including uncommitted and untracked files, marks a result stale when the checkout differs from the state before that check. An agent's statement that tests passed is not a recorded check. Git inspection and check results are encrypted for the requesting paired phone.
Files sent from the phone
The phone encrypts selected images and files before uploading them. The paired connector downloads and decrypts them into its private uploads directory beside connector.json; the relay and object storage receive ciphertext. File names cannot select a destination outside that directory, and an existing symlink or conflicting file is rejected. Local copies remain there until removed.
Messages include the local file paths so the existing agent can read them with its usual permissions. Codex live replies and phone-started or resumed Codex sessions also receive supported images as native local-image inputs. Claude Code sessions started or resumed through Dashup's headless host receive supported images as native base64 image blocks. Other integrations, including the Claude plugin and native queued replies, receive file-path context; this does not claim native image input support for every agent or model. Supported native image MIME types are PNG, JPEG, GIF and WebP. The model and agent still determine which files they can interpret.
Connector tests cover real temporary Git worktrees, stale checks after edits, process timeouts and shutdown, authenticated attachment decryption, path confinement, and image input against mock Claude and Codex transports. These checks do not establish real-phone behavior or provider-backed image interpretation on every host.
Optional ACP wrapper
The default history and native-host path needs no wrapper or editor configuration. For an explicitly configured external ACP agent, use the connector as the editor's stdio wrapper; it uses the official ACP SDK's protocol contracts:
dashup acp -- /absolute/path/to/original-agent ORIGINAL_ARGUMENTSInstall dashup globally and set the editor's existing agent command to it, with the arguments above. Start the connector first and launch the agent through that editor configuration. The proxy starts the original command once and forwards the editor's own ACP stream. Phone messages and approval choices go to that same process and session. Only native approval choices are offered, including native file scope when the agent provides it. The proxy does not create another session when opening a phone thread.
The wrapper and connector must run on the same execution host. For SSH projects, confirm where that particular external agent runs before configuring its command; Zed treats external-agent runtime and authentication as agent-owned. Pair the development machine separately if it owns the wrapper process. Reading the PC's saved SSH project does not attach to a remote agent process.
The wrapper cannot retroactively capture an already-running stdio stream. Saved history is not a live session handle. Zed's built-in agent and providers without a supported native attach interface remain read-only in Dashup. If the connector restarts, the original wrapped agent continues, but this optional wrapper currently needs relaunching to restore its observer connection.
Start at login
Answering yes to the walkthrough's background question, or running dashup install on a paired computer, registers a macOS LaunchAgent, Windows Startup entry, or Linux user systemd service and starts it, taking over from any connector already running for that state file. The service runs watch with the state file it was paired with (DASHUP_CONFIG). Linux requires a user systemd session; without a desktop session, as over SSH, install also turns on lingering so the service keeps running after you log out. Under npx or pnpm dlx, whose caches can be cleared, the service runs a copy of that install kept in app/ beside the state file; a checkout or global install runs in place. The Node executable must stay at its installed location. Signed desktop installers are not included.
dashup uninstall stops Dashup and removes the startup entry and its app/ copy; the computer stays paired. dashup stop leaves the service stopped until the next sign-in; a crash restarts it.
Local state and checks
~/.dashup/connector.json holds this computer's secret, pairing keys, encrypted pending reminders, notification preferences, dashboard sequence counters and small native handoff receipts. It is written atomically with private Unix permissions; it is not currently protected by an OS credential vault. Do not share or copy it to another connector. DASHUP_CONFIG selects a separate state file. DASHUP_ZED_DATA and DASHUP_VSCODE_DATA select custom editor data directories. Native history discovery honors CLAUDE_CONFIG_DIR, CODEX_HOME, DASHUP_KIMI_HOME (else ~/.kimi), and XDG paths. Agent histories are parsed locally on demand; terminal files contain only bounded instance metadata.
From a checkout, run pnpm install and pnpm exec turbo build --filter=@dashup/connector... with pnpm 10.34.5, then use pnpm --filter @dashup/connector dashup in place of dashup. For isolated development fixtures, DASHUP_LIVE_DISCOVERY=0 disables automatic process discovery. Explicit DASHUP_OPENCODE_ENDPOINT, DASHUP_CODEX_SOCKET, and DASHUP_AHP_DATA overrides allow local test endpoints without modifying editor configuration. They are not required for ordinary discovery.
DASHUP_PI_DIRECTORY selects the private Pi registry directory. DASHUP_KILO_DAEMON selects a native Kilo daemon record, DASHUP_JUNIE_COMMAND selects an absolute Junie executable, and DASHUP_JUNIE_HOME selects Junie's native home. These overrides still enforce local authentication and do not permit remote HTTP endpoints. Native smoke tests are opt-in with DASHUP_PI_CLI, DASHUP_KILO_CLI and DASHUP_JUNIE_CLI, pointing at their installed binaries or CLI entry points; they use isolated temporary data and local fixtures.
pnpm --filter @dashup/connector test
pnpm --filter @dashup/connector check-types
pnpm --filter @dashup/connector build
TEST_API_URL=http://127.0.0.1:3049 pnpm --filter @dashup/connector test:workflowThe workflow test needs a running isolated Dashup API and database. It creates disposable accounts and verifies pairing, encrypted dashboard replacement, direct bounded native chat pages, command deduplication, offline behavior and revocation over the real session socket. Unit fixtures exercise real native file formats, HTTP/SSE, Unix WebSockets, and the official AHP client. Actual editor UI compatibility, macOS/Windows startup, and production push credentials require their respective hosts and credentials.
Let an agent ask for phone input
Run dashup phone-tools as an MCP stdio server on the same computer and with the same DASHUP_CONFIG as the running connector. For an MCP client that accepts a JSON configuration:
{
"mcpServers": {
"dashup-phone": { "command": "dashup", "args": ["phone-tools"] }
}
}phone_list lists paired phones with Dashup open. phone_request takes a kind (photo, screenshot, file, sketch, choice, or text) and a prompt explaining what the agent needs. A choice request also needs two to twelve distinct choices. If several phones are open, pass a pairing from phone_list. Optional projectId and threadId identify the originating work; timeoutMs is 10–300 seconds and defaults to 120 seconds.
The person explicitly takes a photo, selects a screenshot/file, annotates an image, draws a sketch, or answers the request. Nothing is silently captured. They review it and choose Send to agent. Photos and screenshots open a drawing surface before sending. The connector returns answers and private local file paths; the agent reads those files on its computer. Attachment bytes are encrypted before upload and opened only on the paired computer. Android's camera uses a temporary private cache file, deleted when capture finishes; accepted images use bounded native memory handles.
At most four requests can wait at once. Leaving the app cancels requests except while the person is answering through a bounded native picker/camera. Expiry, MCP cancellation, disconnect, unpairing, and connector shutdown discard pending requests. Reconnect does not replay them. There is no database row, offline queue, or permanent request journal.
Existing T3 Code and Orca chats
Dashup attaches to already-running, same-user local workbenches. Discovery reads their current session inventory; it never starts a workbench, creates a thread, imports a conversation, or starts a provider. T3 Code uses its v0.1.5 protocol-2 HTTP and WebSocket interfaces. Orca uses its v1.4.244 local CLI IPC. Existing native session ids remain the owners of sends, stops, and supported approval choices.
T3 Code discovery reads ~/.t3/userdata/server-runtime.json, honoring T3CODE_HOME or DASHUP_T3_BASE_DIR. The installed t3 CLI must be on the connector's PATH; DASHUP_T3_CLI selects another executable. Dashup calls only t3 auth session issue, with orchestration:read and orchestration:operate scopes and a ten-minute lifetime. That official auth command opens the existing local auth store and never starts its server or an agent. The bearer stays in connector memory, is never logged or sent in process arguments, and expires in T3. An existing private JSON credential file can instead be selected with DASHUP_T3_AUTH_FILE; it must contain origin, token, and ISO expiresAt, and belong to the exact local environment. Only uncredentialed loopback HTTP origins are accepted.
Orca discovery reads its private orca-runtime.json in the native application data directory, honoring ORCA_USER_DATA_PATH; DASHUP_ORCA_DISCOVERY_PATH selects an explicit record. The connector accepts a current-user Unix socket or local Windows named pipe from that record, with the native credential retained on the computer. It exposes existing local structured chat tabs. Remote-host workspaces and terminal-only tabs remain in Orca. Orca send/stop operations use its runtime fence and payload fingerprint, and approval answers name the exact item revision on screen.
Only selected conversations load message content. Both integrations return at most thirty native message rows per page, then the encrypted phone transport applies its own byte/text limits and whole-message pagination. Orca reads a thirty-item journal tail; T3's native byte-bounded history window stays on the computer while smaller pages are selected from it. Leaving a conversation releases that window and pending approval view. Selected latest pages refresh while visible; older pages do not poll. There is no saved transcript in Dashup. Text, tool previews, sends, stops, and simple native approval choices are supported; complex native question forms, native configuration menus, and attachment detail stay in the workbench. Orca accepts phone images as local image references; T3 attachments are added in T3 itself.
