Repository navigation
Conversation
8bb79e2 to
9d87233
Compare
9d87233 to
05c88ea
Compare
05c88ea to
445272e
Compare
445272e to
4ede2f9
Compare
632c3bf to
b9fb90d
Compare
b9fb90d to
47c4892
Compare
47c4892 to
6014443
Compare
wpfleger96
left a comment
There was a problem hiding this comment.
🤖 thanks for turning the first round around so fast. the record split, the Claude sessions split and the agents2 rename all keep their source now when a write fails, provider changes roll back correctly, and a direct save() retry reaches disk. four persistence issues are still open on 99500019a, details inline:
- blocking: a failed first copy out of
localStoragecan still lose teams and settings (state.ts) - blocking: a failed settings Save leaves the form's Save button disabled, so the user can't retry (
service.tswrite) - blocking: agent attention tools (watches,
interest_set) report success when the write failed (service.tsrunner adapter) - blocking: valid Codex keys on very long hosts still go over the file name limit (
agent_state.rs)
nonblocking, still open from the first round: main.tsx shows a blank window if loading agent state never finishes.
these come from reading the source and testing with injected write failures. nobody has run them in a real window or with two programs.
This comment has been minimized.
This comment has been minimized.
4df4d09 to
c3f5fe1
Compare
c3f5fe1 to
fac7739
Compare
fac7739 to
25cf56c
Compare
25cf56c to
fb880dd
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: no additional changes requested. The three prior findings are addressed: startup retains readable legacy records when the split fails, unfinished hosted-agent changes await persistence and propagate failure, and both provider-default dialogs disable their choices during a save. Source assessment: 9/10 for this repair scope.
The supported hosted provider retains its registration replay key until activation, preserving same-name retry if the initial unfinished-state save fails. Reviewed the repairs, their callers and error/retry paths, and performed a fresh-frame self-review; this is not a new exhaustive review of unrelated stacked changes.
Head 5d343f45b28d9ceedb1518e75edff2d8dd575ef4; base c8c0d52df1fb5a5c08099b2d8836aec35bab0657. Public PR description (no attached images), commit messages and changed publication surface inspected. Source-only: no PR code, tests, builds or app executed; CI was not assessed. Live file migration, concurrent-process behavior, native focus, themes/sizes and enlarged-text acceptance remain unverified. Shared Select, Button and host Dialog ownership is preserved. COMMENT only; not approval or merge authorization.
5d343f4 to
2445e49
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: one P2 finding, detailed inline. Shared catch-up checkpoints can overwrite another host’s progress and replay handled watch events. Source assessment: 8/10 until that persistence boundary is split. This was missed in my earlier review; the newly traced checkpoint producer/consumer establishes the defect. It is not a regression introduced by this rebase.
The three prior findings remain fixed: failed record splitting preserves startup, unfinished hosted-agent saves are awaited, and provider-default selections are disabled while saving. Range-diff confirms the five feature patches are unchanged apart from surrounding context. Rocket, Mantis and Groot completed independent source lanes; I reconciled their evidence and the new agent-start/config integration.
Head 2445e49973dd7625d9174579721735acb8dffdee; base ccd1be5191f1f47b70adb2e3783d4ffd00553edf. Public description (no attached images), changed publication surface and five commit messages inspected. Source-only: no tests, builds or app execution; live migration, cross-process behavior, native keyboard/error-retry focus, themes/sizes and human acceptance remain unverified. One CI snapshot has two failed JavaScript shards and other work still running. Shard 2 logs show TS2741 missing Goose effort fields in launch-boundary.test.ts:560,596, unchanged from the base; Windows native validation is skipped. COMMENT only, not approval.
2445e49 to
747d8a3
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: one P2 finding in the new checkpoint migration, detailed inline. The per-agent files fix the steady-state overwrite, but overlapping first starts can still replace newer saved progress with a stale migration snapshot. Source assessment: 8/10 until that migration write is protected.
The prior startup, unfinished-save and provider-default repairs remain intact. Rocket, Mantis and Groot completed independent lanes; I reconciled their evidence and checked the source path. This review covers the checkpoint repair and rebase integration, not a new exhaustive review of unchanged feature code.
Head 747d8a3290234a0caa37c3577512ce4097081d61; base 330e60ba0e373ff292dcd48da326fcff3c36a711. Public description (no attached images), six commit messages and changed publication surface inspected. Source-only: no tests, builds or app execution; live concurrent-host migration, native focus/error-retry behavior, themes/sizes and human acceptance remain unverified. Shared Select/Button and host Dialog ownership is preserved. One hosted CI snapshot succeeds, including CI required; Windows native validation is skipped. COMMENT only, not approval.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: no additional changes requested. The prior checkpoint-migration finding is addressed: native create-if-absent preserves an existing destination, and checkpoint saves compare this process’s previous snapshot so an unrelated agent’s progress is not rewritten. Source assessment: 9/10 for this repair scope.
Rocket, Mantis and Groot completed independent lanes; I reconciled their evidence and checked the production callers and failure paths. The startup, unfinished-save and provider-default repairs remain intact. Existing limits still apply: a later edit of the same agent from an older process snapshot can replace newer state; this repair does not provide live cross-process synchronization. This is a follow-up of the eight-file repair, not a new exhaustive review of unchanged feature code.
Head 496533da4c2e43ffe4769bbb2e45b1f637be09b5; base 330e60ba0e373ff292dcd48da326fcff3c36a711. Public description (no attached images), seven commit messages and changed publication surface inspected. Shared Select/Button and host Dialog ownership remains intact. Source-only: no tests, builds or app execution; live concurrent-host migration, crash recovery, performance, native keyboard/error-retry focus, themes/sizes and human acceptance remain unverified. One hosted CI snapshot shows 34 successful checks, including CI required; Windows native validation is skipped. COMMENT only, not approval or merge authorization.
496533d to
100d653
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: two P2 findings, detailed inline. Timer progress can overwrite a pending settings edit, and synchronous storage refusal can admit the same overdue timer repeatedly. Source assessment: 8/10 until these persistence paths are repaired. Both existed at the prior reviewed head and were missed in my earlier review; neither is a new rebase regression.
The prior migration, per-agent checkpoint and provider-default repairs remain intact. The rebase preserves the feature patches while retaining the model-loading and save guards. Rocket, Mantis and Groot completed independent systems, correctness/security and product/accessibility lanes; I reconciled their evidence and verified both findings against the source. This is a repair/integration follow-up, not a new exhaustive audit of unchanged feature code.
Head 100d6534a5c32350f343bca674e0c0f1b7a96d63; base dcd3960c9f6613ded457232903d250caa6e7e1fd. Public description (no attachments), seven commit messages and changed publication surface inspected. Shared Select/Button and host Dialog ownership remains intact. Source-only: no tests, builds or app execution, and current CI was not assessed. Live migration, concurrent-host operation, native keyboard/error-retry focus, themes/sizes, performance and human acceptance remain unverified. COMMENT only, not approval or merge authorization.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: one P2 finding, detailed inline. Source assessment: 8/10 because timer progress can still overwrite a pending timer rearm’s saved usage, granting an unintended fresh occurrence budget.
The synchronous storage-refusal fix is confirmed in source, and pending non-timer settings now survive progress writes. The remaining issue is the per-timer state within that merge. Rocket, Mantis and Groot completed independent lanes; I checked the finding against the supported attention-write path and reconciled their results.
Reviewed head d914c830ebfaa007b042a52449c89e0871014d55, base dcd3960c9f6613ded457232903d250caa6e7e1fd; repair delta from 100d6534a5c32350f343bca674e0c0f1b7a96d63 is three files. Public description (no image attachments), changed publication surface and eight commit messages inspected. Source-only: no tests, builds or app execution; CI was not assessed. Live persistence/concurrency, native focus and error/retry interactions, themes/sizes and human acceptance remain unverified. This is a non-blocking COMMENT review, not approval.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: one P2 finding, detailed inline. Source assessment: 8/10 because a timer can consume an occurrence while its own rearm is saving, then lose that consumed count and exceed its configured budget.
The prior different-timer overwrite is repaired: only changed slugs are merged, and unrelated pending timer state is retained. Rocket, Mantis and Groot completed independent systems, correctness/security and product lanes; I reconciled their evidence and checked the runner lifecycle. Later invalidation cannot undo an occurrence that already completed before the save settled.
Head e71ab26c907a93eae0e7da1e2d1ceb843a0baef5; base dcd3960c9f6613ded457232903d250caa6e7e1fd. Scope: three-file repair delta from d914c830ebfaa007b042a52449c89e0871014d55, prior finding and affected callers, not a new exhaustive audit of unchanged feature code. Public description (no attachments), commit messages and repair publication surface inspected. Source-only: no tests, builds or app execution; current CI was not assessed. Live persistence/concurrency, native focus/error-retry, performance and human acceptance remain unverified. This is a non-blocking COMMENT review, not approval.
Plan: restructure agent storage instead of another patch roundThe last several review rounds on this PR found the same kind of bug in a new place each time. The latest finding (a timer that uses an occurrence while its own rearm saves) is one more. I fixed each case where it was found. Those fixes are correct, but they do not remove the cause, so I expect more. I will change the structure in this PR. Why the bugs keep coming1. File storage looks like 2. No single owner changes an agent's record. Owner settings, the attention tools, timer progress, retype and the migrations each copy the whole record from a snapshot and write all of it back. The snapshot can be the shown record, the one still saving, or storage. Each pair of writers that overlap is a new bug: timer vs settings save, timer vs another timer's rearm, and now timer vs its own rearm. The The old What I will change
Scope and limits
I will reply to the open thread when the change is pushed. |
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes's account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/user-flow) lanes.
Follow-up review of head 8aa080b against base dcd3960; repair delta from previously reviewed e71ab26. The prior pending-rearm occurrence-budget defect is repaired in source. One new P2 is recorded inline. Assessment: 8/10 pending that lifecycle repair.
Inspected the three-file repair, relevant runner/storage/caller context, public description (no attachments), and commit messages. Source-only: no tests, builds, app execution, live persistence/concurrency reproduction, native focus/retry testing, current CI assessment, or human acceptance. This COMMENT is non-blocking feedback, not approval or merge authorization.
1c35a19 to
f3ef785
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: one P2 finding, detailed inline. The AgentStore conversion leaves the documented Codex live acceptance caller on the old storage interface, so that workflow fails when saving its first session. Source assessment: 8/10 until that caller is adapted. The production plugin supplies the new store correctly.
The prior timer-wake finding is addressed in source: pending settings changes wake their runner on settlement, and timer progress no longer blocks a free Interest lane. Rocket, Mantis and Groot completed independent systems/lifecycle, correctness/security/concurrency and product/accessibility lanes; I reconciled their evidence and checked the supported callers. This is a follow-up of the storage refactor, timer repair and rebase integration, not a new exhaustive audit of unchanged feature code.
Head c1479a63f9575b9964fd2c9cf0698015347fed56; base a5b3391ecd2f7cfc141ba6ecd0886226daaaee9a. Public description (no attached images), twelve commit messages and changed publication surface inspected. Shared Select/Button and host Dialog ownership is preserved. Source-only: no PR code, tests, builds or app execution; CI was not assessed. Live migration/concurrent-host persistence, native keyboard/error-retry focus, themes/sizes, performance and human acceptance remain unverified. Non-blocking COMMENT only, not approval or merge authorization.
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source follow-up via Wes’s account: no additional changes requested. The prior Codex live-acceptance finding is addressed: the fixture now provides AgentStore get/keys and promise-returning set/add, including deletion and create-if-absent behavior. The thread-name assertion matches the existing title plus conversation-tag format. Source assessment: 9/10 for this repair scope.
This uses the small-follow-up solo exception: comparison with previously team-reviewed c1479a6 shows only src/bundled/codex/live.mjs changed (17 additions, 4 deletions), with the same base and unchanged feature source. I checked the repair against AgentStore, CodexRuntime save/load and sessionName/sessionTag, then reread the delta for integration mistakes. No new independent team lanes were run.
Head 9eb07892a1425aee31e5c848ec76a64d562460b6; base a5b3391ecd2f7cfc141ba6ecd0886226daaaee9a. Public description (no attachments), commit messages and changed publication surface inspected. Source-only: no acceptance command, tests, builds or app execution; current CI was not assessed. Live saved-session recovery, native focus/error-retry behavior and human acceptance remain unverified. This is a bounded repair follow-up, not a new exhaustive audit of unchanged feature code. Non-blocking COMMENT only, not approval or merge authorization.
The app kept each agent's settings, the owner's teams, unfinished setups, the Claude and Codex sessions and their default settings in the WebView's localStorage, which no program outside the app can read. Keep them in agents/state/ beside identities.json instead, one file per key, through two native commands. The app reads the folder once before it starts, keeps a copy in memory, and saves each write to its key's file in order. On first start it moves the agent keys it had in localStorage into the folder. Each agent's record and its Claude sessions now have their own key, so two programs that run different agents never write over each other. Agent types get the storage from the agents service (agents.storage). Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
A failed file write during the one-time moves (the shared record value, the shared Claude sessions value, the agents2 rename) still removed the source, so the next start lost that agent's settings or sessions. Each move now removes its source only after every new copy is saved. A failed write also no longer passes as saved: agent storage puts back the key's saved value, saves of settings, providers and teams reject, and the same value can be saved again. A failed timer-progress save still keeps the run's memory, so a timer does not run again at once. Agent state keys are limited by their file name (255 bytes), not by a 200-byte key, so Codex sessions on long community hosts are saved. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
A settings, team or attention change was shown before its save finished and stayed shown when the save failed. The settings form then saw no change and turned off Save, and an agent's watch or interest_set edit reported success. Each now goes back to what storage still has when its save fails, and an attention write passes the error to the tool. Only a timer's progress stays, so the timer does not run again at once. The first move out of localStorage deleted a key whose copy failed from the storage the app reads, so the app started with no teams and default settings, and a later save replaced them. Now every key is copied before any leaves localStorage, and if a copy fails, or loading takes longer than 15 seconds, the app uses localStorage until the next start. The agent keys still in localStorage then replace the copies in the folder, since the app wrote them last. A key whose encoded file name is over 255 bytes, such as a Codex session key on a long community host, could not be saved. Its file is now named by the key's SHA-256 and holds the key with the value. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
…saved Each start let agent keys in localStorage replace the agent storage files. After the first move, localStorage has no agent state, so a start that could not use agent storage began with none, and what it saved then replaced the full files at the next start: for example, a session list with one conversation replaced one with three. Agent storage now keeps a marker once every key was moved. After that, the files win, and keys from such a start only fill in keys the files do not have. A settings save was shown before it was saved. The Codex settings form resets its draft when the shown settings change, so when the save failed, the owner's edits were replaced with the saved settings and Save was turned off. Settings are now shown only once they are saved. Later changes still build on a write that is being saved. Timer progress is still shown at once. The Claude Code and Codex provider defaults dialogs closed before the defaults were saved, and a failed save was lost at the next start. They now wait for the save, close only when it succeeds, and otherwise keep the draft and show the error, so the owner can try again. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
- A full store no longer stops startup. If the move of the old shared agent records fails, the app logs it and reads the old value, which stays for the next start to move. - Unfinished hosted-agent changes now wait for their save. When it fails, Delete and setup report the error and the app shows the saved list again, so a restart shows the same state. - The default-model and thinking choices stay fixed while defaults save, so the dialog never closes over a choice it did not save. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Catch-up progress was one shared value. With agent state in shared files, two programs that run different agents each rewrote the whole value from their own copy, so one could undo the other's saved progress and an agent could get already handled events again after a restart. Each agent's progress now has its own key, and a save writes only the agents whose progress changed. The old shared value is split into the per-agent keys at start, before any progress is read, and removed once they are saved. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Two programs can start from the old shared value before either moves it. If one moves it and runs its agent on, the other's late move wrote its older copy over the newer file, so a restart could replay handled events or bring back an older record. A move now adds each agent's key only where no file holds it. The native store does that in one step and returns the file's value, which the copy then takes. Catch-up progress is also saved only for the agents this program moved since its last save, so an older copy of another program's agent is never written. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
A timer that came due while a settings or attention change was still saving wrote the shown record with its progress, after the change. The change was lost on disk and in the app, though its Save succeeded. Timer progress now goes into the record being saved, and the app still shows the saved settings until that save finishes. A save refused at once by storage (localStorage quota) now throws at once again, so the runner does not start a timer whose progress it could not save. Before, the refusal became a logged rejection, and the timer ran again after each run. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
…ress Timer progress replaced the whole timers map of a pending change with the shown one. So when an agent or owner rearmed timer A while timer B came due, B's progress put back A's old armed time, and A then got a new budget of runs. The runner now reports only the timers whose state changed. The service copies each into the pending change only when that change left the timer's state as shown; a timer it rearmed, restarted or removed keeps that. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
Timers ran from the shown record while a change to it was still saving, and their progress was then merged into that change. Each kind of change needed its own merge rule, and a timer rearmed during the save could run from its old schedule and lose that run from its count. Now a timer does not start while a save of its agent's record is pending; the next tick runs it from the record that save left. So every write to the record starts from the latest one, and the progress merge is gone. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
…wner Review rounds on this PR kept finding the same two kinds of bug in new places. This fixes their cause instead of the next case. Agent storage is now an explicit async store (AgentStore). Its set and add return a promise that settles once the value is saved and rejects when it was not. The fake Storage over the agent state files, and the persisted() and afterSaved() helpers callers had to remember, are gone. The compiler now shows every caller that writes agent state. Doing so found one more: an imported team's save was not awaited, so a failed save was not reported as a team error. Each agent's record now changes only through one ordered queue in the agents service. Owner settings, the agent's attention tools, provider changes, removal and timer progress all send a change. Each applies to the newest saved record after the change before it settles. Timer progress is a change to run state only: when a timer was rearmed or restarted since the pass read it, the new deadline stays and only the occurrences the pass used are added. The shown/keep/saving rules are gone. Timers still wait while another change to their record is queued, so a pending rearm keeps its budget. A timer whose progress cannot be saved keeps it in memory, as a failed save did before. It now runs only when it is due, not never: an async store cannot refuse at once. Cross-process writes are still a documented limit. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
… saved Timers wait while a change other than timer progress is waiting or saving, since it may rearm, restart or remove one. When the last such change settled, nothing woke the runner, so a timer due meanwhile waited for the next five-second tick and could expire first. The change owner now wakes the agent's runner once its last change is saved or fails. Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> Signed-off-by: Logan Johnson <loganj@squareup.com>
The live acceptance check (`bin/node src/bundled/codex/live.mjs`) still
passed a `{ getItem, setItem }` fixture to CodexRuntime. Its first session
save threw, since agent storage now has `get`, `set`, `add` and `keys`, and
JavaScript callers are not type-checked. Its thread name check also predates
the conversation tag in thread names (#846).
Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz>
Signed-off-by: Logan Johnson <loganj@squareup.com>
9eb0789 to
d3786b6
Compare
wesbillman
left a comment
There was a problem hiding this comment.
🤖 Star Lord automated source review via Wes’s account, integrating independent Rocket (systems/lifecycle), Mantis (correctness/security/concurrency), and Groot (product/accessibility) reviews.
No new actionable findings in this revision-focused review. Source-review assessment: 9/10.
Reviewed head: d3786b6
Reviewed base: dc305c9
Previous reviewed head: 9eb0789
The 13-commit range-diff retains 11 identical patches; the remaining two differ only in service import context for the Me→Solo rename. We checked the rebased service/runner and Claude/Codex routing integration, startup and fallback handling, ordered persistence and session-storage consumers. The prior Codex acceptance-fixture repair remains present. Provider-default save failures retain drafts and expose retryable errors; the shared button preserves focus during saving. The public description and commit messages were inspected; the description has no attached images.
Scope and limits: this is a follow-up integration review, not a fresh exhaustive review of unchanged feature patches. Source only: no tests, typecheck, builds, app launches, or PR code execution. Live migration/restart and cross-process behavior, rendered accessibility/focus, and performance remain unverified. A single hosted-check snapshot had jobs still running; Windows native validation was skipped. This COMMENT is not an approval or merge authorization.
🤖
Summary
localStorage). Only the app can read that. So a program outside the app could run the agent's code, but not with the agent's settings, its team instructions, or its saved conversations.agentsfolder where it already keeps the list of agents. The standalone program in feat(agent-host): run a saved agent without the desktop app #967 reads and writes the same files. An agent then behaves the same in both places.Why
Buzz agents are AI assistants, such as Claude or Codex, that a person sets up in the Buzz desktop app. They answer when someone mentions them in a channel, and they can also watch for events and run on a timer. Today an agent runs only while its owner's desktop app is open, because the code that runs agents lives inside the app.
The goal of this stack is a small command-line program that runs an agent with the app closed. It must use the same code and the same saved state as the app, so the agent behaves the same wherever it runs.
Stack
Review in order. Each PR keeps the app working.
buzz-agent-host, the program that runs an agent with the app closed.What moves
localStoragevalue for all agentslocalStoragelocalStoragelocalStoragevalue for all agentslocalStoragevalue per agent and communityThe files are in
agents/state/in the app's data folder, besideidentities.json.Details
src-tauri/src/agent_state.rs): two commands, load all and set one key. Each key is one file. A write goes to a temporary file first and is then renamed, so a crash leaves the last complete copy. Characters that are not safe in a file name are written as%XX. If that name is longer than 255 bytes (the longest file name macOS, Linux and Windows all allow), as a Codex session key on a long community host can be, the file is named~plus the key's SHA-256 instead, and it holds the key with the value so a load gets the key back. The standalone host (feat(agent-host): run a saved agent without the desktop app #967) names files the same way.src/features/agents/state.ts): web page storage reads must be synchronous, so the app reads all the files once before it starts (main.tsx) and keeps a copy in memory. Each write changes the copy at once and is then saved to its file, in order. If the folder cannot be read, or reading and moving take longer than 15 seconds, the app useslocalStoragefor that start, as before, and the window still opens.localStorageis copied into the folder. Agent keys are inlocalStorageonly before the first move, or after a start that could not use the folder, so they are the newer copy and replace what the folder has. They are removed fromlocalStorageonly once every copy is saved. If any copy fails, the app useslocalStoragefor that start, so nothing it shows is missing, and the next start tries again.localStoragedirectly. They now useagents.storage, which the app provides.Limits
interest_setchange) reports the failure. A failed save of timer progress only logs: the app keeps the progress in memory so the timer does not run again at once, but after a restart the timer can run once more.localStoragebecause a copy failed, and the owner deletes an agent's settings or a team during that start, a copy saved to the folder before the failure can bring it back on the next start.