Repository navigation
feat(run,automations): --context and checkout none (agent contexts C2) - #63
Merged
Merged
Conversation
govulncheck, which CI runs as a failing check, reports GO-2026-6809 (crypto/x509 trusting compromised intermediates) on go1.26.9, reached through every HTTPS call this CLI makes. It is fixed in go1.26.10. The same finding is on main today, so without this the vulnerability job fails here and on the next push to main, and tag.yml publishes nothing from a commit whose CI did not pass. Only the go directive moves; no dependency changes. Co-authored-by: Pau Morillas <pmorillas@helmcode.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…ctor, 0.1.35 (#60) nan auth login asks for the authenticator code (or a recovery code) after the emailed link when the account has two-factor on, without echo, again after a wrong one; --totp - reads it from stdin for scripts. The panel's sign-in does the same. The verify call now sends mfa=1 so the platform can answer with a challenge; with two-factor off the sign-in is unchanged. Bumps internal/tui.Version to 0.1.35, which publishes the release. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntexts C1) (#62) * feat(context): nan context ls|show|create|push|pull|edit|rm (agent contexts C1) The CLI side of agent contexts (helmcode/nan-devops AGENT-CONTEXT.md §6, C1), against the /v1/contexts API merged in cloud-api (#391, #395). - internal/contexts/path.go is a verbatim copy of cloud-api's validator, with its parity table (path_test.go) and a test of the shared pins. - push: walks DIR, NFC-normalises names (macOS gives NFD), skips dotfiles with a notice, prints every refused file with its reason and exits 65 before uploading unless --skip-invalid (CLAUDE.md gets a rename hint), checks the version limits, hashes, asks blobs/check, uploads only missing blobs (4 at a time; single PUT up to 16 MiB, multipart above, resumed within a push via the upload status and across pushes via a remembered upload id), publishes with base_version and an Idempotency-Key. Handles blob_missing (re-check, re-upload), version_conflict (exit 1, or --force shows the diff and rebases), context_secret_detected (--allow-secrets), per-file refusals and Retry-After (up to 2 minutes). --dry-run prints the add/change/remove list and the bytes to upload. - pull: refuses a non-empty DIR (--force overrides), validates every server path with the shared validator before writing anything, writes through os.OpenRoot, pins downloads to the version read and verifies sha256/size. - golang.org/x/text becomes a direct dependency at v0.39.0. CI gains a job (scripts/check-cloud-api-pins.sh, secret CLOUD_API_READ_TOKEN) comparing x/text, the Go toolchain's Unicode tables and path.go with cloud-api. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: move the cloud-api parity check to cloud-api's CI nan-cli is public and cloud-api private: cloud-api's CI reads this repository's go.mod and path.go without a token, so the check lives there and no secret is added here. The unit test keeps pinning golang.org/x/text v0.39.0 and the Unicode tables (15.0.0). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(contexts): point the pins test at cloud-api's parity check Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(context): address the QA and Security review of #62 Security: - A DIR that is a symlink is resolved once and its target walked; WalkDir alone saw one non-directory and push published an empty tree. - push refuses to publish no files over a version that has some unless --allow-empty (also after a --force rebase). - Files are hashed and uploaded through os.OpenRoot on DIR and refused if they stopped being regular files. - pull downloads into a temporary name, verifies, sets the mode both ways and renames into place: a failed download never deletes a member's file, and a link or folder at a file's path is never replaced. The total of a version is capped at 250 MiB; a partial pull says how many files were written and points at --force. - NAME|id is checked locally (context name or id) before any request. - Remembered multipart uploads are keyed by API host and credential hash. QA: - Tests for a symlinked folder inside DIR and a symlinked file on pull, the blob_missing re-check body and single PUT, the version limits (31 skills, 1001 files, 250 MiB, 100 MiB per file, SKILL.md 64 KiB), aborting an unusable remembered upload, forgetting an upload dropped mid-parts, exit mappings (entitlement_required and others), the inherited executable bit, pull --force modes, the total cap and local ref checks. - Unchanged files keep the remote executable bit where the file system has none (Windows). - Dead ContextVersions/ContextVersionInfo removed. - The fake follows cloud-api's publish check order, decodes strictly and answers 411 without Content-Length. - Help says API keys are not used here; pins comment wrapped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: barckcode <cristian@helmcode.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ne (agent contexts C2) nan run --context NAME (repeatable, at most 5, order kept) sends "contexts" on POST /v1/runs. An ephemeral run may leave out --repo only with a context; --github-token-secret without --repo is refused. nan automations create|edit take --context NAME and --checkout none (an ephemeral automation without a repository, which needs a context); edit accepts the flags without -f, and --checkout none on edit sets github_repo to null unless the file says otherwise. A field given both in the file and as a flag is refused. Every mistake (a sixth context, a repeat, an invalid name, a contexts field that is not a list) exits 64 before any request. The platform's 404 context_not_found (naming contexts[i]), 422 context_skill_conflict and 413 context_too_large read as what to do, also on automation edit where a 404 is no longer taken for a missing automation. api.Run carries the pinned contexts so --json shows them. Request goldens under cmd/testdata/contexts, help text and README. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Agent contexts C2 (devops
AGENT-CONTEXT.md§6 and §8 row C2), against the cloud-api B4 API (#406 runs, #407 automations).nan run --context NAME: repeatable, at most 5, order kept, sent ascontextsonPOST /v1/runs. Works for workspace and ephemeral runs.nan run --ephemeralwithout--repois allowed only with--context: nogithub_repois sent, and the agent works in an empty folder.--github-token-secretwithout--repois refused.nan automations create|edit --context NAME(repeatable, at most 5) and--checkout none(an ephemeral automation without a repository, which needs at least one context).edittakes the flags without-f. On edit,--checkout nonealso sendsgithub_repo: nullunless the file sets it. A field given both in the file and as a flag is refused.contexts:that is not a list,checkout: nonewith a repository, on a workspace automation, or with no context.context_not_foundnames the context fromcontexts[i], 422context_skill_conflict, 413context_too_large, and 400 oncontexts[...]. Onautomations edit, a 404context_not_foundno longer reads as "automation not found".api.Runnow carries the pinnedcontexts(omitempty), sonan run --jsonshows them. The run announcement lists the contexts.nan run,nan automations createandedit, the README (flags table, ephemeral runs, the agent contexts section, exit codes).Base and deviations
feat/ephemeral-e2-cliwithorigin/mainmerged in (commit 804751f) so thenan contextcode from C1 is there. The one conflict was incmd/json_output_test.go: I kept both the ephemeral fixture route and the contexts fake. Because of that merge, the diff againstfeat/ephemeral-e2-clialso shows main's commits (feat(auth): two-factor sign-in for nan auth login and the panel (0.1.35) #60, build: go 1.26.10 for GO-2026-6809 #61, feat(context): nan context ls|show|create|push|pull|edit|rm (agent contexts C1) #62). The C2 change on its own is commit 82f8620:git diff 804751f 82f8620.cmd/ephemeral.go(the repo-or-context rule incheckEphemeralFlags, andcheckout: noneincheckAutomationExecutor) andinternal/api/runs.go(CreateRunRequest.Contexts,Run.Contexts). Both are needed for this change.--checkouttakesworkspace,freshornone. It sets the file'scheckoutfield, so the other two values come for free.Tests (spec first)
cmd/run_contexts_test.go: order and body, nocontextswithout the flag, request goldens (cmd/testdata/contexts/run_request_*.json), a repo-less ephemeral run, a table of usage errors with no request sent, ids in any case, the flag run through cobra (repeat, a sixth one, a comma is not a separator), refusal mapping,Run.Contextsdecoding, help.cmd/automations_contexts_test.go: create/edit body goldens (automation_*.json), the file as written when no flags are given, edit without-f, a table of usage errors with zero requests, refusal mapping on create, on edit and from a file's contexts, help.TestCheckAutomationExecutor: 13 new rows forcheckout: noneandcontexts.🤖 Generated with Claude Code