Skip to content

Add headless CI setup commands: ci apply and ci install#923

Draft
0x0079 wants to merge 5 commits into
mainfrom
claude/plan-ci-command-uxBAQ
Draft

Add headless CI setup commands: ci apply and ci install#923
0x0079 wants to merge 5 commits into
mainfrom
claude/plan-ci-command-uxBAQ

Conversation

@0x0079

@0x0079 0x0079 commented May 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds headless one-shot agent setup for CI and fully-managed environments via two new commands: tingly-box ci apply (configure provider/model/agent from flags) and tingly-box ci install (install agent CLI via npm). Both commands are non-interactive, idempotent, and designed for automation.

Key Changes

  • New ci apply command (internal/command/ci.go, ci_runner.go):

    • Accepts flags for agent type, provider URL/token/style, and model
    • Validates all required flags and collects errors into a single message
    • Upserts provider by URL (updates existing provider with same URL rather than creating duplicates)
    • Delegates to agent.ApplyAgent with Force=true to skip confirmation prompts
    • Supports --dry-run to preview changes without applying
    • Redacts tokens in output for safe CI log capture
  • New ci install command (internal/command/ci_install.go):

    • Installs agent CLI packages via npm
    • Resolves package names from agent type or accepts --package override
    • Supports version pinning via --version
    • Validates npm availability before execution
    • Propagates npm exit codes for CI gate integration
  • Installation scripts (script/install.sh, script/install-mirror.sh):

    • install.sh: Standard installation from official sources (nvm + Node.js LTS + tingly-box)
    • install-mirror.sh: Mirror-aware variant for mainland China networks (gitee nvm, npmmirror registry)
    • Both idempotent and shell-agnostic (require bash explicitly)
  • Comprehensive test coverage (internal/command/ci_test.go, ci_install_test.go):

    • Flag validation and error collection
    • Agent type parsing and API style normalization
    • Provider upsert idempotency (same URL updates in place, different URLs create separate rows)
    • Token redaction logic
    • Package resolution with version/override handling
  • Agent metadata extension (ai/agent/info.go):

    • Added NPMPackage field to AgentInfo struct
    • Registered npm packages for claude-code, opencode, and codex agents
  • CLI integration (cli/tingly-box/main.go):

    • Wired CICmdKong as top-level ci command with apply as default subcommand

Implementation Details

  • Configuration errors exit with status 2 (distinct from runtime failures at status 1) for CI gate differentiation
  • Provider upsert uses URL as both the lookup key and display name for simplicity
  • Token redaction shows first/last 4 characters for operator sanity-checking without leaking secrets
  • API style validation rejects OAuth providers (no browser flow in CI context)
  • Whitespace-only flag values treated as absent for robustness

https://claude.ai/code/session_01HPEmfNiFZEMELLg858CCLJ

claude added 5 commits May 13, 2026 05:24
CI / fully-managed environments need to configure (provider, model, agent)
without any interactive prompts. Existing `provider add` + `agent apply`
both fall through to stdin reads, which hang in non-TTY contexts. This
adds a flat command that takes everything via flags, upserts the provider
by name (idempotent re-runs), and delegates to ApplyAgent with Force=true.
Provider name added no value — URL already uniquely identifies an endpoint.
Upsert now iterates ListProviders() matching APIBase; new providers use the
URL as their display name too. Remove --provider-name flag and ciSpec field.
New subcommand wraps `npm install -g <pkg>[@Version]` for the three
supported agents. Package mapping lives in AgentInfo.NPMPackage so each
agent owns its own canonical name; --package and --version flags allow
overrides for forks and version pinning. Sudo is intentionally not
handled — npm's own EACCES message is more informative.
install.sh fetches nvm, installs LTS Node, then `npm install -g tingly-box`
from defaults. install-mirror.sh routes the same flow through gh-proxy
(github), npmmirror node binaries, and registry.npmmirror.com so users on
restricted networks can finish the bootstrap without manual mirror config.

Both scripts are idempotent: re-running detects an existing nvm install and
skips re-fetching it. Mirror endpoints are env-overridable. Unignore the
script/ directory so these (and future) helpers are tracked.
Drop the gh-proxy hop for nvm bootstrap and clone directly from
gitee.com/mirrors/nvm — fewer moving parts, more reliable inside CN.
Skip the upstream install.sh entirely; replicate its profile-snippet
append manually (idempotent grep) so subsequent shells still pick up
nvm. Node binaries and the npm registry continue to use Taobao
(npmmirror.com), which was already the default.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants