/** * Thin client for the server's session-target resolution (Issue #1925, * design §4 D5 決定 1 / §6.4). * * The CLI used to carry its own copy of the precedence rules. It was not the * same copy: the server resolves an unregistered instance id that happens to * name a CLI tool to that tool's primary instance (#868), and the CLI's copy had * no such stage — it fell through to `--agent`, or to nothing. So the same * `--instance codex` produced different tmux session names depending on which * side answered. The fix is not to make the copies agree (they cannot: the CLI * build sets `paths: {}` and cannot import the server resolver); it is to stop * having two answers. The server decides; this module asks. * * The old two-stage local resolution survives as one thing only: the * compatibility path for a daemon older than the endpoint, reported as * `resolvedBy: 'client-fallback'` with a warning on stderr. It is deliberately * NOT kept in step with the server — adding the primary-anchor stage to it would * be growing the second authority back (DR2-008). The one exception is a * refusal, not a choice: an `--agent` that contradicts an unregistered * tool-named instance is reported exactly as the server reports it (Issue * #2487), because a copy that obeys it sends where the server would refuse to. */ import type { ApiClient } from './api-client'; /** * Which stage of the precedence chain produced the answer. Mirrors * SessionTargetResolvedBy in `src/lib/session/resolve-session-target.ts`; the * CLI keeps its own copy of API shapes (see api-responses.ts). */ export type SessionTargetResolvedBy = 'explicit' | 'roster' | 'primary' | 'worktree-default' | 'fallback' | 'client-fallback'; /** * An explicit `--agent` that the instance's declaration contradicts: its roster * row, or — with no row — its own id when that id is a CLI tool id (the * primary-instance anchor, #868; Issue #2487). */ export interface SessionTargetConflict { instanceId: string; /** The tool the instance is declared as; for a primary-anchor conflict, the id itself. */ rosterCliTool: string; requestedCliTool: string; /** * Set when the declaration is the primary-instance anchor rather than a * roster row. Mirrors the server's field of the same name, which * `resolve-target` sends; absent for a roster contradiction. */ primaryAnchor?: true; } export interface CliSessionTarget { /** * The agent to address, or undefined when nothing declared one. * * Undefined only reaches a caller on the `client-fallback` path: the server * always answers with a concrete tool, and an old server keeps the behavior it * always had, which is to decide for itself when the CLI sends no `cliToolId`. */ cliToolId: string | undefined; /** The instance addressed, echoed back so callers do not re-derive it. */ instanceId: string | undefined; resolvedBy: SessionTargetResolvedBy; /** The contradiction, when there is one. Callers decide whether it is fatal. */ conflict: SessionTargetConflict | null; } export interface ResolveSessionTargetOptions { instanceId?: string; /** The `--agent` / `--cli-tool` value, already validated as a known tool id. */ requestedCliTool?: string; } /** * Resolve which agent and instance a command should address. * * @param client - API client aimed at the server * @param worktreeId - Worktree ID * @param options - `--instance` and `--agent` as the user gave them * @returns The resolved target, with `conflict` set when `--agent` contradicts * the roster or the primary-instance anchor * @throws ApiError when the server's capabilities cannot be determined (auth * failure, redirect, non-JSON body) — those are never treated as "old server" */ export declare function resolveSessionTarget(client: ApiClient, worktreeId: string, options?: ResolveSessionTargetOptions): Promise; /** * The sentence shown when the instance's declaration and `--agent` disagree. * Names both declarations and the three ways out, because only the operator * knows which of the two is wrong. A primary-anchor conflict has no roster row * to re-register — `instances add --id ` answers "already exists" — so its * third way out is another instance. */ export declare function describeSessionTargetConflict(conflict: SessionTargetConflict): string; //# sourceMappingURL=session-target.d.ts.map