# ags-cli

`ags-cli` 是 AGS 的本地 `git` / filtered `gh` 启动器。普通 Human 与 Multica Agent 只面向 AGS；Forgejo/GitLab credential、repository/PR mapping、CI observation 与 merge execution 由 AGS 服务端 provider adapter 拥有。Human 另有一个有界的仓库初始化入口；它不进入 Multica workload 命令面。

## 普通使用面

```text
Human / Agent -> ags-cli git / ags-cli pr -> AGS -> server-owned provider adapter
Human         -> ags-cli repo create    -> AGS repo + configured Forgejo projection
```

公开 root 只保留：

```bash
ags-cli --version
ags-cli git <git argv...>
ags-cli pr <accepted pr argv...>
ags-cli gh <accepted gh argv...>
ags-cli repo create <owner/repo> [--description <text>] [--json]
```

`ags-cli pr` 与 `ags-cli gh pr` 共用同一 registry / native REST / effect 路径。`repo create`只读取当前Context拥有的Human credential，创建私有、`main`、带初始README的AGS仓，并等待配置好的Forgejo exact-SHA投影；检测到Multica task token时在credential和network I/O前拒绝。维护面需显式进入 `ags-cli ctl ...`，不属于普通 Agent 心智。旧 `ci|review|profile|grant|session|access|principal-session` public roots已hard-cut。

当前 `gh-core-v1` 接受：

```text
pr create/view/checks/list/status/comment/edit/review/close/reopen/update-branch/merge
run list/view
```

未知命令、flag 或 JSON field 在 engine、credential 与 provider I/O 前拒绝；不回退系统 `gh`。

## Caller 与 credential

### Human

repo 内命令从 credential-free AGS `origin` 解析唯一 Context。目标状态每个 AGS instance 只需要：

```text
~/.ags-cli/contexts/<context>.yaml   # secret-free route
~/.ags-cli/secrets/<context>.token  # personal Human AGS token; regular file, non-symlink, mode 0600
~/.ags-cli/config.yaml              # optional machine preferences; regular file, non-symlink, mode 0600
```

`config.yaml`当前只接受以下schema；文件可不存在，旧`config/current-context`不会读取或隐式迁移：

```yaml
schema: ags.cli-config.v1
default_context: mini-local
```

Human repo命令按以下规则路由：不传`--repo`时由credential-free `origin`唯一解析Context，单独传`--context`只断言该origin结果；显式`--repo`不传`--context`时使用`default_context`；显式`--repo + --context`时直接选择命名Context，因此同名repo也可在多个AGS之间切换。repo外命令必须传`--repo`，可再用`--context`覆盖default。Multica workload不接受Human `--context`，仍只由workspace + endpoint匹配Context，且不读取`config.yaml`。

```bash
ags-cli pr list --repo jackie/agent-kit --context mini-imile-win
ags-cli pr list --repo ux/merdi-express-shipping --context imile-win-local
```

Human ordinary Git/PR 不创建 Access Grant 或 transport Session。每次 PR write/merge 前都向 AGS `/api/v3/user` 回读并要求 `user_kind=human`；repository permission、protected branch 与 effect gate 仍由 AGS 校验。

安全路由诊断不读 credential 文件，也不发网络请求：

```bash
ags-cli context current --json name,serverUrl,route,repository,identity
```

该命令只报告 Context endpoint、origin/current 路由、repository、Context-owned canonical human-facing URLs 和 caller identity mode；Human 与 workload 都明确输出 `credentialRead=false`，不声称已验证 live login、权限或网络可达性。

Human在repo外可用当前Context创建团队仓库：

```bash
ags-cli repo create ux/repo-flow \
  --description "RepoFlow CLI and workflow assets" \
  --json
```

命令只提交一次AGS create请求；已存在或响应不确定时先做exact readback，不盲重试。`--json`输出`ags.repo-create.v1`嵌套事实：`repository`/`git`/`forgejo`/`readback`，含正整数IDs、secret-free URL、private/`main`/40位SHA、`forgejo.state=linked|pending|failed`和projection drift。AGS clone/html URL必须属于当前Context endpoint或已声明alias，且不得携带query/fragment。`linked`还要求投影target等于请求仓、投影双SHA等于branch readback、以及必要URL。缺少仓库ID或默认分支SHA时fail-closed。Forgejo由AGS当前integration配置自动创建和投影，CLI只等待并验证`main`同SHA；超时返回已创建但未linked的部分结果及非零退出码。

现有 `interactive_default` profile 只作为有界迁移兼容：仅当 Context-owned token 不存在且该 Context 恰有一个兼容 profile 时读取。新安装不得创建 Human profile；repo 内 authority 不依赖 global current-context。

### Multica workload

存在 `MULTICA_TOKEN` 时强制 profile-free：

```text
required  MULTICA_TOKEN + origin/Context + workspace/agent/task binding
optional  MULTICA_RUN_ID
forbidden Human token/profile、provider token/profile、mixed durable selector
```

内部 Access Grant / Session 只负责短时 AGS transport，不进入 Agent 命令面。Task在worktree外启动clone时，以`MULTICA_WORKSPACE_ID + MULTICA_SERVER_URL`只读匹配唯一受信Context，不读取或切换Human current-context；零匹配或多匹配均fail closed。普通 Access Grant HTTP请求只对HTTP 503或Node transport exception做一次有界、无状态重试；`pr.merge` effect 的transport失败保持outcome-unknown并只走invocation readback，绝不自动重发POST。401/403/422、invalid response与authority denial不重试，也不切换endpoint或credential。standard operation 与association分离：纯External PR/link association unavailable不改写已完成operation；但Task的request-level AGS transport未绑定时，任何broker error都必须在stock-gh engine前停止，禁止无凭据落到Provider默认路由。Invalid credential、wrong target/repo/operation、identity binding missing/conflict、revoked/expired authority与protected/effect denial均fail closed。

## Git credential helper

`ags-cli ctl runtime bootstrap` 安装薄 `git`/`gh` shim 与generic credential helper。`git` shim对Human单次命令先清空system/keychain helper链，再绑定`!ags-cli ctl git-credential`和`credential.useHttpPath=true`；存在`MULTICA_TOKEN`时则改走exact repo/operation的Access Grant transport，clone从credential-free AGS URL解析repo，其他命令从origin解析。Task transport取得失败立即停止，不再执行plain system Git，也不读取Human helper。

Human workstation若绕过shim直接调用system Git，必须按每个Context endpoint做URL-scoped reset，避免系统keychain先返回同host旧凭据，同时不影响GitHub等其他host：

```bash
git config --global credential.useHttpPath true
git config --global --replace-all 'credential.http://127.0.0.1:6666.helper' ''
git config --global --add 'credential.http://127.0.0.1:6666.helper' '!ags-cli ctl git-credential'
```

helper 按 Git protocol + host + `owner/repo` path匹配唯一Context。Context 以 `endpoint` 为权威 AGS 基址，可选 `endpoint_aliases` 接纳短名等同 host（例如 MagicDNS 权威地址加 `http://mini:6666`）；匹配到后仍用 `endpoint` 访问 AGS API。不持久化`store`，也不使用global current-context。别名必须写在 Context 里，且跨 Context 必须唯一。Context还可在`ags.context-bundle.v2`中用secret-free `provider_public_urls.<provider>`固定人类可见provider origin；CLI优先使用该值，缺失时才用所选Context的稳定`instance_id`精确选择target registry中的provider `publicUrl`，缺失或歧义时保留服务端URL。Provider origin不从AGS主机名猜测。

Multica daemon在Task process tree内检查完整shim pair：`~/.ags-cli/shims/git`与`gh`（Windows可为`.exe/.cmd/.bat` launcher）都存在才前置PATH；若`~/.local/bin/ags-cli`存在，managed bin紧随shims进入PATH，避免shim解析到陈旧Volta等tool-manager link；缺任一个shim则保持原PATH，避免Git与PR使用不同身份。该注入属于Task环境边界，不依赖Pi/Codex/Claude插件，也不永久替换普通Human shell的官方`gh`。

## PR write 与 provider effect

- Human `pr create/comment/edit/review/close/reopen`：origin-bound Context personal token只请求 AGS REST。`pr create` 成功后 stdout 先打 **Forgejo PR URL**（给人看），再打 AGS locator；`--json` 另有 `forgejo_url` / `forgejo_number`。Agent 日常仍以 AGS PR 号做事，但要把 Forgejo URL 报给 Human。
- Workload 同一命令：exact standard operation通过内部 Access Grant transport请求 AGS。
- `pr view <ags-pr> --json ...`：精确编号 JSON read 走 AGS-native REST；缺失 `-R` 且当前目录没有 credential-free AGS origin 时，在 credential/network I/O 前失败。`--json` 接受 `externalProjections`。Human与workload路由的顶层`url`都按本次选中的Context `endpoint`规范化；`externalProjections[].externalUrl`优先使用该Context的`provider_public_urls`，再按Context `instance_id`精确绑定target registry中的provider `publicUrl`。该策略只改写human-facing URL，不改变请求所用Context endpoint、Access Grant route或authority；它不读取global default target、不接受ambient URL覆盖，也不猜测跨主机projection。`externalProjections[]` 暴露 Forgejo 投影 `status=pending|projected|failed|conflict`、`jobId`、`attempt`、稳定 public URL 和 `lastError`。0 条 Forgejo mapping 是 `pending`，不是缺失 mapping；2+ 条是 `conflict`。`statusCheckRollup`与`pr checks`在投影已 projected 后复用同一份 exact-head provider evidence；投影 pending 时 `pr checks` 返回 `projection_pending`（exit 8），冲突返回 `mapping_conflict`（exit 1），都不把 0 行和 2 行收成同一句 exception。`externalProjections`还为每个投影附加`consistency=consistent|stale|optional`、`requiredForMerge`和`affectsMergeReadiness`。Forgejo是当前merge projection；其它provider mismatch标成optional，不由客户端臆测为merge blocker。Merge 在投影 required 且尚未 projected 时继续 fail-closed。
- `pr checks` / `run list` / `run view`：从 AGS provider-evidence 读 Forgejo CI。check JSON显式提供`required`和`requirementSource`；`--required`仅在所有run都有服务端required事实时过滤，事实缺失或不完整时fail closed，绝不把全部checks当required。`run view <run-id> --pr <ags-pr> --log` / `--log-failed`再读`.../provider/ci/runs/{id}/logs`。客户端不直连Forgejo、不猜AGS/Forgejo号相同。
- Human `pr merge --match-head-commit <sha> [--merge-method <method>]`：请求 AGS provider merge endpoint；AGS解析provider coordinate并使用server-owned executor。`method`完整覆盖`merge|rebase|rebase-merge|squash|fast-forward-only`；既有`--merge/--rebase/--squash`保持兼容，但不得与`--merge-method`混用。省略时保持`merge`默认值。非法、重复或冲突选择在credential/network I/O前拒绝。
- Workload merge：必须有服务端返回的effective `pr.merge` maintainer authority，走独立effect endpoint；generic Session transport禁止merge。

AGS source write成功与provider projection状态分开。provider pending/drift不得回滚已成功的AGS branch/PR，也不得伪装为caller permission denial。

## Engine 与发布 pin

生产 package 只从 `<packageRoot>/libexec/ags-gh` 定位 engine，并用同包 `release-manifest.json` 同时校验：

- platform launcher SHA-256；
- launcher内固定的`darwin-arm64`与`linux-amd64` engine SHA-256；
- `registry/gh-core-v1.registry.json` SHA-256。

当前平台不受支持或任一drift都在authority broker或engine执行前fail closed。仅测试/源码集成可同时设置 `AGS_GH_ALLOW_MANIFEST_OVERRIDE=1` 与显式 engine/manifest override；生产不得设置。

当前 package 版本与 source commit 以同目录 `package.json` 和 `dist/build-info.json` 为准，不在 README 再写易漂移的 current version。远端 `ctl repo` 委派以调用方本机已验证的 full build-info identity 与 CLI 实际 SHA-256 为信任根；`AGS_CLI_EXPECTED_SOURCE_COMMIT` 只能附加校验该本机 identity，不能单独授权委派。`0.2.8`已修复live F01/F12发现的带端口`GH_HOST`、fresh bootstrap目录权限与ambient system/keychain helper问题，并在mini完成published-package验证；随后F10在imile-win发现单一Mach-O engine无法在Linux执行。`0.2.9`保留受pin的platform launcher，打包并逐次校验`darwin-arm64`与`linux-amd64` engine，并给单次隔离GH配置写入当前schema version，阻止Linux误探测ambient keyring。`0.2.10`进一步把Task的broker denial/conflict/target mismatch收紧为engine前hard failure，同时保留typed unavailable的无ambient credential association语义。`source_verified`只证明本仓测试与package assembly；在clean source publish、目标Runtime安装和完整live matrix evidence完成前，不声明`ags-single-frontdoor-ready`。

## Bootstrap

```bash
ags-cli ctl runtime bootstrap --plan --json
ags-cli ctl runtime bootstrap --json
ags-cli ctl runtime inspect --json
```

Bootstrap只创建本地目录、薄`git`/`gh` shim和generic helper，不创建`config.yaml`、身份、不签发credential、不配置provider，也不检测或推荐任何coding-agent插件。不创建`~/.ags-cli/bin/ags-cli`第二 command path。`ctl install`在安装manifest Context后原子写入`config.yaml`的`default_context`。Task PATH由Multica等Runtime统一管理。

## Command launcher

全局`ags-cli`唯一 PATH 入口是`~/.local/bin/ags-cli`（`ags-cli.launcher.v1`）。默认 exec 本机 single-active npm release：`~/.local/share/ags-cli/current/bin/ags-cli`。调试源码用环境变量，不要换第二命令名：

```bash
export AGS_CLI_DEV=1
export AGS_CLI_SOURCE_ROOT=/path/to/agent-kit   # bun run $AGS_CLI_SOURCE_ROOT/packages/ags-cli/src/cli.ts
# 或
export AGS_CLI_ENTRY=/path/to/agent-kit/packages/ags-cli/src/cli.ts
```

未设置`AGS_CLI_DEV`/`AGS_CLI_ENTRY`时必须走 npm 字节。`AGS_CLI_DEV`已开但缺 source root/entry 时 fail closed，不得静默落到陈旧 checkout。

Endpoint installer使用隐藏维护面，不恢复已经hard-cut的旧top-level命令：

```bash
ags-cli ctl release inspect --json
ags-cli ctl release install-current --user --json
ags-cli ctl release capabilities --json
ags-cli ctl context provision --mode plan --name <name> --file <bundle> --source-sha <sha> --json
ags-cli ctl context doctor --name <name> --json
```

`ctl release install-current`只安装当前exact npm package，写入single-active/previous状态并保持`~/.local/bin/ags-cli`为稳定launcher；endpoint rollout不得用浮动tag或普通`npm -g`安装替代。Context迁移仍要求显式`--expected-current-hash`。

## Maintainer Forgejo authority

隐藏维护面正式入口是 `ags-cli ctl repo onboard-forgejo` 与 `ags-cli ctl repo verify`。公开 ordinary root 仍只有 `repo create`、`git`、`pr`、`gh`。operator credential 继续来自 target file paths，命令不接受也不打印 token 值。

维护面 onboarding 若收敛 Forgejo base protection，当前 desired 是 `enable_push=true`、`enable_force_push=false`，push/merge whitelist 全关（空名单、`apply_to_admins=false`）。不把 Human 从已有名单剥掉，也不再要求 exact-only-bot。反例 `enable_push=false` 仍会围栏 AGS projection writer。未显式覆盖时，apply/verify 保留已观察的全部 non-authority review/security gates。书面裁决见 [`../../docs/adr/practice-alignment/2026-09-03-forgejo-open-whitelists.md`](../../docs/adr/practice-alignment/2026-09-03-forgejo-open-whitelists.md)。本段不把该能力提升为普通 Agent 命令面。AGS `/readyz` 仍用 runtime 自己的谓词。

## Release

不要在功能 PR 里改 `package.json` 的 version。先写 pending changeset，release 分支再 `prepare`：

```bash
bun run --filter @yoyooyoooyoooo/ags-cli release add -- --kind patch --summary "..."
bun run --filter @yoyooyoooyoooo/ags-cli release prepare
bun run --filter @yoyooyoooyoooo/ags-cli release pack
bun run --filter @yoyooyoooyoooo/ags-cli release publish
bun run --filter @yoyooyoooyoooo/ags-cli release verify
```

只发 `https://registry.npmjs.org/`。已存在的 version 不得覆盖。`pack` 把当前 HEAD 写入 `AGS_CLI_EXPECTED_SOURCE_COMMIT`，并传给 `build:release` 与 `npm pack` 的 prepack 校验。`publish` 在无 TTY 时用 `script` 拿伪终端：macOS 为 `script -q /dev/null /bin/sh -c ...`，Linux 为 `script -qec ... /dev/null`。仍要本机浏览器 web auth，不是 GitHub Actions trusted publishing。约定见 [`../../.changesets/README.md`](../../.changesets/README.md)。

## Claim limit

本README声明当前source contract：Context-owned Human credential、profile compatibility boundary、workload isolation、accepted filtered surface与server-owned provider execution。它不声明任意AGS/provider自动可用，也不把source tests冒充mini/imile runtime、clean release、provider health或完整cross-runtime claim。
