@cleocode/core 2026.10.8 → 2026.10.9-rc.ci.676

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) hide show
  1. package/dist/build-provenance.json +2 -2
  2. package/dist/cloud/auto-sync-command-entry.d.ts +13 -0
  3. package/dist/cloud/auto-sync-command-entry.d.ts.map +1 -0
  4. package/dist/cloud/auto-sync-command-entry.js +18 -0
  5. package/dist/cloud/auto-sync-command-entry.js.map +1 -0
  6. package/dist/cloud/auto-sync-command.d.ts +64 -0
  7. package/dist/cloud/auto-sync-command.d.ts.map +1 -0
  8. package/dist/cloud/auto-sync-command.js +109 -0
  9. package/dist/cloud/auto-sync-command.js.map +1 -0
  10. package/dist/cloud/auto-sync.d.ts +111 -0
  11. package/dist/cloud/auto-sync.d.ts.map +1 -0
  12. package/dist/cloud/auto-sync.js +275 -0
  13. package/dist/cloud/auto-sync.js.map +1 -0
  14. package/dist/cloud/nexus-cloud-device-overview.d.ts +52 -0
  15. package/dist/cloud/nexus-cloud-device-overview.d.ts.map +1 -0
  16. package/dist/cloud/nexus-cloud-device-overview.js +105 -0
  17. package/dist/cloud/nexus-cloud-device-overview.js.map +1 -0
  18. package/dist/cloud/nexus-cloud-journal-activity.d.ts +56 -0
  19. package/dist/cloud/nexus-cloud-journal-activity.d.ts.map +1 -0
  20. package/dist/cloud/nexus-cloud-journal-activity.js +98 -0
  21. package/dist/cloud/nexus-cloud-journal-activity.js.map +1 -0
  22. package/dist/cloud/nexus-cloud-status.d.ts.map +1 -1
  23. package/dist/cloud/nexus-cloud-status.js +88 -5
  24. package/dist/cloud/nexus-cloud-status.js.map +1 -1
  25. package/dist/cloud/nexus-vault.d.ts +19 -5
  26. package/dist/cloud/nexus-vault.d.ts.map +1 -1
  27. package/dist/cloud/nexus-vault.js +376 -71
  28. package/dist/cloud/nexus-vault.js.map +1 -1
  29. package/dist/cloud/replica-rebind.d.ts +14 -0
  30. package/dist/cloud/replica-rebind.d.ts.map +1 -1
  31. package/dist/cloud/replica-rebind.js +20 -1
  32. package/dist/cloud/replica-rebind.js.map +1 -1
  33. package/dist/config.d.ts +10 -0
  34. package/dist/config.d.ts.map +1 -1
  35. package/dist/config.js +19 -0
  36. package/dist/config.js.map +1 -1
  37. package/dist/docs/docs-ops.d.ts +4 -2
  38. package/dist/docs/docs-ops.d.ts.map +1 -1
  39. package/dist/docs/docs-ops.js +107 -15
  40. package/dist/docs/docs-ops.js.map +1 -1
  41. package/dist/doctor/system-health.d.ts +76 -2
  42. package/dist/doctor/system-health.d.ts.map +1 -1
  43. package/dist/doctor/system-health.js +264 -41
  44. package/dist/doctor/system-health.js.map +1 -1
  45. package/dist/hooks/project-runner.d.ts +10 -0
  46. package/dist/hooks/project-runner.d.ts.map +1 -0
  47. package/dist/hooks/project-runner.js +328 -0
  48. package/dist/hooks/project-runner.js.map +1 -0
  49. package/dist/hooks/project-state.d.ts +41 -0
  50. package/dist/hooks/project-state.d.ts.map +1 -0
  51. package/dist/hooks/project-state.js +331 -0
  52. package/dist/hooks/project-state.js.map +1 -0
  53. package/dist/hooks/release-gate.d.ts +61 -0
  54. package/dist/hooks/release-gate.d.ts.map +1 -0
  55. package/dist/hooks/release-gate.js +70 -0
  56. package/dist/hooks/release-gate.js.map +1 -0
  57. package/dist/nexus/analyze-orchestrator.d.ts +2 -0
  58. package/dist/nexus/analyze-orchestrator.d.ts.map +1 -1
  59. package/dist/nexus/analyze-orchestrator.js +1 -0
  60. package/dist/nexus/analyze-orchestrator.js.map +1 -1
  61. package/dist/nexus/freshness.d.ts +67 -3
  62. package/dist/nexus/freshness.d.ts.map +1 -1
  63. package/dist/nexus/freshness.js +130 -9
  64. package/dist/nexus/freshness.js.map +1 -1
  65. package/dist/nexus/refresh-child.d.ts +14 -0
  66. package/dist/nexus/refresh-child.d.ts.map +1 -0
  67. package/dist/nexus/refresh-child.js +24 -0
  68. package/dist/nexus/refresh-child.js.map +1 -0
  69. package/dist/orchestrate/spawn-ops.d.ts +8 -1
  70. package/dist/orchestrate/spawn-ops.d.ts.map +1 -1
  71. package/dist/orchestrate/spawn-ops.js +42 -12
  72. package/dist/orchestrate/spawn-ops.js.map +1 -1
  73. package/dist/orchestration/spawn.d.ts +5 -0
  74. package/dist/orchestration/spawn.d.ts.map +1 -1
  75. package/dist/orchestration/spawn.js +4 -1
  76. package/dist/orchestration/spawn.js.map +1 -1
  77. package/dist/release/channel.d.ts.map +1 -1
  78. package/dist/release/channel.js +10 -0
  79. package/dist/release/channel.js.map +1 -1
  80. package/dist/release/github-pr.d.ts.map +1 -1
  81. package/dist/release/github-pr.js +1 -0
  82. package/dist/release/github-pr.js.map +1 -1
  83. package/dist/release/plan.d.ts +8 -3
  84. package/dist/release/plan.d.ts.map +1 -1
  85. package/dist/release/plan.js +72 -15
  86. package/dist/release/plan.js.map +1 -1
  87. package/dist/release/reconcile.d.ts.map +1 -1
  88. package/dist/release/reconcile.js +6 -15
  89. package/dist/release/reconcile.js.map +1 -1
  90. package/dist/sentient/daemon-entry.d.ts +6 -0
  91. package/dist/sentient/daemon-entry.d.ts.map +1 -1
  92. package/dist/sentient/daemon-entry.js +12 -0
  93. package/dist/sentient/daemon-entry.js.map +1 -1
  94. package/dist/sentient/worktree-dispatch.d.ts +7 -0
  95. package/dist/sentient/worktree-dispatch.d.ts.map +1 -1
  96. package/dist/sentient/worktree-dispatch.js +37 -1
  97. package/dist/sentient/worktree-dispatch.js.map +1 -1
  98. package/dist/sessions/session-end-snapshot-entry.d.ts +4 -1
  99. package/dist/sessions/session-end-snapshot-entry.d.ts.map +1 -1
  100. package/dist/sessions/session-end-snapshot-entry.js +9 -1
  101. package/dist/sessions/session-end-snapshot-entry.js.map +1 -1
  102. package/dist/spawn/agent-identity.d.ts.map +1 -1
  103. package/dist/spawn/agent-identity.js +96 -1
  104. package/dist/spawn/agent-identity.js.map +1 -1
  105. package/dist/spawn/branch-lock.d.ts +27 -8
  106. package/dist/spawn/branch-lock.d.ts.map +1 -1
  107. package/dist/spawn/branch-lock.js +57 -73
  108. package/dist/spawn/branch-lock.js.map +1 -1
  109. package/dist/store/agent-resolver.d.ts +6 -0
  110. package/dist/store/agent-resolver.d.ts.map +1 -1
  111. package/dist/store/agent-resolver.js +2 -0
  112. package/dist/store/agent-resolver.js.map +1 -1
  113. package/dist/store/dual-scope-db.d.ts +20 -0
  114. package/dist/store/dual-scope-db.d.ts.map +1 -1
  115. package/dist/store/dual-scope-db.js +81 -8
  116. package/dist/store/dual-scope-db.js.map +1 -1
  117. package/dist/store/exodus/bare-family.d.ts.map +1 -1
  118. package/dist/store/exodus/bare-family.js +4 -1
  119. package/dist/store/exodus/bare-family.js.map +1 -1
  120. package/dist/store/exodus/migrate.d.ts.map +1 -1
  121. package/dist/store/exodus/migrate.js +2 -0
  122. package/dist/store/exodus/migrate.js.map +1 -1
  123. package/dist/store/exodus/on-open.d.ts.map +1 -1
  124. package/dist/store/exodus/on-open.js +16 -4
  125. package/dist/store/exodus/on-open.js.map +1 -1
  126. package/dist/store/exodus/reconcile.d.ts.map +1 -1
  127. package/dist/store/exodus/reconcile.js +2 -0
  128. package/dist/store/exodus/reconcile.js.map +1 -1
  129. package/dist/store/portable-bundle-import.d.ts +17 -0
  130. package/dist/store/portable-bundle-import.d.ts.map +1 -1
  131. package/dist/store/portable-bundle-import.js +46 -31
  132. package/dist/store/portable-bundle-import.js.map +1 -1
  133. package/dist/store/portable-bundle-scan.d.ts.map +1 -1
  134. package/dist/store/portable-bundle-scan.js +5 -0
  135. package/dist/store/portable-bundle-scan.js.map +1 -1
  136. package/dist/store/row-identity-registry.d.ts +4 -3
  137. package/dist/store/row-identity-registry.d.ts.map +1 -1
  138. package/dist/store/row-identity-registry.js +37 -35
  139. package/dist/store/row-identity-registry.js.map +1 -1
  140. package/dist/store/row-identity.d.ts.map +1 -1
  141. package/dist/store/row-identity.js +6 -1
  142. package/dist/store/row-identity.js.map +1 -1
  143. package/dist/store/schema/cleo-global/agent-registry.d.ts +16 -0
  144. package/dist/store/schema/cleo-global/agent-registry.d.ts.map +1 -1
  145. package/dist/store/schema/cleo-global/agent-registry.js +4 -1
  146. package/dist/store/schema/cleo-global/agent-registry.js.map +1 -1
  147. package/dist/store/schema/cleo-project/provenance-orphans.d.ts +126 -1
  148. package/dist/store/schema/cleo-project/provenance-orphans.d.ts.map +1 -1
  149. package/dist/store/schema/cleo-project/provenance-orphans.js +41 -1
  150. package/dist/store/schema/cleo-project/provenance-orphans.js.map +1 -1
  151. package/dist/store/sqlite-data-accessor.d.ts +40 -0
  152. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  153. package/dist/store/sqlite-data-accessor.js +122 -0
  154. package/dist/store/sqlite-data-accessor.js.map +1 -1
  155. package/dist/store/sync/activity.d.ts +64 -0
  156. package/dist/store/sync/activity.d.ts.map +1 -0
  157. package/dist/store/sync/activity.js +220 -0
  158. package/dist/store/sync/activity.js.map +1 -0
  159. package/dist/store/sync/apply/applier.d.ts.map +1 -1
  160. package/dist/store/sync/apply/applier.js +58 -2
  161. package/dist/store/sync/apply/applier.js.map +1 -1
  162. package/dist/store/sync/apply/write-api.d.ts.map +1 -1
  163. package/dist/store/sync/apply/write-api.js +45 -3
  164. package/dist/store/sync/apply/write-api.js.map +1 -1
  165. package/dist/store/sync/capture.d.ts +6 -4
  166. package/dist/store/sync/capture.d.ts.map +1 -1
  167. package/dist/store/sync/capture.js +16 -4
  168. package/dist/store/sync/capture.js.map +1 -1
  169. package/dist/store/sync/collision-settle.d.ts +120 -0
  170. package/dist/store/sync/collision-settle.d.ts.map +1 -1
  171. package/dist/store/sync/collision-settle.js +342 -5
  172. package/dist/store/sync/collision-settle.js.map +1 -1
  173. package/dist/store/sync/flags.d.ts +34 -0
  174. package/dist/store/sync/flags.d.ts.map +1 -1
  175. package/dist/store/sync/flags.js +46 -0
  176. package/dist/store/sync/flags.js.map +1 -1
  177. package/dist/store/sync/genesis.d.ts +8 -0
  178. package/dist/store/sync/genesis.d.ts.map +1 -1
  179. package/dist/store/sync/genesis.js +18 -5
  180. package/dist/store/sync/genesis.js.map +1 -1
  181. package/dist/store/sync/push.d.ts +4 -2
  182. package/dist/store/sync/push.d.ts.map +1 -1
  183. package/dist/store/sync/push.js +10 -1
  184. package/dist/store/sync/push.js.map +1 -1
  185. package/dist/store/sync/rebind.d.ts +20 -0
  186. package/dist/store/sync/rebind.d.ts.map +1 -1
  187. package/dist/store/sync/rebind.js +86 -4
  188. package/dist/store/sync/rebind.js.map +1 -1
  189. package/dist/store/sync/reconcile-copy.d.ts +152 -0
  190. package/dist/store/sync/reconcile-copy.d.ts.map +1 -0
  191. package/dist/store/sync/reconcile-copy.js +428 -0
  192. package/dist/store/sync/reconcile-copy.js.map +1 -0
  193. package/dist/store/sync/reconcile.d.ts +80 -0
  194. package/dist/store/sync/reconcile.d.ts.map +1 -1
  195. package/dist/store/sync/reconcile.js +97 -5
  196. package/dist/store/sync/reconcile.js.map +1 -1
  197. package/dist/store/sync/repair.d.ts +11 -0
  198. package/dist/store/sync/repair.d.ts.map +1 -1
  199. package/dist/store/sync/repair.js +14 -3
  200. package/dist/store/sync/repair.js.map +1 -1
  201. package/dist/store/sync/replica.d.ts +74 -1
  202. package/dist/store/sync/replica.d.ts.map +1 -1
  203. package/dist/store/sync/replica.js +104 -6
  204. package/dist/store/sync/replica.js.map +1 -1
  205. package/dist/store/sync/row-meta.d.ts +4 -2
  206. package/dist/store/sync/row-meta.d.ts.map +1 -1
  207. package/dist/store/sync/row-meta.js +6 -4
  208. package/dist/store/sync/row-meta.js.map +1 -1
  209. package/dist/store/sync/sealer.d.ts +2 -0
  210. package/dist/store/sync/sealer.d.ts.map +1 -1
  211. package/dist/store/sync/sealer.js +33 -4
  212. package/dist/store/sync/sealer.js.map +1 -1
  213. package/dist/store/sync/structural.d.ts.map +1 -1
  214. package/dist/store/sync/structural.js +3 -1
  215. package/dist/store/sync/structural.js.map +1 -1
  216. package/dist/store/sync/timestamp-canon.d.ts.map +1 -1
  217. package/dist/store/sync/timestamp-canon.js +2 -0
  218. package/dist/store/sync/timestamp-canon.js.map +1 -1
  219. package/dist/store/table-classification.d.ts +29 -0
  220. package/dist/store/table-classification.d.ts.map +1 -1
  221. package/dist/store/table-classification.js +85 -19
  222. package/dist/store/table-classification.js.map +1 -1
  223. package/dist/store/twin-collapse.d.ts.map +1 -1
  224. package/dist/store/twin-collapse.js +28 -10
  225. package/dist/store/twin-collapse.js.map +1 -1
  226. package/dist/store/vault-manifest.d.ts +5 -0
  227. package/dist/store/vault-manifest.d.ts.map +1 -1
  228. package/dist/store/vault-manifest.js +14 -1
  229. package/dist/store/vault-manifest.js.map +1 -1
  230. package/dist/tasks/affected-packages.d.ts +15 -5
  231. package/dist/tasks/affected-packages.d.ts.map +1 -1
  232. package/dist/tasks/affected-packages.js +20 -8
  233. package/dist/tasks/affected-packages.js.map +1 -1
  234. package/dist/tasks/done-record.d.ts +14 -4
  235. package/dist/tasks/done-record.d.ts.map +1 -1
  236. package/dist/tasks/done-record.js +21 -9
  237. package/dist/tasks/done-record.js.map +1 -1
  238. package/dist/tasks/evidence.d.ts.map +1 -1
  239. package/dist/tasks/evidence.js +45 -4
  240. package/dist/tasks/evidence.js.map +1 -1
  241. package/dist/tasks/gate-runner.d.ts +5 -4
  242. package/dist/tasks/gate-runner.d.ts.map +1 -1
  243. package/dist/tasks/gate-runner.js +18 -11
  244. package/dist/tasks/gate-runner.js.map +1 -1
  245. package/dist/tasks/tool-cache.d.ts +27 -1
  246. package/dist/tasks/tool-cache.d.ts.map +1 -1
  247. package/dist/tasks/tool-cache.js +110 -6
  248. package/dist/tasks/tool-cache.js.map +1 -1
  249. package/dist/tools/fs.d.ts +3 -1
  250. package/dist/tools/fs.d.ts.map +1 -1
  251. package/dist/tools/fs.js +35 -2
  252. package/dist/tools/fs.js.map +1 -1
  253. package/dist/validation/engine-ops.d.ts +10 -3
  254. package/dist/validation/engine-ops.d.ts.map +1 -1
  255. package/dist/validation/engine-ops.js +17 -8
  256. package/dist/validation/engine-ops.js.map +1 -1
  257. package/migrations/drizzle-cleo-global/20261010180000_t12915-agent-registry-uids/migration.sql +18 -0
  258. package/migrations/drizzle-cleo-project/20261010170000_t12896b-brain-task-observations/migration.sql +37 -0
  259. package/migrations/sync-journal/20261009150000_t13335-capture-pin/migration.sql +13 -0
  260. package/package.json +18 -13
  261. package/schemas/config.schema.json +12 -0
  262. package/schemas/project-context.schema.json +5 -0
  263. package/templates/CLEO-INJECTION.md +2 -2
  264. package/templates/CLEO-REFERENCE.md +6 -4
  265. package/templates/git-hooks/pre-push +29 -1
  266. package/templates/workflows/release-prepare.yml.tmpl +1 -0
@@ -0,0 +1,220 @@
1
+ /**
2
+ * Journal activity: what each device changed and when, read from this
3
+ * store's journal inbox (T13369).
4
+ *
5
+ * Every transaction a pull stages is an `_sync_inbox` row carrying the
6
+ * writing replica, the Nexus device that signed its segment, the
7
+ * transaction's HLC (its write time) and the times this store staged and
8
+ * applied it. Own transactions come back through the same inbox as echoes,
9
+ * so the inbox shows every device on the stream, this one included.
10
+ *
11
+ * A transaction its replica wrote after a server-confirmed retire is marked
12
+ * `history` once applied (§1.5, T13366): the merge recorded no conflict for it.
13
+ *
14
+ * The inbox is the window: applied rows pruned after a verified checkpoint
15
+ * are no longer listed. Read-only: nothing is written.
16
+ *
17
+ * @task T13369
18
+ * @module store/sync/activity
19
+ */
20
+ import { getStableDeviceId } from '../../llm/stable-device-id.js';
21
+ import { parseHlc } from './hlc.js';
22
+ import { isInheritedHistory } from './retire.js';
23
+ import { hasTable } from './schema.js';
24
+ /** Largest page {@link journalActivity} returns. */
25
+ export const JOURNAL_ACTIVITY_PAGE_MAX = 200;
26
+ /** Thrown for a `before` cursor this module did not issue. */
27
+ export class JournalActivityCursorError extends Error {
28
+ code = 'E_VALIDATION';
29
+ constructor(cursor) {
30
+ super(`not a journal activity cursor: ${cursor}`);
31
+ this.name = 'JournalActivityCursorError';
32
+ }
33
+ }
34
+ function encodeCursor(c) {
35
+ return Buffer.from(JSON.stringify([c.hlc, c.stream, c.seq, c.txnIdx]), 'utf8').toString('base64url');
36
+ }
37
+ function decodeCursor(raw) {
38
+ try {
39
+ const v = JSON.parse(Buffer.from(raw, 'base64url').toString('utf8'));
40
+ if (Array.isArray(v) &&
41
+ v.length === 4 &&
42
+ typeof v[0] === 'string' &&
43
+ typeof v[1] === 'string' &&
44
+ Number.isSafeInteger(v[2]) &&
45
+ Number.isSafeInteger(v[3])) {
46
+ return { hlc: v[0], stream: v[1], seq: v[2], txnIdx: v[3] };
47
+ }
48
+ }
49
+ catch {
50
+ // Falls through to the refusal.
51
+ }
52
+ // @sync-invariant none:input-shape a read-only listing refuses a cursor it did not issue
53
+ throw new JournalActivityCursorError(raw);
54
+ }
55
+ /** The HLC's physical time as ISO-8601, or the raw HLC when it does not parse. */
56
+ function hlcTime(hlc) {
57
+ try {
58
+ return new Date(parseHlc(hlc).phys).toISOString();
59
+ }
60
+ catch {
61
+ return hlc;
62
+ }
63
+ }
64
+ /** The replicas this machine bound in this store. */
65
+ function ownReplicas(db, localDeviceId) {
66
+ if (!hasTable(db, '_sync_replica'))
67
+ return new Set();
68
+ const rows = db
69
+ .prepare('SELECT replica_id FROM _sync_replica WHERE device_id = ?')
70
+ .all(localDeviceId);
71
+ return new Set(rows.map((r) => r.replica_id));
72
+ }
73
+ function summarise(txnJson) {
74
+ let t = {};
75
+ try {
76
+ const parsed = JSON.parse(txnJson);
77
+ if (parsed !== null && typeof parsed === 'object')
78
+ t = parsed;
79
+ }
80
+ catch {
81
+ // A row the stager accepted always parses; an unreadable one shows empty.
82
+ }
83
+ const tables = {};
84
+ const ops = Array.isArray(t.ops) ? t.ops : [];
85
+ for (const op of ops) {
86
+ if (op === null || typeof op !== 'object')
87
+ continue;
88
+ const { t: table, o } = op;
89
+ if (typeof table !== 'string' || (o !== 'I' && o !== 'U' && o !== 'D' && o !== 'K'))
90
+ continue;
91
+ tables[table] ??= { I: 0, U: 0, D: 0, K: 0 };
92
+ tables[table][o] += 1;
93
+ }
94
+ const actor = t.actor !== null && typeof t.actor === 'object'
95
+ ? Object.fromEntries(Object.entries(t.actor).filter(([, v]) => typeof v === 'string'))
96
+ : null;
97
+ return {
98
+ txn: typeof t.txn === 'string' ? t.txn : '',
99
+ kind: typeof t.kind === 'string' ? t.kind : '',
100
+ via: typeof t.via === 'string' ? t.via : '',
101
+ actor,
102
+ project: typeof t.project === 'string' ? t.project : null,
103
+ ops: ops.length,
104
+ tables,
105
+ };
106
+ }
107
+ /** The WHERE clause and parameters of the filters (the cursor excluded). */
108
+ function filters(opts) {
109
+ const where = [];
110
+ const params = [];
111
+ if (opts.deviceId !== undefined) {
112
+ where.push('device_id = ?');
113
+ params.push(opts.deviceId);
114
+ }
115
+ if (opts.sinceMs !== undefined) {
116
+ // HLCs sort lexically by physical time; a bare 13-digit prefix sorts first.
117
+ where.push('hlc >= ?');
118
+ params.push(String(Math.max(0, Math.trunc(opts.sinceMs))).padStart(13, '0'));
119
+ }
120
+ if (opts.project !== undefined) {
121
+ where.push("json_extract(txn_json, '$.project') = ?");
122
+ params.push(opts.project);
123
+ }
124
+ return { where, params };
125
+ }
126
+ /**
127
+ * List the transactions this store's journal received, newest first (by
128
+ * HLC), with the device that wrote each one and a per-device summary.
129
+ *
130
+ * @param db - The store.
131
+ * @param opts - Paging and filters.
132
+ * @returns A page of transactions, the per-device summary and the next cursor.
133
+ * @throws {JournalActivityCursorError} When `before` is not a cursor this module issued.
134
+ */
135
+ export function journalActivity(db, opts = {}) {
136
+ if (!hasTable(db, '_sync_inbox'))
137
+ return { items: [], devices: [], nextBefore: null };
138
+ const requested = opts.limit !== undefined && Number.isFinite(opts.limit) ? Math.trunc(opts.limit) : 50;
139
+ const limit = Math.min(Math.max(requested, 1), JOURNAL_ACTIVITY_PAGE_MAX);
140
+ const own = ownReplicas(db, opts.localDeviceId ?? getStableDeviceId());
141
+ const names = opts.deviceNames ?? new Map();
142
+ const { where, params } = filters(opts);
143
+ const devRows = db
144
+ .prepare(`SELECT device_id, replica_id, count(*) AS n, max(hlc) AS last
145
+ FROM _sync_inbox ${where.length ? `WHERE ${where.join(' AND ')}` : ''}
146
+ GROUP BY device_id, replica_id`)
147
+ .all(...params);
148
+ const byDevice = new Map();
149
+ for (const r of devRows) {
150
+ const d = byDevice.get(r.device_id) ?? { txns: 0, last: '', mine: false };
151
+ d.txns += Number(r.n);
152
+ if (r.last > d.last)
153
+ d.last = r.last;
154
+ if (own.has(r.replica_id))
155
+ d.mine = true;
156
+ byDevice.set(r.device_id, d);
157
+ }
158
+ const devices = [...byDevice.entries()]
159
+ .sort((a, b) => (a[1].last < b[1].last ? 1 : a[1].last > b[1].last ? -1 : 0))
160
+ .map(([deviceId, d]) => ({
161
+ deviceId,
162
+ deviceName: names.get(deviceId) ?? null,
163
+ thisDevice: d.mine,
164
+ txns: d.txns,
165
+ lastAt: hlcTime(d.last),
166
+ lastSeenAt: opts.deviceLastSeen?.get(deviceId) ?? null,
167
+ }));
168
+ const pageWhere = [...where];
169
+ const pageParams = [...params];
170
+ if (opts.before !== undefined) {
171
+ const c = decodeCursor(opts.before);
172
+ pageWhere.push('(hlc, stream, seq, txn_idx) < (?, ?, ?, ?)');
173
+ pageParams.push(c.hlc, c.stream, c.seq, c.txnIdx);
174
+ }
175
+ const rows = db
176
+ .prepare(`SELECT stream, seq, txn_idx, replica_id, device_id, txn_json, hlc, status, reason,
177
+ staged_at, applied_at
178
+ FROM _sync_inbox ${pageWhere.length ? `WHERE ${pageWhere.join(' AND ')}` : ''}
179
+ ORDER BY hlc DESC, stream DESC, seq DESC, txn_idx DESC
180
+ LIMIT ?`)
181
+ .all(...pageParams, limit + 1);
182
+ const page = rows.slice(0, limit);
183
+ const items = page.map((r) => {
184
+ const s = summarise(r.txn_json);
185
+ return {
186
+ txn: s.txn,
187
+ stream: r.stream,
188
+ seq: Number(r.seq),
189
+ txnIdx: Number(r.txn_idx),
190
+ replicaId: r.replica_id,
191
+ deviceId: r.device_id,
192
+ deviceName: names.get(r.device_id) ?? null,
193
+ thisDevice: own.has(r.replica_id),
194
+ hlc: r.hlc,
195
+ at: hlcTime(r.hlc),
196
+ stagedAt: r.staged_at,
197
+ appliedAt: r.applied_at,
198
+ status: r.status,
199
+ reason: r.reason,
200
+ history: r.status === 'applied' && isInheritedHistory(db, r.stream, r.replica_id, Number(r.seq)),
201
+ kind: s.kind,
202
+ via: s.via,
203
+ actor: s.actor,
204
+ project: s.project,
205
+ ops: s.ops,
206
+ tables: s.tables,
207
+ };
208
+ });
209
+ const last = page.at(-1);
210
+ const nextBefore = rows.length > limit && last !== undefined
211
+ ? encodeCursor({
212
+ hlc: last.hlc,
213
+ stream: last.stream,
214
+ seq: Number(last.seq),
215
+ txnIdx: Number(last.txn_idx),
216
+ })
217
+ : null;
218
+ return { items, devices, nextBefore };
219
+ }
220
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/store/sync/activity.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"applier.d.ts","sourceRoot":"","sources":["../../../../src/store/sync/apply/applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAiCtD,OAAO,EAUL,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAU1B,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAysCD,0FAA0F;AAC1F,eAAO,MAAM,eAAe,OAAQ,CAAC;AACrC,sEAAsE;AACtE,eAAO,MAAM,cAAc,KAAK,CAAC;AAgNjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,GAAG,WAAW,CA2JvF"}
1
+ {"version":3,"file":"applier.d.ts","sourceRoot":"","sources":["../../../../src/store/sync/apply/applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4DG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA2CtD,OAAO,EAUL,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAU1B,wCAAwC;AACxC,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,+FAA+F;IAC/F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gCAAgC;IAChC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yFAAyF;IACzF,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6FAA6F;IAC7F,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AA4vCD,0FAA0F;AAC1F,eAAO,MAAM,eAAe,OAAQ,CAAC;AACrC,sEAAsE;AACtE,eAAO,MAAM,cAAc,KAAK,CAAC;AAgNjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,kBAAkB,GAAG,WAAW,CA4KvF"}
@@ -61,7 +61,7 @@
61
61
  */
62
62
  import { BIRTH_FP_COLUMN, UID_COLUMN } from '../../row-identity-registry.js';
63
63
  import { captureTableDef } from '../capture.js';
64
- import { announcePlacedRekeys, settleLostUidCollisions } from '../collision-settle.js';
64
+ import { announcePlacedRekeys, displayKeyColumn, displayKeyReferrers, foldDisplayRemints, followLocalTaskRefs, remintLostKeyCollisions, repointOwnDecisionText, settleLostUidCollisions, } from '../collision-settle.js';
65
65
  import { recordConflictOnce, recordConflicts, resolveHeldConflicts } from '../conflicts.js';
66
66
  import { clearFieldLeaves, readFieldFrontiers, readFieldLeaves, recordFieldLeaves, restoreFieldState, setFieldFrontiers, } from '../field-leave.js';
67
67
  import { accountRebaseRows, heldOp, holdOp, txnHasHold, unholdOp } from '../held.js';
@@ -685,9 +685,13 @@ function applyOne(c, opIdx, op) {
685
685
  });
686
686
  }
687
687
  }
688
+ const keyMove = displayKeyMove(def, before, out);
688
689
  const sp = `apply_op_${opIdx}`;
689
690
  c.db.exec(`SAVEPOINT ${sp}`);
690
691
  try {
692
+ // A display key that moves leaves its referrers behind until they follow.
693
+ if (keyMove)
694
+ c.db.exec('PRAGMA defer_foreign_keys = ON');
691
695
  // cascade-with-ops: the remaining children go first, with ops' tombstones.
692
696
  const actor = c.st.txn.actor ? JSON.stringify(c.st.txn.actor) : null;
693
697
  for (const x of live)
@@ -697,6 +701,8 @@ function applyOne(c, opIdx, op) {
697
701
  : c.st;
698
702
  const history = c.history === true && out.status !== 'void';
699
703
  const recorded = effect(c.db, c.api, st, opIdx, { op, def, before, out, refKeys }, c.nowIso, c.replay !== undefined || history);
704
+ if (keyMove)
705
+ followDisplayKey(c, op.t, op.u, keyMove);
700
706
  const n = history ? 0 : recorded;
701
707
  c.db.exec(`RELEASE ${sp}`);
702
708
  const result = out.status === 'applied' || out.status === 'partial'
@@ -724,6 +730,42 @@ function applyOne(c, opIdx, op) {
724
730
  });
725
731
  }
726
732
  }
733
+ /** Decision key moves applied in the current apply call, by store (T13433). */
734
+ const decisionMoves = new WeakMap();
735
+ /** A counter display key an applied update moves (T13405), or null. */
736
+ function displayKeyMove(def, before, out) {
737
+ const column = displayKeyColumn(def.table);
738
+ if (!column || out.effect !== 'update' || !before.live)
739
+ return null;
740
+ const from = before.fields[column]?.value;
741
+ const to = out.next.fields[column]?.value;
742
+ return typeof from === 'string' && typeof to === 'string' && from !== to
743
+ ? { column, from, to }
744
+ : null;
745
+ }
746
+ /**
747
+ * Point the local rows that reference a moved display key at the new key
748
+ * (T13405): a replica that had placed a re-minted loser keeps its own
749
+ * children on it, never on the winner that takes the old key. Writes go
750
+ * through the write API, so each is an apply intent, not a local change.
751
+ */
752
+ function followDisplayKey(c, table, uid, move) {
753
+ // Its own text references re-point after the passes, in a local frame (T13433).
754
+ if (table === 'brain_decisions' && !c.replay) {
755
+ const moves = decisionMoves.get(c.db) ?? [];
756
+ moves.push({ uid, from: move.from, to: move.to });
757
+ decisionMoves.set(c.db, moves);
758
+ }
759
+ for (const ref of displayKeyReferrers(c.db, c.defs, table, move.column)) {
760
+ const rows = c.db
761
+ .prepare(`SELECT "${UID_COLUMN}" AS uid FROM main."${ref.table.replaceAll('"', '""')}" WHERE "${ref.column.replaceAll('"', '""')}" = ? AND "${UID_COLUMN}" IS NOT NULL`)
762
+ .all(move.from);
763
+ for (const r of rows)
764
+ c.api.writeFields(ref.table, r.uid, { [ref.column]: move.to });
765
+ }
766
+ if (table === 'tasks_tasks')
767
+ followLocalTaskRefs(c.db, c.defs, move.from, move.to);
768
+ }
727
769
  /** The rows a transaction's ops write (a re-key's both uids). */
728
770
  function touchedRows(ops) {
729
771
  return ops.flatMap((o) => o.o === 'K' && o.nu && o.nu !== o.u
@@ -1330,7 +1372,8 @@ export function applyStagedTxns(db, opts) {
1330
1372
  passes += 1;
1331
1373
  const heldReplicas = new Set();
1332
1374
  const held = new Set(); // rows written by a pending transaction
1333
- const staged = stagedTxns(db, opts.stream).map((st) => followUidAliases(db, withoutLocalRowids(st, defs), defs));
1375
+ // An origin's display-key re-mint folds into the insert it held (T13405).
1376
+ const staged = foldDisplayRemints(db, stagedTxns(db, opts.stream).map((st) => followUidAliases(db, withoutLocalRowids(st, defs), defs)), defs);
1334
1377
  // Each page is one frame and one scoped rebase (§3.5 Rule 3): rewind the
1335
1378
  // page's scope once, apply its transactions in stream order, replay once.
1336
1379
  for (let at = 0; at < staged.length;) {
@@ -1423,6 +1466,19 @@ export function applyStagedTxns(db, opts) {
1423
1466
  opts.seal?.();
1424
1467
  runPasses();
1425
1468
  }
1469
+ // The origin of a row that lost a key collision re-mints its key, then the
1470
+ // held insert places (T13405). Driven by the open conflicts, so a failed
1471
+ // re-mint is retried by the next apply (T13431).
1472
+ if (remintLostKeyCollisions(db, opts).length > 0) {
1473
+ opts.seal?.();
1474
+ runPasses();
1475
+ }
1476
+ // Forget the moves only once their frames committed: a busy or failed frame
1477
+ // keeps them for the next apply on this handle (re-pointing is idempotent).
1478
+ const moves = decisionMoves.get(db) ?? [];
1479
+ if (repointOwnDecisionText(db, opts, moves) > 0)
1480
+ opts.seal?.();
1481
+ decisionMoves.delete(db);
1426
1482
  // Every other replica that had placed a re-keyed loser announces the
1427
1483
  // re-key, so its earlier references follow the loser too (T13399).
1428
1484
  if (announcePlacedRekeys(db, opts, new Date(now()).toISOString()) > 0)