Commit Graph

38 Commits

Author SHA1 Message Date
Peter Pistorius bcd5f0e356 docs: make packages/cli/README the main README (symlinked from root) (#247)
* docs: promote packages/cli/README as the main README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: symlink root README to packages/cli/README

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: reframe Why section — remote CI is the gatekeeper, agent-ci is the pre-flight check

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: note Docker Desktop is also supported on Linux

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:56:51 +02:00
Peter Pistorius ef2ee43835 Catch any missing tool in runner image hint (#231)
* fix: skip orphan cleanup when running inside a Docker container

When agent-ci runs nested inside a container (e.g. smoke-bun-setup step 8),
it shares the host's Docker socket. killOrphanedContainers() checks
agent-ci.pid labels using process.kill(pid, 0), but host PIDs don't
exist in the container's PID namespace — so every container looks like
an orphan. This caused the nested agent-ci to force-remove its own
parent container (exit 137).

Both pruneOrphanedDockerResources() and killOrphanedContainers() now
bail out when /.dockerenv exists.

Fixes #228

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: ignore inherited AGENT_CI_DTU_HOST inside containers

When agent-ci runs nested inside a container (e.g. smoke-bun-setup),
the outer container's AGENT_CI_DTU_HOST=host.docker.internal is
inherited. The nested agent-ci used this to tell the inner container
where the DTU is, but the nested DTU is inside the outer container,
not on the host. The inner container got "Connection refused" trying
to reach host.docker.internal:PORT.

Now when /.dockerenv exists, AGENT_CI_DTU_HOST is ignored and the
container's own IP (via hostname -I) is used instead, so sibling
containers can reach the DTU.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: move /.dockerenv guard to call site so tests still work

The /.dockerenv check inside killOrphanedContainers() broke the
shutdown integration tests — they run inside a Docker container (the
test runner) and need the function to work. Moved the guard to the
session bootstrap in cli.ts where the nested agent-ci problem occurs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add global concurrency limiter across all workflows

In --all mode, each workflow created its own per-wave limiter, allowing
20+ containers to run simultaneously and exhaust available memory (OOM
kills with exit 137). Now a single global limiter (CPU/2) is created in
the orchestrator and shared by all handleWorkflow calls, including
single-job workflows and cold-cache first jobs.

Closes #225

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: factor Docker VM memory into concurrency limit

CPU-based limit alone (cpuCount/2 = 7) still causes OOM kills. Now
reads MemAvailable from /proc/meminfo inside the Docker VM and caps
at floor(available / 3GB per container). Falls back to docker info
with a 4GB reserve if busybox isn't available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: guard orphan cleanup in the function, not just the call site

The /.dockerenv guard was only in cli.ts, but killOrphanedContainers
is also called directly by the Docker integration tests (via a spawned
tsx subprocess). Inside a container, the test's subprocess would see
the parent container's PID label, misidentify it as an orphan, and
kill the container running the tests.

Put the guard back in both functions AND keep the cli.ts guard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: increase per-container memory estimate to 4 GB

3 GB per container wasn't enough — tests.yml (vitest + Docker
integration tests) and smoke-binary.yml (full build) both got killed
at 3 concurrent containers. 4 GB gives 2 concurrent containers on a
12 GB Docker VM, with ~5.4 GB each.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: mock fs.existsSync in shutdown unit tests for /.dockerenv guard

The unit tests mock execSync but not fs. Inside a runner container,
the real fs.existsSync("/.dockerenv") returns true, causing
killOrphanedContainers to bail before reaching the mocked execSync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: skip Docker integration tests for orphan cleanup inside containers

The integration tests spawn a real killOrphanedContainers() subprocess.
Inside a container, the function bails due to /.dockerenv (PID namespace
mismatch), so the tests can't exercise it. Skip them with insideDocker().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add --jobs flag and document concurrency

Adds -j/--jobs <n> to override the auto-detected concurrency limit.
Adds a Concurrency section to the README explaining how the limit is
calculated and how to override it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: catch any missing tool in runner image hint, add Nix recipe and docs

Closes #229

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Revert "feat: catch any missing tool in runner image hint, add Nix recipe and docs"

This reverts commit ca261639e9.

* feat: generic missing-tool detection with Nix/xz recipe

Replace the hardcoded per-tool pattern list with a single generic
"command not found" regex that catches any missing tool. Add detection
for the Nix installer's "you do not have 'xz' installed" message.
Update hint to point to runner-image.md docs instead of inlining a
Dockerfile snippet. Add Nix recipe to runner-image.md and a runner
image section to the README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:48:26 +02:00
Peter Pistorius b31fc80ff7 docs: simplify usage to npx @redwoodjs/agent-ci everywhere (#233)
No install step needed. Just run with npx.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:11:01 +02:00
Peter Pistorius 3f964c00db docs: unify agent instructions across repo, README, and website (#220)
* docs: unify agent instructions across repo, README, and website

Remove the .agents/ hook system and Machinen-specific CLAUDE.md instructions.
Public-facing docs (README, website) now show generic commands that work with
any agent harness. CLAUDE.md uses the /validate skill directly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: mention /validate skill on website

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add Agent Skills spec skill and update docs with `npx skills add`

Ship an agentskills.io-compatible skill at skills/agent-ci/SKILL.md so
users can install with `npx skills add redwoodjs/agent-ci --skill agent-ci`.
Works with Claude Code, Cursor, Codex, and 40+ other agents.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add penberg testimonial, update bebraw quote

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: simplify agent instructions to reference the skill

Instead of repeating raw commands, tell agents to run the `agent-ci` skill
that was installed via `npx skills add`.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add AI disclosure to blog posts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: move AI disclosure to top of blog posts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: clarify runner image vs VM image in blog post

Explain that agent-ci uses the ~400 MB official runner binary, not
GitHub's ~30 GB VM image.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: show nav links on mobile across all pages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: wrap nav links to second row on mobile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: show Star us button on mobile

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:35:33 +02:00
Peter Pistorius 2cf4034821 feat: resolve workflow secrets from environment variables (#193)
* feat: resolve workflow secrets from shell environment variables

Shell env vars now act as a fallback for .env.agent-ci when resolving
${{ secrets.FOO }} references. Also auto-populates secrets.GITHUB_TOKEN
from --github-token.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add loadMachineSecrets env fallback tests, update README

Add 7 tests covering process.env fallback behavior in loadMachineSecrets:
file precedence, env-only resolution, key scoping, and merge behavior.
Add a Secrets section to the README documenting resolution order.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 15:54:38 +02:00
Peter Pistorius 1f24fecc14 fix: make GitHub auth opt-in for remote workflow fetching (#183)
* fix: make GitHub auth opt-in for remote reusable workflow fetching

Remove implicit credential resolution (gh auth token / GITHUB_TOKEN fallback)
that could silently send user credentials. Auth is now opt-in via
--github-token CLI flag or AGENT_CI_GITHUB_TOKEN env var.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* chore: add changeset for opt-in GitHub auth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: add --github-token flag and AGENT_CI_GITHUB_TOKEN to docs

Update CLI reference tables, environment variables section, and
compatibility matrix to reflect opt-in GitHub auth for remote
reusable workflows.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix: make commit status posting opt-in via --github-token

Gate postCommitStatus() on the githubToken parameter. When no token
is provided, print a warning instead of silently using implicit
gh CLI credentials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* feat: add --commit-status flag to opt in to posting GitHub commit statuses

Commit status posting now requires both --commit-status and
--github-token. Without --commit-status, no warning is printed
and no status is posted.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* test: add tests for 403 error hint and public repo fetch without auth

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 11:55:26 +02:00
Peter Pistorius bdd269ff10 feat: move website to apps/website, improve content and fix SSR
- Move website from website/ to apps/website/ (update pnpm workspace)
- Remove logo icon from navbar, keep AGENT-CI text
- Configure domain routes for agent-ci.dev in wrangler.jsonc
- Replace tabs with stacked tables in compatibility matrix
- Expand all ⚠️ and ❌ notes with reasons and details
- Update compatibility.md to match website content
- Fix useContext SSR error by removing motion/react, using CSS animations
- Add img-src CSP header for pbs.twimg.com (Twitter profile images)
- Remove npx run --all command from hero, rename button to Quick start
- Remove decorative border elements from hero section
- Update footer "Built by" link to rwsdk.com

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:27:26 +11:00
Peter Pistorius 97227c4251 Merge pull request #77 from simoncrypta/fix/docker-host-ip
fix: make Docker host resolution universal
2026-03-26 02:41:29 +13:00
Simon Gagnon 345b24ba34 docs: deduplicate docker host config guidance
Keep root README concise by linking to the CLI README section as the source of truth for custom Docker host resolution configuration.
2026-03-24 19:31:00 -04:00
Simon Gagnon 79c7d65f36 refactor: remove host-side DNS probe for DTU host resolution
Simplify resolveDtuHost to deterministic precedence: AGENT_CI_DTU_HOST > AGENT_CI_DOCKER_BRIDGE_GATEWAY (outside Docker) > host.docker.internal. Removes misleading host-side dns.lookup that did not predict container-side reachability.
2026-03-24 19:31:00 -04:00
Simon Gagnon 1d1e4ec68c fix: preserve external DTU URLs and align host fallback docs
Limit Docker API URL rewrites to loopback hosts, keep alias-based defaults unless an explicit bridge gateway override is configured, and update docs/tests to match behavior.
2026-03-24 19:31:00 -04:00
Simon Gagnon a9878186a0 fix: make Docker host resolution universal 2026-03-24 19:31:00 -04:00
Peter Pistorius 53a6f05a6d feat: add demo recording and embed GIF in README
Add a VHS-based terminal recording that demonstrates the core agent-ci
workflow: pause on failure, fix the bug, retry the failed step.

The demo uses tmux split panes to show fixing code in one pane while
agent-ci is paused in the other. The tape auto-resets state on each
recording for easy re-recording.

No changeset needed — no packages/ code changed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:33:17 +13:00
Peter Pistorius 99c794a517 fix: use scoped package name @redwoodjs/agent-ci in npx commands
Ensures the commands work even when the package isn't installed as a
local devDependency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:32:08 +13:00
Peter Pistorius 6971663e04 fix: address PR review comments on SKILL.md and README
- Add "(in Docker)" clarification to SKILL.md
- Explain --all flag matches on triggers like GitHub
- Add --no-matrix tip for collapsing matrix jobs locally
- Use --quiet flag in CLAUDE.md snippet
- Add "CI was green before you started" instruction for agents

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:18:53 +13:00
Peter Pistorius 179405b960 feat: add package metadata, SKILL.md, and AI agent discoverability
Improve npm and AI agent discoverability by filling in package.json
keywords/description, creating a SKILL.md for node_modules scanning,
and adding a ready-to-paste CLAUDE.md snippet to the README.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 07:07:09 +13:00
Peter Pistorius 54ef949483 Add docs. 2026-03-23 22:45:46 +13:00
Peter Pistorius 7357393c0e fix: add shebang to CLI entry point for npx compatibility
The dist/cli.js was missing #!/usr/bin/env node, causing npx to execute it as a shell script. Version 0.3.2
2026-03-18 07:04:34 +13:00
Peter Pistorius d74b1e634e Fix publishing. 2026-03-16 18:24:38 +13:00
Peter Pistorius e2fdc0c359 feat: add paths/paths-ignore filtering to isWorkflowRelevant 2026-03-12 23:33:07 +02:00
Peter Pistorius 5b8acda506 Rename machinen to agent-ci
- Rename package from 'machinen' to 'agent-ci' across all source, tests, scripts, configs, and docs
- Rename CLI binary from 'machinen' to 'agent-ci'
- Rename .machinen → .agent-ci, .env.machinen → .env.agent-ci, MACHINEN_* → AGENT_CI_*
- Rename --runner flag to --name/-n (--runner still accepted for compat)
- agent-ci-dev script now builds DTU before running CLI
- Extract YAML compatibility tables to cli/compatibility.md
- Expand CLI usage docs with per-command flag tables
- Document DOCKER_HOST support for remote Docker
2026-03-12 22:35:26 +02:00
Peter Pistorius f58618c67f Add dev containers script. 2026-03-10 13:04:04 +02:00
Peter Pistorius d81da85fc9 chore: improve README docs, add machinen-dev alias, default pause-on-failure
- Document workflow relevance criteria for --all in README
- Add machinen-dev script alias to root package.json
- Make --pause-on-failure the default, add --exit-on-failure/-x to opt out
- Remove unused dev script, concurrently, and wait-on deps
- Move tagline from root README to cli/README
2026-03-09 22:22:18 +02:00
Peter Pistorius baabf8e0df Rename supervisor to cli. 2026-03-06 22:57:53 +02:00
Peter Pistorius 838ace96f0 Remove unused env-file. 2026-03-06 22:26:38 +02:00
Peter Pistorius 922b01df41 Rewrite the past. Closes #14. 2026-03-06 21:54:22 +02:00
Peter Pistorius b349c3557a chore(core): centralize default working directory in working-directory.ts 2026-03-06 08:50:29 +02:00
Peter Pistorius f0a37d2249 docs: document headless mode + update README for OrbStack and machinen naming
README.md:
- Recommend OrbStack as the preferred Docker provider on macOS
- Rename dtu/github-actions → dtu-github-actions throughout
- Add 'Headless Mode (This Repository Only)' section with oa run examples
- Add 'Full Services Stack' heading before existing pnpm dev content

.env.example: fix GITHUB_REPO example value to use machinen repo name
2026-03-05 18:28:18 +02:00
Peter Pistorius cd0d996567 X 2026-02-27 17:06:51 +02:00
Peter Pistorius 030a2b1ed9 Update readme. 2026-02-26 20:20:29 +02:00
Peter Pistorius 45a0177de6 Fix nodejs cache. 2026-02-25 14:06:24 +02:00
Peter Pistorius c763c304df Rename runner to supervisor. 2026-02-20 11:17:49 +02:00
Peter Pistorius 1bc7b6321e feat: Introduce broad updates across SDK, runner components, and build infrastructure, including new git configuration and documentation. 2026-02-19 18:28:06 +02:00
Peter Pistorius b1b510e93e feat: Orchestrate the official GitHub Actions self-hosted runner and add a presence check API for workflow routing. 2026-02-11 23:28:37 +02:00
Peter Pistorius 617321d836 docs: Update product name from "Opposite-Action" to "Opposite-Actions" across documentation and README. 2026-02-11 22:12:17 +02:00
Peter Pistorius 48b339f642 feat: Orchestrate local development with concurrently and wait-on, updating service ports and streamlining DTU scripts. 2026-02-11 11:48:28 +02:00
Peter Pistorius 19dacf5ca9 feat: Initialize pnpm monorepo with workspace configuration, package.json, and .env.example, while removing a placeholder workflow. 2026-02-10 22:00:56 +02:00
Peter Pistorius 5c86649892 feat: Implement Opposite-Action local-first CI bridge with GitHub webhook and heartbeat APIs, job monitoring, and KV persistence. 2026-02-09 21:56:08 +02:00