@botiverse/stamp-cli
v0.3.8
Published
CLI for Stamp — Agent Git gateway in the Raft loop (bin stamp; future origin stamp.build)
Downloads
877
Keywords
Readme
stamp
CLI for the Agent Git gateway. Bin stamp. Package @botiverse/stamp-cli.
Session storage is @botiverse/agent-session-store (fail-closed Raft agent
admission, atomic 0600 auth.json). Future public origin: stamp.build.
npm i -g @botiverse/stamp-cli
# One-shot staging use must name the executable because the package has two bins.
npx --yes --package @botiverse/stamp-cli stamp-staging --help
stamp login
stamp key enroll
stamp identity bind --email [email protected]
stamp repo clone org/repo
git push ssh://[email protected]:443/org/repo.git HEAD:refs/heads/agent/my-change
stamp receipt get <id>
stamp receipt list
stamp pr create --receipt <published-id> --repo org/repo --head agent/my-change --sha <exact-sha> --base main --title "My change" --body-file ./pr-body.md
stamp pr list
stamp pr view 123 --repo org/repo
stamp pr diff 123 --repo org/repo
stamp pr checks 123 --repo org/repo
stamp pr comment 123 --repo org/repo --body-file ./comment.md
stamp pr edit 123 --repo org/repo --title "Clearer title" --body-file ./pr-body.md
stamp pr approve 123 --repo org/repo --head <exact-head-sha> --base <exact-base-sha>
stamp pr unapprove 123 --repo org/repo --head <exact-head-sha> --base <exact-base-sha>- Agent:
stamp login(PKCE grant viaraft integration invoke --action agent-login) - Human / CI:
STAMP_TOKEN - Instance:
STAMP_URL(defaulthttps://staging.stamp.build) - Raft app slug:
STAMP_SERVICE(must match the gateway:STAMP_SERVICEorRAFT_OAUTH_CLIENT_ID; staging today israft-git-gateway-staging, futurestamp)
Two installed bins, sharing one implementation:
stamp— default service slugstamp(the future production registration)stamp-staging— pinned to today's staging registration: originhttps://staging.stamp.build, serviceraft-git-gateway-staging, push remotessh://[email protected]:443/...; works with zero environment configuration
Configuration layering is environment > executable defaults: STAMP_URL and
STAMP_SERVICE override either bin explicitly. There are no per-run URL or
service command-line flags today.
repo clone carries the SSH identity itself (task #475): it uses the key
key enroll enrolled. key enroll records the private key next to the public
key it read (the path without .pub), per instance, in ~/.stamp/identities.json
(STAMP_IDENTITIES to relocate; nothing is recorded for a public key read from
stdin or one whose private half is not on this machine, and the command says so).
A bare repo clone then uses that record; --identity FILE and STAMP_SSH_IDENTITY
still win, and without a record the default ~/.ssh/id_ed25519 applies. The CLI
never scans ~/.ssh or guesses paths: a recorded key that is not on this machine
is named, with key enroll here or --identity as the ways out (task #514). It
also pins the host key the instance publishes at /.well-known/ssh-known-hosts into
~/.stamp/known_hosts (--known-hosts FILE / STAMP_KNOWN_HOSTS), then records
the same command as the clone's core.sshCommand so later git push/git fetch
inherit it. No GIT_SSH_COMMAND export is needed.
When STAMP_URL is not explicit, an existing Agent session stored against the
exact legacy staging origin https://github-staging.botiverse.dev or the
former CLI placeholder https://github.botiverse.dev is used against the new
default origin. This keeps the same service-bound token while the compatibility
DNS alias remains live; every other stored custom origin is preserved unchanged.
stamp pr create calls the service directly using the Agent's service session.
The receipt must belong to that Agent and be PUBLISHED; head/ref/repository/SHA
must match it. Identical payloads derive a stable idempotency key, so rerunning
the command after a lost response does not create a second PR. You can supply
--idempotency-key explicitly (16–128 letters/digits/._:-). Branch names are
expanded to refs/heads/...; full refs also work. Use --body-file - for stdin,
--body for inline text. A non-empty description is required. --json prints the
service receipt; a denial exits nonzero with recovery guidance.
The read-only PR commands follow the familiar gh pr command group while
reading through Stamp rather than a local GitHub credential:
stamp pr listlists every PR that the current Agent created through Stamp. Filtering and pagination are intentionally not advertised until the service implements them.stamp pr view,stamp pr diff, andstamp pr checksaccept a PR URL or a number with--repo OWNER/REPO(-Ralso works).stamp pr diff --name-onlyprints only paths.stamp pr checksexits8while checks are pending and1when a terminal check failed or no checks are reported, matching the usefulgh pr checksautomation convention.--jsonreturns the service's validated machine envelope. Human-formatted output strips terminal control characters from provider-authored text.
stamp pr edit changes the title, description, or both on a PR the current
Agent created through Stamp. Ownership comes from Stamp's durable creation
receipt, not the shared GitHub App author: another Agent, another Raft Server,
or a PR opened outside Stamp is refused before any provider write. Updating the
description regenerates the protected Stamp attribution/footer; callers supply
only their description text. If the provider outcome cannot be confirmed, the
command exits nonzero and requires a PR re-read before any retry.
Approving as an Agent
With an Agent session, stamp pr approve records the approval in Stamp (a
durable receipt), not as a GitHub review: PRs opened through Stamp are authored
on GitHub by the shared App, so an App review would read as self-approval.
--head and --base must be the exact current SHAs (a move is refused with
PR_HEAD_MOVED / PR_BASE_MOVED), the approval counts only for that head, the
PR's own author is refused (SELF_APPROVAL_NOT_ALLOWED), and there is no
--body. stamp pr unapprove withdraws it. With a human session, stamp pr
approve submits a GitHub review as the bound user, as before.
Merging as an Agent
With an Agent session, stamp pr merge works once there is an independent
approval of the PR's exact current head from someone other than its author
(another Agent's Stamp approval, or a GitHub approval from a human with write
access) and no outstanding request for changes; otherwise it is refused with
PR_NOT_APPROVED and the reasons. The author may merge too, once someone else
approved. --head and --base must be the exact current SHAs (PR_HEAD_MOVED /
PR_BASE_MOVED). The merge happens as the Stamp App, pinned to that head, so
GitHub refuses it if the head moved; GitHub's branch protection still applies.
The result names mergedBy: "stamp-app" and the merging Agent.
stamp pr close withdraws a PR the current Agent created through Stamp, under
the same receipt-ownership gate as pr edit — another Agent, another Raft
Server, or a PR opened outside Stamp is refused before any provider write, and
an already-closed or merged PR is reported as not open rather than as a silent
success. If the provider outcome cannot be confirmed, the command exits nonzero
and requires a PR re-read before any retry.
Ordinary PR comments
stamp pr comment 123 -R org/repo --body-file ./comment.md uses a human Stamp
session with a bound GitHub account, and posts as that GitHub user. Agent
sessions are rejected; there is no fallback to an App or another person's token.
The existing human session authentication applies; this command does not create
a new login flow. The web inbox does not yet provide a comment composer.
Use --body TEXT (-b) or --body-file FILE (-F); --body-file - reads stdin
and preserves paragraphs. A PR URL can replace the number/repository pair.
Comments must be nonempty and at most 64 KiB of UTF-8 text. Closed or merged PRs
can still receive comments. This is an ordinary conversation comment, not a
review, inline code comment, approval or merge.
GitHub must permit the bound user's token to create comments; its issue-comment API accepts GitHub App user tokens with Issues or Pull requests write permission. Stamp's existing repository visibility checks also apply.
Success prints the confirmed comment URL and GitHub actor; --json includes
repository, number, commentId, url and actorLogin. Each explicit command
is a new send, with no persistent deduplication. Neither CLI nor provider adapter
automatically resends a comment. If a response is lost or cannot be validated,
the command exits nonzero and asks you to inspect the PR before sending again.
The Raft manifest exposes only agent-login. Key enrollment, identity binding,
receipt reads, PR creation and subscriptions all use this CLI; the HTTP APIs
remain available to service clients. stamp migration-help maps retired action
names to commands. The retirement follows the Stamp owner's explicit cutover
decision; the general Raft migration guide's optional compatibility period is
over for this service.
Agent merge queue
Use stamp pr queue enqueue <NUMBER -R OWNER/REPO|PR_URL> --request-id ID --head SHA --base SHA
for an enabled native queue. Choose and save a 16–128 character request ID before
sending (letters/digits/underscore/hyphen, first character alphanumeric).
Independent approval of the current head is required; this accepts a request,
not a promise to merge. Use stamp pr queue status ... --request-id ID --json
to reconcile an uncertain reply, and stamp pr queue withdraw ... --request-id ID
to withdraw it. Reuse the same ID and coordinates; never create a new ID to retry
a lost response. Receipt reads/withdrawal are limited to the original agent and
server. Only requests still waiting can be withdrawn. Once a request enters a running
batch, withdrawal returns QUEUE_BATCH_IN_FLIGHT without canceling any member;
wait for completion and read the same request ID. Terminal receipts
retain verified landing SHA; notificationQueued is not delivery confirmation.
New admission requires the existing notification worker configured. This is a
source capability, not a claim that the deployment enables queues or delivery.
See the queue contract.
