Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/verify-agent-tty/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ENV=$(.agents/skills/verify-agent-tty/scripts/start-run.sh <name>)

`start-run.sh` does this, from an empty folder to a usable CLI:

1. If `node_modules/.bin/tsc` is missing (a partial install), it runs `aube ci`. Otherwise it runs `aube install --frozen-lockfile`, which brings `node_modules` up to date after a change to `aube-lock.yaml` and returns at once when nothing changed. Without that, a run after a dependency change builds and runs the old packages.
1. It runs `pnpm install --frozen-lockfile`, which brings `node_modules` up to date after a change to `pnpm-lock.yaml`, repairs a partial install that lacks `node_modules/.bin`, and returns at once when nothing changed. Without that, a run after a dependency change builds and runs the old packages.
2. It runs `npm run build`. If `stale-dist.sh` then finds a module of `src/` without its built module in `dist/`, or a `.ts` or `.tsx` file in `src/` newer than `dist/cli/main.js`, it removes `.tsconfig.build.tsbuildinfo` and `dist/` and builds again. A stale build info file makes `tsc` exit 0 and write nothing, also when only one built module was deleted.
3. It makes the run folder `<root>/<UTC time>-<name>-<random>/` with `mktemp -d`, and `home/`, `state/` and `evidence/` in it. The root is `$VERIFY_ROOT`, or `${TMPDIR:-/tmp}/verify-agent-tty-<uid>`. The script refuses a root that is a symlink or that you do not own, and sets it to mode 700, so another user on a shared machine cannot plant files there.
4. It writes `env.sh` there and prints its path.
Expand Down
32 changes: 12 additions & 20 deletions .agents/skills/verify-agent-tty/scripts/start-run.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Prepares one verification run of the agent-tty CLI from this checkout:
# brings deps up to date with aube-lock.yaml, builds dist/, and makes an
# brings deps up to date with pnpm-lock.yaml, builds dist/, and makes an
# isolated run folder. Prints the path of the run's env.sh; source it in
# every shell.
#
Expand Down Expand Up @@ -37,27 +37,19 @@ mkdir "$RUN/home" "$RUN/state" "$RUN/evidence"
RUN=$(cd "$RUN" && pwd -P)
cd "$REPO"

command -v aube >/dev/null 2>&1 || {
echo "start-run.sh: aube is not on PATH; run 'mise install' first" >&2
command -v pnpm >/dev/null 2>&1 || {
echo "start-run.sh: pnpm is not on PATH; run 'mise install' first" >&2
exit 2
}
# Bring node_modules up to date with pnpm-lock.yaml, so a run after a
# dependency change does not build and run the old packages. This also
# repairs a partial install that lacks node_modules/.bin, where
# `npm run build` fails with "tsc: not found". pnpm returns quickly when
# nothing changed.
pnpm install --frozen-lockfile >"$RUN/install.log" 2>&1 || {
echo "start-run.sh: pnpm install --frozen-lockfile failed, see $RUN/install.log" >&2
exit 2
}
# A partial install leaves node_modules without .bin, and then `npm run build`
# fails with "tsc: not found": only a clean install repairs that. Otherwise
# bring node_modules up to date with aube-lock.yaml, so a run after a
# dependency change does not build and run the old packages. aube returns
# quickly when nothing changed.
if [ ! -x node_modules/.bin/tsc ]; then
echo "Installing dependencies (aube ci)" >&2
aube ci >"$RUN/install.log" 2>&1 || {
echo "start-run.sh: aube ci failed, see $RUN/install.log" >&2
exit 2
}
else
aube install --frozen-lockfile >"$RUN/install.log" 2>&1 || {
echo "start-run.sh: aube install --frozen-lockfile failed, see $RUN/install.log" >&2
exit 2
}
fi

build() {
npm run build >"$RUN/build.log" 2>&1 || {
Expand Down
23 changes: 23 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
version: 2
updates:
# pnpm project (Dependabot detects pnpm from pnpm-lock.yaml and the
# packageManager field). The 7-day cooldown (zizmor's minimum) also exceeds
# pnpm-workspace.yaml's 1-day minimumReleaseAge, so version updates never
# propose a release pnpm would refuse to resolve.
- package-ecosystem: npm
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
commit-message:
prefix: chore(deps)

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
cooldown:
default-days: 7
commit-message:
prefix: chore(ci)
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ jobs:
- name: Set up mise
uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3.6.3
with:
install_args: --locked node python aube
install_args: --locked node python npm:pnpm

- name: Install CI dependencies
run: mise run bootstrap-ci
Expand Down Expand Up @@ -319,8 +319,8 @@ jobs:
uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3.6.3
with:
# The macOS jobs do not run workflow linting or Communique, so avoid
# installing release-only tools. They still need aube for bootstrap-ci.
install_args: --locked node python aube
# installing release-only tools. They still need pnpm for bootstrap-ci.
install_args: --locked node python npm:pnpm

- name: Install CI dependencies
run: mise run bootstrap-ci
Expand Down Expand Up @@ -366,7 +366,7 @@ jobs:
- name: Set up mise
uses: jdx/mise-action@5228313ee0372e111a38da051671ca30fc5a96db # v3.6.3
with:
install_args: --locked node python aube
install_args: --locked node python npm:pnpm

- name: Install CI dependencies
run: mise run bootstrap-ci
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ jobs:
run: mise run bootstrap-ci

# bootstrap-ci intentionally skips browser downloads so jobs that do not
# need Chromium can stay on deterministic `npm ci`. This release workflow
# runs the full Linux quality bar, so install Chromium explicitly just as
# `.github/workflows/ci.yml` does.
# need Chromium can stay on a deterministic frozen `pnpm install`. This
# release workflow runs the full Linux quality bar, so install Chromium
# explicitly just as `.github/workflows/ci.yml` does.
- name: Install Playwright Chromium
run: npx playwright install chromium

Expand Down
3 changes: 2 additions & 1 deletion .mux/init
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ if [ -f "$_mux_mise_config" ]; then
fi

"$_mux_mise_bin" install
"$_mux_mise_bin" exec -- aube exec playwright install chromium
"$_mux_mise_bin" exec -- pnpm install
"$_mux_mise_bin" exec -- pnpm exec playwright install chromium

unset _mux_mise_bin
unset _mux_mise_config
2 changes: 1 addition & 1 deletion .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"dist",
"node_modules",
"package-lock.json",
"aube-lock.yaml",
"pnpm-lock.yaml",
"dogfood/agent-uses-agent-tty/README.md",
"dogfood/agent-uses-agent-tty/promoted-run-summary.md",
"dogfood/agent-uses-agent-tty/manifest.json",
Expand Down
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,18 @@ Important implications:

# Essential commands

Preferred setup uses `mise`; fall back to direct `aube` only when necessary.
Preferred setup uses `mise`; fall back to direct `pnpm` only when necessary.

```sh
mise install
mise run bootstrap
```

If `mise` is unavailable but `aube` is available:
If `mise` is unavailable, install pnpm 10 (`npm install -g pnpm@10`). It switches to the version that `packageManager` in `package.json` pins. Newer pnpm majors can refuse that pin, so do not use them here. Then run:

```sh
aube exec playwright install chromium
pnpm install
pnpm exec playwright install chromium
```

Core commands:
Expand Down
5 changes: 3 additions & 2 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ mise install
mise run bootstrap
```

Fallback setup after installing `aube` directly:
Fallback setup without mise: install pnpm 10 from npm (`npm install -g pnpm@10`). It switches to the version that the `packageManager` field of `package.json` pins, and its npm build bundles the `node-gyp` that `node-pty` needs on Linux. Newer pnpm majors can refuse that pin, so do not use them here. Then run:

```bash
aube exec playwright install chromium
pnpm install
pnpm exec playwright install chromium
```

## Day-to-day workflow
Expand Down
2 changes: 1 addition & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ When you need a deterministic local artifact before publishing a GitHub Release,

```bash
TARBALL_DIR=$(mktemp -d)
aube ci
pnpm install --frozen-lockfile
npm run pack:private -- --pack-destination "$TARBALL_DIR"

INSTALL_PREFIX=$(mktemp -d)
Expand Down
2 changes: 1 addition & 1 deletion docs/adr/0009-release-please-with-communique-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Decisions inside that frame:
- **`[Unreleased]` stays, as Communique's anchor and draft inbox.** Communique hard-requires the heading and reconciles any hand-staged draft body into the notes it generates. Release-please's stock Changelog updater would insert new sections _above_ that heading (its insertion regex matches `## [Unreleased]`), so a custom updater — wired in by re-registering the `node` release type with a small strategy subclass — inserts the release section below the anchor and clears the reconciled draft so it cannot leak into later releases. The two workflows that maintained/consumed the old heading pair are still retired; the release PR remains the authoritative unreleased view.
- **Version bumps from Conventional Commits** with `bump-minor-pre-major` + `bump-patch-for-minor-pre-major`, matching the project's pre-1.0 history (breaking → minor, feat/fix → patch); `Release-As` footers override.
- **Tags and releases are created non-draft** by the runner, which then dispatches the existing `release.yml` by tag input — tags created with the workflow token never fire `push: tags` triggers, and the repo already uses explicit `gh workflow run` dispatch for exactly this class of problem (CI on bot branches). `release.yml` keeps quality gates, the verified tarball, editorial Communique notes, assets, and npm trusted publishing unchanged; it briefly leaves the Release with changelog-style notes and no assets until it completes.
- **release-please is a pinned devDependency** installed by the normal `aube ci` bootstrap. Its CJS-only octokit 9.x line carries no npm provenance attestations, so `@octokit/endpoint@9.0.6` is excluded from aube's trust policy in `pnpm-workspace.yaml` with justification.
- **release-please is a pinned devDependency** installed by the normal frozen `pnpm install` bootstrap. Its CJS-only octokit 9.x line carries no npm provenance attestations, so `@octokit/endpoint@9.0.6` is excluded from the package manager's trust policy in `pnpm-workspace.yaml` with justification.

## Consequences

Expand Down
38 changes: 4 additions & 34 deletions mise.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions mise.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
[tools]
actionlint = "1.7.12"
aube = "1.10.4"
communique = "1.1.3"
jq = "1.8.1"
node = "26"
# The npm build of pnpm bundles node-gyp, which node-pty needs on Linux (it
# ships no Linux prebuilds). The standalone binary (`pnpm = ...`) does not.
# Stay on pnpm 10 until Dependabot's pnpm 11+ support settles.
"npm:pnpm" = "10.34.5"
python = "3"
tmux = "3.6a"
# VHS needs ttyd, but ttyd ships no macOS binary, so it's Linux/CI-only here.
Expand All @@ -14,11 +17,11 @@ zizmor = "1.25.2"

[tasks.bootstrap]
description = "Install deps and Chromium for local development"
run = "aube exec playwright install chromium"
run = "pnpm install && pnpm exec playwright install chromium"

[tasks.bootstrap-ci]
description = "Install deps for CI without browser downloads"
run = "aube ci"
run = "pnpm install --frozen-lockfile"

[tasks.clean]
description = "Clean artifacts"
Expand Down Expand Up @@ -129,7 +132,7 @@ sources = [

[tasks.audit]
description = "Fail on high-severity dependency advisories"
run = "aube audit --audit-level high"
run = "pnpm audit --audit-level high"

[tasks.format]
description = "Format"
Expand Down Expand Up @@ -201,3 +204,6 @@ run = "mise run format-check && mise run workflow-lint && mise run lint && mise

[settings]
lockfile = true
# Install npm-backend tools (pnpm) with npm itself, not whichever package
# manager mise auto-detects on the host.
npm.package_manager = "npm"
42 changes: 21 additions & 21 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"url": "git+https://github.com/coder/agent-tty.git"
},
"type": "module",
"packageManager": "aube@1.2.0",
"packageManager": "pnpm@10.34.5",
"engines": {
"node": ">=24.0.0 <27"
},
Expand Down Expand Up @@ -90,26 +90,26 @@
"@coder/libghostty-vt-node": "0.1.0-beta.7"
},
"pnpm": {
"allowBuilds": {
"@coder/libghostty-vt-node": true,
"esbuild": true,
"fsevents": true,
"node-pty": true,
"@parcel/watcher": true,
"msgpackr-extract": true
"onlyBuiltDependencies": [
"@coder/libghostty-vt-node",
"esbuild",
"fsevents",
"msgpackr-extract",
"node-pty",
"@parcel/watcher"
],
"overrides": {
"@xmldom/xmldom": "0.8.15",
"brace-expansion": "5.0.11",
"esbuild": "0.28.1",
"handlebars": "4.7.10",
"js-yaml": "4.3.2",
"nanoid": "3.3.18",
"postcss": "8.5.18",
"source-map-js": "1.2.2",
"tinypool": "2.1.2",
"vite": "8.1.6",
"ws": "8.21.0"
}
},
"overrides": {
"@xmldom/xmldom": "0.8.15",
"brace-expansion": "5.0.11",
"esbuild": "0.28.1",
"handlebars": "4.7.10",
"js-yaml": "4.3.2",
"nanoid": "3.3.18",
"postcss": "8.5.18",
"source-map-js": "1.2.2",
"tinypool": "2.1.2",
"vite": "8.1.6",
"ws": "8.21.0"
}
}
Loading
Loading