AgentMove
Moves: a coding agent's session on a laptop (Claude Code, Codex, OpenCode, Hermes or OpenClaw) copies itself onto a NoClick agent and carries on there. The laptop keeps its own session.
Your side makes the move and follows it; the agent in the session does the rest, from the guide its prompt names:
move = noclick.AgentMove.create(name="Docs fixer")
print(move.prompt) # paste into the session you want moved
...
move.refresh()
print(move.status, move.arrived["files"]) # moving, what it carried so far
print(move.agent_id, move.conversation) # once doneThe agent's side runs with the move's own key, which its code is redeemed for once (AgentMove.redeem): it can
reach nothing but the move, and ends with it.
key = noclick.AgentMove.redeem("nc_move_...", host="ana-mbp")
moving = noclick.AgentMove.current(client=noclick.Client(api_key=key))
moving.upload_session(tar_bytes, harness="claude_code", cwd="/Users/ana/code/acme")
moving.finish()class AgentMoveA move from a laptop. Make one with create (its code and prompt come only then), follow it with
refresh on each platform:resource frame of kind agent_move, and cancel it to call it off.
- Like every live object, it also has hydrate(), refresh() and raw.
| id | string | |
| status | AgentMoveStatus | One of |
| code | string | null | The one-time code (from |
| prompt | string | null | What a person pastes into the session to move (from |
| guideUrl | string | The guide the moving agent follows. |
| workspaceId | string | null | The space the agent joins. |
| draft | JsonObject | What the move was made with: |
| source | AgentMoveSource | null | Where it moves from, once the moving agent says. |
| arrived | AgentMoveArrived | What arrived so far, for the "Found on your laptop" list. |
| steps | AgentMoveStep[] | The finish's progress, in order. |
| landsAs | JsonObject | null | Where it lands (the moving side): the agent's |
| question | string | null | What a finish asks before it makes anything (a session that carried no MCP server and no skill: none?). |
| endpoints | string[] | The move's calls (the moving side), one line each: method, path and what it does. |
| agentId | string | null | The agent it made, once |
| conversation | string | null | The agent's conversation holding the moved session, once |
| error | string | null | Why it failed. |
| expiresAt | Date | null | When it ends if nobody finishes it. |
| createdAt | Date | null |
/** `waiting` (its code unused), `moving` (things arriving), `finishing`, `done`, `failed` (finish again), `canceled`, `expired`. */
type AgentMoveStatus = "waiting" | "moving" | "finishing" | "done" | "failed" | "canceled" | "expired";
type JsonObject = { [key: string]: unknown };
/** Where the session moves from, as the moving agent says. */
interface AgentMoveSource {
harness: string;
host: string;
cwd: string;
cliVersion: string | null;
sessionId: string | null;
title: string | null;
}
/** What arrived so far: names, sizes and counts, never a value. */
interface AgentMoveArrived {
session: { harness: string; sessionId: string | null; title: string | null; messages: number; toolCalls: number } | null;
repo: { repoId: string; name: string; branch: string } | null;
files: { path: string; sizeBytes: number }[];
/** The secrets the person said yes to carrying: each by name, what it is and where it goes, never a value. */
consent: { name: string; kind: string; to: string }[];
/** Each secret carried, by name, and where it goes in the copy: `{env}`, `{file, mode}`, `{model}` or `{}`. */
secrets: { name: string; to: JsonObject }[];
setup: string[];
checkout: { url: string; branch: string; path: string; secret: string | null; username: string | null } | null;
/** Each tool server carried; `needsSignIn` when its login lived in a browser and the person signs in to it here. */
mcpServers: { name: string; url: string; transport: string; headers: { name: string; secret?: string }[]; needsSignIn: boolean }[];
skills: { name: string; files: number }[];
memories: { name: string; description: string }[];
note: { chars: number } | null;
instructions: { chars: number } | null;
/** Once finished: what it made the account's of each secret, model key and tool server login, never a value. */
carried: JsonObject[];
}
/** One step of the finish, in order: `secrets`, `agent`, `space`, `files`, `tools`, `skills`, `memories`, `conversation`. */
interface AgentMoveStep {
name: "secrets" | "agent" | "space" | "files" | "tools" | "skills" | "memories" | "conversation";
label: string;
status: "running" | "done" | "failed";
detail?: string;
error?: string;
}createstatic
static create(options?: AgentMoveCreateOptions): Promise<AgentMove>Make a move: a one-time code, good once for 30 minutes, and the prompt a person pastes into the coding-agent session they want moved. The agent there carries what its work needs and finishes the move, which makes the agent.
Its name; omitted, the moving agent's choice, else its folder's.
claude_code, codex, opencode, hermes or openclaw; omitted, the session's own.
Its model in the harness's format; omitted, the session's or the harness's default.
The connection holding its model's key or plan; omitted, the account's own that runs it.
undefined = the ambient user (asUser), null = the account itself.
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
The space (workspace) the agent joins.
The move, with code and prompt (only here).
/** `undefined` = the ambient user (from `asUser`), `null` = the account itself. */
type UserOption = UserRef | null | undefined;
/** A `User` or your own id for the user. */
type UserRef = string | UserLike;
/** Anything that can name a user lazily (a `User`). */
interface UserLike {
_userId(): Promise<string>;
}fromIdstatic
static fromId(moveId: string, options?: CallOptions): AgentMoveA lazy reference to a move by id.
A move that loads the first time you read a field. Nothing is sent yet.
/** `undefined` = the ambient user (from `asUser`), `null` = the account itself. */
type UserOption = UserRef | null | undefined;
/** A `User` or your own id for the user. */
type UserRef = string | UserLike;
/** Anything that can name a user lazily (a `User`). */
interface UserLike {
_userId(): Promise<string>;
}cancel
cancel(): Promise<this>Call the move off: its key stops working and what arrived goes. A finished move's agent stays.
This move, canceled.
connectSignIn
connectSignIn(name: string, credentialId: string): Promise<this>Give a tool server the move carried needing sign-in the person's sign-in to it: the mcp_oauth connection
NoClick's own MCP sign-in made for its URL. Its carried entry then no longer needs sign-in.
This move, its carried entry for the server no longer needing sign-in.
redeemstatic
static redeem(
code: string,
options?: { host?: string; client?: NoClick },
): Promise<string>Redeem a move code for the move's own key, once: it reaches only this move, for an hour. Keep it out of anything you print.
The key: it reaches only this move, for an hour.
currentstatic
static current(options?: { client?: NoClick }): Promise<AgentMove>The move a move's own key belongs to (the moving agent's side).
The client to send with; defaults to the module client built from NOCLICK_API_KEY.
The move, with lands_as and the limits.
setSource
setSource(
source: {
harness: string;
host: string;
cwd: string;
cliVersion?: string;
sessionId?: string;
title?: string;
model?: string;
},
): Promise<this>Say where the session moves from: its harness, machine and folder.
This move.
uploadSession
uploadSession(
data: Uint8Array,
options: { harness: string; cwd: string; sessionId?: string },
): Promise<this>The session's own files: a tar of paths relative to the harness's home (~/.claude for Claude Code).
This move; arrived["session"] says what NoClick read.
repo
repo(options?: { name?: string; branch?: string }): Promise<JsonObject>A NoClick repo for the code (made once) and a push url, good for 10 minutes: treat it as a secret.
repo_id, name, branch, path, url, expires_at and cwd.
type JsonObject = { [key: string]: unknown };putFile
putFile(path: string, data: Uint8Array | string): Promise<this>A file from outside the repo, placed at /workspace/ (up to 100 MB).
This move.
consent
consent(
secrets: { name: string; kind: string; to: string }[],
options: { confirmed: boolean },
): Promise<this>The secrets the person said yes to carrying, each {name, kind, to} as they read it (never a value);
confirmed: true once they said yes in the session. A secret is carried only once it's listed here.
This move; arrived["consent"] lists them.
putSecret
putSecret(
name: string,
value: string,
options?: { to?: JsonObject },
): Promise<this>One secret the session uses, sealed as it lands, and where it goes in the copy: {env: NAME},
{file: path, mode?}, {model: provider} (the model key it runs on), or none for one a tool server's header
or the checkout refers to by name.
This move; arrived["secrets"] names it, never its value.
type JsonObject = { [key: string]: unknown };setSetup
setSetup(commands: string[]): Promise<this>What the copy's sandbox runs as it starts (after its secrets' files are written): the CLIs the session used.
This move.
setCheckout
setCheckout(
url: string,
branch: string,
options?: { path?: string; secret?: string; username?: string },
): Promise<this>The session's own git remote, checked out in the copy at the branch it pushed its work to.
This move; lands_as["cwd"] is where it's checked out.
planLink
planLink(): Promise<JsonObject>The person's one-tap sign-in to the plan the session's harness runs on: its tokens never move.
{connection, integration, status, url, expires_at}.
type JsonObject = { [key: string]: unknown };addMcpServer
addMcpServer(
name: string,
url: string,
options?: { transport?: "http" | "sse"; headers?: Record<string, string | {
secret: string }>; signIn?: "browser";
},
): Promise<this>A remote MCP server it used (a public https URL); the agent gets its tools. A header is text, or {secret}.
signIn: "browser" for one whose login lives in a browser (a claude.ai connector, an OAuth sign-in): it moves
with no headers and no login, and the person signs in to it once on NoClick.
"http"This move.
addSkill
addSkill(name: string, data: Uint8Array): Promise<this>A skill: its folder as a tar, SKILL.md at its top.
This move.
addMemory
addMemory(
name: string,
content: string,
options: { description: string },
): Promise<this>Something it learned, kept in its NoClick memory.
This move.
setNote
setNote(text: string): Promise<this>The handoff note: what it's in the middle of and what's next. The agent reads it first.
This move.
setInstructions
setInstructions(text: string): Promise<this>Its instructions: what it was told for every project (a user-level CLAUDE.md or AGENTS.md).
This move.
finish
finish(
options?: {
name?: string;
model?: string;
modelConnection?: string;
harness?: string;
none?: ("mcp_servers" | "skills")[];
},
): Promise<this>Make the agent from what arrived (the moving agent's side, with the move's own key).
This move: done, with agent_id and conversation; or still moving with a question.