fix(cli): discover resumable sessions from /resume - #3582
Conversation
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at exact head e23405ce34db55480faf0f2a269cc2105935c8a2.
Coverage: how /resume discovers sessions, and the call chain from picking one to actually resuming. Not covered: wording.
Thanks for adding this entry point — the gap it targets is real. Two things need fixing before it does what it says, and both are reproducible on the ordinary user path.
[P2] onlyResumable filters on "attachable", not "has a safe boundary to resume"
packages/cli/src/pi-tui-runner.ts:2214-2215 selects entries with availability.get(session.id)?.available === true. But that availability comes from inspectSessionResumeAvailability at packages/cli/src/session-driver.ts:182-190, which only checks that session.cwd exists and is realpath-able. The Runtime Host implementation is the same shape, and for remote sessions it returns true for anything that has a cwd at all.
The authority for "is there something to resume" is elsewhere: the Host's turn.resume.query, where the Runtime plans a continuation only from that session's failed/cancelled inline run and otherwise reports resume_candidate_missing. The list path never calls it, and does not consult runningTurnIds or corrupted/unexecutable state either.
So an ordinary completed session, a session that is currently running, or one with no continuable run all appear in /resume as long as their working directory still exists. On remote, runtime-host-tui-command.ts:97-102 pins the scope to all while the new path applies no project predicate, so sessions from other projects are listed too. The same weak predicate also drives the startup hint at pi-tui-runner.ts:2282-2297, which will tell the user a plain attachable session "has an interrupted run".
Suggested direction: have a Runtime-owned resumability query return each session's real disposition, and filter here on current project, deleted workspace, running, and corrupted state — rather than reusing SessionResumeAvailability, which only answers cwd attachability.
[P2] Selecting from the picker does not actually resume
With no attached session, pi-tui-runner.ts:2134-2137 opens showSessionList({ onlyResumable: true }) and returns. The picker's onSelect at :2251-2260 calls goToSession(item.value), which on the idle path runs switchSession (:1649-1652) — and the comment right above goToSession says it plainly: /session is view navigation.
switchSession in runtime-host-session-driver.ts:471-524 validates cwd and the execution boundary, opens a subscription, and attaches a still-running root turn. It never calls turn.resume.query or turn.resume.start. The only driver path that starts a safe-boundary continuation is resumeLatest() at :325-349.
The user therefore picks a session, the picker closes as if the action succeeded, and the interrupted turn does not continue — they typically have to type /resume a second time so the current-session path reaches resumeLatest. That is the core function of the new entry point.
The new test at pi-tui-runner.test.ts:3265-3292 only asserts list text and filtering; it does not press Enter and assert that resumeLatest or a turn start follows, which is why this got through.
Suggested direction: make the selection path call a Runtime-owned switch-and-resume operation, or call resumeLatest once explicitly after a successful switchSession, keeping race/parked/failure outcomes visible.
Note on CI
check-runs on this head is total_count 0 — no run at all, which is neither green nor red. Even once the two items above are fixed, the gate needs terminal green on the new head.
Verification and limits
Changed-file Biome and git diff --check pass. A full CLI build could not be completed in our environment — pre-existing workspace drift unrelated to this PR blocked it — so no targeted-suite pass is claimed here; the findings above are established by reading the call chains at this exact head.
|
Follow-up fix pushed in the new head.
Verification on the new head: CLI build, typecheck, lint, format check, |
320abe1 to
acc96c0
Compare
Generated-by: Codex
Generated-by: Codex
acc96c0 to
f2c24a3
Compare
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at exact head f2c24a35. Two [P1]s, both inline. Publishing on behalf of a reviewer without write access here; the analysis is theirs, and I re-verified both against this head before posting.
Gate status is red, but not because of this PR. The test job's Build step fails on apps/desktop/src/main/__tests__/goal-services-adapter.test.ts:64,70,76 with TS2353: 'type' does not exist in type 'SessionChangedEvent'. That file is untouched here — this PR changes four packages/cli files. The root cause was already fixed on main by cded195 (#3642), so merging current main into this branch and re-running should clear it.
The direction is right: /resume should be able to open a picker when there is no current session, and startup should tell you an interrupted run exists. The two findings are both about the resume predicate being reused where an attachability predicate is what the caller needs.
) * refactor(cli): unify transcript reconciliation Generated-by: Codex * refactor(cli): remove derived transcript mirrors Generated-by: Codex * fix(cli): fence transcript replacements across recovery Generated-by: Codex * refactor(cli): remove shell poll side state Generated-by: Codex * refactor(cli): delete runtime transcript materializer Generated-by: Codex * refactor(cli): use projector snapshot authority Generated-by: Codex * refactor(ui): remove unreachable tool states Generated-by: Codex * refactor(cli): unify transcript settlement signals Generated-by: Codex * refactor(cli): discard hidden polls on interruption Generated-by: Codex * fix(cli): preserve hidden polls during reconciliation Generated-by: Codex * refactor(cli): make live tool events presentation authority * refactor(cli): derive tool presentation from authoritative facts * style(cli): format transcript probes
* fix(desktop): reflow narrow trace turn headers * test(desktop): preserve trace minimum-width viewport
* 修复 Windows 最大化后渲染区未同步 * 补充 Windows 最大化打包烟测 * 改用原生窗口句柄验证最大化 * 强化 Windows 最大化尺寸烟测 * 补充 Windows 最大化文件许可头 * 合并窗口尺寸同步事件处理器 * 收紧 Windows 最大化同步容错
Generated-by: Codex
Generated-by: Codex
…irectory (apache#3578) Sharing one instruction file across the names different agent CLIs read is the documented way to do it — Claude Code's docs recommend symlinking CLAUDE.md to AGENTS.md, and apache/airflow and deepseek-ai/deepseek-harness both ship that link. Maka read every candidate name and appended each one, so such a repository had the same bytes injected twice and spent most of the 14000-character workspace-instruction budget on the duplicate. Deduplicate on the digest of the cleaned text, scoped to one directory. That catches the symlink and a byte-identical copy alike, where a realpath check would only catch the link. Directories stay independent: the same text at global and project scope is a user repeating themselves deliberately. The digest is taken before truncation, so two files that diverge only past the per-file cap still count as different. The shape follows deepseek-harness, which reads several names and ships the symlink, and reconciles them by content rather than by path. Generated-by: Claude Code Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Generated-by: Codex
* fix(desktop): prevent WorkHub result overlap Allow WorkHub target buttons to grow beyond the fixed medium control height so Session metadata stays clear of the result text. Add an Electron layout regression test. Generated-by: Codex * fix(desktop): address WorkHub layout review
…6 updates (apache#3640) * chore(deps): bump the minor-and-patch group across 1 directory with 26 updates Bumps the minor-and-patch group with 25 updates in the / directory: | Package | From | To | | --- | --- | --- | | [@ai-sdk/provider-utils](https://github.com/vercel/ai/tree/HEAD/packages/provider-utils) | `5.0.27` | `5.0.28` | | [@astryxdesign/cli](https://github.com/facebook/astryx/tree/HEAD/packages/cli) | `0.4.0` | `0.4.5` | | [@astryxdesign/core](https://github.com/facebook/astryx/tree/HEAD/packages/core) | `0.4.0` | `0.4.5` | | [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) | `2.5.6` | `2.5.9` | | [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) | `26.1.2` | `26.2.0` | | [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) | `6.26.0` | `6.32.2` | | [@ai-sdk/anthropic](https://github.com/vercel/ai/tree/HEAD/packages/anthropic) | `4.0.39` | `4.0.40` | | [@ai-sdk/code-mode](https://github.com/vercel/ai/tree/HEAD/packages/code-mode) | `1.0.23` | `1.0.27` | | [@ai-sdk/cohere](https://github.com/vercel/ai/tree/HEAD/packages/cohere) | `4.0.27` | `4.0.28` | | [@ai-sdk/google](https://github.com/vercel/ai/tree/HEAD/packages/google) | `4.0.44` | `4.0.47` | | [@ai-sdk/open-responses](https://github.com/vercel/ai/tree/HEAD/packages/open-responses) | `2.0.28` | `2.0.29` | | [@ai-sdk/openai](https://github.com/vercel/ai/tree/HEAD/packages/openai) | `4.0.42` | `4.0.44` | | [@ai-sdk/openai-compatible](https://github.com/vercel/ai/tree/HEAD/packages/openai-compatible) | `3.0.30` | `3.0.32` | | [@larksuiteoapi/node-sdk](https://github.com/larksuite/node-sdk) | `1.72.0` | `1.73.0` | | [@openai/agents-core](https://github.com/openai/openai-agents-js) | `0.14.3` | `0.17.0` | | [ai](https://github.com/vercel/ai/tree/HEAD/packages/ai) | `7.0.66` | `7.0.70` | | [ws](https://github.com/websockets/ws) | `8.21.2` | `8.21.3` | | [electron](https://github.com/electron/electron) | `43.2.0` | `43.4.1` | | [@earendil-works/pi-tui](https://github.com/earendil-works/pi/tree/HEAD/packages/tui) | `0.83.0` | `0.84.2` | | [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) | `1.28.0` | `1.33.0` | | [mermaid](https://github.com/mermaid-js/mermaid) | `11.16.1` | `11.17.0` | | [@astryxdesign/theme-neutral](https://github.com/facebook/astryx/tree/HEAD/packages/themes/neutral) | `0.4.0` | `0.4.5` | | [@storybook/react-vite](https://github.com/storybookjs/storybook/tree/HEAD/code/frameworks/react-vite) | `10.5.6` | `10.5.10` | | [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/tree/HEAD/packages/plugin-react) | `6.0.5` | `6.1.0` | | [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) | `8.1.5` | `8.2.2` | Updates `@ai-sdk/provider-utils` from 5.0.27 to 5.0.28 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/provider-utils/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/provider-utils@5.0.28/packages/provider-utils) Updates `@astryxdesign/cli` from 0.4.0 to 0.4.5 - [Release notes](https://github.com/facebook/astryx/releases) - [Changelog](https://github.com/facebook/astryx/blob/main/packages/cli/CHANGELOG.md) - [Commits](https://github.com/facebook/astryx/commits/v0.4.5/packages/cli) Updates `@astryxdesign/core` from 0.4.0 to 0.4.5 - [Release notes](https://github.com/facebook/astryx/releases) - [Changelog](https://github.com/facebook/astryx/blob/main/packages/core/CHANGELOG.md) - [Commits](https://github.com/facebook/astryx/commits/v0.4.5/packages/core) Updates `@biomejs/biome` from 2.5.6 to 2.5.9 - [Release notes](https://github.com/biomejs/biome/releases) - [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md) - [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.5.9/packages/@biomejs/biome) Updates `@types/node` from 26.1.2 to 26.2.0 - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Updates `knip` from 6.26.0 to 6.32.2 - [Release notes](https://github.com/webpro-nl/knip/releases) - [Commits](https://github.com/webpro-nl/knip/commits/knip@6.32.2/packages/knip) Updates `@ai-sdk/anthropic` from 4.0.39 to 4.0.40 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/anthropic/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/anthropic@4.0.40/packages/anthropic) Updates `@ai-sdk/code-mode` from 1.0.23 to 1.0.27 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/code-mode/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/code-mode@1.0.27/packages/code-mode) Updates `@ai-sdk/cohere` from 4.0.27 to 4.0.28 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/cohere/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/cohere@4.0.28/packages/cohere) Updates `@ai-sdk/google` from 4.0.44 to 4.0.47 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/google/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/google@4.0.47/packages/google) Updates `@ai-sdk/open-responses` from 2.0.28 to 2.0.29 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/open-responses/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/open-responses@2.0.29/packages/open-responses) Updates `@ai-sdk/openai` from 4.0.42 to 4.0.44 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/openai/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/openai@4.0.44/packages/openai) Updates `@ai-sdk/openai-compatible` from 3.0.30 to 3.0.32 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/openai-compatible/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/@ai-sdk/openai-compatible@3.0.32/packages/openai-compatible) Updates `@larksuiteoapi/node-sdk` from 1.72.0 to 1.73.0 - [Commits](https://github.com/larksuite/node-sdk/commits) Updates `@openai/agents-core` from 0.14.3 to 0.17.0 - [Release notes](https://github.com/openai/openai-agents-js/releases) - [Commits](openai/openai-agents-js@v0.14.3...v0.17.0) Updates `ai` from 7.0.66 to 7.0.70 - [Release notes](https://github.com/vercel/ai/releases) - [Changelog](https://github.com/vercel/ai/blob/main/packages/ai/CHANGELOG.md) - [Commits](https://github.com/vercel/ai/commits/ai@7.0.70/packages/ai) Updates `ws` from 8.21.2 to 8.21.3 - [Release notes](https://github.com/websockets/ws/releases) - [Commits](websockets/ws@8.21.2...8.21.3) Updates `electron` from 43.2.0 to 43.4.1 - [Release notes](https://github.com/electron/electron/releases) - [Commits](electron/electron@v43.2.0...v43.4.1) Updates `@earendil-works/pi-tui` from 0.83.0 to 0.84.2 - [Release notes](https://github.com/earendil-works/pi/releases) - [Changelog](https://github.com/earendil-works/pi/blob/main/packages/tui/CHANGELOG.md) - [Commits](https://github.com/earendil-works/pi/commits/v0.84.2/packages/tui) Updates `lucide-react` from 1.28.0 to 1.33.0 - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/1.33.0/packages/lucide-react) Updates `mermaid` from 11.16.1 to 11.17.0 - [Release notes](https://github.com/mermaid-js/mermaid/releases) - [Commits](https://github.com/mermaid-js/mermaid/compare/mermaid@11.16.1...mermaid@11.17.0) Updates `@astryxdesign/theme-neutral` from 0.4.0 to 0.4.5 - [Release notes](https://github.com/facebook/astryx/releases) - [Changelog](https://github.com/facebook/astryx/blob/main/packages/themes/neutral/CHANGELOG.md) - [Commits](https://github.com/facebook/astryx/commits/v0.4.5/packages/themes/neutral) Updates `@storybook/react-vite` from 10.5.6 to 10.5.10 - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v10.5.10/code/frameworks/react-vite) Updates `@vitejs/plugin-react` from 6.0.5 to 6.1.0 - [Release notes](https://github.com/vitejs/vite-plugin-react/releases) - [Changelog](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite-plugin-react/commits/plugin-react@6.1.0/packages/plugin-react) Updates `storybook` from 10.5.6 to 10.5.10 - [Release notes](https://github.com/storybookjs/storybook/releases) - [Changelog](https://github.com/storybookjs/storybook/blob/next/CHANGELOG.md) - [Commits](https://github.com/storybookjs/storybook/commits/v10.5.10/code/core) Updates `vite` from 8.1.5 to 8.2.2 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v8.2.2/packages/vite) --- updated-dependencies: - dependency-name: "@ai-sdk/anthropic" dependency-version: 4.0.40 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/code-mode" dependency-version: 1.0.27 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/cohere" dependency-version: 4.0.28 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/google" dependency-version: 4.0.47 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/open-responses" dependency-version: 2.0.29 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/openai" dependency-version: 4.0.44 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/openai-compatible" dependency-version: 3.0.32 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@ai-sdk/provider-utils" dependency-version: 5.0.28 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@astryxdesign/cli" dependency-version: 0.4.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@astryxdesign/core" dependency-version: 0.4.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@astryxdesign/theme-neutral" dependency-version: 0.4.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@biomejs/biome" dependency-version: 2.5.9 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@earendil-works/pi-tui" dependency-version: 0.84.2 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: "@larksuiteoapi/node-sdk" dependency-version: 1.73.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: "@openai/agents-core" dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: "@storybook/react-vite" dependency-version: 10.5.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: "@types/node" dependency-version: 26.2.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: "@vitejs/plugin-react" dependency-version: 6.1.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: ai dependency-version: 7.0.70 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: electron dependency-version: 43.4.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: knip dependency-version: 6.32.2 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: lucide-react dependency-version: 1.33.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: mermaid dependency-version: 11.17.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: storybook dependency-version: 10.5.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: minor-and-patch - dependency-name: vite dependency-version: 8.2.2 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: minor-and-patch - dependency-name: ws dependency-version: 8.21.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com> * fix(deps): adapt the grouped bump to current contracts Retarget the provider-utils and Astryx patches, migrate the CLI to pi-tui's main-screen implementation, and keep layer tests on the client-mounted surface. Refresh the reviewed dependency notices, Astryx theme artifacts, and surface inventory for the upgraded graph. Generated-by: Codex * test(desktop): use the session change payload contract Remove the IPC channel discriminator from SessionChangedEvent fixtures so the test matches the payload emitted by Runtime Host and restores the current main build. Generated-by: Codex * fix(deps): update the source license inventory Point the source candidate's legal inventory at the retargeted provider-utils and Astryx patch files and record the upgraded Astryx theme input. Generated-by: Codex * chore(deps): align with knip 6.32 analysis Remove unused compatibility re-exports and obsolete binary ignores that the upgraded Knip now reports. Keep the underlying implementations and public types that still have consumers. Generated-by: Codex * chore(deps): remove an unused UI type forwarder Keep QuietPreview owned by @maka/core and stop re-exporting it from the UI adapter when no consumer uses that compatibility path. This lets Knip 6.32 finish its packages/ui analysis. Generated-by: Codex * fix(legal): preserve exact upstream MIT notices Use the complete version-pinned README license blocks for fastdom 1.0.12 and strictdom 1.0.1 instead of synthesizing copyright holders from author metadata. Add a regression check for the exact notices and regenerate the Desktop inventory. Generated-by: Codex --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: AstroHan <lei.yuhan@outlook.com>
Generated-by: OpenAI Codex Co-authored-by: k4its1t <306379390+k4its1t@users.noreply.github.com>
…audit (apache#3603) * refactor(core): drop retired 'execute' permission mode from capability audit Remove the 'execute' member from CAPABILITY_AUDIT_PERMISSION_MODES and the associated Exclude<> workaround in SkillAuditRecord, since the retired mode is already folded to 'ask' at all persistence decode sites. - scheduledTaskPermissionMode: active tasks now map to 'ask' instead of the retired 'execute' (behavioural equivalent). - executableScheduledTaskCount: filters enabled non-explore tasks instead of the now-unreachable 'execute' permissionMode literal. - CLI activation-command retains the execute→ask alias for external callers per the original comment. Refs: apache#3385 Generated-by: OpenAI Codex Signed-off-by: Yunare Maia <yunare@gmail.com> * style: apply biome formatting to capability-audit (CI fix) --------- Signed-off-by: Yunare Maia <yunare@gmail.com>
* refactor: publish canonical session catalog activity Carry the storage catalog's materialized activity timestamp through Runtime Host projections and cursors. This removes the protocol's dependence on the redundant last-used timestamp and gives all clients one ordering fact. Generated-by: Maka * refactor: share canonical catalog projection Generated-by: Maka * refactor: accept complete desktop catalog snapshots Generated-by: Maka * refactor: retire session last-used authority Generated-by: Maka * refactor: remove session settings list patches Generated-by: Maka * refactor: remove desktop catalog upserts Generated-by: Maka * refactor: delete session summary merge layer Generated-by: Maka * refactor: drop legacy session activity column Generated-by: Maka * refactor: remove remaining desktop catalog patches Generated-by: Maka * chore: restore canonical ASF source header Generated-by: Maka * fix(desktop): repaint committed session settings Generated-by: Maka * fix(desktop): keep plan state outside catalog snapshots Generated-by: Maka * fix(desktop): retain healthy host catalogs Generated-by: Maka * fix(desktop): reconcile mode intents with catalog snapshots Keep the latest Plan and orchestration intent in one setting owner until the Host commit is observed in a catalog snapshot. Catalog refresh failures no longer roll presentation back or prevent a queued latest intent from reaching the Host. Generated-by: Maka * fix(desktop): retire settings on newer catalog snapshots Fence committed mode overlays by successful catalog observation revision instead of value equality. Runtime-owned transitions such as Plan approval can now supersede an older renderer commit without letting failed reads discard it. Generated-by: Maka * fix(runtime-host): advance catalog protocol epoch Current main already owns epoch 43 for shell-run poll correlation. Advance the retired Session timestamp wire change to epoch 44 and pin that compatibility floor. Generated-by: Maka
Refresh the stale surface count and run the repository-wide inventory gate before Build whenever code validation is selected. Fixes apache#3646 Generated-by: OpenAI Codex
* refactor(core): introduce persisted value boundary Generated-by: Codex * refactor(core): separate persisted record decoders Generated-by: Codex * refactor(storage): enforce persisted decode paths Generated-by: Codex * ci(runtime-host): declare compatible session turn decoder change Generated-by: Codex * ci(runtime-host): refresh compatible session turn declaration Generated-by: Codex * test(core): mark new stored message fixture persisted Generated-by: Codex
* fix(mcp): drop JSON Schema annotations from tool schemas Client Capability validation intentionally keeps a strict keyword allowlist. Normalize MCP tool descriptors during discovery by removing only the non-semantic $schema and $comment annotations from supported schema positions. Keep $id because it changes $ref base resolution and must remain subject to protocol validation. Generated-by: pi (gpt-5.6-sol) * fix(mcp): scrub annotations under every subschema keyword Add patternProperties, dependentSchemas, dependencies, prefixItems, additionalItems, unevaluatedItems, unevaluatedProperties, contains, not, if, then, and else to subschema traversal. Keep the traversal explicit so instance-data keywords such as default, const, examples, and enum retain payload keys named $schema or $comment. $id remains untouched and survives normalization. Generated-by: pi (gpt-5.6-sol)
* fix(storage): import Codex item_completed messages Generated-by: OpenAI Codex * fix(storage): preserve Codex content-part concatenation Match the upstream Codex contract by concatenating completed user and agent text parts without injecting separators. Strengthen the regression fixture so split-word boundaries fail under the previous behavior. Generated-by: OpenAI Codex --------- Co-authored-by: sunrioa <178722768+sunrioa@users.noreply.github.com>
…3549) The gateway serves muse-spark-1.2-contributor correctly through the Responses API, while its Chat Completions stream lacks a reliable terminal finish reason. Pin this provider/model pair to Responses instead of weakening the shared truncation guard, and cover both the scoped protocol choice and final request endpoint. Fixes apache#3548 Generated-by: OpenAI Codex
Generated-by: Codex
Astro-Han
left a comment
There was a problem hiding this comment.
Reviewed at 253fb50e595de0604c0c22b303fae1fa8023af82. Both of the [P1]s we raised earlier are fixed by this commit. No P0-P2 remain. Two gate blockers below, one of which is not yours to fix in code.
Correcting our own scope first
An earlier round of this review was working from a 252-file, +7405/-6516 diff. That is not what this PR changes. This branch was rebased onto main and replayed roughly twenty squash-merged commits; because squashing produces new SHAs, git cannot see them as shared history, so the merge-base is stuck at an old commit and every merge-base-relative view — the Files tab and the REST file list included — inflates accordingly. Those views are not wrong; they accurately report merge-base-to-head, which is simply not the same question as "what did the author change here".
The author-owned delta is one commit:
253fb50e fix(cli): separate session attach and resume discovery
packages/cli/src/__tests__/pi-tui-runner.test.ts +30
packages/cli/src/pi-tui-runner.ts +37/-14
packages/cli/src/runtime-host-session-driver.ts +17/-17
packages/cli/src/session-driver.ts +1
4 files, +68 / -17
We are stating this because we got it wrong in this thread before stating it, and because the wrong number changed a conclusion further down.
Both prior [P1]s are closed
Attach availability no longer answers the resume-candidate question. getSessionResumeAvailability drops its host branch and returns inspectRuntimeHostSessionResumeAvailability unconditionally; the narrow turn.resume.query path moves into a new getSessionResumeCandidateAvailability. showSessionList picks by mode, and — this is the line that fixes the reported symptom — the selection handler changed from if (availability.get(item.value)?.available === false) return; to if (options.onlyResumable && availability.get(item.value)?.available === false) return;. /session no longer refuses to navigate to a session because a resume-candidate check said false. The commit subject says exactly this, and the code matches it.
The startup enumeration race is fixed at the mechanism, not by moving the timer. A memoised sessionListPromise now backs a shared listSessions(), so showSessionList and announceResumeAvailability join one in-flight enumeration instead of issuing two. announceResumeAvailability also returns early when the driver lacks getSessionResumeCandidateAvailability. The setTimeout(..., 0) is still there, and that is fine: the timer was never the defect — the concurrent duplicate enumeration was, and it is now memoised away.
One supporting argument from our earlier review should be retired rather than repeated: we noted that the availability map was built with a bare Promise.all(sessions.map(...)) while the sibling foreign-session branch had per-item containment. That asymmetry is gone — and specifically, this commit is what added the per-session try/catch. It is not that our evidence went stale; the author fixed it.
Gate: two blockers, both needing one push
1. Formatting. The test job fails at Check formatting on pi-tui-runner.ts around the new resume-availability expression. That step runs before the tests, which has a consequence worth naming: no test on this head has executed, so CI currently cannot tell you anything about the change itself. npm run format resolves it.
2. TS2304: Cannot find name 'decodeStoredMessage' in the package job — please do not hand-edit this. The symbol is in packages/storage/src/__tests__/codex-session-adapter.test.ts:267, which your commit does not touch. The branch replayed the older versions of #3562 and #3520 in the order that briefly broke main: the rename landed first, then an assertion still using the old symbol. main was repaired afterwards by #3656, but this branch replayed before that fix existed. Rebasing onto current main brings #3656 with it and clears this. Editing line 267 by hand would mean changing a file that is not part of your change.
The PR is also CONFLICTING, so a rebase is required regardless — one push can settle all three.
One thing to check on your side
The two review threads above show replies from you reading System.Collections.Hashtable[...]. That is a PowerShell object stringified by whatever tooling posted them, so no text of yours actually arrived. From the GitHub UI the threads look answered, which is why we are pointing it out rather than assuming you chose not to reply. If you meant to say something there, it will need reposting.
Astro-Han
left a comment
There was a problem hiding this comment.
Correction to my previous review on this PR (5004256305), specifically to the scope paragraph.
I wrote that the author-owned delta is one commit, 4 files, +68/-17. That is wrong. It is three commits and 5 files.
9e24a005 fix(cli): discover resumable sessions from /resume 2 files, +63/-2
f2c24a35 fix(cli): resume the selected interrupted session 4 files, +25/-6
253fb50e fix(cli): separate session attach and resume discovery 4 files, +68/-17
Union: pi-tui-runner.ts, runtime-host-session-driver.ts, session-driver.ts, __tests__/pi-tui-runner.test.ts, __tests__/runtime-host-session-driver.test.ts. The +68/-17 I quoted is the tip commit alone, not this branch's contribution.
How I got it wrong is worth stating, because the previous review's whole first section was about scope. I listed the commits between the merge-base and the head, truncated the output, and read the top entry as the PR's own work. The other two author commits are further down that list, interleaved among the twenty-odd replayed main commits. A truncated observation reported as a fact — the same failure mode I was describing one paragraph earlier.
The reliable way to separate them is patch equivalence rather than reading a commit list:
git log --cherry-pick --right-only --no-merges origin/main...<head>
which returns exactly these three and marks the other nineteen as already present on main. Credit to a reviewer on our side for pointing out that subject-line matching is not sufficient here; this is what caught my error.
Nothing else in that review changes. Both [P1]s are still closed, and I verified that by reading the tip commit's actual diff — the removal of the host branch from getSessionResumeAvailability, the new getSessionResumeCandidateAvailability, the options.onlyResumable && guard on the selection handler, and the memoised sessionListPromise. The two gate blockers are unchanged: run npm run format, and rebase onto current main so that #3656 clears the TS2304 on a file that is not part of your change.
The practical difference for you is only in how much of this branch a reviewer should be reading: five files across three commits, not four files in one.
Astro-Han
left a comment
There was a problem hiding this comment.
Correcting one sentence in 5004276704 — a tooling claim, not a conclusion about this PR.
I wrote that
git log --cherry-pick --right-only --no-merges origin/main...<head>
"returns exactly these three and marks the other nineteen as already present on main". It does not mark anything. --cherry-pick omits commits whose patch is already present on the other side; nothing in its output refers to them. The marking form is git cherry -v (+ / -) or --cherry-mark, which prints = for a patch-equivalent commit and > for one only on the right side. On this branch --cherry-mark gives 19 = and 3 >.
Two limits on that command that my wording also glossed over:
It produces a candidate classification, not a proof of ownership. A replayed commit rewritten during conflict resolution is no longer patch-equivalent and will appear as author work; conversely, a commit the author genuinely wrote that happens to be patch-identical to something already on main is omitted and silently disappears from their delta. The first direction costs extra reading, the second can hide real author work, and neither is detectable from the command's output alone.
--no-merges is --max-parents=1, so any delta introduced by a merge commit's own conflict resolution is excluded. That is harmless here — this branch has no merge commits, it was rebased — but the exclusion is silent, so it is worth stating rather than assuming.
None of this changes the facts in the previous correction, which an independent reviewer on our side re-derived from a fresh fetch: three author commits (9e24a005, f2c24a35, 253fb50e), five files in the union, none of them the Codex adapter test, and all three on this head's first-parent chain. The [P1] closures and the two gate items are likewise unaffected — still npm run format, and rebase onto current main so #3656 clears the TS2304.
…overy # Conflicts: # packages/storage/src/__tests__/codex-session-adapter.test.ts
|
CI note, with one part that needs your judgement rather than a mechanical fix. This head's checks had never executed — the run was parked awaiting maintainer approval. I released it ( Unlike the other parked runs I released today, this one gets all the way through. Lint, formatting, the Astryx inventory, 1.
The id column is eight characters wide, so 2. What I established:
The expected/actual gap is not a near-miss. It expects the session list to render a row reading roughly and then an otherwise empty screen — no list at all, and a resume that did happen. The test's whole point is that this session must stay visible but must not be resumable. I am not going to guess which of your changes causes it, because two new paths could and I would rather you check than have me assert. For what it is worth, both are in
To be fair to the second one: Neither failure is flaky. The first is deterministic by construction, and the second contradicts a green run on its own merge base. Both are reproducible with 中文CI 提示,其中一条需要你判断,不是机械修复。 这个 head 的检查此前从没执行过——run 卡在等 maintainer 放行,我已放行( 与我今天放行的其他几个不同,这个 run 一路走到了很后面:lint、格式、Astryx 清单、 1.
2. 已确立的事实:这个测试在 merge base 期望与实际的差距不是"差一点":它期望会话列表渲染出一行大致为 我不去猜是哪一处改动导致的,因为有两条新路径都可能,我宁愿你去查,也不愿我来断言。两条都在 为第二条说句公道话: 两个失败都不是 flake:第一个由构造决定必然失败,第二个与它自己 merge base 上的绿色 run 相矛盾。都可以用 |
Summary
Fixes #3508.
When the TUI has no attached session,
/resumenow opens a picker limited to sessions whose resume availability is ready, instead of attempting an attached-session-only resume. Startup also performs a best-effort availability check and surfaces a passive hint for the current or cwd session when safe-boundary resume is available.Implementation
/resumewithout an attached session./sessionrows, attached-session resume behavior, sandbox boundaries, and Desktop policy unchanged.Verification
node --test --test-name-pattern="opens a picker containing only resumable" packages/cli/dist/__tests__/pi-tui-runner.test.js— passed.npm --workspace maka-agent run build— passed.npm --workspace maka-agent run typecheck— passed.npm run lint -- packages/cli/src/pi-tui-runner.ts packages/cli/src/__tests__/pi-tui-runner.test.ts— passed.npm run format:check -- packages/cli/src/pi-tui-runner.ts packages/cli/src/__tests__/pi-tui-runner.test.ts— passed.git diff --check— passed.npm --workspace maka-agent test— 378 passed, 12 failed, 1 skipped; failures are existing environment/Windows-dependent tests outside this diff.Not run: full repository build and Docker-based checks; this is a pure CLI/TUI unit behavior change with no external service dependency.
AI use
Tool(s) and scope: Codex assisted with remote issue selection, implementation, regression testing, and PR text. The commit includes a
Generated-by: Codextrailer.Checklist
Does this PR entail a change in behavior?
/resumenow discovers resumable sessions when no session is attached.