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 done

The 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 AgentMove

A 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.

Attributes
idstring
statusAgentMoveStatus

One of waiting, moving, finishing, done, failed, canceled, expired.

codestring | null

The one-time code (from create only).

promptstring | null

What a person pastes into the session to move (from create only).

guideUrlstring

The guide the moving agent follows.

workspaceIdstring | null

The space the agent joins.

draftJsonObject

What the move was made with: name, harness, model, model_connection.

sourceAgentMoveSource | null

Where it moves from, once the moving agent says.

arrivedAgentMoveArrived

What arrived so far, for the "Found on your laptop" list.

stepsAgentMoveStep[]

The finish's progress, in order.

landsAsJsonObject | null

Where it lands (the moving side): the agent's name and harness, and cwd, where its session moves to.

questionstring | null

What a finish asks before it makes anything (a session that carried no MCP server and no skill: none?).

endpointsstring[]

The move's calls (the moving side), one line each: method, path and what it does.

agentIdstring | null

The agent it made, once done.

conversationstring | null

The agent's conversation holding the moved session, once done.

errorstring | null

Why it failed.

expiresAtDate | null

When it ends if nobody finishes it.

createdAtDate | null
Types
/** `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.

Parameters
options.namestring

Its name; omitted, the moving agent's choice, else its folder's.

options.harnessstring

claude_code, codex, opencode, hermes or openclaw; omitted, the session's own.

options.modelstring

Its model in the harness's format; omitted, the session's or the harness's default.

options.modelConnectionstring | ApiObject

The connection holding its model's key or plan; omitted, the account's own that runs it.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.workspaceIdstring

The space (workspace) the agent joins.

Returns

The move, with code and prompt (only here).

Types
/** `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): AgentMove

A lazy reference to a move by id.

Parameters
moveIdstringrequired
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

options.userUserOption

undefined = the ambient user (asUser), null = the account itself.

(defaults to the current user)
Returns

A move that loads the first time you read a field. Nothing is sent yet.

Types
/** `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.

Returns

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.

Parameters
namestringrequired
credentialIdstringrequired
Returns

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.

Parameters
codestringrequired
options.hoststring
options.clientNoClick
Returns

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).

Parameters
options.clientNoClick

The client to send with; defaults to the module client built from NOCLICK_API_KEY.

Returns

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.

Parameters
source{ harness: string; host: string; cwd: string; cliVersion?: string; sessionId?: string; title?: string; model?: string }required
Returns

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).

Parameters
dataUint8Arrayrequired
options.harnessstringrequired
options.cwdstringrequired
options.sessionIdstring
Returns

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.

Parameters
options.namestring
options.branchstring
Returns

repo_id, name, branch, path, url, expires_at and cwd.

Types
type JsonObject = { [key: string]: unknown };

putFile

putFile(path: string, data: Uint8Array | string): Promise<this>

A file from outside the repo, placed at /workspace/<path> (up to 100 MB).

Parameters
pathstringrequired
dataUint8Array | stringrequired
Returns

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.

Parameters
secrets{ name: string; kind: string; to: string }[]required
options.confirmedbooleanrequired
Returns

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.

Parameters
namestringrequired
valuestringrequired
options.toJsonObject
Returns

This move; arrived["secrets"] names it, never its value.

Types
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.

Parameters
commandsstring[]required
Returns

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.

Parameters
urlstringrequired
branchstringrequired
options.pathstring
options.secretstring
options.usernamestring
Returns

This move; lands_as["cwd"] is where it's checked out.

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.

Parameters
namestringrequired
urlstringrequired
options.transport"http" | "sse"default "http"
options.headersRecord<string, string | { secret: string }>
options.signIn"browser"
Returns

This move.

addSkill

addSkill(name: string, data: Uint8Array): Promise<this>

A skill: its folder as a tar, SKILL.md at its top.

Parameters
namestringrequired
dataUint8Arrayrequired
Returns

This move.

addMemory

addMemory(
  name: string,
  content: string,
  options: { description: string },
): Promise<this>

Something it learned, kept in its NoClick memory.

Parameters
namestringrequired
contentstringrequired
options.descriptionstringrequired
Returns

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.

Parameters
textstringrequired
Returns

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).

Parameters
textstringrequired
Returns

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).

Parameters
options.namestring
options.modelstring
options.modelConnectionstring
options.harnessstring
options.none("mcp_servers" | "skills")[]
Returns

This move: done, with agent_id and conversation; or still moving with a question.