Skip to content

chore(acp): bump codebuddy and dimcode registry pins to probed versions - #931

Merged
kaizhou-lab merged 2 commits into
mainfrom
chore/acp-lock-sync-20260825
Aug 24, 2026
Merged

chore(acp): bump codebuddy and dimcode registry pins to probed versions#931
kaizhou-lab merged 2 commits into
mainfrom
chore/acp-lock-sync-20260825

Conversation

@kaizhou-lab

Copy link
Copy Markdown
Contributor

Summary

Scheduled ACP Registry version sync. Two npx pins drifted since #921, each backed by a fresh serial ACP probe of the exact pinned version. The diff is the lock file plus the one lock-derived test assertion that embeds codebuddy's version.

backend package old → new initialize session/new
codebuddy @tencent-ai/codebuddy-code 2.137.1 → 2.138.0 ok (protocolVersion 1) auth required (-32000, category auth)
dimcode dimcode 0.3.18 → 0.3.19 ok (agentInfo version 0.3.19) auth required (-32000, "Provider credentials are required")

Both meet the release-lock criterion: initialize succeeds and session/new returns a clearly classified authentication requirement. Probes ran serially with no inherited HOME or credentials. codebuddy's --acp entrypoint is unchanged across the minor bump.

Derived assertion updated: registry_npx_lock.rs pins codebuddy's exact version inside a --package-form argument list, so it moves with the lock — 2.137.12.138.0. This is the same assertion that broke CI in #909 when a package-name regex missed it; the per-version scan introduced afterwards (grep each OUTGOING version across crates/**/*.rs) caught it before push this time. dimcode's 0.3.18 has no such assertion. npx_cache_repair.rs keeps its own version literals: those are cache-path hash fixtures, not lock assertions, and changing them would break their hash expectations.

The other 9 Registry-pinned packages (autohand, deepagents, dirac, glm-acp-agent, grok, kilo, nova, pi, sigit) match the snapshot exactly. Package names and entrypoint args are unchanged for all 11. Drifted but not upgraded: none. mimo-code remains the one non-Registry builtin (no registry_json_id), excluded from drift reconciliation.

dimcode continues to self-report agentInfo.title as "DimAgent" against a public listing that says "DimCode" — the standing observation since #814; no metadata change.

Registry snapshot

  • Audit pinned to release tag v2026.08.24-06dfed0 of agentclientprotocol/registry, fetched via the versioned CDN path for reproducibility.
  • No newly listed and no delisted agents versus the 39-id baseline (which includes antigravity-acp, deferred as binary-only since 2026-08-21).

Validation

  • just migration-check — pass
  • just lint-fix (cargo fix + clippy --fix --workspace -D warnings) — clean
  • just fmt — clean
  • Local cargo nextest intentionally skipped, by standing policy for lock-only bumps (established 2026-08-11). The Test check on this PR is the authority for this change: the merge decision depends on CI rather than the local run, and this host's load only manufactures timeout-shaped test failures, which nothing in the local steps above is subject to.

Logging

No logging changes: lock version bumps plus one test assertion; existing startup/session error paths already identify a failing agent by backend.

@kaizhou-lab
kaizhou-lab merged commit 9608137 into main Aug 24, 2026
6 checks passed
@kaizhou-lab
kaizhou-lab deleted the chore/acp-lock-sync-20260825 branch August 24, 2026 17:24
kaizhou-lab added a commit that referenced this pull request Aug 25, 2026
…obed versions (#934)

## Summary

Scheduled ACP Registry version sync. Four npx pins drifted since #931,
each backed by a fresh serial ACP probe of the exact pinned version. The
diff is the lock file plus the one lock-derived test assertion that
embeds codebuddy's version.

| backend | package | old → new | initialize | session/new |
|---|---|---|---|---|
| codebuddy | `@tencent-ai/codebuddy-code` | 2.138.0 → **2.139.0** | ok
(protocolVersion 1) | auth required (`-32000`, `data.category: auth`) |
| dimcode | `dimcode` | 0.3.19 → **0.3.20** | ok (agentInfo version
0.3.20) | auth required (`-32000`, "Provider credentials are required")
|
| glm-acp-agent | `glm-acp-agent` | 1.6.0 → **1.6.1** | ok
(protocolVersion 1) | **succeeded** unauthenticated |
| grok | `@xai-official/grok` | 1.0.8 → **1.0.10** | ok (protocolVersion
1) | auth required (`-32000`, "no auth method id provided") |

All four meet the release-lock criterion: `initialize` succeeds, and
`session/new` either succeeds or returns a clearly classified
authentication requirement. Probes ran serially with no inherited HOME
or credentials.

glm-acp-agent's session opened without auth and advertised
`thought_level`, `mode`, and `model` option categories, including a
`bypass_permissions` mode value. That is recorded as probe evidence only
— this PR changes no metadata, so no `yolo_id` or mode data is derived
from it. It also continues to self-report `agentInfo.version` as `1.0.0`
while the package is 1.6.1; a standing vendor quirk, not an AionCore
defect.

**Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's
exact version inside a `--package`-form argument list, so it moves with
the lock — `2.138.0` → `2.139.0`. Every outgoing version (`2.138.0`,
`0.3.19`, `1.6.0`, `1.0.8`) was grepped across `crates/**/*.rs` before
committing; codebuddy's was the only real assertion, and the remaining
textual matches are unrelated (a codex sample path, a Windows socket
error code). `npx_cache_repair.rs` keeps its own version literals: those
are cache-path hash fixtures, not lock assertions, and changing them
would break their hash expectations.

The other 7 Registry-pinned packages (autohand, deepagents, dirac, kilo,
nova, pi, sigit) match the snapshot exactly. Package names and
entrypoint args are unchanged for all 11. Drifted but not upgraded:
none. `mimo-code` remains the one non-Registry builtin (no
`registry_json_id`), excluded from drift reconciliation.

## Registry snapshot

- Audit pinned to release tag
[`v2026.08.25-fbfe844`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.25-fbfe844/registry.json)
of `agentclientprotocol/registry`, fetched via the versioned CDN path
for reproducibility.
- 39 ids in the snapshot: no newly listed and no delisted agents versus
the baseline. (`antigravity-acp` remains listed and deferred as
binary-only since 2026-08-21; `fast-agent` and `minion-code` remain
listed but uvx-only and therefore out of scope.)

## Validation

- `just migration-check` — pass
- `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`)
— clean
- `just fmt` — clean
- **Local `cargo nextest` intentionally skipped, by standing policy for
lock-only bumps** (established 2026-08-11). The Test check on this PR is
the authority for this change: the merge decision depends on CI rather
than the local run, and this host's load only manufactures
timeout-shaped test failures, which nothing in the local steps above is
subject to.

## Logging

No logging changes: lock version bumps plus one test assertion; existing
startup/session error paths already identify a failing agent by backend.

Co-authored-by: zk <>
acetaxxxx added a commit to acetaxxxx/AionCore that referenced this pull request Sep 7, 2026
* feat(auth): dual-token refresh with singleflight (#926)

## Background & goal

Root-cause groundwork for iOfficeAI/AionUi#4124: on the remote WebUI
(phone browser) the session token expires and never refreshes, trapping
the client in a 401/reconnect loop. This is **PR-1, the server-side
foundation** of a phased dual-token refresh.

The access-token TTL intentionally **stays 30d** in this PR. Shortening
it before the frontend can auto-refresh would turn "expires once" into
"forced logout every few hours", so the shortening lands last (PR-3),
after frontend/mobile consumption (PR-2) ships.

## Changes

- **Dual-token model**: short-lived access token + long-lived refresh
token, distinguished by an explicit `token_type` JWT claim (stateless
HS256). The refresh token rides an HttpOnly cookie scoped to the refresh
endpoint (browser) or the request body (native clients).
- **Refresh endpoint**: reads the refresh token from the HttpOnly cookie
first, falling back to the request body (native); every issue point now
emits both access + refresh tokens; the JSON response returns the new
access token **and** the rotated refresh token.
- **Refresh-storm singleflight**: concurrent refreshes presenting the
*same* refresh token coalesce into a single execution.
- Key = the full token string (a hash could collide, which here is a
security defect: credential cross-contamination, not just a perf loss).
- Success and failure both coalesce (the whole `Result` is stored via
`get_or_init`), so a storming refresh hits the backend once, not once
per caller.
- Failure is not cached across bursts (retryable); no lock is held
across the await.

## Review fixes (this round)

- The refresh JSON now returns the rotated `refresh_token`, so native
clients can migrate to dual-token.
- The failure path is truly singleflight (`get_or_try_init` ->
`get_or_init`): concurrent failures share one execution instead of
re-running serially.
- New test modules extracted to `*_test.rs` per workspace rules.
- Internal errors are logged via `tracing::error` + a static reason
string (no `format!` detail leak).

## Verification

- `cargo fmt --all --check` clean; `cargo clippy --workspace -D
warnings` clean.
- Workspace full test: **9225 passed, 0 failed**.
- New coverage: singleflight (5 tests, incl. a
concurrent-failure-coalescing regression guard), refresh response
carries both tokens, WS / session-generation auth cases.

## Out of scope (by design)

- Access-TTL shortening -> PR-3 (last, to avoid amplifying #4124).
- Frontend + mobile consumption of the refresh flow -> PR-2.

* chore(acp): bump codebuddy, dimcode, glm and grok registry pins to probed versions (#934)

## Summary

Scheduled ACP Registry version sync. Four npx pins drifted since #931,
each backed by a fresh serial ACP probe of the exact pinned version. The
diff is the lock file plus the one lock-derived test assertion that
embeds codebuddy's version.

| backend | package | old → new | initialize | session/new |
|---|---|---|---|---|
| codebuddy | `@tencent-ai/codebuddy-code` | 2.138.0 → **2.139.0** | ok
(protocolVersion 1) | auth required (`-32000`, `data.category: auth`) |
| dimcode | `dimcode` | 0.3.19 → **0.3.20** | ok (agentInfo version
0.3.20) | auth required (`-32000`, "Provider credentials are required")
|
| glm-acp-agent | `glm-acp-agent` | 1.6.0 → **1.6.1** | ok
(protocolVersion 1) | **succeeded** unauthenticated |
| grok | `@xai-official/grok` | 1.0.8 → **1.0.10** | ok (protocolVersion
1) | auth required (`-32000`, "no auth method id provided") |

All four meet the release-lock criterion: `initialize` succeeds, and
`session/new` either succeeds or returns a clearly classified
authentication requirement. Probes ran serially with no inherited HOME
or credentials.

glm-acp-agent's session opened without auth and advertised
`thought_level`, `mode`, and `model` option categories, including a
`bypass_permissions` mode value. That is recorded as probe evidence only
— this PR changes no metadata, so no `yolo_id` or mode data is derived
from it. It also continues to self-report `agentInfo.version` as `1.0.0`
while the package is 1.6.1; a standing vendor quirk, not an AionCore
defect.

**Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's
exact version inside a `--package`-form argument list, so it moves with
the lock — `2.138.0` → `2.139.0`. Every outgoing version (`2.138.0`,
`0.3.19`, `1.6.0`, `1.0.8`) was grepped across `crates/**/*.rs` before
committing; codebuddy's was the only real assertion, and the remaining
textual matches are unrelated (a codex sample path, a Windows socket
error code). `npx_cache_repair.rs` keeps its own version literals: those
are cache-path hash fixtures, not lock assertions, and changing them
would break their hash expectations.

The other 7 Registry-pinned packages (autohand, deepagents, dirac, kilo,
nova, pi, sigit) match the snapshot exactly. Package names and
entrypoint args are unchanged for all 11. Drifted but not upgraded:
none. `mimo-code` remains the one non-Registry builtin (no
`registry_json_id`), excluded from drift reconciliation.

## Registry snapshot

- Audit pinned to release tag
[`v2026.08.25-fbfe844`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.25-fbfe844/registry.json)
of `agentclientprotocol/registry`, fetched via the versioned CDN path
for reproducibility.
- 39 ids in the snapshot: no newly listed and no delisted agents versus
the baseline. (`antigravity-acp` remains listed and deferred as
binary-only since 2026-08-21; `fast-agent` and `minion-code` remain
listed but uvx-only and therefore out of scope.)

## Validation

- `just migration-check` — pass
- `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`)
— clean
- `just fmt` — clean
- **Local `cargo nextest` intentionally skipped, by standing policy for
lock-only bumps** (established 2026-08-11). The Test check on this PR is
the authority for this change: the merge decision depends on CI rather
than the local run, and this host's load only manufactures
timeout-shaped test failures, which nothing in the local steps above is
subject to.

## Logging

No logging changes: lock version bumps plus one test assertion; existing
startup/session error paths already identify a failing agent by backend.

Co-authored-by: zk <>

* chore(cli-version): verify agy against 1.1.20 (#935)

Moves `VERIFIED_AGY_VERSION` from 1.1.19 to 1.1.20.

| Gate | Result |
| --- | --- |
| A — contract | DEGRADED — agy publishes no protocol schema; gate B
carries the weight |
| B — live e2e | **PASS 7/7**, 171.02s |
| C — release notes | **CLEAR** — read from `agy changelog` on the
candidate binary |

## What supports this bump

Gate B, 7/7 against a manifest-downloaded 1.1.20 whose sha512 was
checked before it ran. The suite log reports only `version=1.1.20`, so
it cannot be a green against a different binary.

Gate C read from `agy changelog` on the candidate itself, captured as
`changelog-from-cli.txt`. The rendered web page is no longer the source
— it has been frozen at 1.1.17 since 2026-08-22.

## A retracted A/B

1.1.20’s notes say print mode stopped "treating benign tool execution
errors and permission denials as fatal run failures". We drive that
surface and deny tools routinely, so an A/B was attempted against what
was believed to be a retained 1.1.19 binary. **That attribution does not
hold, and the comparison is retracted.**

The two runs did differ — `result.status` was `ERROR` in one and
`SUCCESS` in the other — but the "1.1.19" binary rewrote itself
mid-probe. Its mtime is `02:02:48`, the probe ran at `02:02`, and its
size is now byte-for-byte 1.1.20’s:

```
/tmp/agy-1.1.18   mtime=08:47:56  size=177913904  ver=1.1.18   <- untouched
/tmp/agy-1.1.19   mtime=02:02:48  size=179469984  ver=1.1.20   <- self-updated during the probe
/tmp/agy-1.1.20   mtime=08:26:49  size=179469984  ver=1.1.20
```

**agy self-updates any copy of itself that is executed**, including one
in a temp directory under a version-named path. The path name is not a
pin. So the `ERROR` may be 1.1.19’s behaviour or an artifact of a binary
being rewritten under a running process, and nothing here separates
them. It is not repeatable either: the manifest now serves 1.1.20 and no
1.1.19 binary exists here or on npm.

Both captures are kept in the record as
`probe-benign-tool-error-run-{a,b}.ndjson`, renamed off their misleading
version labels.

## What is verified, by reading rather than by probe

`translate.rs:80-86` maps the terminal frame, so a `result.status` other
than `SUCCESS` becomes a failed turn for the user whatever emits it:

```rust
let is_error = !r.status.eq_ignore_ascii_case("SUCCESS");
match status {
    "SUCCESS"     => TurnOutcome::EndTurn,
    "INTERRUPTED" => TurnOutcome::Cancelled { .. },
    _             => TurnOutcome::Failed,
}
```

And the exit code the note talks about is **not** our channel:
`conn.rs:805` consults it only when no terminal frame arrived (`if
!saw_terminal`), and `result` was emitted in both runs.

## The other permission note does not reach us

> Improved permission management by automatically granting
workspace-scoped read access **under the default review mode**…

We never run in that mode: `build_argv` always passes
`--dangerously-skip-permissions` (`argv.rs:76`), because agy cannot
prompt headlessly, and AionUi gates each call in its own PreToolUse hook
bridge. *Stated limit:* gate B does not exercise that bridge — its only
permission test is claude’s — so this rests on the argv and the CLI’s
own scoping, not on a live run.

## Flag surface

`--help` 1.1.19 → 1.1.20 adds `mic-serve` and removes nothing; `models
--help` is unchanged; all nine flags `build_argv` emits are still
present.

## Tests

Pinned assertions moved with the constant, including the literal
verified-release case. `cargo test -p aionui-session --lib cli_version`:
14/14. Clippy clean, fmt clean.

Record: `~/aion/protocols/samples/antigravity-cli/1.1.20/`

Constants and record only — no source change.

Co-authored-by: zk <>

* feat(skills)!: deliver skills through an AionUi-owned view instead of the workspace (#938)

## Summary

Reworks how a conversation's skills are delivered to an agent CLI.
Previously AionUi materialized skill symlinks (`.claude/skills/` and
friends) **inside the conversation's working directory**, which may be a
user's git repository. This branch moves the symlink landing site into
an AionUi-owned directory and delivers it to each vendor through the
most native mechanism that vendor supports, falling back to prompt
injection.

## What changed

**Skill view directory (AionUi-owned).** Skill symlinks now land under
an AionUi-managed per-conversation directory instead of the working
directory. Because AionUi owns this tree, rebuilds are an exact match
against the enabled-skill snapshot (a dropped skill actually disappears)
and cleanup is safe. There is deliberately no copy fallback: a failed
link is skipped with a warning rather than materializing user files into
a disposable directory.

**Two-layer, per-vendor delivery.** A new `skill_delivery` column on
`agent_metadata` (JSON, migration `043`) declares how each vendor
receives skills:
- **Layer 1 — native.** `argv` hands the view directory to the CLI via
launch arguments (claude `--plugin-dir` + `--add-dir`); `protocol`
registers it over the wire (codex `skills/extraRoots/set`).
- **Layer 2 — injected (safe default).** A truncated skill index plus
two on-demand load channels is injected into the prompt. This is what a
`NULL` column reads as, so an unprobed vendor is zero-intrusion by
default and needs no migration to work.

The column intentionally has **no CHECK constraint**: shipping a new
vendor capability should be a data change, not a migration + release.
Validation lives in the application layer and is tolerant — an unknown
mode warns and degrades to `injected`.

**Two on-demand load channels for injected-mode vendors:**
- **Channel A** — a read-only `aioncore skills` CLI (`list` / `show` /
`cat` / `capabilities`) scoped to the current conversation,
authenticated with a session runtime token. A normal tool call instead
of a text round-trip.
- **Channel B** — the `[LOAD_SKILL: <name>]` text protocol as a fallback
for agents that cannot execute commands; the requested body is provided
on the next turn.

**Injection path for the non-ACP backends.** The two backends without a
prompt pipeline (Antigravity, aionrs) previously received skills only
through workspace links; with those removed they gained a dedicated
injection path so they keep their skills (and, for Antigravity, their
assistant preset context, which was being dropped entirely before).

**Breaking / behavior changes** (call out in release notes):
- Skills are no longer written into the working directory; historical
leftovers are not auto-cleaned.
- A custom agent's previously-set `native_skills_dirs` no longer affects
delivery (kept as historical metadata; such agents fall to `injected`,
skills still available).
- In claude sessions, skill names are surfaced with an `aionui:` prefix.

## Fixes made during dev-environment verification

Three defects were found while exercising the branch against real agent
CLIs and fixed here — none were caught by the pre-existing unit suite
because they only surface under real concurrency / real agent behavior:

- **`fix(skills): serialize the session skill view rebuild per
conversation`** — the view rebuild had no synchronization, and a first
turn rebuilds it three times within milliseconds. Concurrent rebuilds
interleaved destructively (observed: spurious "skills added" warnings,
wrong link counts, an `ENOTEMPTY` failure, and one session left missing
a skill for hours). Now serialized per conversation with an idempotent
early-return when the view already matches. Regression test drives
concurrent rebuilds and asserts on the converged result.
- **`fix(skills): teach channel A the invocation the CLI actually
accepts`** — the injected index taught `skills show <name>`, but the
subcommands read a JSON object from stdin and reject positional
arguments; `--help` also omitted the stdin contract. Live agents burned
several failed tool calls recovering. Corrected the injected text and
`--help`, and added a cross-crate test that parses every command line
the index teaches.
- **`docs(skills): record why aionrs stays off the shared delivery
decision`** — comment-only: documents that the in-process agent is
`injected`-only by architecture, so it deliberately does not route
through the shared delivery decision.

## Verification (dev environment, real agent CLIs)

Per-vendor behavior was first probed against specific real CLI versions
(recorded in the migration comments — e.g. the repeatable `--plugin-dir`
/ `--add-dir` paired probe for claude, the process-scoped `extraRoots`
schema for codex, the permission-mode measurement for Antigravity). This
branch then added live end-to-end verification, in two phases, with
evidence checked in logs / DB / prompt dumps rather than by assertion.

**Phase 1 — live run of the original branch (defects surfaced).**
Exercising the five delivery modes against real CLIs surfaced two
defects that the unit suite could not catch because they only appear
under real concurrency / real agent behavior:
- the view rebuild race (spurious warnings, wrong link counts, an
`ENOTEMPTY` failure, one session left missing a skill);
- the Channel A index teaching an invocation the CLI rejects (agents
burned several failed tool calls recovering).

Both were fixed in this branch (see the fixes section above).

**Phase 2 — end-to-end verification on the post-fix build (the state
this PR ships).** After rebuilding with all three fixes and confirming
the running binary contained them, the full set was re-run:
- **Workspace untouched (the goal of the refactor):** with a
git-repository working directory, no skill files are written to it; the
view directory is created under AionUi's own data instead.
- **All five delivery modes** resolve as declared: claude → `argv`,
codex → `protocol`, Antigravity / aionrs / opencode → `injected`;
migration applied cleanly and the per-vendor rows are correct.
- **Layer 1 usable, not just registered:** claude and codex agents see
and invoke the delivered skills and read their supplementary files.
Confirmed under a **non-full-auto** permission mode, not only under
bypass.
- **Injected lane:** the skill index reaches the agent, enabled skills
are listed, and Channel A (`list` / `show`) works end-to-end.
- **Channel B:** a `[LOAD_SKILL]` request is detected and the skill body
is injected on the next turn; the injected body is anchored with the
skill's absolute directory, so its relative references resolve to the
real skill files — verified against a deliberately planted same-named
file in the working directory, which was **not** read.
- **Antigravity preset context** now reaches the model (previously
dropped).
- **Concurrent sessions of the same protocol vendor** with different
enabled skill sets stay isolated — no cross-contamination — because each
conversation runs its own process with its own view root.
- **Fix re-check:** the previously-observed rebuild race symptoms no
longer appear, and Channel A succeeds on the first attempt.

Not covered: codebuddy (its `--plugin-dir` visibility could not be
confirmed without an authenticated account, so it is deliberately kept
on `injected`); the thinking-block variant of Channel B detection on a
backend that inlines think tags (this backend surfaces reasoning on a
separate channel, so that path is covered by an integration test rather
than live).

## Test plan

- [x] `cargo test` for the touched crates (extension / ai-agent / app /
conversation) — green
- [x] `cargo clippy -- -D warnings` on the touched crates — clean
- [x] `cargo fmt --all -- --check` — clean
- [x] Live end-to-end verification across all five backends (see above)
- [ ] Full `cargo test --workspace` via the pre-push gate

---------

Co-authored-by: zynx <>

* chore(cli-version): verify codex 0.150.1 and agy 1.1.22 (#939)

Two candidates, both through their gates against the real binaries.

| CLI | from → to | Gate A | Gate B | Gate C |
| --- | --- | --- | --- | --- |
| codex | 0.149.1 → **0.150.1** | **PASS** — 401 → 411 files,
`ServerNotification` 75 → 79, `ClientRequest` 150 → 153, nothing removed
| **PASS 11/11**, 679.80s | **CLEAR** — 220 notes over 2 releases, 0
REVIEW |
| agy | 1.1.20 → **1.1.22** | DEGRADED (no protocol schema) | **PASS
7/7**, 161.88s | **CLEAR** |

Both suites prove the candidate from their own logs — `version=codex-cli
0.150.1` and `version=1.1.22`, each with the drift lines that only
appear because the binary disagrees with the not-yet-bumped constant.
codex ran through an npm PATH shim; agy from a manifest download whose
sha512 was checked before it executed. Neither of the operator’s
installed CLIs was touched.

## agy: everything on our surface is a fix in our favour

- **"Fixed sessions stalling mid-response when a tool result or file
diff contained invalid UTF-8."** (1.1.21) — a stall is a hung turn for
our user, and print-mode sessions are what we run.
- **"Fixed transient HTTP 502 Bad Gateway errors terminating runs by
adding automatic retry handling with backoff."** (1.1.22) — a terminated
run reaches us as a failed turn.
- **"Fixed corrupted file edits in documents containing non-ASCII text…
producing invalid UTF-8."** (1.1.21) — same family as the U+FFFD delta
corruption #888 works around, different surface.
- **"Fixed file writes being reported as failures after successfully
saving to disk."** (1.1.21)

None changes a contract; each removes a way a turn could look broken.

**The one permission item does not reach us.** 1.1.21 improved the
`always-proceed` mode to auto-approve MCP tool calls, but `build_argv`
sends `--mode` only for `accept-edits` and `plan` and opens the gate
with `--dangerously-skip-permissions` (`argv.rs:76,107`), gating each
call in AionUi’s own PreToolUse hook bridge. *Stated limit:* gate B does
not exercise that bridge — its only permission test is claude’s — so
this rests on the argv we build, not on a live run.

`--help` and `models --help` are byte-identical 1.1.20 → 1.1.22, diffed
against the 08-26 capture rather than by re-running the 1.1.20 binary,
which would have self-updated it and destroyed the control.

## agy gate C came from the web page this time, and that is the news

Three days ago the web changelog was frozen at 1.1.17 while the binary’s
bundled `agy changelog` covered 1.1.19, so gate C switched to reading
the binary. **Tonight it is the other way round.** The 1.1.22 build is
genuine (size 179,586,688 vs 1.1.20’s 179,469,984) and its bundled
changelog **stops at 1.1.20** — no 1.1.21, no 1.1.22 — while the web
page has un-frozen and carries both.

The bundled copy is a snapshot from whenever that build was cut, not a
live document. Neither source is authoritative; both are checked from
now on, and the record says which one was used.

## codex

Gate A grew by 10 schema files and removed nothing. The only note
flagged in 220 was `Preserve sandbox errors during session
initialization` (#40381), which is additive error preservation. 0.147.0
remains deliberately skipped.

## Tests

Pinned fixtures for both CLIs moved with their constants — re-pointed
above the new values rather than loosened, and both literal
verified-release assertions now name the new releases. `cargo test -p
aionui-session --lib cli_version`: 14/14. Clippy clean, fmt clean.

## Follow-up, not included here

agy 1.1.21 now generates conversation titles automatically. Whether it
surfaces one on the print-mode wire, and whether we should consume it
instead of generating our own, is **not investigated** — a capability
question, and any change would be a source PR. No existing PR or issue
covers it (searched).

Records: `~/aion/protocols/samples/codex-cli/0.150.1/` and
`~/aion/protocols/samples/antigravity-cli/1.1.22/`

Constants and records only — no source change.

Co-authored-by: zk <>

* chore(acp): bump codebuddy, dimcode, dirac, grok and kilo registry pins to probed versions (#941)

## Summary

Scheduled ACP Registry version sync, covering two days of drift (the
2026-08-27 run did not execute; the state file's last checked tag was
`v2026.08.25-fbfe844`). Five npx pins drifted since #934, each backed by
a fresh serial ACP probe of the exact pinned version. The diff is the
lock file plus the one lock-derived test assertion that embeds
codebuddy's version.

| backend | package | old → new | initialize | session/new |
|---|---|---|---|---|
| codebuddy | `@tencent-ai/codebuddy-code` | 2.139.0 → **2.140.0** | ok
(protocolVersion 1) | auth required (`-32000`, `data.category: auth`) |
| dimcode | `dimcode` | 0.3.20 → **0.3.21** | ok (agentInfo version
0.3.21) | auth required (`-32000`, "Provider credentials are required")
|
| dirac | `dirac-cli` | 0.4.37 → **0.5.1** | ok (agentInfo dirac 0.5.1)
| **succeeded** unauthenticated |
| grok | `@xai-official/grok` | 1.0.10 → **1.0.12** | ok
(protocolVersion 1) | auth required (`-32000`, "no auth method id
provided") |
| kilo | `@kilocode/cli` | 7.4.23 → **7.5.5** | ok (agentInfo Kilo
7.5.5) | **succeeded** unauthenticated |

All five meet the release-lock criterion: `initialize` succeeds, and
`session/new` either succeeds or returns a clearly classified
authentication requirement. Probes ran serially with no inherited HOME
or credentials.

dirac is the one bump crossing a minor version (0.4.x → 0.5.x), so its
entrypoint was checked rather than assumed: the Registry distribution
still declares `dirac-cli` with `--acp`, and that exact invocation
completed `initialize` and opened a session advertising mode, model, and
thought_level options. kilo likewise opened a session on the new minor.
Neither session's catalog is persisted — per skill step 11 those columns
are runtime-filled — and no metadata changes ride along with this PR.

**Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's
exact version inside a `--package`-form argument list, so it moves with
the lock — `2.139.0` → `2.140.0`. Every outgoing version (`2.139.0`,
`0.3.20`, `0.4.37`, `1.0.10`, `7.4.23`) was grepped across
`crates/**/*.rs` before staging; codebuddy's was the only real
assertion. `npx_cache_repair.rs` keeps its own version literals: those
are cache-path hash fixtures, not lock assertions, and changing them
would break their hash expectations.

The other 6 Registry-pinned packages (autohand, deepagents,
glm-acp-agent, nova, pi, sigit) match the snapshot exactly. Package
names and entrypoint args are unchanged for all 11. Drifted but not
upgraded: none. `mimo-code` remains the one non-Registry builtin (no
`registry_json_id`), excluded from drift reconciliation.

## Registry snapshot

- Audit pinned to release tag
[`v2026.08.27-ae4dcc8`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.27-ae4dcc8/registry.json)
of `agentclientprotocol/registry`, fetched via the versioned CDN path
for reproducibility.
- 39 ids in the raw snapshot: no newly listed and no delisted agents
versus the baseline. (`antigravity-acp` remains listed and deferred as
binary-only since 2026-08-21; `fast-agent` and `minion-code` remain
listed but uvx-only and therefore out of scope.)

## Validation

- `just migration-check` — pass
- `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`)
— clean
- `just fmt` — clean
- **Local `cargo nextest` intentionally skipped, by standing policy for
lock-only bumps** (established 2026-08-11). The Test check on this PR is
the authority for this change: the merge decision depends on CI rather
than the local run, and this host's load only manufactures
timeout-shaped test failures, which nothing in the local steps above is
subject to.

## Logging

No logging changes: lock version bumps plus one test assertion; existing
startup/session error paths already identify a failing agent by backend.

Co-authored-by: zk <>

* chore(main): release 0.2.0 (#933)

:robot: I have created a release *beep* *boop*
---


##
[0.2.0](https://github.com/iOfficeAI/AionCore/compare/v0.1.72...v0.2.0)
(2026-08-28)


### ⚠ BREAKING CHANGES

* **skills:** deliver skills through an AionUi-owned view instead of the
workspace ([#938](https://github.com/iOfficeAI/AionCore/issues/938))

### Features

* **auth:** dual-token refresh with singleflight
([#926](https://github.com/iOfficeAI/AionCore/issues/926))
([3f5c9f9](https://github.com/iOfficeAI/AionCore/commit/3f5c9f900433dd846798a82353df03dfed8db697))
* **skills:** deliver skills through an AionUi-owned view instead of the
workspace ([#938](https://github.com/iOfficeAI/AionCore/issues/938))
([7032b3b](https://github.com/iOfficeAI/AionCore/commit/7032b3b410440c0081fb3cfe4a09f2ccfb2dd574))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* chore(acp): bump codebuddy and dimcode registry pins to probed versions (#943)

## Summary

Scheduled ACP Registry version sync. Two npx pins drifted since #941,
each backed by a fresh serial ACP probe of the exact pinned version. The
diff is the lock file plus the one lock-derived test assertion that
embeds codebuddy's version.

| backend | package | old → new | initialize | session/new |
|---|---|---|---|---|
| codebuddy | `@tencent-ai/codebuddy-code` | 2.140.0 → **2.141.0** | ok
(protocolVersion 1) | auth required (`-32000`, `data.category: auth`) |
| dimcode | `dimcode` | 0.3.21 → **0.3.22** | ok (agentInfo version
0.3.22) | auth required (`-32000`, "Provider credentials are required")
|

Both meet the release-lock criterion: `initialize` succeeds and
`session/new` returns a clearly classified authentication requirement.
Probes ran serially with no inherited HOME or credentials, and both
entrypoints (`--acp` for codebuddy, `acp` for dimcode) are unchanged
from the previous snapshot.

**Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's
exact version inside a `--package`-form argument list, so it moves with
the lock — `2.140.0` → `2.141.0`. Both outgoing versions were grepped
across `crates/**/*.rs` before staging: codebuddy's was the only real
assertion, and `0.3.21`'s single hit was a false positive (a `"003421"`
string literal in `pairing.rs`, matched because `.` is a regex
wildcard). `npx_cache_repair.rs` keeps its own version literals: those
are cache-path hash fixtures, not lock assertions, and changing them
would break their hash expectations.

The other 9 Registry-pinned packages (autohand, deepagents, dirac,
glm-acp-agent, grok, kilo, nova, pi, sigit) match the snapshot exactly.
Package names and entrypoint args are unchanged for all 11. Drifted but
not upgraded: none. `mimo-code` remains the one non-Registry builtin (no
`registry_json_id`), excluded from drift reconciliation.

dimcode continues to self-report `agentInfo.title` as "DimAgent" against
a public listing that says "DimCode" — a standing observation since
#814; no metadata change.

## Registry snapshot

- Audit pinned to release tag
[`v2026.08.28-e9b1b2d`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.28-e9b1b2d/registry.json)
of `agentclientprotocol/registry`, fetched via the versioned CDN path
for reproducibility.
- 39 ids in the raw snapshot: no newly listed and no delisted agents
versus the baseline. (`antigravity-acp` remains listed and deferred as
binary-only since 2026-08-21; `fast-agent` and `minion-code` remain
listed but uvx-only and therefore out of scope.)

## Validation

- `just migration-check` — pass
- `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`)
— clean
- `just fmt` — clean
- **Local `cargo nextest` intentionally skipped, by standing policy for
lock-only bumps** (established 2026-08-11). The Test check on this PR is
the authority for this change: the merge decision depends on CI rather
than the local run, and this host's load only manufactures
timeout-shaped test failures, which nothing in the local steps above is
subject to.

## Logging

No logging changes: lock version bumps plus one test assertion; existing
startup/session error paths already identify a failing agent by backend.

Co-authored-by: zk <>

* chore(cli-version): verify claude against 2.1.236 (#944)

Moves `VERIFIED_CLAUDE_VERSION` from 2.1.235 to 2.1.236, and
**discharges the hold placed on 2026-08-21**.

| Gate | Result |
| --- | --- |
| A — contract | DEGRADED — claude publishes no protocol schema; gate B
carries the weight |
| B — live e2e | **PASS 14/14**, 304.35s |
| C — release notes | **CLEAR** — 33 notes, 0 REVIEW |

## Why this one was stuck

The constant has been sitting **above** the stable channel for eight
days. An earlier version of the detector read npm’s `latest` tag, which
for `@anthropic-ai/claude-code` points at the bleeding edge rather than
the release most users run, so 2.1.235 was qualified off the `next`
channel. Once the detector was corrected to track `stable`, every
nightly run reported `drift: behind`, and the standing decision was to
hold the floor rather than walk it down — walking it down would have
flagged the majority of users (who install via `npm` or the native
installer, both ahead of stable) as `Newer`.

stable has now caught up and passed it, so the normal flow resumes:

```
stable: 2.1.236    next: 2.1.251    latest: 2.1.250
```

## The candidate is proven from the suite log

```
version=2.1.236 (Claude Code)
```

with the drift lines that only appear because the binary disagrees with
the not-yet-bumped constant. Run through an npm PATH shim into a temp
dir; `~/.local/bin/claude` was read before and after and did not move
off 2.1.239.

## Gate C

Both flagged notes are usage-credits UI — a Fable 5 first-run prompt
auto-selecting a fallback model under Remote Control, and a `/usage`
spend row for Team and Enterprise members. Neither is a surface this
repo drives.

## Also checked

The promotion condition this repo does not machine-check:
`THINKING_DISPLAY_MIN_VERSION` is `2.1.191` (`claude_flags.rs:34`),
comfortably below the new constant. So nobody on exactly the verified
release is told they match while thinking display is silently off.

## Tests

The literal verified-release assertion moves with the constant, so a
future bump that forgets to re-verify still breaks the test. `cargo test
-p aionui-session --lib cli_version`: 14/14. `cargo test -p
aionui-ai-agent --lib claude_flags`: 5/5. Clippy clean, fmt clean.

Record: `~/aion/protocols/samples/claude-cli/2.1.236/`

Constants and record only — no source change.

Co-authored-by: zk <>

* chore: remove accidentally committed .opencode symlinks (#948)

## What

Removes three tracked entries under `.opencode/skills/` that are
symlinks
pointing to a contributor's personal machine path:

```
.opencode/skills/cron          -> /Users/zhoukai/.aionui-dev/builtin-skills/auto-inject/cron
.opencode/skills/officecli     -> /Users/zhoukai/.aionui-dev/builtin-skills/auto-inject/officecli
.opencode/skills/skill-creator -> /Users/zhoukai/.aionui-dev/builtin-skills/auto-inject/skill-creator
```

## Why

- These are broken on every checkout except the original author's
machine — the
  targets live under `/Users/zhoukai/...`.
- `.opencode` is the opencode CLI's local working directory (same
category as
`.claude` / `.codex`). We do not use opencode routinely in this repo, so
it is
intentionally absent from `.gitignore` — just like `.codex`. Nothing to
guard,
  no `.gitignore` change needed.
- They slipped in via #758 (`f0422ca2`), which was unrelated to
`.opencode`.
  This is purely an accidental-commit cleanup.

## Scope

- `3 files changed, 3 deletions(-)` — symlink removals only, no code
impact.
- Verified AionUi is clean (no `.opencode` tracked, no history), so no
follow-up
  needed there.

Co-authored-by: zynx <>

* feat(conversation): route @@ mentions to the session-message skill (#949)

## What & why

Cross-session delivery could pick the wrong mechanism. The
`[[AION_SESSIONS]]` block that a `@@` mention appends to the user's
message deliberately carried no usage instructions, on the assumption
the agent would load the `session-message` skill before deciding how to
deliver. That assumption does not hold: a competing built-in
cross-session tool can be reached first, and in `Injected`
skill-delivery mode the skill body is lazy-loaded, so at tool-selection
time the routing guidance is not present. The result was delivery
attempts through the wrong tool until the skill was named explicitly.

## Change

- Emit one positive routing hint as the **first in-marker line** of the
`[[AION_SESSIONS]]` block, naming the `session-message` skill (address
by conversation id). It carries **no command template** — the skill body
stays the single source of the actual command, so the block and the
skill cannot drift. The hint has no tab, so the frontend drops it from
the sender's bubble and the chip parser skips it, while every agent
backend still receives it in the message content.
- Write the block's remaining **agent-facing** text in English, since
these bytes are read by the agent (the frontend strips the block and
renders human-facing labels separately via i18n): the sender-side and
recipient-side cross-workspace warnings and the reply pointer. This
keeps the whole block single-language and portable across agents.
- Update the skill doc example and the affected unit tests; add comments
recording that in-block text is agent-facing and therefore English.

## Verification (dev environment)

Exercised real `@@` cross-session sends and replies in the dev app, then
inspected the stored messages, the prompt dumps fed to each agent, and
the structured logs. Confirmed (local-only details omitted):

- The routing hint is emitted as the first in-marker line and reaches
the agent's actual input.
- Across all four agent backends (**codex, claude, opencode, aionrs**),
senders routed to the `session-message` skill and deliveries were
accepted, with no failures (no unreachable-target / reject /
rate-limit).
- Both skill-delivery modes were covered: **native (Argv)** — invoked
via the Skill tool; **injected** — skill body fetched via the `skills
show` channel.
- The English recipient-block text (cross-workspace warning, reply
pointer) appears in the delivered content, while the UI shows the
localized "different workspace" label; the hint and warning do not leak
into visible bubble text.

## Test plan

- [x] `cargo test -p aionui-conversation -p aionui-session-message`
- [x] `cargo fmt --all -- --check`
- [x] `cargo clippy -p aionui-conversation -p aionui-session-message --
-D warnings`
- [x] Full workspace pre-push gate via `just push`

Co-authored-by: zynx <>

* feat(session-message): add session capabilities fallback to @@ blocks (#952)

## Summary

Follow-up robustness hardening for the merged `@@` cross-session
delivery work (#949).

The `session-message` auto-inject skill can be unchecked by the user in
the assistant editor. When it is, the routing hint in the sender block
(`[[AION_SESSIONS]]`) and the reply pointer in the recipient block
(`[[AION_SESSION_MESSAGE]]`) lose their how-to — even though the
`session send-message` CLI always exists. This adds one
**unconditional** pointer to `session capabilities` in each block, so an
agent can fetch the self-describing delivery contract and complete
delivery even with the skill turned off. No "skill checked or not"
branching is introduced — the fallback is always emitted.

`session capabilities` is a descriptor-generated, self-describing
discovery command (not a payload template), so it cannot drift from the
wired CLI. This keeps the original convergence invariant intact: the
blocks still carry **no `send-message` payload command template**.

## What changed

- **Sender block** (`aionui-conversation/src/session_mentions.rs`): the
routing hint now ends with a fallback pointing at `session capabilities`
for the delivery contract.
- **Recipient block** (`aionui-session-message/src/service.rs`): a
`session capabilities` pointer is appended on its own line before the
end marker. It carries no `from:`/`workspace:`/`reply_to:` prefix and no
tab, so the frontend parser ignores it and the `reply_to` address parse
(which splits on the first tab) is unaffected.
- **Doc comments** updated on both block builders: agent-facing,
English, capabilities fallback, still no `send-message` payload
template.
- **Tests**: exact-shape and first-line assertions updated; the sender
invariant test renamed and refocused (still forbids a `send-message`
payload template, now asserts the capabilities pointer +
`$AIONUI_HELPER_BIN` are present); a new recipient test asserts the
capabilities line does not break `reply_to` parsing; the delivery
happy-path integration test asserts the pointer reaches the delivered
content.
- **`session_skill.rs` content guard**:
`the_skill_points_at_capabilities_only_as_a_fallback` now anchors on the
runnable, start-of-line commands (`session send-message` before `session
capabilities`) instead of bare substrings — the example blocks
legitimately quote `session capabilities` inline as a conditional
fallback, which is exactly the framing this guard is named for. The test
intent is unchanged; the check is more precise, not weaker.
- **`SKILL.md`** (builtin auto-inject skill): both example blocks and
the surrounding prose synced to match the real emitted output.

## Runtime Verification

Verified by the automated suite and in a dev environment.

**Automated:** full pre-push gate green — migration-immutability check,
workspace lint, format check, and the complete `cargo nextest` workspace
suite (all tests passed).

**Dev environment:** exercised real `@@` sends/replies and inspected the
stored messages and structured logs (local paths, conversation
ids/names, and model names omitted here).

- Both blocks carry the `session capabilities` pointer in real
deliveries, across all four agent backends (codex, claude, opencode,
aionrs).
- **Skill-off scenario — the case this change targets:** with
`session-message` disabled, a sender received the `@@` block, ran
`session capabilities` from the pointer, fetched the self-describing
contract (including the `send-message` input schema), and completed
delivery end-to-end. A control group with the skill enabled delivered
normally.
- All deliveries were accepted (`delivered`); no unreachable-target /
reject / rate-limit failures.
- The recipient-block pointer sits on its own line and did not perturb
`reply_to` address parsing.

## Notes

- `team` messaging is untouched: `team_send_message` is an MCP tool
whose usage is fixed in the team system prompt and is unaffected by this
skill toggle.

Co-authored-by: zynx <>

* fix(session-message): align recipient block capabilities wording with sender (#955)

## Summary

Wording-alignment follow-up to #952 (merged).

The recipient block (`[[AION_SESSION_MESSAGE]]`) pointed at `session
capabilities` unconditionally — *"For the full delivery contract, run
..."* — which reads as always-required. That could nudge a recipient
that already has the `session-message` skill into a needless `session
capabilities` round trip, and it clashed in tone with the sender block
and with the `the_skill_points_at_capabilities_only_as_a_fallback`
content guard, both of which frame capabilities strictly as a fallback.

This rewords the recipient line to match the sender block's conditional
framing:

> If the session-message skill is unavailable, run `"$AIONUI_HELPER_BIN"
session capabilities` for the full delivery contract.

The pointer is still **emitted unconditionally** (no skill-toggle
branch); only the phrasing changes. It stays on its own line with no
`from:`/`workspace:`/`reply_to:` prefix and no tab, so the frontend
parser still ignores it and `reply_to` address extraction is unchanged.

## What changed

- **`aionui-session-message/src/service.rs`**: recipient block line
reworded to the conditional/fallback framing; doc comment updated (still
notes the line is always emitted, UI-safe, and carries no `send-message`
payload template).
- **`service_test.rs`**: the exact-shape assertion and the
reply-to-safety assertion updated to the new text (the "line is always
present" semantics are unchanged).
- **`tests/delivery_semantics.rs`**: happy-path assertion updated to the
new text.
- **`SKILL.md`** (builtin auto-inject skill): recipient example block
synced.

Sender block, `team` messaging, and the `session_skill.rs` anchor guard
are untouched (the guard anchors on start-of-line runnable commands;
this inline mention doesn't affect it — verified by the full suite).

## Runtime Verification

Verified by the automated suite and confirmed in a dev environment.

**Automated:** full pre-push gate green — migration-immutability check,
workspace lint, format check, and the complete `cargo nextest` workspace
suite (9325 tests passed).

**Dev environment (latest build):** ran real `@@` sends/replies and
inspected the stored messages and structured logs (local paths,
conversation ids/names, and model names omitted here).

- The recipient block now emits the reworded conditional-fallback line,
and `reply_to` address parsing is unaffected.
- Real cross-session sends/replies across all four agent backends
(codex, claude, opencode, aionrs) were all accepted (`delivered`), with
no failures (no unreachable-target / reject / rate-limit).
- The skill-off fallback path remains functional: a recipient without
the `session-message` skill fetched the contract via `session
capabilities` and completed delivery end-to-end.

Co-authored-by: zynx <>

* chore(acp): bump codebuddy, dimcode, dirac, glm, grok and kilo registry pins to probed versions (#957)

## Summary

Scheduled ACP Registry version sync, covering three days of drift (the
2026-08-30 and 08-31 runs did not execute; the state file's last checked
tag was `v2026.08.28-e9b1b2d`). Six npx pins drifted since #943, each
backed by a fresh serial ACP probe of the exact pinned version. The diff
is the lock file plus the one lock-derived test assertion that embeds
codebuddy's version.

| backend | package | old → new | initialize | session/new |
|---|---|---|---|---|
| codebuddy | `@tencent-ai/codebuddy-code` | 2.141.0 → **2.142.0** | ok
(protocolVersion 1) | auth required (`-32000`, `data.category: auth`) |
| dimcode | `dimcode` | 0.3.22 → **0.3.25** | ok (agentInfo version
0.3.25) | auth required (`-32000`, "Provider credentials are required")
|
| dirac | `dirac-cli` | 0.5.1 → **0.5.2** | ok (agentInfo dirac 0.5.2) |
**succeeded** unauthenticated |
| glm-acp-agent | `glm-acp-agent` | 1.6.1 → **1.7.0** | ok
(protocolVersion 1) | **succeeded** unauthenticated |
| grok | `@xai-official/grok` | 1.0.12 → **1.0.13** | ok
(protocolVersion 1) | auth required (`-32000`, "no auth method id
provided") |
| kilo | `@kilocode/cli` | 7.5.5 → **7.5.6** | ok (agentInfo Kilo 7.5.6)
| **succeeded** unauthenticated |

All six meet the release-lock criterion: `initialize` succeeds, and
`session/new` either succeeds or returns a clearly classified
authentication requirement. Probes ran serially with no inherited HOME
or credentials, and every entrypoint is unchanged from the previous
snapshot.

glm-acp-agent is the one bump crossing a minor version (1.6.x → 1.7.0),
so its entrypoint was exercised rather than assumed: the Registry
distribution still declares a bare `glm-acp-agent` invocation with no
arguments, and that exact call completed `initialize` and opened a
session advertising thought_level, mode, and model options. It also
continues to self-report `agentInfo.version` as `1.0.0` while the
package is 1.7.0 — a standing vendor quirk, not an AionCore defect.
dimcode likewise still reports `agentInfo.title` "DimAgent" against a
public listing that says "DimCode". No session catalog is persisted
(skill step 11 leaves those columns to the runtime), and no metadata
changes ride along.

**Derived assertion updated:** `registry_npx_lock.rs` pins codebuddy's
exact version inside a `--package`-form argument list, so it moves with
the lock — `2.141.0` → `2.142.0`. All six outgoing versions were grepped
across `crates/**/*.rs` before staging; codebuddy's was the only real
assertion. The other hits were verified false positives from substring
and wildcard matching: `0.3.22` inside a `@anthropic-ai/claude-agent-sdk
0.3.220` comment, `0.5.1` inside `"block005-1111"` and a Discord
snowflake timestamp, `1.6.1` inside npm `11.6.1` version-parser
fixtures. `npx_cache_repair.rs` keeps its own version literals: those
are cache-path hash fixtures, not lock assertions, and changing them
would break their hash expectations.

The other 5 Registry-pinned packages (autohand, deepagents, nova, pi,
sigit) match the snapshot exactly. Package names and entrypoint args are
unchanged for all 11. Drifted but not upgraded: none. `mimo-code`
remains the one non-Registry builtin (no `registry_json_id`), excluded
from drift reconciliation.

## Registry snapshot

- Audit pinned to release tag
[`v2026.08.31-f6fdb56`](https://cdn.agentclientprotocol.com/registry/v1/v2026.08.31-f6fdb56/registry.json)
of `agentclientprotocol/registry`, fetched via the versioned CDN path
for reproducibility.
- 39 ids in the raw snapshot: no newly listed and no delisted agents
versus the baseline. (`antigravity-acp` remains listed and deferred as
binary-only since 2026-08-21; `fast-agent` and `minion-code` remain
listed but uvx-only and therefore out of scope.)

## Validation

- `just migration-check` — pass
- `just lint-fix` (`cargo fix` + `clippy --fix --workspace -D warnings`)
— clean
- `just fmt` — clean
- **Local `cargo nextest` intentionally skipped, by standing policy for
lock-only bumps** (established 2026-08-11). The Test check on this PR is
the authority for this change: the merge decision depends on CI rather
than the local run, and this host's load only manufactures
timeout-shaped test failures, which nothing in the local steps above is
subject to.

## Logging

No logging changes: lock version bumps plus one test assertion; existing
startup/session error paths already identify a failing agent by backend.

Co-authored-by: zk <>

* chore(cli-version): verify codex against 0.151.0 (#958)

Moves `VERIFIED_CODEX_VERSION` from 0.150.1 to 0.151.0.

| Gate | Result |
| --- | --- |
| A — contract | **PASS** — 411 → 413 schema files, `ServerNotification`
79 → 79, `ClientRequest` 153 → 154, nothing removed, no enum value
dropped |
| B — live e2e | **PASS 11/11**, 427.58s |
| C — release notes | **CLEAR** — 27 notes, 0 REVIEW |

## Gate C: two notes land on app-server, and both are exercised

Most of the range is TUI, but two items touch the surface this repo
actually drives:

- *"Preserved structured MCP tool and resource errors in app-server
responses."* (#41196)
- *"Improve sandboxing, MCP errors, and cached approvals."* (#41196)

Both sound additive, and neither is left resting on that. The gate B run
includes `live_codex_team_mcp_tools_call_and_runtime_env` (drives a real
MCP tool call) and `live_codex_survives_a_broken_mcp_server` (drives an
MCP server that fails) — both passed. Approval policy is covered by gate
A on the enum side: no value was removed from either of the two enums
the manifest depends on.

## The candidate is proven from the suite log

```
direct CLI version detected  cli=codex version=codex-cli 0.151.0
direct CLI version drift     cli=codex version=codex-cli 0.151.0
```

All 11 sessions, each with the drift line that only appears because the
binary disagrees with the not-yet-bumped constant. Installed codex on
this machine is 0.148.0, so a shim failure would have been visible
immediately. `latest` on npm is `0.151.0`; `alpha` is separately at
`0.152.0-alpha.7` and was not touched.

## Tests

Three pinned fixtures re-pointed above the new constant rather than
loosened, and the literal verified-release assertion now names
`codex-cli 0.151.0`. `cargo test -p aionui-session --lib cli_version`:
14/14. Clippy clean, fmt clean.

0.147.0 remains deliberately unverified — the gate walks over it rather
than through it, so it never becomes an accepted floor.

Record: `~/aion/protocols/samples/codex-cli/0.151.0/`

Constants and record only — no source change.

Co-authored-by: zk <>

* feat(scm): enumerate a repository's linked worktrees during discovery (#959)

## Summary

When a project root is itself a git repository, its linked worktrees
were never surfaced in the Source Control panel. Discovery opens the
root as at most one repository, and (only for a workspace root that is
not itself a repo) scans one level of immediate child directories while
skipping dot-directories. A repository's own linked worktrees —
typically under `.worktrees/<name>` — are therefore invisible.

This change enumerates a repository's linked worktrees from git itself
(`Repository::worktrees` / `find_worktree`) during discovery and
surfaces those living inside the project-root tree, so each nests under
its primary in the panel via the existing `worktree_of` correlation —
with no frontend, wire, or DB change.

## What changed

`crates/aionui-project/src/scm/git_provider.rs`:

- **`enumerate_linked_worktrees`** — asks git for the worktree set
(never scans the filesystem, so a submodule or nested repo is never
mis-captured) and opens each worktree that resolves inside the project
root.
- **`pe_relative_path`** — computes a worktree's path relative to the
project root; rejects anything needing `..` or an absolute/root
component (not representable as a pe-relative `FileRef`).
- **`dedup_by_workdir`** — a worktree can be both enumerated and walked
as a child (workspace-container case); surface it once.
- **`discover`** — now appends each surfaced non-worktree repo's in-tree
linked worktrees, reusing the existing `worktree_of` correlation and
repository-building code.

## Scope / boundary

- Enumeration applies to every surfaced non-worktree repository (a root
that is itself a repo, and each child repo under a workspace container).
- Only worktrees **inside** the project-root tree are surfaced. A
worktree outside the tree has no pe-relative `FileRef` and is skipped
with a debug log; supporting it would require an absolute-root escape
hatch threaded through identity/diff/containment, intentionally out of
scope.
- The worktree set comes from git, not a filesystem scan, so worktrees
behind dot-directories or deeper than one level are reachable while
submodules/nested repos are never mis-captured.

## Runtime verification

Built this branch and exercised the Source Control panel against a
repository opened directly as the project root, with several linked
worktrees created at different locations:

- Worktree at the conventional `.worktrees/<name>` → surfaced, nested
under its primary.
- Worktree at a hidden, multi-level path (a dot-directory several levels
deep) → surfaced, confirming enumeration reaches where the one-level,
dot-skipping child walk cannot.
- Worktree at a non-conventional in-tree path → surfaced, confirming
location independence.
- Worktree living outside the project-root tree → correctly not
surfaced; the skip is recorded in a debug log.
- Selecting a worktree carrying staged + unstaged + untracked changes →
change list shows the correct staged/unstaged groups and states.
- Clean worktrees → "no changes".

No screenshots attached (the states are text-only lists whose content is
covered by the scenarios above).

## Test plan

- [x] `cargo test` for `aionui-project` — added
`root_repo_surfaces_its_internal_linked_worktree` and
`root_repo_skips_linked_worktree_outside_its_tree`.
- [x] Full workspace suite via `just push` (9327 passed).
- [x] `cargo fmt --check` and `clippy` clean.

Co-authored-by: zynx <>

* chore(main): release 0.2.1 (#951)

:robot: I have created a release *beep* *boop*
---


##
[0.2.1](https://github.com/iOfficeAI/AionCore/compare/v0.2.0...v0.2.1)
(2026-09-01)


### Features

* **conversation:** route @@ mentions to the session-message skill
([#949](https://github.com/iOfficeAI/AionCore/issues/949))
([1c37366](https://github.com/iOfficeAI/AionCore/commit/1c37366f5d94994282c920323f159946b38a9b30))
* **scm:** enumerate a repository's linked worktrees during discovery
([#959](https://github.com/iOfficeAI/AionCore/issues/959))
([8da6c31](https://github.com/iOfficeAI/AionCore/commit/8da6c31ad93f3d7f38faaaec4f1bba6f8b6129a1))
* **session-message:** add session capabilities fallback to @@ blocks
([#952](https://github.com/iOfficeAI/AionCore/issues/952))
([1f511e5](https://github.com/iOfficeAI/AionCore/commit/1f511e5e863e3a76a65400e6f189c7e23e8dde2a))


### Bug Fixes

* **session-message:** align recipient block capabilities wording with
sender ([#955](https://github.com/iOfficeAI/AionCore/issues/955))
([9bfb2ad](https://github.com/iOfficeAI/AionCore/commit/9bfb2adbab1aca47bcd1a644446aeee6c41aab4f))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

* fix(db): avoid duplicate push subscription migration version

* fix(db): preserve migration history and lock workspace version

* fix(test): align memory evidence resolver with v0.2.1 API

* style(test): format memory evidence resolver stub

---------

Co-authored-by: Boii <i@tcp404.com>
Co-authored-by: kaizhou-lab <1558390418@qq.com>
Co-authored-by: zynx <3362922+piorpua@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
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.

1 participant