Skip to content

Commit 6d05c4b

Browse files
committed
chore(wheelhouse): cascade template@e78e38af
Auto-applied by socket-wheelhouse sync-scaffolding into cascade-socket-cli-68977. 145 file(s) touched: - .agents/skills/fleet-agent-ci/SKILL.md - .agents/skills/fleet-agent-ci/reference.md - .agents/skills/fleet-auditing-api-surface/SKILL.md - .agents/skills/fleet-auditing-api-surface/lib/audit-api-surface.mts - .agents/skills/fleet-auditing-gha/SKILL.md - .agents/skills/fleet-auditing-gha/run.mts - .agents/skills/fleet-cascading-fleet/SKILL.md - .agents/skills/fleet-cascading-fleet/lib/cascade-template.mts - .agents/skills/fleet-cascading-fleet/lib/cascade-tool-pins.mts - .agents/skills/fleet-cascading-fleet/lib/fleet-repos.json - .agents/skills/fleet-cascading-fleet/lib/fleet-repos.txt - .agents/skills/fleet-cascading-fleet/lib/reconcile-lockfiles.mts - .agents/skills/fleet-cleaning-ci/SKILL.md - .agents/skills/fleet-cleaning-ci/lib/clean-ci.mts - .agents/skills/fleet-codifying-disciplines/SKILL.md - .agents/skills/fleet-driving-cursor-bugbot/SKILL.md - .agents/skills/fleet-driving-cursor-bugbot/reference.md - .agents/skills/fleet-greening-ci-local/SKILL.md - .agents/skills/fleet-greening-ci/SKILL.md - .agents/skills/fleet-greening-ci/run.mts ... and 125 more
1 parent 8bd9830 commit 6d05c4b

145 files changed

Lines changed: 18568 additions & 259 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
name: fleet-agent-ci
3+
description: Run this repo's GitHub Actions workflows locally in Docker with Agent-CI to validate changes before pushing. Use before opening or updating a PR, after editing a workflow YAML under .github/workflows, or whenever catching a CI failure locally beats waiting on a remote runner.
4+
user-invocable: true
5+
allowed-tools: Bash, Read, Edit
6+
model: claude-haiku-4-5
7+
context: fork
8+
---
9+
10+
# agent-ci
11+
12+
Run the repo's CI pipeline locally before pushing. CI was green before you started, so any failure the local run surfaces comes from your changes.
13+
14+
RedwoodJS wrote the upstream tool and skill (MIT, https://github.com/redwoodjs/agent-ci). The fleet pins `@redwoodjs/agent-ci` in the wheelhouse catalog and wires it as the `ci:local` package script (resolved via `node_modules/.bin`, never `pnpm exec`/`npx`). Edit only in `socket-wheelhouse/template/`; the cascade refreshes downstream copies.
15+
16+
## Requirements
17+
18+
- **Docker must be running** — each job runs in a container. On macOS the fleet uses **OrbStack** (`open -a OrbStack`; recommended over Docker Desktop). If the daemon is down, agent-ci fails fast with `couldn't use a Docker socket at /var/run/docker.sock … missing or a dangling symlink` and exit 1 — that's the daemon, not a workflow failure. Start the provider, confirm with `docker info`, re-run. No daemon and can't start one → fall back to `greening-ci` (push + watch remote).
19+
- **The dep is already installed**`@redwoodjs/agent-ci` is a fleet devDependency (`catalog:`), provisioned by `pnpm install`.
20+
- **`--github-token` for remote reusable workflows** — every socket-\* repo's `ci.yml` calls a `SocketDev/socket-registry/.github/workflows/…` reusable workflow. agent-ci can't fetch it without a token; pass `--github-token` (no value → auto-resolves via `gh auth token`). Omitting it makes a remote-reusable CI silently fail to resolve.
21+
- **macOS jobs (`runs-on: macos-*`)** run in a throwaway VM and need `tart` + `sshpass` on an Apple Silicon host (`brew install cirruslabs/cli/tart hudochenkov/sshpass/sshpass`). Without both, macOS jobs are skipped with a reason — the rest of the run still proceeds.
22+
23+
## Run
24+
25+
The blessed entry is the canonical `ci:local` script — it already carries the full flag set (`--all --quiet --pause-on-failure --github-token`), and pnpm resolves the `agent-ci` binary from `node_modules/.bin` cross-platform:
26+
27+
```bash
28+
pnpm run ci:local
29+
```
30+
31+
`--all` runs the PR/push workflows for the current branch. `--quiet` suppresses the live renderer (pipe-safe). `--pause-on-failure` stops at the first failed step and holds the container open for `retry`. `--github-token` (bare → `gh auth token`) fetches the socket-registry reusable workflow every fleet `ci.yml` calls. Pipes are safe: when stdout is not a TTY the launcher detaches and the foreground process exits **77** the moment a step pauses, so `| tee log` and `> log.txt` work.
32+
33+
There is no `--list` or dry-run flag — `run` executes. Args after the subcommand pass through, so a typo'd flag becomes a workflow arg rather than an error.
34+
35+
To resolve the binary from a `.mts` script (not a package.json script — those resolve `node_modules/.bin` themselves), use the fleet helper, never a shelled-out `which`/`command -v` (which searches the global PATH and resolves the wrong binary — enforced by `socket/no-which-for-local-bin`):
36+
37+
```ts
38+
import { whichSync } from '@socketsecurity/lib-stable/bin/which'
39+
40+
const agentCi = whichSync('agent-ci', { path: nodeModulesBinDir, nothrow: true })
41+
```
42+
43+
## Fix and retry
44+
45+
When a step fails the run pauses (and the `run.paused` event carries the exact `retry_cmd` to copy). Fix the code, then retry the paused runner — don't restart the whole pipeline:
46+
47+
```bash
48+
node_modules/.bin/agent-ci retry --name <runner-name>
49+
```
50+
51+
Call the linked binary directly (the fleet form for an ad-hoc bin invocation, same as `node_modules/.bin/oxfmt` / `tsgo` in build scripts) — never `pnpm exec`/`npx`. Re-run from an earlier step with `--from-step <N>`. Repeat fix → retry until every job passes. Don't push to trigger remote CI when agent-ci can run it locally.
52+
53+
## Reference
54+
55+
- **Machine-readable `--json` event stream, the full requirements rationale, and the agent-ci-vs-remote-CI decision matrix**: see [reference.md](reference.md).
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# agent-ci reference
2+
3+
## Contents
4+
5+
- Machine-readable output (`--json`)
6+
- The exit-77 pause contract
7+
- Requirements rationale (Docker, install)
8+
- When to use agent-ci vs. remote CI
9+
- Command summary
10+
11+
## Machine-readable output (`--json`)
12+
13+
Add `--json` (or set `AGENT_CI_JSON=1`) to emit an NDJSON event stream on stdout — one JSON object per line. Use it for programmatic monitoring instead of grepping plaintext.
14+
15+
Events:
16+
17+
- `run.start` — carries `schemaVersion: 1` and `runId`.
18+
- `job.start`, `job.finish``status: passed | failed`.
19+
- `step.start`, `step.finish``status: passed | failed | skipped`.
20+
- `run.paused` — carries `runner` and `retry_cmd` (the exact command to resume).
21+
- `run.finish``status: passed | failed`.
22+
- `diagnostic` — non-fatal notices.
23+
24+
`--json` is independent of `--quiet`. The diff renderer is auto-suppressed under `--json` so ANSI escapes don't collide with the stream.
25+
26+
The robust agent loop: parse the stream, react to `run.paused` (fix the failure named in `runner`), then run the `retry_cmd` it carries. No plaintext parsing required.
27+
28+
## The exit-77 pause contract
29+
30+
When stdout is not a TTY (piped, redirected, captured by a parent process), the launcher detaches the run. The foreground process exits **77** the instant a step pauses. This frees the pipe — `| tee`, `> log.txt`, command substitution — while the container stays paused in the background, ready for `retry`. Exit 77 means "paused, awaiting retry," not "failed."
31+
32+
## Requirements rationale
33+
34+
- **Docker.** agent-ci executes each workflow job inside a container, the same way GitHub's runners do. It connects via `AGENT_CI_DOCKER_HOST` (default `unix:///var/run/docker.sock`) — **not** the standard `DOCKER_HOST` (setting `DOCKER_HOST` makes agent-ci exit with a rename error; use `AGENT_CI_DOCKER_HOST` for a remote `ssh://`/`tcp://` daemon). Without a running daemon the run cannot start; it fails fast with a dangling-socket message and exit 1. On macOS the fleet provider is **OrbStack** (`open -a OrbStack`, then `docker info` to confirm). There is no degraded mode; if you can't start a daemon, use `greening-ci` (push and watch remote CI) instead.
35+
- **Remote reusable workflows.** A fleet `ci.yml` doesn't contain the jobs — it `uses:` a `SocketDev/socket-registry/.github/workflows/ci.yml@<sha>` reusable workflow. agent-ci fetches that over the network, which needs `--github-token` (bare flag → `gh auth token`, or `AGENT_CI_GITHUB_TOKEN`). Without it the reusable workflow can't resolve and the run can't assemble the job graph.
36+
- **macOS jobs.** `runs-on: macos-*` jobs run in a real throwaway macOS VM via `tart` (Apple Silicon only) with `sshpass`. Missing either tool, or on Linux/Intel, those jobs **skip with a reason** rather than failing the run; the Linux/container jobs still execute. VM concurrency caps at `AGENT_CI_MACOS_VM_CONCURRENCY` (default 2 — tart's free tier). Windows jobs (`runs-on: windows-*`) always skip (unsupported).
37+
- **Missing tools in the runner image.** Jobs run in `ghcr.io/actions/actions-runner:latest`, which ships node/git/curl/jq/unzip but **not** build toolchains, `python3`, or `xz`. A job failing on a missing tool isn't your code — add a `.github/agent-ci.Dockerfile` (`FROM ghcr.io/actions/actions-runner:latest` + `apt-get install`); agent-ci picks it up automatically and caches by content hash.
38+
- **Install.** `@redwoodjs/agent-ci` is a fleet devDependency declared as `catalog:` in every repo's `package.json`, pinned in the wheelhouse `pnpm-workspace.yaml` catalog. `pnpm install` provisions it. The published package is a self-contained Node CLI (`dist/cli.js`) — it has no platform-binary dependencies and its `ssh2` native build scripts are declined in the fleet's `allowBuilds`/`allowScripts` (the CLI runs without them).
39+
40+
## When to use agent-ci vs. remote CI
41+
42+
| Situation | Use |
43+
| ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
44+
| Edited a workflow YAML (`.github/workflows/*.yml`) | agent-ci first — a malformed workflow fails the same locally and remotely, skipping the push/wait loop. |
45+
| Code change that only needs lint / typecheck / unit tests | `pnpm run check --all` — faster than spinning up containers for the pure-Node gates. |
46+
| Workflow does something the local scripts don't (matrix, container steps, action wiring, secrets-shaped env) | agent-ci. |
47+
| No Docker, or the failure needs an off-machine action (a deploy, a remote service) | push and use `greening-ci`. |
48+
49+
## Command summary
50+
51+
| Command | Purpose |
52+
| -------------------------------------------------------------------- | ----------------------------------------------------------- |
53+
| `pnpm run ci:local` | Blessed entry — `agent-ci run --all` via `node_modules/.bin`. |
54+
| `node_modules/.bin/agent-ci run --all --pause-on-failure --github-token` | Run the branch's PR/push workflows; pause on first failure; fetch remote reusable workflows. |
55+
| `node_modules/.bin/agent-ci run --workflow <path>` | Run a single workflow file. |
56+
| `node_modules/.bin/agent-ci retry --name <runner>` | Resume a paused runner after a fix. |
57+
| `node_modules/.bin/agent-ci retry --name <runner> --from-step <N>` | Resume from an earlier step. |
58+
| `node_modules/.bin/agent-ci abort --name <runner>` | Tear down a paused runner without retrying. |
59+
60+
Add `--quiet` to suppress the live renderer, `--json` for the NDJSON stream. Invoke the binary via `node_modules/.bin/agent-ci` or the `ci:local` script — never `pnpm exec`/`npx` (fleet tooling ban).
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
name: fleet-auditing-api-surface
3+
description: Audits a lib's published export surface for dead/unconsumed subpaths. For each `package.json#exports` subpath, checks whether any other fleet repo imports it and whether the lib's own `src/` references it, then classifies every subpath (dead / single-consumer / internal-only / consumed) into a ranked report. Read-only — reports prune candidates, never deletes. Use weekly (the `audit-api-surface.yml` cron drives it), before a major version bump, or when trimming bundle size on an infra lib.
4+
user-invocable: true
5+
allowed-tools: Read, Grep, Glob, Bash(node:*), Bash(rg:*), Bash(git:*), Bash(gh:*)
6+
model: claude-haiku-4-5
7+
context: fork
8+
---
9+
10+
# auditing-api-surface
11+
12+
Find published API that nobody uses. A core infra lib like `@socketsecurity/lib`
13+
exports 500+ subpaths; some are referenced by no other fleet repo and not even
14+
by the lib's own internals. That dead surface is pure carrying cost — bundle
15+
weight, a wider type-check graph, a tax on every refactor. This skill surfaces
16+
it. Read-only: it reports prune candidates, it never removes an export (mirrors
17+
`auditing-gha`, which reports drift but flips no setting).
18+
19+
Repo-generic: it reads the host repo's own `package.json` name + export map, so
20+
the same skill audits any lib-shaped fleet repo. socket-lib is the primary
21+
target; other libs get a meaningful report too.
22+
23+
## When to use
24+
25+
- **Weekly health check** — the `audit-api-surface.yml` cron runs this and opens
26+
a tracking issue. Dead surface accumulates silently; a weekly sweep keeps it
27+
visible.
28+
- **Before a major version bump** — a `dead` or `single-consumer` export is a
29+
candidate to remove (major) or inline into its one consumer.
30+
- **Bundle trimming** — pairs with `trimming-bundle`; an unconsumed subpath is
31+
weight no downstream needs.
32+
33+
## What it does NOT do
34+
35+
- **Delete anything.** Every finding is a candidate for a human. A `dead` row
36+
may be a deliberate public entry point a not-yet-released consumer will use.
37+
- **Prove a `dead` export is safe to remove.** The scan sees only the fleet
38+
repos present under `$PROJECTS` (CI clones the full roster first). A repo on
39+
the roster but absent locally is reported `unscanned`, and any subpath with an
40+
unscanned repo is classed `unverifiable` — never silently "dead".
41+
- **Go to symbol granularity.** Classification is per-subpath (per exported
42+
file), not per named export. A subpath with one live symbol and ten dead ones
43+
reads as `consumed`. Symbol-level analysis is a future pass.
44+
45+
## How it classifies
46+
47+
| Class | Meaning | Action |
48+
| --- | --- | --- |
49+
| `dead` | no internal refs, no external consumers, all repos scanned | prune candidate |
50+
| `single-consumer` | exactly one external consumer | candidate to inline there |
51+
| `internal-only` | used inside the lib, by no other repo | keep (flagged for awareness) |
52+
| `consumed` | ≥2 external consumers | healthy, keep |
53+
| `unverifiable` | no consumer found, but a roster repo was unscanned | re-run with that repo cloned |
54+
55+
Both import forms are matched: `<pkg>/<subpath>` and the `-stable` alias
56+
`<pkg>-stable/<subpath>` (every consumer aliases the lib both ways in
57+
`pnpm-workspace.yaml`).
58+
59+
## Run
60+
61+
From the repo being audited:
62+
63+
```bash
64+
node .claude/skills/fleet/auditing-api-surface/lib/audit-api-surface.mts --report
65+
```
66+
67+
Or target a sibling checkout by name (greps the others as consumers):
68+
69+
```bash
70+
PROJECTS=~/projects \
71+
node .claude/skills/fleet/auditing-api-surface/lib/audit-api-surface.mts \
72+
--repo socket-lib --report
73+
```
74+
75+
`--report` (default) writes `.claude/reports/api-surface-audit.md` (untracked,
76+
per the report-location rule). `--json` prints the machine-readable result to
77+
stdout — the cron workflow consumes this to build its issue body.
78+
79+
## Verify before trusting
80+
81+
The report header states the scanned-repo count and the exact import forms
82+
matched. The internal-ref counter is a loose basename match (it errs toward
83+
keeping an export, never toward calling a live one dead). Before acting on a
84+
`dead` finding, confirm by hand:
85+
86+
```bash
87+
rg '@socketsecurity/<pkg>(-stable)?/<subpath>' ~/projects/socket-* --glob '!**/node_modules/**'
88+
```
89+
90+
A finding is a lead, not a verdict.

0 commit comments

Comments
 (0)