Payload
{
"ref": "refs/heads/jp/refactor-the-refactor",
"before": "e77c3d3c4b1e454e06a8e9f61def41f3abe4ee34",
"after": "972e9da181d8a732aa52dc35355e626a02b66c98",
"repository": {
"id": 1209959628,
"node_id": "R_kgDOSB6EzA",
"name": "nixmac",
"full_name": "darkmatter/nixmac",
"private": false,
"owner": {
"name": "darkmatter",
"email": "hello@dm.sh",
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/darkmatter",
"html_url": "https://github.com/darkmatter",
"followers_url": "https://api.github.com/users/darkmatter/followers",
"following_url": "https://api.github.com/users/darkmatter/following{/other_user}",
"gists_url": "https://api.github.com/users/darkmatter/gists{/gist_id}",
"starred_url": "https://api.github.com/users/darkmatter/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/darkmatter/subscriptions",
"organizations_url": "https://api.github.com/users/darkmatter/orgs",
"repos_url": "https://api.github.com/users/darkmatter/repos",
"events_url": "https://api.github.com/users/darkmatter/events{/privacy}",
"received_events_url": "https://api.github.com/users/darkmatter/received_events",
"type": "Organization",
"user_view_type": "public",
"site_admin": false
},
"html_url": "https://github.com/darkmatter/nixmac",
"description": "Home manager and nix-darwin that understands plain English",
"fork": false,
"url": "https://api.github.com/repos/darkmatter/nixmac",
"forks_url": "https://api.github.com/repos/darkmatter/nixmac/forks",
"keys_url": "https://api.github.com/repos/darkmatter/nixmac/keys{/key_id}",
"collaborators_url": "https://api.github.com/repos/darkmatter/nixmac/collaborators{/collaborator}",
"teams_url": "https://api.github.com/repos/darkmatter/nixmac/teams",
"hooks_url": "https://api.github.com/repos/darkmatter/nixmac/hooks",
"issue_events_url": "https://api.github.com/repos/darkmatter/nixmac/issues/events{/number}",
"events_url": "https://api.github.com/repos/darkmatter/nixmac/events",
"assignees_url": "https://api.github.com/repos/darkmatter/nixmac/assignees{/user}",
"branches_url": "https://api.github.com/repos/darkmatter/nixmac/branches{/branch}",
"tags_url": "https://api.github.com/repos/darkmatter/nixmac/tags",
"blobs_url": "https://api.github.com/repos/darkmatter/nixmac/git/blobs{/sha}",
"git_tags_url": "https://api.github.com/repos/darkmatter/nixmac/git/tags{/sha}",
"git_refs_url": "https://api.github.com/repos/darkmatter/nixmac/git/refs{/sha}",
"trees_url": "https://api.github.com/repos/darkmatter/nixmac/git/trees{/sha}",
"statuses_url": "https://api.github.com/repos/darkmatter/nixmac/statuses/{sha}",
"languages_url": "https://api.github.com/repos/darkmatter/nixmac/languages",
"stargazers_url": "https://api.github.com/repos/darkmatter/nixmac/stargazers",
"contributors_url": "https://api.github.com/repos/darkmatter/nixmac/contributors",
"subscribers_url": "https://api.github.com/repos/darkmatter/nixmac/subscribers",
"subscription_url": "https://api.github.com/repos/darkmatter/nixmac/subscription",
"commits_url": "https://api.github.com/repos/darkmatter/nixmac/commits{/sha}",
"git_commits_url": "https://api.github.com/repos/darkmatter/nixmac/git/commits{/sha}",
"comments_url": "https://api.github.com/repos/darkmatter/nixmac/comments{/number}",
"issue_comment_url": "https://api.github.com/repos/darkmatter/nixmac/issues/comments{/number}",
"contents_url": "https://api.github.com/repos/darkmatter/nixmac/contents/{+path}",
"compare_url": "https://api.github.com/repos/darkmatter/nixmac/compare/{base}...{head}",
"merges_url": "https://api.github.com/repos/darkmatter/nixmac/merges",
"archive_url": "https://api.github.com/repos/darkmatter/nixmac/{archive_format}{/ref}",
"downloads_url": "https://api.github.com/repos/darkmatter/nixmac/downloads",
"issues_url": "https://api.github.com/repos/darkmatter/nixmac/issues{/number}",
"pulls_url": "https://api.github.com/repos/darkmatter/nixmac/pulls{/number}",
"milestones_url": "https://api.github.com/repos/darkmatter/nixmac/milestones{/number}",
"notifications_url": "https://api.github.com/repos/darkmatter/nixmac/notifications{?since,all,participating}",
"labels_url": "https://api.github.com/repos/darkmatter/nixmac/labels{/name}",
"releases_url": "https://api.github.com/repos/darkmatter/nixmac/releases{/id}",
"deployments_url": "https://api.github.com/repos/darkmatter/nixmac/deployments",
"created_at": 1776127033,
"updated_at": "2026-06-10T15:32:59Z",
"pushed_at": 1781121838,
"git_url": "git://github.com/darkmatter/nixmac.git",
"ssh_url": "git@github.com:darkmatter/nixmac.git",
"clone_url": "https://github.com/darkmatter/nixmac.git",
"svn_url": "https://github.com/darkmatter/nixmac",
"homepage": "https://nixmac.com",
"size": 681620,
"stargazers_count": 5,
"watchers_count": 5,
"language": "Rust",
"has_issues": true,
"has_projects": false,
"has_downloads": true,
"has_wiki": false,
"has_pages": false,
"has_discussions": false,
"forks_count": 1,
"mirror_url": null,
"archived": false,
"disabled": false,
"open_issues_count": 85,
"license": {
"key": "mit",
"name": "MIT License",
"spdx_id": "MIT",
"url": "https://api.github.com/licenses/mit",
"node_id": "MDc6TGljZW5zZTEz"
},
"allow_forking": true,
"is_template": false,
"web_commit_signoff_required": false,
"has_pull_requests": true,
"pull_request_creation_policy": "all",
"topics": [
"home-manager",
"nix",
"nix-darwin",
"nix-flake",
"opencode"
],
"visibility": "public",
"forks": 1,
"open_issues": 85,
"watchers": 5,
"default_branch": "develop",
"stargazers": 5,
"master_branch": "develop",
"organization": "darkmatter",
"custom_properties": {}
},
"pusher": {
"name": "arximboldi",
"email": "juanpe@sinusoid.es"
},
"forced": false,
"organization": {
"login": "darkmatter",
"id": 17834193,
"node_id": "MDEyOk9yZ2FuaXphdGlvbjE3ODM0MTkz",
"url": "https://api.github.com/orgs/darkmatter",
"repos_url": "https://api.github.com/orgs/darkmatter/repos",
"events_url": "https://api.github.com/orgs/darkmatter/events",
"hooks_url": "https://api.github.com/orgs/darkmatter/hooks",
"issues_url": "https://api.github.com/orgs/darkmatter/issues",
"members_url": "https://api.github.com/orgs/darkmatter/members{/member}",
"public_members_url": "https://api.github.com/orgs/darkmatter/public_members{/member}",
"avatar_url": "https://avatars.githubusercontent.com/u/17834193?v=4",
"description": ""
},
"enterprise": {
"id": 469843,
"slug": "darkmatter",
"name": "darkmatter",
"node_id": "E_kgDOAAcrUw",
"avatar_url": "https://avatars.githubusercontent.com/b/469843?v=4",
"description": "",
"website_url": "darkmatter.io",
"html_url": "https://github.com/enterprises/darkmatter",
"created_at": "2025-09-07T16:01:00Z",
"updated_at": "2026-06-07T16:53:26Z"
},
"sender": {
"login": "arximboldi",
"id": 4521138,
"node_id": "MDQ6VXNlcjQ1MjExMzg=",
"avatar_url": "https://avatars.githubusercontent.com/u/4521138?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/arximboldi",
"html_url": "https://github.com/arximboldi",
"followers_url": "https://api.github.com/users/arximboldi/followers",
"following_url": "https://api.github.com/users/arximboldi/following{/other_user}",
"gists_url": "https://api.github.com/users/arximboldi/gists{/gist_id}",
"starred_url": "https://api.github.com/users/arximboldi/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/arximboldi/subscriptions",
"organizations_url": "https://api.github.com/users/arximboldi/orgs",
"repos_url": "https://api.github.com/users/arximboldi/repos",
"events_url": "https://api.github.com/users/arximboldi/events{/privacy}",
"received_events_url": "https://api.github.com/users/arximboldi/received_events",
"type": "User",
"user_view_type": "public",
"site_admin": false
},
"installation": {
"id": 131074261,
"node_id": "MDIzOkludGVncmF0aW9uSW5zdGFsbGF0aW9uMTMxMDc0MjYx"
},
"created": false,
"deleted": false,
"base_ref": null,
"compare": "https://github.com/darkmatter/nixmac/compare/e77c3d3c4b1e...972e9da181d8",
"commits": [
{
"id": "577cf70a65ff9050baad6b75d6ac543983ac36ea",
"tree_id": "7d0b3c508aeed224b5b1c7f8c7a5456bf5acb897",
"distinct": true,
"message": "state: introduce Observable<T> alongside Slice<T>\n\nNew src/observable.rs introduces a typed state holder that fans out\nchanges to a list of subscriber closures. Subscribers run synchronously\nfrom the write guard's Drop, the same point where Slice<T> emits and\nflushes today.\n\nTwo recurring patterns get convenience builders:\n\n * .emit_to(&app, \"event_name\") — Tauri event emission\n * .persist_to(backend) — JSON-serialize and flush via the\n existing Persistence trait\n\nAnything more exotic (debouncing, breadcrumbs, custom backends) is just\n.subscribe(move |value| ...). Persistence stays as a trait so future\nbackends can layer debouncing/batching without touching the core type.\n\nNo callers in this commit; existing Slice<T> users keep working. The new\nmodule carries #![allow(dead_code)] until callers migrate in C2-C5.\n\ncargo test on src-tauri: 378 passed / 2 ignored (4 new tests).\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T14:52:06+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/577cf70a65ff9050baad6b75d6ac543983ac36ea",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T14:52:06+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T14:52:06+02:00",
"username": "arximboldi"
},
"added": [
"apps/native/src-tauri/src/observable.rs"
],
"removed": [],
"modified": [
"apps/native/src-tauri/src/main.rs"
]
},
{
"id": "f90783da372284655912ff46f1ccce42903cbf28",
"tree_id": "3d6be593ce7094baa30c372a1240c9af68759570",
"distinct": true,
"message": "state: migrate EvolutionLimits from Slice to Observable\n\nevolve::config::load_slice becomes load_observable; persistence is now\nattached via the .persist_to() subscriber, and the change-event name flows\nthrough .emit_to() rather than being a struct field of the slice.\n\nThe onboarding fallback that used VolatileJson is now simply: if no\nstorage path is available, build the observable without a persistence\nsubscriber. That deletes VolatileJson (it had no other users) and removes\none layer of indirection.\n\nConfigurable derive updated to look for `Observable<#name>` in tauri::State\nand call `write_sync()` without an emitter argument. EvolutionLimits is\ncurrently the only Configurable in the codebase, so this change is\nisolated.\n\nOther callers updated to use the new type:\n - storage/store.rs (4 get/set helpers)\n - commands/settings_io.rs (export + import)\n - main.rs (two manage() call sites)\n\ncargo test on src-tauri: 378 passed / 2 ignored.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T14:58:58+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/f90783da372284655912ff46f1ccce42903cbf28",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T14:58:58+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T14:58:58+02:00",
"username": "arximboldi"
},
"added": [],
"removed": [],
"modified": [
"apps/native/src-tauri/configurable-derive/src/codegen.rs",
"apps/native/src-tauri/src/commands/settings_io.rs",
"apps/native/src-tauri/src/evolve/config.rs",
"apps/native/src-tauri/src/main.rs",
"apps/native/src-tauri/src/state/preferences.rs",
"apps/native/src-tauri/src/storage/store.rs"
]
},
{
"id": "d77f1a7e0b3e85f62306ac0e88803f1620ac6308",
"tree_id": "1cf0d913e5be29116960184f00bd016383686773",
"distinct": true,
"message": "state: migrate EvolveState from Slice to Observable\n\nevolve_state::load_slice becomes load_observable. The change-event name\nflows through .emit_to() and persistence is attached via .persist_to().\n\nget() and set() switch from try_state::<Slice<EvolveState>> to\ntry_state::<Observable<EvolveState>>; write_sync() drops its emitter\nargument. The \"no managed observable\" fallback path (used during early\nstartup before app.manage) keeps its bespoke emit + flush sequence.\n\nmain.rs updated for both manage() call sites.\n\ncargo test on src-tauri: 378 passed / 2 ignored.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T15:05:56+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/d77f1a7e0b3e85f62306ac0e88803f1620ac6308",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T15:05:56+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T15:05:56+02:00",
"username": "arximboldi"
},
"added": [],
"removed": [],
"modified": [
"apps/native/src-tauri/src/main.rs",
"apps/native/src-tauri/src/state/evolve_state.rs"
]
},
{
"id": "cfcbc66bba685bbba946696f3158fe4004533857",
"tree_id": "075ec9f89fdd90f9237ac9e26f2be4028b2b73de",
"distinct": true,
"message": "state: migrate GlobalPreferences from Slice to Observable\n\nstate::preferences::load_global_slice becomes load_global_observable.\nEvent name flows through .emit_to(); persistence is attached via\n.persist_to(). main.rs updated for both manage() call sites;\ncommands/settings_io.rs switches the export and import paths to\ntry_state::<Observable<GlobalPreferences>>(), and the write_sync call\ndrops its emitter argument.\n\nThis is the last Slice<T> caller. The type itself, SliceWriteGuard, and\nthe SliceEventEmitter trait now have no users; state/slice/mod.rs gets\n#![allow(dead_code)] as a one-commit shim. The next commit (C6) deletes\nthe dead code and moves persistence + json_io under src/observable/.\n\ncargo test on src-tauri: 378 passed / 2 ignored.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T17:21:41+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/cfcbc66bba685bbba946696f3158fe4004533857",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T17:21:41+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T17:21:41+02:00",
"username": "arximboldi"
},
"added": [],
"removed": [],
"modified": [
"apps/native/src-tauri/src/commands/settings_io.rs",
"apps/native/src-tauri/src/main.rs",
"apps/native/src-tauri/src/state/preferences.rs",
"apps/native/src-tauri/src/state/slice/mod.rs"
]
},
{
"id": "972e9da181d8a732aa52dc35355e626a02b66c98",
"tree_id": "a215b5307025f797cec5b58b4fa9ec9962987727",
"distinct": true,
"message": "state: delete Slice<T>, move persistence under observable\n\nAfter the three caller migrations, Slice<T> has no users left. This\ncommit:\n\n- Deletes Slice, SliceWriteGuard, and the SliceEventEmitter trait from\n state/slice/mod.rs. The three slice-level tests are absorbed by\n observable's own tests; persistence + registry tests move with their\n respective code.\n- Moves apps/native/src-tauri/src/observable.rs to\n src/observable/mod.rs and pulls persistence.rs + json_io.rs under it.\n The Persistence trait + AppDataJson + RepoScopedJson are re-exported\n at crate::observable::*, so callers say\n `use crate::observable::{AppDataJson, Persistence, Observable}`.\n- Shrinks state/slice/mod.rs to a thin re-export of registry.rs. The\n module stays as the home for SliceRegistry until B1 retires it.\n- Updates state/mod.rs prose to describe the new shape (observables, not\n slices).\n\ncargo test on src-tauri: 377 passed / 2 ignored.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T20:29:56+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/972e9da181d8a732aa52dc35355e626a02b66c98",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T20:29:56+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T20:29:56+02:00",
"username": "arximboldi"
},
"added": [
"apps/native/src-tauri/src/observable/json_io.rs",
"apps/native/src-tauri/src/observable/mod.rs",
"apps/native/src-tauri/src/observable/persistence.rs"
],
"removed": [
"apps/native/src-tauri/src/observable.rs",
"apps/native/src-tauri/src/state/slice/json_io.rs",
"apps/native/src-tauri/src/state/slice/persistence.rs"
],
"modified": [
"apps/native/src-tauri/src/evolve/config.rs",
"apps/native/src-tauri/src/state/evolve_state.rs",
"apps/native/src-tauri/src/state/mod.rs",
"apps/native/src-tauri/src/state/preferences.rs",
"apps/native/src-tauri/src/state/slice/mod.rs",
"apps/native/src-tauri/src/state/slice/registry.rs"
]
}
],
"head_commit": {
"id": "972e9da181d8a732aa52dc35355e626a02b66c98",
"tree_id": "a215b5307025f797cec5b58b4fa9ec9962987727",
"distinct": true,
"message": "state: delete Slice<T>, move persistence under observable\n\nAfter the three caller migrations, Slice<T> has no users left. This\ncommit:\n\n- Deletes Slice, SliceWriteGuard, and the SliceEventEmitter trait from\n state/slice/mod.rs. The three slice-level tests are absorbed by\n observable's own tests; persistence + registry tests move with their\n respective code.\n- Moves apps/native/src-tauri/src/observable.rs to\n src/observable/mod.rs and pulls persistence.rs + json_io.rs under it.\n The Persistence trait + AppDataJson + RepoScopedJson are re-exported\n at crate::observable::*, so callers say\n `use crate::observable::{AppDataJson, Persistence, Observable}`.\n- Shrinks state/slice/mod.rs to a thin re-export of registry.rs. The\n module stays as the home for SliceRegistry until B1 retires it.\n- Updates state/mod.rs prose to describe the new shape (observables, not\n slices).\n\ncargo test on src-tauri: 377 passed / 2 ignored.\n\nCo-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>",
"timestamp": "2026-06-05T20:29:56+02:00",
"url": "https://github.com/darkmatter/nixmac/commit/972e9da181d8a732aa52dc35355e626a02b66c98",
"author": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T20:29:56+02:00",
"username": "arximboldi"
},
"committer": {
"name": "Juan Pedro Bolívar Puente",
"email": "raskolnikov@gnu.org",
"date": "2026-06-05T20:29:56+02:00",
"username": "arximboldi"
},
"added": [
"apps/native/src-tauri/src/observable/json_io.rs",
"apps/native/src-tauri/src/observable/mod.rs",
"apps/native/src-tauri/src/observable/persistence.rs"
],
"removed": [
"apps/native/src-tauri/src/observable.rs",
"apps/native/src-tauri/src/state/slice/json_io.rs",
"apps/native/src-tauri/src/state/slice/persistence.rs"
],
"modified": [
"apps/native/src-tauri/src/evolve/config.rs",
"apps/native/src-tauri/src/state/evolve_state.rs",
"apps/native/src-tauri/src/state/mod.rs",
"apps/native/src-tauri/src/state/preferences.rs",
"apps/native/src-tauri/src/state/slice/mod.rs",
"apps/native/src-tauri/src/state/slice/registry.rs"
]
}
}