Skip to content
Open
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
40 changes: 38 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -290,10 +290,44 @@ jobs:
retention-days: 7
overwrite: true

acp_lifecycle_smoke:
if: ${{ always() && !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.rehearsal == 'main-nontag' || inputs.rehearsal == 'nightly-release') && needs.main_plan.outputs.has_tasks == 'true' && needs.main_native.result != 'failure' && needs.main_native.result != 'cancelled' }}
needs: [main_plan, main_native]
runs-on: ubuntu-22.04
timeout-minutes: 15
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: "24"
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2
with:
bun-version: "1.3.14"
- name: Cache bun dependencies
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: ~/.bun/install/cache
key: bun-1.3.14-${{ runner.os }}-${{ hashFiles('**/bun.lock') }}
- run: bun install --frozen-lockfile
- name: Download native addon(s)
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: main-native-${{ github.run_id }}
path: packages/natives/native
- name: Run ACP lifecycle smoke
# bunfig `[test] pathIgnorePatterns` keeps this out of the default suite, and
# naming the path does NOT re-include it: `bun test <path>` filters files that
# were already discovered, so a pruned file never matches. Overriding the list
# is the only way in. The canonical argv — which restates every repository
# ignore pattern so the override does not widen discovery — lives in
# ci-dev-affected.ts (BUN_TEST_IGNORE_OVERRIDES / dedicatedTestCommand), so
# this job invokes the planner task instead of duplicating the pattern list.
run: bun scripts/ci-dev-affected.ts --task=acp-lifecycle-smoke

# Branch protection must keep requiring this stable aggregate status.
test:
if: ${{ always() && !startsWith(github.ref, 'refs/tags/v') && (github.event_name != 'workflow_dispatch' || inputs.rehearsal == 'main-nontag' || inputs.rehearsal == 'nightly-release') }}
needs: [main_plan, main_native, main_shards, acp_conformance]
needs: [main_plan, main_native, main_shards, acp_conformance, acp_lifecycle_smoke]
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
Expand All @@ -303,11 +337,13 @@ jobs:
native='${{ needs.main_native.result }}'
shards='${{ needs.main_shards.result }}'
conformance='${{ needs.acp_conformance.result }}'
echo "main_plan=$plan main_native=$native main_shards=$shards acp_conformance=$conformance"
lifecycle='${{ needs.acp_lifecycle_smoke.result }}'
echo "main_plan=$plan main_native=$native main_shards=$shards acp_conformance=$conformance acp_lifecycle_smoke=$lifecycle"
test "$plan" = success
case "$native" in success|skipped) ;; *) echo "native gate failed"; exit 1;; esac
test "$shards" = success
test "$conformance" = success
test "$lifecycle" = success

nightly_gate:
if: ${{ always() && (github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.rehearsal == 'nightly-release')) }}
Expand Down
7 changes: 7 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ pathIgnorePatterns = [
"**/node_modules/**",
".wt/**",
".worktrees/**",
# Spawns a broker plus a session host per run and costs tens of seconds, so it
# stays out of the default suite. Naming the path on the command line does NOT
# re-include it -- `bun test <path>` is a filter over already-discovered files,
# so a pruned file can never match. The only way to run it is the canonical
# dedicated argv (ci-dev-affected.ts BUN_TEST_IGNORE_OVERRIDES override), which
# the planner emits; the fresh-process shard inventory also excludes it.
"**/test/acp/acp-lifecycle-smoke.test.ts",
]

[run]
Expand Down
1 change: 1 addition & 0 deletions packages/coding-agent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
### Added
- Added implicit discovery and keyless local support for oMLX (`http://127.0.0.1:8080/v1`) with `OMLX_BASE_URL` and `OMLX_API_KEY` configuration.

- ACP session lifecycle (`session/list`, `fork`, `resume`, `close`, `delete`) is now gated in CI. `initialize` advertised all five capabilities to every ACP client and all five worked, but the pinned upstream `acp-core-v1` corpus contains 21 cases and exercised none of them, so the advertised surface had no release-gate coverage. A new stdio smoke test drives the credential-free conformance fixture and asserts the five happy paths, that a forked session id is distinct from its source, that `session/list` returns the created session under `cwd` filtering, and that duplicate `close` is idempotent. Because it spawns a broker plus a session host it is a *dedicated-only* test: `bunfig.toml` prunes it from default `bun test` discovery, the fresh-process shard inventory excludes it (`DEDICATED_ONLY_TESTS`), and exactly one canonical argv — the full ignore-list override from `ci-dev-affected.ts` `BUN_TEST_IGNORE_OVERRIDES` — runs it. The planner routes every path: PR-mode targeted plans emit `test:<path>` with that override, Main CI's full plan emits the `acp-lifecycle-smoke` task, the `acp_lifecycle_smoke` CI job invokes the planner task, and the aggregate `test` job fails closed unless it succeeds. A bunfig prune removes a file from *discovery*, so plain `bun test <path>` — a filter over already-discovered files — can never run a pruned file; any caller that schedules it without the override fails deterministically, which is what both initial CI failures were. Duplicate `close` intentionally pins the already-closed no-op, but the unknown-session *error* shape is deliberately left unasserted: `resume`/`prompt` reject unknown ids with `-32603` while `close`/`delete` no-op on unowned ones (`AcpAgent.closeSession` gates on connection ownership), and whether that asymmetry and that error code are correct is a separately filed open question.
- Gajae Pet now renders in iTerm2 through a bounded inline GIF protected from ordinary TUI redraws by a reserved raster lease, with the same composer-side layout and lifecycle cleanup guarantees used by Kitty and Sixel.
- Added the bundled `ouroboros` dark theme, translating the official navy, teal, green, and gold identity into terminal-safe semantic colors while retaining the pet's vivid `#AEE80E` lime and `#7092BE` cool-scale accents. Live previews now recolor the open `/theme` selector and Settings theme submenu instead of leaving their construction-time theme visible, and confirmation consistently settles the preview into the active appearance mapping.
- Added the 16×16 `Ouroboros` terminal pet: a vivid lime snake with a cool `#7092BE` underside that rests in a soft coil, blinks, flicks its tongue upward, and occasionally sobs with `><` eyes. Its signature flex rolls the same silhouette through a symmetric circle into an exact 180-degree heart pose, blinks a small pink heart twice, and reuses the authored frames in reverse; agent work enters and exits a stable six-frame infinity loop through explicit unwind transitions. Pet skins now own their frame registry, source resolution, idle loop, work transitions, work loop, and signature burst; a saved skin removed by a later installation falls back to RedGajae while an explicit `off` remains off.
Expand Down
Loading
Loading