Skip to content

docs(state): add migration plan issues#244

Open
cooper (czxtm) wants to merge 3 commits into
graphite-base/244from
05-29-docs_state_migration_plan_issues
Open

docs(state): add migration plan issues#244
cooper (czxtm) wants to merge 3 commits into
graphite-base/244from
05-29-docs_state_migration_plan_issues

Conversation

@czxtm
Copy link
Copy Markdown
Member

Summary

Test Plan

Docs

  • Docs updated (companion PR in darkmatter/nixmac-web: #___)
  • No docs update needed

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 29, 2026

Warnings
⚠️

Your ## Test Plan section is empty or only contains placeholder text. Describe the steps a reviewer should take to verify this change, or check No test plan needed.

📋 PR Overview

Lines changed 358 (+334 / -24)
Files 2 added, 2 modified, 0 deleted
Draft / WIP no
Has Test Plan no
No Test Plan Needed no
New UI components no
New Storybook stories no
New Rust modules no
New TS source files no
New tests no
package.json touched no
Cargo.toml touched no
Infra / CI touched no

🔬 Coverage

Report Lines Statements Functions Branches
apps/native/coverage/coverage-summary.json 17.9% 17.9% 30.9% 54.1%

Generated by 🚫 dangerJS against 81f71f9

@czxtm cooper (czxtm) changed the base branch from cm/configurable-derive to graphite-base/244 May 29, 2026 22:26
Co-authored-by: cooper <czxtm@users.noreply.github.com>
Comment thread .beads/issues.json
Comment on lines +1 to +42
{"_type":"issue","id":"nixmac-h85.2","title":"Phase 2: migrate SQLite access to Diesel pooled connections","description":"Replace per-operation rusqlite::Connection::open calls with a Diesel SQLite r2d2 pool managed by tauri::State.\n\nScope:\n- Add Diesel dependencies and embedded migrations.\n- Snapshot the current schema into apps/native/src-tauri/migrations as the initial Diesel migration baseline.\n- Generate/maintain schema.rs for changesets, commits, evolutions, queued_summaries, change_summaries, bare_changesets, and any other current tables.\n- Define typed models where the mapping is straightforward.\n- Port call sites in this order: db/commits.rs, db/evolutions.rs, db/changesets.rs, db/restore_commits.rs, db/store_bare_changeset.rs, db/store_new_changeset.rs, db/store_evolved_changeset.rs, summarize/find_existing.rs, summarize/queue_summarizer.rs, state/build_state.rs.\n- GUI startup and CLI mode initialize the same pool and run migrations.\n\nNon-goals:\n- No schema redesign.\n- No summary/checkpoint model changes.\n- No removal of SQLite.\n","design":"Create a DbPool newtype and keep raw sql_query as an allowed escape hatch for recursive or aggregate changeset queries. Do not redesign the schema in this phase; preserve current tables and semantics so later state changes are isolated from the DB-client migration.","acceptance_criteria":"apps/native/src-tauri uses diesel, diesel_migrations, and r2d2 for SQLite; migrations snapshot the current schema and run at startup; DbPool is managed in tauri::State for GUI and CLI modes; listed rusqlite open sites no longer open fresh connections; behavior and schema are unchanged; tmp-DB migration tests pass.","status":"open","priority":1,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:17:46Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:17:46Z","labels":["architecture","backend","database","diesel","state-management"],"dependencies":[{"issue_id":"nixmac-h85.2","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:12:25Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.1","title":"Phase 1: introduce Slice\u003cT\u003e state infrastructure","description":"Build the typed slice primitive the architecture doc sketches, without moving existing call sites yet.\n\nScope:\n- Slice\u003cT\u003e with async read() and write(\u0026app) APIs.\n- SliceWriteGuard derefs mutably, emits the configured change event, and flushes persistence when dropped.\n- Persistence trait with AppDataJson and RepoScopedJson implementations.\n- Registry support so commands such as dev_configs_list/dev_config_set can enumerate future slices and schemas without app.store(path) reads.\n- Tests covering JSON persistence, event emission, and global vs repo-scoped routing.\n\nNon-goals:\n- No preference migration yet.\n- No frontend store changes yet.\n- No rusqlite/Diesel work here.\n","design":"Add apps/native/src-tauri/src/state/slice.rs or an equivalent state module. Use Arc\u003cdyn Persistence\u003e for pluggable storage. RepoScopedJson resolves through storage::configurable_scope::repo_store_path and must fall back to defaults when config_dir is unavailable. Keep this primitive independent from specific app state so later phases can migrate incrementally.","acceptance_criteria":"Slice\u003cT\u003e supports typed read/write access; SliceWriteGuard emits \u003cslice\u003e_changed and flushes persistence on Drop; AppDataJson and RepoScopedJson persistence backends exist; registry exposes registered slice metadata for commands; round-trip, event emission, and scope-routing tests pass; no application behavior changes.","status":"open","priority":1,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:15:28Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:15:28Z","labels":["architecture","backend","state-management"],"dependencies":[{"issue_id":"nixmac-h85.1","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:10:08Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":0,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"nixmac-cmu","title":"Rust dead_code errors in e2e_runtime.rs (release build)","description":"cargo build fails on apps/native/src-tauri/src/e2e_runtime.rs with five dead_code/unused_imports errors:\\n\\n- unused import: std::fs\\n- constant RUNTIME_FILE_NAME is never used\\n- constant BUNDLE_ID is never used\\n- struct E2eRuntimeFile is never constructed\\n- function runtime_file_path is never used\\n\\nFile was added in 911b08e4 (PR #90, Peekaboo Product Proof lane) as debug-only runtime overrides. The cfg-gating on consumers excludes them in release builds, but the declarations are unconditional, so cargo (with warnings-as-errors) flags them as dead.\\n\\nSurfaced now (not earlier) because env.ts fix (9cc24118) lets the build progress past tsc into cargo. Previously the run failed at tsc with TS6133/TS6192/TS2339 errors and never reached cargo compilation.\\n\\nFix options:\\n1. Add #[cfg(debug_assertions)] to the affected declarations\\n2. Add #[allow(dead_code)] on the affected items\\n3. Use the declarations in release builds too (probably wrong intent)\\n\\nOption 1 is most correct semantically — matches the comment 'Release builds ignore the file.'\\n\\nNot blocking PR #195 (nightly-release): this PR adds shell scripts / workflow YAML / one Schema migration, zero Rust changes. Surfaced as part of the cascade unblocked by nixmac-62s fix.","status":"open","priority":1,"issue_type":"bug","owner":"me@cooperm.com","created_at":"2026-05-24T10:38:44Z","created_by":"Cooper Maruyama","updated_at":"2026-05-24T10:38:44Z","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-62s","title":"Fix TypeScript errors blocking build on main","description":"The build.yaml check has been red on main since 2026-05-10 (commit bd658afc). Errors:\\n\\n- apps/native/src/components/widget/promptinput/prompt-input.tsx:20 — unused Plus import (TS6133)\\n- apps/native/src/components/widget/promptinput/prompt-input.tsx:22 — all imports unused (TS6192)\\n- apps/native/src/lib/env.ts:5 — Schema.BooleanFromString missing (TS2339)\\n- apps/native/src/lib/env.ts:10 — Decoder type mismatch (TS2345)\\n\\nLast green build: 502d2dfc on 2026-05-04. The env.ts errors look like effect-ts beta-version regression (effect@4.0.0-beta.62 in lockfile). Fix tsc errors so PR builds pass and the nightly-release shipping path is unblocked.\\n\\nDiscovered while triaging build failure on PR #195 (nightly-release feature, beads nixmac-srn).","status":"closed","priority":1,"issue_type":"bug","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-24T08:12:27Z","created_by":"Cooper Maruyama","updated_at":"2026-05-24T09:21:32Z","started_at":"2026-05-24T09:17:59Z","closed_at":"2026-05-24T09:21:32Z","close_reason":"Fixed in 44780754: removed unused Plus and DropdownMenu imports from prompt-input.tsx. env.ts errors did not reproduce — apps/native resolves effect to 3.21.0 (transitive) which still has BooleanFromString. tsc + vite build pass clean.","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-ntg","title":"Fix CI failures on filesystem branch","description":"Investigate the latest CI failures on branch claude/implement-filesystem-0EY4O, reproduce the root cause locally where possible, and apply the minimal fix with verification.","notes":"Local fixes applied for Build macOS App, Danger unit failures, and E2E artifact race. Verified: bun -F native build; bunx vitest run --project=unit --coverage --coverage.reporter=json-summary --coverage.reporter=text --reporter=basic; bash -n tests/e2e/ci-runner.sh; ReadLints on edited files.","status":"in_progress","priority":1,"issue_type":"bug","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-07T05:37:56Z","created_by":"Cooper Maruyama","updated_at":"2026-05-07T05:46:29Z","started_at":"2026-05-07T05:37:59Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.7","title":"Phase 7: split frontend view-model from UI state","description":"Split the current widget-store responsibilities into a backend mirror and UI-only state.\n\nScope:\n- Add apps/native/src/stores/view-model.ts with slices for backend-owned state: evolve, git/status view, build/rebuild view, changeMap/history as applicable, permissions, nix, darwinRebuild, evolution telemetry/events.\n- Add apps/native/src/stores/ui-state.ts for settings dialog state, history/filesystem visibility, feedback modal state, panic/error/editing details, prompt draft, processing/summarizing flags, console logs, and local analysis flags.\n- Add apps/native/src/view-model-sync/\u003cslice\u003e.ts modules as the only write path for mirrored backend state: hydrate with invoke('get_\u003cslice\u003e_state') and listen to \u003cslice\u003e_changed.\n- Migrate hooks and components away from manually setting gitStatus/evolveState/changeMap after commands; command return types stop carrying mirrored state unless needed for the command result itself.\n- Keep widget-store.impl.ts as a shim during migration.\n\nNon-goals:\n- No backend decommission here; this works against the Phase 3 compatibility layer.\n","design":"Use one Zustand view-model store composed from slices plus a separate UI state store. Actions in the view-model only invoke backend commands; all backend-owned state updates enter through sync modules, not components or hooks.","acceptance_criteria":"view-model.ts mirrors backend slices with no public data setters; ui-state.ts owns UI-only flags/drafts/modals/errors; each backend slice has a single view-model-sync module that hydrates via get_\u003cslice\u003e_state and listens to \u003cslice\u003e_changed; migrated hooks/components no longer manually set backend-owned state after invoke; widget-store.impl.ts is reduced to a compatibility re-export shim.","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:30:29Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:30:29Z","labels":["architecture","frontend","state-management","zustand"],"dependencies":[{"issue_id":"nixmac-h85.7","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:25:08Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.7","depends_on_id":"nixmac-h85.3","type":"blocks","created_at":"2026-05-28T23:43:00Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.6","title":"Phase 6: serialize summarizer work through a tokio mpsc worker","description":"Replace the implicit SQLite-as-scheduler pattern with one startup worker and a tokio mpsc queue.\n\nScope:\n- Add SummarizerState { tx: mpsc::Sender\u003cSummarizeJob\u003e } as managed tauri::State.\n- Spawn one worker at startup that awaits rx.recv() and calls queue_summarizer::process.\n- Change pipelines/fresh_changeset.rs and pipelines/evolved_changeset.rs to send jobs rather than spawning their own summarizer tasks.\n- Remove the \"is queue empty?\" gate/check pattern.\n- Keep queued_summaries as the durable Diesel-backed table so jobs survive restarts and missed in-memory sends can be recovered.\n- Add tests for concurrent sends, single-worker behavior, and no double-processing.\n\nDependency note:\n- This phase depends on the Diesel pool so worker DB access is pooled and migration-backed.\n","design":"Use mpsc for in-process coordination and keep queued_summaries as durable recovery state. The queue is not a replacement for the database; it removes the current racy 'check queue then spawn' coordination pattern.","acceptance_criteria":"SummarizerState with mpsc::Sender is managed in tauri::State; exactly one worker is spawned at startup; fresh/evolved changeset pipelines enqueue jobs instead of spawning processors; queued_summaries remains Diesel-backed for restart recovery; concurrency tests show N sends produce one worker path and no double-processing.","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:27:45Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:27:45Z","labels":["architecture","backend","database","state-management","summarizer"],"dependencies":[{"issue_id":"nixmac-h85.6","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:22:24Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.6","depends_on_id":"nixmac-h85.2","type":"blocks","created_at":"2026-05-28T23:40:27Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.5","title":"Phase 5: retarget Configurable derive to scoped slices","description":"Rewrite the Configurable runtime and derive output so configurable settings are stored through the new slice infrastructure.\n\nScope:\n- Add #[config(scope = \"repo\")] and #[config(scope = \"global\")], defaulting to global.\n- Generated load/set_field/schema functions go through Slice\u003cT\u003e and inherit event emission, caching, and persistence.\n- EvolutionLimits becomes repo-scoped and evolve/mod.rs reads app.state::\u003cSlice\u003cEvolutionLimits\u003e\u003e().read() instead of loading from disk each iteration.\n- dev_configs_list and dev_config_set walk the slice registry and operate through registered schema/set_field functions.\n- commands/settings_io.rs export/import serializes/deserializes slice-backed settings and keeps sensitive-key filtering.\n\nNon-goals:\n- Do not migrate API keys into JSON; keychain remains the credential backend.\n","design":"Keep the Configurable derive as the declarative knob surface, but remove direct coupling to tauri-plugin-store/store_path_fn. This phase should retire the old store_path/store_path_fn direction once slice scopes are available.","acceptance_criteria":"#[config(scope = \"global\"|\"repo\")] is supported with global as default; generated load/set/schema functions use the Slice registry and persistence backends; EvolutionLimits is repo-scoped and read from Slice\u003cEvolutionLimits\u003e; dev_configs_list/dev_config_set enumerate registered slices; settings export/import is slice-aware and still filters sensitive values.","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:25:09Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:25:09Z","labels":["architecture","configurable","preferences","state-management"],"dependencies":[{"issue_id":"nixmac-h85.5","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:19:48Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.5","depends_on_id":"nixmac-h85.1","type":"blocks","created_at":"2026-05-28T23:35:25Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.5","depends_on_id":"nixmac-h85.4","type":"blocks","created_at":"2026-05-28T23:37:56Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":2,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.4","title":"Phase 4: split preferences into global and repo-scoped slices","description":"Make preference scope explicit and stop mixing preferences, caches, and runtime state in one settings blob.\n\nScope:\n- Add GlobalPreferences for hostAttr, configDir, repoRoot, diagnostics, provider/model defaults, API base URLs, developer/update settings, confirmation prefs, autoSummarizeOnFocus, scanHomebrewOnStartup, defaultToDiffTab, and other app-wide/per-device knobs.\n- Add RepoPreferences for maxIterations, maxBuildAttempts, and future repo-scoped tuning.\n- Persist GlobalPreferences through AppDataJson and RepoPreferences through RepoScopedJson.\n- Keep storage/credential_store.rs and keychain-backed API keys unchanged.\n- Move cachedModels_*, cachedGitStatus, and promptHistory out of preferences into dedicated slices or memory-only state.\n- Add one-shot migration from the old tauri-plugin-store blob into the typed slices.\n- Shrink storage/store.rs to a compatibility/migration layer.\n\nNotes:\n- Existing repo-scoped Configurable issue nixmac-gr3 overlaps this work.\n- Existing UiPrefs-to-Configurable umbrella nixmac-e53 and its subissues should be reconciled with this scoped preference design.\n","design":"Use AppDataJson for per-device/global preferences and RepoScopedJson for repo-following preferences such as EvolutionLimits. Existing issues nixmac-gr3 and nixmac-e53 should be folded into or superseded by this phase instead of continued as a parallel architecture.","acceptance_criteria":"GlobalPreferences and RepoPreferences exist as typed managed state; API keys remain in credential_store/keychain; cachedModels_*, cachedGitStatus, and promptHistory are no longer written as preferences; first-launch migration reads legacy tauri-plugin-store data and writes new JSON files; legacy store is retained only as a migration shim.","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:22:41Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:22:41Z","labels":["architecture","preferences","state-management"],"dependencies":[{"issue_id":"nixmac-h85.4","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:17:20Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.4","depends_on_id":"nixmac-h85.1","type":"blocks","created_at":"2026-05-28T23:32:59Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.3","title":"Phase 3: migrate backend runtime owners to slices","description":"Move backend runtime state off tauri-plugin-store and ad-hoc emit paths onto Slice\u003cT\u003e, while preserving the architecture response's caution about computed git/build state.\n\nScope:\n- Replace state/evolve_state.rs tauri-plugin-store plumbing with Slice\u003cEvolveState\u003e; keep recompute_step as EvolveState behavior.\n- Split watcher emissions into slice-specific updates where backend-owned state changes.\n- Keep git:status-changed / WatcherEvent as a deprecated compatibility event for one release.\n- For GitState, BuildState, and ChangeMapState, decide per value whether it is owned runtime state or derived from git/nix/SQLite; implement slices only for owned state and expose read-through hydrate commands for derived state.\n- Ensure current_state_built and related build-state reads no longer open ad hoc DB connections after Phase 2 is available, or record the dependency clearly if that port remains staged.\n\nNon-goals:\n- No frontend migration beyond preserving compatibility events.\n- No decommission of old events yet.\n","design":"Start with EvolveState because it is clearly backend-owned runtime state. Treat GitState and BuildState carefully: where the source of truth is git status or nix generations, expose hydration/events as a view over that source instead of inventing durable mutable state. Keep the old WatcherEvent during migration so the frontend can split safely.","acceptance_criteria":"EvolveState and other backend-owned runtime state write through Slice\u003cT\u003e; watcher emits slice-specific events while retaining deprecated git:status-changed compatibility for one release; state/build and change-map paths either use slices or are documented as derived/read-through with equivalent hydration commands; backend tests cover event compatibility and independent event ordering.","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-28T23:20:15Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:20:15Z","labels":["architecture","backend","state-management"],"dependencies":[{"issue_id":"nixmac-h85.3","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:14:54Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.3","depends_on_id":"nixmac-h85.1","type":"blocks","created_at":"2026-05-28T23:30:30Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"nixmac-h85","title":"Apply state-management architecture direction","description":"Turn the state-management architecture review and response into an executable migration sequence for the current branch.\n\nLocked decisions:\n- Repo-scoped preferences are a first-class scope alongside global app-data preferences.\n- SQLite stays for project/summarization data; replace rusqlite with Diesel plus an r2d2 pool in tauri::State.\n- The Configurable derive stays, but targets the new Slice infrastructure and accepts an explicit persistence scope.\n- Backend slices should own runtime/persistent app state where the backend is the source of truth. Git/build values that are better computed from git or nix generations should stay read-through or derived instead of becoming artificial mutable state.\n- Frontend view-model mirrors backend state through hydrate + event sync. UI-only state lives separately.\n\nThis epic exists to keep the architecture migration reviewable in sequenced phases instead of one cross-cutting rewrite.\n","acceptance_criteria":"All phase issues are closed or explicitly superseded; SQLite remains for project/summarization data but uses Diesel pooling; runtime and preference state have typed tauri::State-backed slices; frontend view-model and UI state are separated; legacy tauri-plugin-store runtime usage and widget-store shim are removed.","status":"open","priority":2,"issue_type":"epic","owner":"me@cooperm.com","created_at":"2026-05-28T23:13:21Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:13:21Z","labels":["architecture","state-management"],"dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-15c","title":"Address PR configurable macro review checks","description":"Add the missing Storybook stories, Rust module tests, and PR Test Plan required by the review checks on PR #201.","status":"closed","priority":2,"issue_type":"task","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-25T12:50:53Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T13:05:20Z","started_at":"2026-05-25T12:52:46Z","closed_at":"2026-05-25T13:05:20Z","close_reason":"Added missing settings Storybook stories, Rust module tests, and PR Test Plan for PR #201.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-4lz","title":"Tweak diff diagnostics padding and default theme","description":"Add right-side padding in the diff editor for LSP diagnostics readability, and include the minted theme from the local apathy-theme checkout as the app default.","status":"closed","priority":2,"issue_type":"task","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-25T12:32:27Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T12:44:20Z","started_at":"2026-05-25T12:34:26Z","closed_at":"2026-05-25T12:44:20Z","close_reason":"Added Minted theme defaults and right padding for diff editor diagnostics","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-gr3","title":"Add repo-scoped storage backend for Configurable settings (.nixmac/settings.json)","description":"Today, Configurable structs read from tauri-plugin-store's default location (OS app data dir) — per-device, doesn't survive reinstall, doesn't sync across machines. The user's nix-darwin config repo IS the source of truth for their machine setup, and it already syncs across devices (they clone/pull it).\n\nAdding a repo-scoped store at \u003cconfig_dir\u003e/.nixmac/settings.json lets settings that are 'about how I use nixmac' (max iterations, provider preferences, confirmations) ride along with the config repo via git. Per-device settings (developer_mode, pinned_version, update_channel) stay in the OS app data dir where they belong.\n\nDesign:\n- configurable-derive learns #[config(store_path_fn = \u003cpath\u003e)] in addition to #[config(store_path = \"...\")]. The fn variant calls a path resolver at runtime, so the derive stays decoupled from nixmac internals.\n- New storage::configurable_scope module exposes repo_store_path(app) -\u003e Result\u003cString\u003e which returns absolute path to \u003cconfig_dir\u003e/.nixmac/settings.json and ensures the dir exists.\n- EvolutionLimits opts into repo scope (these are user prefs that should follow the user).\n- Auto-write a small .nixmac/README.md the first time the dir is created, so a curious git user understands what's there.\n\nOut of scope for this issue:\n- Migration of existing local-store EvolutionLimits values (users with non-default values will see them reset to defaults on first launch after upgrade — acceptable since this is dev-mode/pre-launch software)\n- UiPrefs migration (still tracked under nixmac-e53)\n- UI toggle to disable repo sync (premature — gitignore is the existing escape hatch)","acceptance_criteria":"repo_store_path() function returns absolute path under \u003cconfig_dir\u003e/.nixmac/; #[config(store_path_fn = ...)] supported by the derive; EvolutionLimits uses repo scope; on first read, .nixmac/ directory and a small README.md are auto-created in the config dir; existing per-device behavior preserved for any Configurable still using store_path; cargo + bun tests green","status":"open","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-25T03:21:14Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T03:21:14Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-4yh","title":"Rename VLLM provider label","description":"Rename the provider shown in settings from VLLM to OpenAI Compatible.","status":"closed","priority":2,"issue_type":"task","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-25T03:10:50Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T03:21:26Z","started_at":"2026-05-25T03:12:41Z","closed_at":"2026-05-25T03:21:26Z","close_reason":"Renamed settings provider label from vLLM to OpenAI Compatible","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-cqb","title":"Add Tuning + Backup/Restore sections to Developer settings tab","description":"Move Evolution Limits (max_iterations, max_build_attempts) out of the AI Models tab (where it's awkward) into a new Tuning section in the Developer tab. Add a sibling Backup \u0026 Restore section with Export/Import settings.json buttons.\n\nUX:\n- Tuning section: home for behavior knobs (currently 2 numbers, will grow with future Configurable structs)\n- Backup \u0026 Restore section: Export button (sanitized by default — strips API keys; opt-in checkbox to include); Import button (replace entire store, with confirmation dialog)\n- Both gated behind existing developerMode toggle (no new gating needed — they live in the already-gated Developer tab)\n\nBackend:\n- New Tauri commands: settings_export(path, include_secrets) -\u003e Result\u003c()\u003e, settings_import(path) -\u003e Result\u003c()\u003e\n- Denylist for sanitized export: openrouterApiKey, openaiApiKey, vllmApiKey, and anything matching *ApiKey naming convention\n- Import validates the JSON structure, then replaces the store contents (replace semantics, not merge)\n\nFrontend:\n- Move Evolution Limits inputs out of ai-models-tab.tsx into developer-tab.tsx Tuning section\n- Add Backup \u0026 Restore section with file-picker dialogs via tauri-plugin-dialog\n\nSnapshot test for ai-models-tab.stories.tsx will need updating after the move.","acceptance_criteria":"Evolution Limits moved out of AI Models tab; Tuning section visible in Developer tab; Backup \u0026 Restore section with Export/Import buttons; export defaults to sanitized (API keys stripped); export checkbox opt-in adds them; import shows confirmation dialog then wholesale-replaces store contents; bun test green; cargo test green","status":"closed","priority":2,"issue_type":"feature","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-25T03:06:33Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T03:18:04Z","started_at":"2026-05-25T03:08:38Z","closed_at":"2026-05-25T03:18:04Z","close_reason":"Shipped in c1ca5bbd. Tuning + Backup/Restore sections live in Developer tab; Evolution Limits moved out of AI Models.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-8ka","title":"Configurable derive macro for typed dev settings (PoC)","description":"Build a Rust proc-macro derive Configurable that eliminates per-setting boilerplate. Today a single knob (e.g. max_build_attempts) touches 6+ files: store.rs getter/setter, UiPrefs + UiPrefsUpdate fields, ui_get_prefs read + ui_set_prefs write, TS bindings (via specta), and UI form. The derive co-locates config with the module that uses it; the dev settings panel auto-discovers via an inventory registry.\n\nPoC scope: implement the configurable crate + migrate EvolutionLimits (max_iterations + max_build_attempts) only. Validates the macro design before broader migration.\n\nBug-fix bonus: DEFAULT_MAX_BUILD_ATTEMPTS is declared in evolve/mod.rs:281 AND hardcoded as 5 in ui_prefs.rs:32 — the single-source-of-truth field default eliminates this drift.","acceptance_criteria":"configurable crate exists at apps/native/src-tauri/configurable/; EvolutionLimits struct with #[derive(Configurable)] replaces DEFAULT_MAX_BUILD_ATTEMPTS + DEFAULT_MAX_ITERATIONS; evolve/mod.rs:458 uses EvolutionLimits::load(app); existing store::get_max_iterations / set_max_iterations / get_max_build_attempts / set_max_build_attempts still work for back-compat during transition; specta-derived TS types still emitted for the new struct; cargo build + cargo test green","status":"closed","priority":2,"issue_type":"feature","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:27Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:53:19Z","started_at":"2026-05-25T02:43:21Z","closed_at":"2026-05-25T02:53:19Z","close_reason":"Shipped in 94a90036. EvolutionLimits migrated, macro proves the pattern, full migration tracked under nixmac-e53.","dependency_count":0,"dependent_count":6,"comment_count":0}
{"_type":"issue","id":"nixmac-k8d","title":"Snapshot platform drift in file-view.stories.tsx (Monaco mac class)","description":"Two related issues in apps/native/src/components/widget/summaries/file-view.stories.tsx 'New Json File' snapshot:\\n\\n1. Platform-dependent Monaco CSS class\\n Expected (committed): class=\"monaco-editor no-user-select mac showUnused...\"\\n Received (CI Linux): class=\"monaco-editor no-user-select showUnused...\"\\n Monaco adds the 'mac' class on macOS. Snapshot was captured on macOS, CI runs on ubuntu-latest, so the snapshot is non-portable.\\n\\n2. Monaco JSON worker fails to load in CI:\\n 'The file does not exist at .../sb-vitest/deps/json.worker.js?worker_file\u0026type=module ... Try adding it to optimizeDeps.exclude.'\\n 'You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker'\\n Stderr from the same test. Monaco's JSON worker isn't being bundled correctly for the storybook vitest run.\\n\\nFix options:\\n- Normalize the snapshot to strip platform-specific classes (e.g. a custom serializer that elides 'mac'/'linux'/'windows' classes)\\n- Mock Monaco's environment in the storybook setup to always claim a fixed platform\\n- Exclude monaco workers from vite's optimizer (per Monaco's vite integration docs)\\n- Configure MonacoEnvironment.getWorkerUrl in storybook setup so workers load\\n\\nSurfaced (along with nixmac-rva) once the env.ts fix (9cc24118) let tests progress to snapshot comparison. Not from PR #195 (nightly-release), which adds only shell scripts / workflow YAML / env.ts migration.","status":"open","priority":2,"issue_type":"bug","owner":"me@cooperm.com","created_at":"2026-05-24T16:43:34Z","created_by":"Cooper Maruyama","updated_at":"2026-05-24T16:43:34Z","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-rva","title":"Snapshot flake in rebuild-overlay-panel.stories.tsx (Framer Motion timing)","description":"Two snapshot tests fail intermittently due to Framer Motion animation-frame timing: 'Infinite Recursion Error 1' and 'Many Lines 1' in apps/native/src/components/widget/overlays/rebuild-overlay-panel.stories.tsx.\\n\\nThe component uses motion.div with initial={{ opacity: 0, y: 10 }} and animate={{ y: 0 }}. Snapshot captures HTML mid-animation; the exact frame depends on render speed. Diff between Expected and Received is a single property: transform: translateY(10px) vs translateY(1px).\\n\\nSurfaced after nixmac-62s env.ts fix landed (9cc24118) — previously these tests crashed at module load with 'Cannot read properties of undefined (reading ast)' so the snapshot comparison never ran. With env.ts working, the test progresses far enough to fail on the animation timing.\\n\\nFix options:\\n- Disable animations in test mode (motion.config or globalThis.__SNAPSHOT_NO_MOTION__)\\n- Wait for onAnimationComplete before capturing snapshot\\n- Snapshot only the post-animation steady state\\n- Mock framer-motion's \u003cmotion.div\u003e to render without transitions\\n\\nNot blocking PR #195 (nightly-release) — that PR doesn't touch this file or its dependencies; surfaced only because the env.ts fix it depends on is on main.","status":"open","priority":2,"issue_type":"bug","owner":"me@cooperm.com","created_at":"2026-05-24T10:28:20Z","created_by":"Cooper Maruyama","updated_at":"2026-05-24T10:28:20Z","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-srn","title":"Nightly develop→main release with minor version bump","description":"Add a GitHub Actions cron that nightly merges develop into main and tags a minor version bump (vMAJ.(MIN+1).0), skipping silently when develop has no new commits. Reuses existing build.yaml tag-push release path. Files: .github/workflows/nightly-release.yaml and ops/scripts/release/nightly-release.sh.","notes":"PR #195 opened: https://github.com/darkmatter/nixmac/pull/195. Awaiting review + merge. Will close on merge.","status":"in_progress","priority":2,"issue_type":"feature","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-24T07:16:31Z","created_by":"Cooper Maruyama","updated_at":"2026-05-24T08:10:38Z","started_at":"2026-05-24T07:16:53Z","dependencies":[{"issue_id":"nixmac-srn","depends_on_id":"nixmac-62s","type":"blocks","created_at":"2026-05-24T02:14:20Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-srn","depends_on_id":"nixmac-cmu","type":"blocks","created_at":"2026-05-24T03:38:48Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-srn","depends_on_id":"nixmac-k8d","type":"blocks","created_at":"2026-05-24T09:43:45Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-srn","depends_on_id":"nixmac-rva","type":"blocks","created_at":"2026-05-24T03:28:36Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":4,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-2pq","title":"overhaul provider and model selection - dont try to be special and veer away from how every other LLM app does this UX. Make the UX match opencode's UX for connecting a provider and selecting a model","status":"open","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-21T22:42:36Z","created_by":"Cooper Maruyama","updated_at":"2026-05-21T22:42:36Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-1t4","title":"when first installing the app - after choosing configuration directory and host, the main prompt window renders an error No","status":"open","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-21T22:41:22Z","created_by":"Cooper Maruyama","updated_at":"2026-05-21T22:41:22Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-031","title":"on the initial \"welcome to nixmac\" screen, after selecting configuration directory, the dropdown to select a host has no way to add a new one. I can only select an existing host. My guess is in the zero state this correctly adds a blank item but not when importing an existing configuration","status":"open","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-21T22:39:05Z","created_by":"Cooper Maruyama","updated_at":"2026-05-21T22:39:05Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-a4y","title":"on the initial \"welcome to nixmac\" screen, when selecint an existing directory, selecting a different directory doesnt update the value in the input. after a long delay, then it eventually updates.","status":"open","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-21T22:36:36Z","created_by":"Cooper Maruyama","updated_at":"2026-05-21T22:36:36Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-a7e","title":"Audit and prune local + remote branches to just main/develop","description":"Cleanup pass requested in session: commit WIP on current branch, fast-forward main/develop, delete all non-main/develop local branches, delete remote branches without open PRs.","status":"closed","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-18T07:10:42Z","created_by":"Cooper Maruyama","updated_at":"2026-05-18T07:18:45Z","closed_at":"2026-05-18T07:18:45Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-qvq","title":"Prevent OpenCode fast context overflows","status":"closed","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-07T01:29:51Z","created_by":"Cooper Maruyama","updated_at":"2026-05-07T01:31:45Z","started_at":"2026-05-07T01:29:57Z","closed_at":"2026-05-07T01:31:45Z","close_reason":"Lowered low-context LiteLLM limits and moved grunt off litellm/fast to avoid vLLM context overflow","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-sts","title":"Align OpenCode LiteLLM models with Zed","status":"closed","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-07T00:48:04Z","created_by":"Cooper Maruyama","updated_at":"2026-05-07T00:50:05Z","started_at":"2026-05-07T00:48:53Z","closed_at":"2026-05-07T00:50:05Z","close_reason":"Aligned OpenCode LiteLLM model IDs, limits, and capabilities with Zed settings","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-qms","title":"Clear actual Tauri plugin store from developer tab","status":"closed","priority":2,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-07T00:35:32Z","created_by":"Cooper Maruyama","updated_at":"2026-05-07T00:41:53Z","started_at":"2026-05-07T00:35:36Z","closed_at":"2026-05-07T00:41:53Z","close_reason":"Changed developer reset to clear the actual Tauri plugin-store files","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-0kv","title":"Add developer tools for clearing Tauri state","status":"closed","priority":2,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-07T00:26:57Z","created_by":"Cooper Maruyama","updated_at":"2026-05-07T00:34:07Z","started_at":"2026-05-07T00:27:00Z","closed_at":"2026-05-07T00:34:07Z","close_reason":"Added developer-tab controls for clearing transient Tauri state and UI buffers","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-h6s","title":"Use UI primitive for config setup choice","description":"Replace the custom New/Existing button pair in DirectoryPicker setup flow with an existing UI component primitive if one fits, preserving behavior and tests.","status":"closed","priority":2,"issue_type":"task","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-06T22:31:12Z","created_by":"Cooper Maruyama","updated_at":"2026-05-06T22:34:00Z","started_at":"2026-05-06T22:31:13Z","closed_at":"2026-05-06T22:34:00Z","close_reason":"Replaced custom setup choice buttons with shared ToggleGroup primitive","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-ivz","title":"Split config directory setup into new and existing flows","description":"Onboarding should first ask whether the user is creating a new config or using an existing one, then either name/create a new directory for bootstrap or browse/select an existing directory.","status":"closed","priority":2,"issue_type":"feature","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-06T22:20:11Z","created_by":"Cooper Maruyama","updated_at":"2026-05-06T22:30:38Z","started_at":"2026-05-06T22:20:12Z","closed_at":"2026-05-06T22:30:38Z","close_reason":"Implemented setup choice for new versus existing config directories","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-3ru","title":"Add review dedupe Storybook case","description":"Add a focused Storybook story for testing the Review summary change-chip dedupe behavior with repeated file hunks, then run Storybook locally for manual verification.","status":"closed","priority":2,"issue_type":"task","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-04T03:30:11Z","created_by":"Cooper Maruyama","updated_at":"2026-05-04T03:32:15Z","started_at":"2026-05-04T03:30:16Z","closed_at":"2026-05-04T03:32:15Z","close_reason":"Added a RepeatedFileHunks Storybook regression case and ran local Storybook for manual testing.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-dgc","title":"Dedupe review change list","description":"The Review summary can render the same manual change path many times, flooding the screen and making the actual changed files hard to inspect. Dedupe repeated file entries before rendering the unsummarized change chips, while preserving the underlying diff details.","status":"closed","priority":2,"issue_type":"bug","assignee":"Cooper Maruyama","owner":"me@cooperm.com","created_at":"2026-05-04T03:12:51Z","created_by":"Cooper Maruyama","updated_at":"2026-05-04T03:16:10Z","started_at":"2026-05-04T03:12:54Z","closed_at":"2026-05-04T03:16:10Z","close_reason":"Review change chips now collapse repeated file hunks and show a count badge for duplicates.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-h85.8","title":"Phase 8: remove legacy state-management shims","description":"Delete the compatibility surfaces kept alive during the migration.\n\nScope:\n- Remove legacy tauri-plugin-store runtime-state usage.\n- Delete or heavily shrink storage/store.rs once preference migration no longer needs it.\n- Remove the deprecated compound WatcherEvent / git:status-changed event after frontend consumers are on slice events.\n- Delete widget-store.impl.ts once all consumers use view-model + ui-state.\n- Remove settings/persistence migration shims after their support window.\n- Regenerate IPC types and update tests/snapshots affected by deleted compatibility APIs.\n\nNon-goals:\n- Do not add new behavior in cleanup; file follow-up issues for any newly discovered redesign.\n","design":"Only start this after backend slices, preferences, Configurable, summarizer worker, and frontend split have landed. This phase should be mostly deletion plus verification, not new architecture.","acceptance_criteria":"storage/store.rs legacy runtime-state paths are deleted or reduced to non-state helpers; tauri-plugin-store runtime-state usage is gone; WatcherEvent/git:status-changed compatibility event is removed; widget-store.impl.ts shim is deleted; migration shims are removed after their support window; tests and generated IPC types are updated.","status":"open","priority":3,"issue_type":"chore","owner":"me@cooperm.com","created_at":"2026-05-28T23:33:13Z","created_by":"Cooper Maruyama","updated_at":"2026-05-28T23:33:13Z","labels":["architecture","cleanup","state-management"],"dependencies":[{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85","type":"parent-child","created_at":"2026-05-28T23:27:52Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85.3","type":"blocks","created_at":"2026-05-28T23:45:33Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85.4","type":"blocks","created_at":"2026-05-28T23:48:01Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85.5","type":"blocks","created_at":"2026-05-28T23:50:35Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85.6","type":"blocks","created_at":"2026-05-28T23:53:09Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-h85.8","depends_on_id":"nixmac-h85.7","type":"blocks","created_at":"2026-05-28T23:55:43Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":5,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"nixmac-27g","title":"Migrate UpdatePrefs (pinned_version + update_channel) to Configurable","description":"Replace pinned_version + update_channel in UiPrefs with an UpdatePrefs Configurable struct. update_channel is an enum (UpdateChannel) — forces enum support in the macro. pinned_version uses double_option semantics (None vs Some(None)) — may need special handling or simplification during migration. Blocked by configurable PoC.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:43:00Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:43:00Z","dependencies":[{"issue_id":"nixmac-27g","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:13Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-elj","title":"Migrate ApiKeys (openrouter/openai/vllm) to Configurable — keychain-backed","description":"Trickiest of the migrations: openrouter_api_key, openai_api_key, vllm_api_key are stored in tauri-plugin-keyring (not the JSON store) — see store::get_effective_openrouter_api_key. The Configurable macro needs to support a #[config(backend = \"keyring\")] attribute or a separate KeyringConfigurable derive. Blocked by configurable PoC AND requires extending the macro.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:57Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:57Z","dependencies":[{"issue_id":"nixmac-elj","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:13Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-2tt","title":"Migrate ApiEndpoints (ollama/vllm base URLs) to Configurable","description":"Replace ollama_api_base_url, vllm_api_base_url in UiPrefs with an ApiEndpoints Configurable struct. May need to support Option\u003cString\u003e (unset = use default URL). Forces the design decision of how the macro handles optional fields. Blocked by configurable PoC.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:53Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:53Z","dependencies":[{"issue_id":"nixmac-2tt","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:12Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-orl","title":"Migrate AppBehaviorPrefs (auto_summarize, dev_mode, etc.) to Configurable","description":"Replace auto_summarize_on_focus, scan_homebrew_on_startup, default_to_diff_tab, developer_mode, send_diagnostics in UiPrefs with an AppBehaviorPrefs Configurable struct. Five booleans currently get five hand-written branches in ui_set_prefs. Blocked by configurable PoC.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:51Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:51Z","dependencies":[{"issue_id":"nixmac-orl","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:11Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-5nc","title":"Migrate ConfirmationPrefs (confirm_build/clear/rollback) to Configurable","description":"Replace confirm_build, confirm_clear, confirm_rollback in UiPrefs with a ConfirmationPrefs Configurable struct. Three booleans currently each get their own store::set_bool_pref branch — replaces them all with one derive. Blocked by configurable PoC.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:49Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:49Z","dependencies":[{"issue_id":"nixmac-5nc","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:10Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-2rr","title":"Migrate ModelPrefs (provider+model selections) to Configurable","description":"Replace evolve_provider, evolve_model, summary_provider, summary_model in UiPrefs with a ModelPrefs Configurable struct. Lives near AI orchestration code. Blocked by configurable PoC.","status":"open","priority":3,"issue_type":"task","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:45Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:45Z","dependencies":[{"issue_id":"nixmac-2rr","depends_on_id":"nixmac-8ka","type":"blocks","created_at":"2026-05-24T19:43:09Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-e53","title":"Full UiPrefs → Configurable migration (umbrella)","description":"Once the PoC lands, dissolve the UiPrefs / UiPrefsUpdate god-blob in apps/native/src-tauri/src/shared_types/prefs.rs into ~6 domain-specific Configurable structs that live next to the code that uses them. Each sub-issue migrates one category and deletes the corresponding store::get_*/set_* helpers + ui_prefs.rs branches.\n\nEnd state: ui_prefs.rs commands shrink to ~10 lines (delegate to the registry). UiPrefs / UiPrefsUpdate structs are deleted. Adding a new knob = one struct field.","acceptance_criteria":"All sub-issues closed; UiPrefs/UiPrefsUpdate removed; ui_get_prefs/ui_set_prefs reduced to registry walkthrough; no per-field store::get_/set_ helpers remain except for genuinely non-trivial cases (e.g. keychain-backed api keys); apps/native/src/ipc/types.ts still resolves cleanly via specta","status":"open","priority":3,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-25T02:42:33Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:42:33Z","dependencies":[{"issue_id":"nixmac-e53","depends_on_id":"nixmac-27g","type":"blocks","created_at":"2026-05-24T19:43:19Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-e53","depends_on_id":"nixmac-2rr","type":"blocks","created_at":"2026-05-24T19:43:14Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-e53","depends_on_id":"nixmac-2tt","type":"blocks","created_at":"2026-05-24T19:43:17Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-e53","depends_on_id":"nixmac-5nc","type":"blocks","created_at":"2026-05-24T19:43:15Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-e53","depends_on_id":"nixmac-elj","type":"blocks","created_at":"2026-05-24T19:43:18Z","created_by":"Cooper Maruyama","metadata":"{}"},{"issue_id":"nixmac-e53","depends_on_id":"nixmac-orl","type":"blocks","created_at":"2026-05-24T19:43:16Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":6,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"nixmac-93p","title":"Auto-generated dev settings UI via Configurable registry","description":"Once all UiPrefs categories are migrated, add a Tauri command dev_configs_list() that walks the inventory registry and returns {struct_name, fields[{name, type, default, range, current_value}]} for every registered Configurable. Frontend renders a ConfigField\u003cT\u003e component per type (number/bool/string/enum). Adding a new struct = new section auto-appears. Future work after full migration.","status":"open","priority":4,"issue_type":"feature","owner":"me@cooperm.com","created_at":"2026-05-25T02:43:03Z","created_by":"Cooper Maruyama","updated_at":"2026-05-25T02:43:03Z","dependencies":[{"issue_id":"nixmac-93p","depends_on_id":"nixmac-e53","type":"blocks","created_at":"2026-05-24T19:43:20Z","created_by":"Cooper Maruyama","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid JSON format: The file contains newline-delimited JSON (JSONL) format but uses a .json extension. Each line is a separate JSON object, which is valid JSONL but not valid JSON. Standard JSON parsers expect either a single object {} or an array [...].

If tooling expects standard JSON, parsing will fail with "Unexpected token" errors. Either:

[
  {"_type":"issue",...},
  {"_type":"issue",...}
]

or rename to .beads/issues.jsonl to match the JSONL format referenced in the migration plan document (line 228: "The committed .beads/issues.jsonl should be treated as the durable review surface").

Spotted by Graphite

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants