North Coder
CLI

快速运行

使用 run 命令一键发送任务给 Agent。

run 是最常用的 CLI 命令,一条命令完成:选择项目、创建工作区、创建会话、发送消息。

基本用法

ncoder run "你的任务描述"

选项

选项默认值说明
--project, -p项目入口时使用配置中的 default_project_id项目 ID。
--workspace, -w工作区 ID(使用已有工作区)。
--conversation, -c会话 ID(在已有会话中继续)。
--workdir任意运行目录,不要求注册为项目/工作区即可直接运行。见 运行外部 Agent Artifact 与任意目录
--registerfalse--workdir 幂等注册为持久项目/工作区,使会话在 UI 可见。需配合 --workdir,且不能与 --workspace / --conversation 同用。
--branch, -b创建工作区时指定的分支。
--source-ref创建工作区时使用的 source ref,可以是 branch、tag 或 commit SHA。
--commit--source-ref 的别名,便于从指定 commit 创建工作区。
--yaml, --agent-yaml外部 agent artifact 的入口 agent.yaml 路径,运行该 artifact 而非内置/已配置 profile。
--profileAgent profile ID(如 builtin:general)。
--model, -m模型 ID。
--permission-modedefault工具权限模式:default(按规则 ask)、acceptEdits(自动放行编辑类工具)、bypassPermissions(全部放行)、plan(只读,编辑/执行类工具拒绝)。
--waitfalse等待任务完成再退出。
--poll-interval1.0轮询间隔(秒),配合 --wait 使用。
--timeout, -t0(无限)等待超时(秒),配合 --wait 使用。

入口解析

run 可以从项目、工作区或会话进入:

入口必要参数行为
项目--projectdefault_project_id创建或选择工作区,再创建会话。
工作区--workspace在指定工作区创建新会话。
会话--conversation在已有会话中追加用户消息。
目录--workdir直接以任意目录为运行目录,不要求项目/工作区。

提供 --workspace--conversation 时,CLI 不会读取配置中的 default_project_id,也不要求传入 --project。如果同时显式传入 --project,服务端只把它作为一致性校验,不作为路由来源。

如果没有提供 --workspace--conversation--workdir,也没有 --projectdefault_project_id,命令退出报错。

--source-ref / --commit 只有在需要创建或收编 worktree workspace 时有意义。CLI 只把该值作为 workspace_options.base_branch 传给后端,不在本地解析 Git ref。

运行外部 Agent Artifact 与任意目录

除了在已注册的项目/工作区里运行,run 还支持直接运行一份外部 agent artifact,或指定任意目录作为运行目录——适合 headless / CI / smoke test 场景。

--yaml:运行外部 agent artifact

传入一份外部 agent.yaml(artifact 入口),后端会把整份 artifact 目录物化为可解析的 agent config,挂载其中声明的本地工具/技能/Python custom tools,并运行该 artifact,而不是内置或已配置的 profile。

ncoder run "演进这个 agent" \
  --yaml /path/to/north_evolver/agent.yaml \
  --workdir /path/to/north_evolver/work \
  --wait

--yaml 的优先级高于 --profile:同时传入时运行 artifact,而非 profile。CLI 会先校验该文件存在。

--workdir:指定运行目录

--workdir 指定本次 agent / 工具运行的文件系统工作目录,无需先把它注册成项目或工作区。注意:

  • --workdir 接受的是路径--project / --workspace 接受的是已注册实体的 ID。两者语义不同。
  • 一经指定即生效:该目录始终作为 agent shell 的运行目录,不会回退到后端进程目录。
  • 默认是「一次性运行目录」,不登记任何项目/工作区实体,因此会话的 workspace_id 为空,不会出现在 Coder UI 的工作区标签里。结果仍可通过 --waitmessage result 或 invocation / result API 获取。

--register:让 --workdir 在 UI 可见

如果希望该目录被持久注册(出现在 UI 标签、获得 worktree 隔离),加上 --register

ncoder run "在这个目录里跑一轮分析" \
  --workdir /path/to/some/repo \
  --register \
  --wait

--register 会复用幂等的项目注册逻辑:同一路径重复运行会复用已有项目/工作区,不会重复登记;传入 git 主仓根目录或 linked worktree 会分别命中默认工作区或对应 worktree 工作区。

约束:--register 必须与 --workdir 同用,且不能与 --workspace / --conversation 同用(运行目标已由后两者确定,注册意图会含糊)。违反时 CLI 直接报错;服务端也会按同样规则二次校验。

示例

最简用法

# 设置默认项目后直接使用
ncoder config set default_project_id proj_abc123
ncoder run "阅读 README,告诉我这个项目是做什么的"

指定项目和分支

ncoder run "修复登录页的样式问题" \
  --project proj_abc123 \
  --branch fix/login-style

从指定 commit 创建工作区

ncoder run "复现旧版本行为" \
  --project proj_abc123 \
  --branch repro/old-state \
  --commit 0123456789abcdef

使用 RFC Mode

ncoder run "设计用户权限系统" \
  --project proj_abc123 \
  --profile builtin:rfc

无人值守运行(跳过权限审批)

脚本 / CI 场景下,用 --permission-mode bypassPermissions 让所有工具直接放行,避免 run 因等待权限审批而暂停:

ncoder run "运行 lint 并修复" \
  --project proj_abc123 \
  --permission-mode bypassPermissions \
  --wait

只读分析则可用 plan,编辑/执行类工具会被拒绝:

ncoder run "审阅这个仓库的架构,给出报告" \
  --workspace ws_abc123 \
  --permission-mode plan \
  --wait

等待结果

ncoder run "运行所有测试并报告结果" \
  --project proj_abc123 \
  --wait \
  --timeout 300

在已有会话中追加

ncoder run "接着上次的工作,把测试补全" \
  --conversation conv_xyz789 \
  --wait

在已有工作区中新建会话

ncoder run "排查当前测试失败原因" \
  --workspace ws_abc123

Headless 运行外部 agent artifact

无需注册项目,直接在指定目录运行一份外部 artifact,并等待结果:

ncoder run "执行一轮演进" \
  --yaml /path/to/north_evolver/agent.yaml \
  --workdir /path/to/north_evolver/work \
  --permission-mode bypassPermissions \
  --wait

如果还希望这次运行在 Coder UI 里可见,追加 --register 把目录注册为持久工作区:

ncoder run "在这个仓库里跑一轮分析" \
  --workdir /path/to/some/repo \
  --register \
  --wait

等待机制(--wait)

使用 --wait 时,CLI 会持续轮询任务状态直到终态:

终态行为
completed获取并显示结果,退出码 0
failed显示失败信息和部分结果(如有),退出码 0
cancelled显示取消信息和部分结果(如有),退出码 0

如果任务进入 requires_action,CLI 会把它当作需要用户处理的半终态:停止轮询、显示待处理内容,并以退出码 0 结束。requires_action 有两种:

  • ask_user(Agent 提问):用 message answer 回答后继续。

    ncoder message answer inv_123 -i --wait
  • permission_request(工具权限等待审批,required_action.type = "permission_request"):用 permission 子命令审批后,run 会自动恢复。

    # 查看待审批的工具权限
    ncoder permission list inv_123
    # 批准 / 仅本次允许 / 拒绝某个 tool_call
    ncoder permission approve inv_123 tc_xyz

    详见 resources 文档的 permission 一节。若希望一开始就不被权限打断,用 --permission-mode bypassPermissions 启动 run。

特殊情况:

事件行为
Ctrl+C从等待中分离,服务端任务继续运行。退出码 0
超时停止等待并报告,服务端任务继续运行。退出码 1
结果获取失败退出码 1

JSON 输出

不带 --wait

{
  "invocation_id": "inv_123",
  "workspace_id": "ws_456",
  "conversation_id": "conv_789",
  "message_id": "msg_abc",
  "delivery": "sent",
  "status": "queued",
  "queue_position": 1,
  "status_url": "/api/invocations/inv_123"
}

--wait 完成:

{
  "status": "completed",
  "result": { "..." }
}

--wait 超时:

{
  "timeout": true,
  "invocation_id": "inv_123",
  "elapsed": 300.0
}

--wait 等待用户回答:

{
  "status": "requires_action",
  "invocation_id": "inv_123",
  "conversation_id": "conv_789",
  "questions": [
    {
      "header": "选择方案",
      "question": "你希望继续采用哪个实现方向?",
      "type": "choice",
      "options": [
        { "label": "继续当前方案" },
        { "label": "改用更保守方案" }
      ]
    }
  ]
}

--wait 等待工具权限审批:

{
  "status": "requires_action",
  "invocation_id": "inv_123",
  "required_action": {
    "type": "permission_request",
    "action_id": "tc_xyz",
    "pending_requests": [
      {
        "tool_call_id": "tc_xyz",
        "tool_name": "run_shell_command",
        "prompt": "Allow running npm install?",
        "permission_key": "npm install"
      }
    ]
  },
  "tool_call_id": "tc_xyz",
  "resolve_endpoint": "/api/invocations/inv_123/permissions/tc_xyz/resolve",
  "resolve_decisions": ["allow", "allow_once", "deny"]
}

--wait 分离(Ctrl+C):

{
  "detached": true,
  "invocation_id": "inv_123"
}

脚本集成

#!/bin/bash
# 提交任务并等待结果
RESULT=$(ncoder --json run "fix lint errors" \
  --project proj_abc --wait --timeout 120)

STATUS=$(echo "$RESULT" | jq -r .status)
if [ "$STATUS" = "completed" ]; then
  echo "任务完成"
else
  echo "任务状态: $STATUS"
  exit 1
fi

本页内容