Repository navigation
feat: show live child session creation cards - #439
Conversation
Publish stable creation progress rows with exact-target status updates and immediate navigation. Preserve completion delivery and keep UI progress independent of lifecycle outcomes. Model: openai-codex/gpt-5.5
Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fdb0b3934b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const merged = mergeOperationProgressContent(existingProgress, content); | ||
| const nextItems = [merged as MessageContent]; |
There was a problem hiding this comment.
Add operation_progress to the persisted history schema
When this updater runs against a real SessionDocument, Mirror.setState validates nextItems with historyMessageItemSchema; its switch in packages/shared/src/schema.ts has no operation_progress case and returns Unknown type. Consequently every MCP and coordinator progress write is rejected (and then intentionally swallowed), so no live creation card is ever persisted or rendered despite the unit tests passing with schema-free fake documents. Add this variant to the Loro history validator and cover a real Mirror round trip.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L68
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and fixed in df78afe. A regression using upsertOperationProgressHistory with a real validating Loro Mirror reproduced Unknown type: operation_progress before the fix. The persisted history validator now accepts the variant, and snapshot reload tests cover created → running → succeeded/failed/cancelled on one stable row. Shared tests (1031), targeted CLI tests (79), typechecks, formatting, docs and boundary checks pass locally.
Register operation_progress in the persisted history schema and cover created, running, and terminal states with real Mirror snapshot round trips. Route creation-card explanations into the README to restore the document-size CI gate. Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df78afeb39
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (operation.completion?.type === 'cancelled') { | ||
| return targetStatus || item.inputDurable ? 'cancelled' : null; | ||
| } | ||
| if (operation.completion?.type === 'error') { | ||
| return targetStatus || item.inputDurable ? 'failed' : null; |
There was a problem hiding this comment.
Preserve the exact target state after root termination
When a materialized target keeps running because best-effort cancellation fails—or has already succeeded before cancellation is reconciled—targetStatus is running or succeeded, but this conditional converts every truthy value to cancelled; the error branch similarly converts it to failed. Since terminal progress is immutable, the card permanently misreports the exact target Turn even when that Session contains successful output. Preserve the collected target status when available and use the root result only when target evidence is unavailable.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L68
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and fixed in 2942697. Fresh exact-target evidence now wins over root cancellation/error. Historical card state is kept separately as materialization evidence, not treated as a current status observation. Regression tests cover a target still running after root cancellation/error, subsequent success, and fallback to the root result when current evidence is unavailable. Targeted history/coordinator tests: 47 passed; CLI typecheck, docs and quick checks pass.
Model: openai-codex/gpt-5.5
Preserve the updated main-branch sidebar invariants while moving ownership and layout explanations into the directory README. Restore the merged-tree document-size check. Model: openai-codex/gpt-5.5
Prefer fresh exact-target evidence over root cancellation or coordinator failure. Keep historical materialization evidence separate from live status so unavailable targets still receive the root fallback. Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 294269718e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| entry.items?.some( | ||
| (item) => item.type === 'operation_progress' && item.operationId === operation.operationId |
There was a problem hiding this comment.
Preserve fallback cards for partial progress rows
When a batch has already persisted a progress card for target A but a later progress write that should add target B fails, this predicate still links the completion merely because any matching progress row exists. OperationCompletionView treats that link as permission to suppress every legacy success card, and the delivery is subsequently consumed, so B permanently loses its navigable card instead of the failed progress write remaining repairable. Only set the link when the row covers every successful/materialized target, or deduplicate completion cards per target.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L68
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and fixed. Completion now sets progressMessageId only if the persisted row covers every successful or durably materialized target (checked by both sessionId and userTurnId, including completion results). Partial rows retain legacy success cards, so a failed progress write cannot hide a batch target. Regression tests seed partial/complete batch rows, reject subsequent progress mutations, and verify completion still delivers with the appropriate fallback link. Targeted CLI tests: 83 passed.
Link completion to progress only when every successful or materialized target is represented. Cover partial batch history with injected progress-write failures while allowing completion delivery. Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 81f4a05e66
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (item.status === 'succeeded') return item.status; | ||
| if (item.status === 'failed' || item.status === 'cancelled') { | ||
| return wasMaterialized ? item.status : null; |
There was a problem hiding this comment.
Preserve the exact target status at the deadline
When a create Operation reaches its deadline while the child Turn is still running, reconcileItem produces a failed/TARGET_TIMEOUT item even though collectOperationProgressTargetStatuses reports running; this branch nevertheless returns the item status. mergeProgressItem then freezes that failure as terminal, so the card remains failed even if the child later succeeds. Fresh evidence after the earlier root-termination fix is that the deadline path still overrides an available exact-target observation; prefer targetStatus here whenever it exists.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L66
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and fixed: failed/cancelled item snapshots now prefer fresh targetStatus as well, including TARGET_TIMEOUT while the exact Turn is still running or has succeeded. Root/item fallback applies only without current evidence. Added explicit timeout regression cases.
| const complete = [...operation.items, ...results].every((item) => | ||
| item.status === 'succeeded' || (item.status === 'active' && item.inputDurable) | ||
| ? covered.has(getOperationProgressTargetKey(item.target)) | ||
| : true | ||
| ); | ||
| return complete ? progressMessageId : undefined; |
There was a problem hiding this comment.
Do not link completions to stale progress state
When a progress row already covers every target but its terminal upserts fail after it reached running, this coverage-only predicate still returns progressMessageId. The completion view consequently suppresses the successful fallback card, and once delivery is consumed there is no active Operation or pending Delivery left to repair the stale row, so the sole card can remain “Running” permanently. Fresh evidence after the earlier partial-row fix is that target coverage is now verified but terminal status freshness is not; link only after the row reflects the terminal results, or retain a durable repair obligation.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L70
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed and fixed: progress links now require each successful completion target to be persisted as succeeded, not merely present. Tests reject terminal progress writes against complete rows still marked created/running and verify completion retains fallback cards. Only a complete succeeded row is linked. Targeted history/coordinator tests: 53 passed.
Prefer observed target status to timeout results and only suppress success fallback cards after the persisted progress row reflects success. Extend deadline and failed-progress-write coverage. Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cf5568ad60
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Progress is presentation-only, but pending Deliveries are the durable | ||
| // repair window after an Operation finished. Retry terminal progress here | ||
| // without letting failures block expiry, continuation, or consumption. | ||
| await this.writeOperationProgress(operation); |
There was a problem hiding this comment.
Continue reconciling running targets after delivery
When an Operation finishes at its deadline while the exact target Turn is still running, this pending-Delivery retry updates the card once and the Delivery can then be consumed while the target continues. Subsequent target-history wakes scan only active Operations and pending Deliveries, so the later terminal state is never written and the durable card remains “Running” even after the target succeeds or fails. Fresh evidence beyond the earlier deadline-snapshot fix is the loss of repair ownership after Delivery consumption; retain a durable reconciliation obligation until every published target is terminal.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L66
Useful? React with 👍 / 👎.
Independently ablate seven candidates against 104 regressions. Keep four equivalent simplifications; retain retry, no-op and freshness safeguards whose removal fails tests. Add transition coverage and results, and remove obsolete PR-generation artifacts while preserving screenshots. Model: openai-codex/gpt-5.5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a9453620d2
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| fileDiff: existing?.fileDiff ?? [], | ||
| finished: true, | ||
| }; | ||
| if (existingIndex < 0) return [...history, entry]; |
There was a problem hiding this comment.
Serialize creation of the stable progress row
When markItemInputDurable wakes the daemon while the MCP process is also persisting progress, the two Loro replicas can both observe existingIndex < 0 and append this ID concurrently. Loro preserves both list inserts, so the merged history contains duplicate IDs; later upserts mutate only the first match while buildChatStreamItems renders only the first, allowing a stale Created/Running copy to remain visible even after the other copy reached Succeeded and the linked completion suppressed its fallback card. Serialize the initial insertion or merge/remove every same-ID row so there is actually one monotonic durable card.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L66
Useful? React with 👍 / 👎.
Track unsettled create progress independently of Delivery consumption, retry through restart and write failures, and acknowledge only after target termination and local Loro durability. Keep root timeout/cancellation separate from the target state. Use the Host-lease Worker as the sole progress writer, fence late writes after stop, and recover duplicate Loro rows without losing terminal snapshots. Cover real replica merges, the root/target outcome matrix, retention and the executable race model. Model: openai-codex/gpt-6-astra
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13b0f8c0f5
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| WHERE workspace_id = ? AND owner_machine_id = ? AND state = 'finished' | ||
| AND kind IN ('session_create', 'session_create_many') | ||
| AND NOT EXISTS (SELECT 1 FROM operation_progress_settlements p |
There was a problem hiding this comment.
Exclude pre-feature completions from progress backfill
On the first startup after this migration, every retained finished create Operation lacks a settlement row, so this query treats it as pending and appends a new progress card. Its already-persisted operation_completion was written by older code and cannot contain progressMessageId; for pre-upgrade Operations whose requester and target documents remain available, the UI therefore renders both the newly backfilled card and the legacy successful-target card permanently. Seed settlements for existing rows or otherwise avoid backfilling Operations whose completion turn predates this feature.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L62-L70
Useful? React with 👍 / 👎.
| const statuses = new Map<string, OperationProgressStatus>(); | ||
| await this.mapItemsWithConcurrency(operation.items, 5, async (item) => { | ||
| if (!('target' in item) || !item.target) return; | ||
| if (item.status === 'active' && !item.inputDurable) return; |
There was a problem hiding this comment.
Recheck preallocated targets after operation cancellation
When cancellation wins after createSessionResult durably writes the target but before markItemInputDurable, the finished Operation retains an active item with inputDurable: false. This return prevents checking that preallocated exact target; with no previously published row, progressIsSettled then sees empty expected and published sets and permanently records the obligation as settled, so the materialized child never receives its navigation card. Finished snapshots with fixed target IDs still need their target evidence checked before settlement.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L65-L75
Useful? React with 👍 / 👎.
Independently test nine removals against 149 regressions. Keep five simplifications, including duplicate Delivery/root-error progress writes, and restore terminal retry after a combined ablation exposes its dependency. Preserve native duplicate repair, local flush and published labels. Record results and full validation. Model: openai-codex/gpt-6-astra
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5264add037
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const statuses = new Map<string, OperationProgressStatus>(); | ||
| await this.mapItemsWithConcurrency(operation.items, 5, async (item) => { | ||
| if (!('target' in item) || !item.target) return; | ||
| if (item.status === 'active' && !item.inputDurable) return; |
There was a problem hiding this comment.
Recheck preallocated targets after cancellation
When cancellation wins after createSessionResult durably writes the fixed target but before markItemInputDurable, store.cancel leaves that item active with inputDurable: false. Fresh evidence despite the earlier claimed fix is that the current collector still returns at this condition, while markItemInputDurable cannot update the now-finished Operation; with no prior card, progressIsSettled then compares two empty sets and permanently settles the obligation, so the materialized child never receives its navigation card. Inspect the fixed target evidence for finished snapshots before allowing settlement.
AGENTS.md reference: apps/cli/src/orchestration/AGENTS.md:L65-L75
Useful? React with 👍 / 👎.
Remove four screenshots and the temporary ablation report from the PR tree. Ignore workspace-local artifacts to prevent accidental recommits; retain implementation and regression tests. Model: openai-codex/gpt-6-astra
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ce8c6c459c
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return Array.isArray(v.commands) ? true : 'Missing commands'; | ||
| case 'system_notice': | ||
| return typeof v.name === 'string' ? true : 'Missing name'; | ||
| case 'operation_progress': |
There was a problem hiding this comment.
Preserve compatibility with older session-history schemas
When a shared Session is opened by a peer running an older build, the new daemon can persist this discriminator unconditionally, but that peer's historyMessageItemSchema falls through to Unknown type: operation_progress; ignoreUnknownProperties only covers undeclared object properties, not values rejected by this custom list-item validator. The older peer then cannot perform its next Mirror state update in that Session. Encode progress using a history shape older clients accept, or gate persistence through an explicit compatibility mechanism; adding this case only repairs current-version readers.
Useful? React with 👍 / 👎.
Related issue
Same-repository improvement; no linked issue.
Problem / pressure
MCP-created conversations and child Tabs were only discoverable from the parent conversation after the creating Operation completed. Long-running child work therefore had no immediate navigation card or visible progress.
Summary
operation_progresssystem row once each create target is materialized, and update its exact target Turn status in place.Before / after
Test plan
pnpm checkpassed (typechecks, lint, tests, i18n and repository boundary checks).pnpm check:quick.pnpm formatpassed; unrelated pre-existing Electron formatting was left unchanged.Sessions/SessionRelationCard/{Created,Running,Succeeded,Failed,Cancelled,AllCreationStates}.Context handoff
Instructions for reviewing agents
operation-progress-history.ts, coordinator reconciliation, and MCP materialization for stable target identity, progress durability, and lifecycle isolation.Authoring context