@astrosheep/square 0.3.106 → 0.4.1

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 (206) hide show
  1. package/dist/activity-feed.js +1 -1
  2. package/dist/artifact-store.d.ts +41 -0
  3. package/dist/artifact-store.js +272 -0
  4. package/dist/artifact.d.ts +6 -12
  5. package/dist/artifact.js +43 -344
  6. package/dist/attention-presentation.d.ts +13 -7
  7. package/dist/attention-presentation.js +29 -68
  8. package/dist/boundary-presentation.d.ts +3 -16
  9. package/dist/boundary-presentation.js +29 -109
  10. package/dist/card-presentation.d.ts +1 -0
  11. package/dist/card-presentation.js +2 -0
  12. package/dist/catch-decisions.d.ts +2 -2
  13. package/dist/catch-decisions.js +7 -3
  14. package/dist/catch-selection.d.ts +8 -0
  15. package/dist/catch-selection.js +5 -0
  16. package/dist/claude-delivery.d.ts +14 -12
  17. package/dist/claude-delivery.js +42 -142
  18. package/dist/claude-mcp-context.js +2 -2
  19. package/dist/claude-mod.js +28 -140
  20. package/dist/claude-transport.d.ts +5 -0
  21. package/dist/claude-transport.js +34 -0
  22. package/dist/cli/context.d.ts +2 -2
  23. package/dist/cli/context.js +7 -10
  24. package/dist/cli/maintenance-commands.d.ts +0 -4
  25. package/dist/cli/maintenance-commands.js +2 -29
  26. package/dist/cli/observation-commands.d.ts +2 -0
  27. package/dist/cli/observation-commands.js +12 -2
  28. package/dist/cli/program.js +1 -1
  29. package/dist/cli/registry.js +4 -3
  30. package/dist/codex-address.d.ts +2 -2
  31. package/dist/codex-boundary-state.d.ts +1 -5
  32. package/dist/codex-boundary-state.js +0 -4
  33. package/dist/codex-hook.d.ts +7 -10
  34. package/dist/codex-hook.js +69 -33
  35. package/dist/codex-queue.d.ts +10 -11
  36. package/dist/codex-queue.js +32 -34
  37. package/dist/codex-watch.d.ts +2 -0
  38. package/dist/codex-watch.js +100 -0
  39. package/dist/decisions.js +3 -3
  40. package/dist/delivery-deferral.d.ts +1 -19
  41. package/dist/delivery-deferral.js +1 -29
  42. package/dist/delivery-frame.d.ts +7 -0
  43. package/dist/delivery-frame.js +11 -0
  44. package/dist/delivery-ledger-sqlite.d.ts +97 -0
  45. package/dist/delivery-ledger-sqlite.js +496 -0
  46. package/dist/delivery-ledger.d.ts +196 -0
  47. package/dist/delivery-ledger.js +268 -0
  48. package/dist/delivery-lifetime.d.ts +6 -0
  49. package/dist/delivery-lifetime.js +45 -0
  50. package/dist/harness-links.js +61 -7
  51. package/dist/harness.js +12 -17
  52. package/dist/help.js +3 -6
  53. package/dist/http-delivery.d.ts +5 -9
  54. package/dist/http-delivery.js +20 -79
  55. package/dist/inbox.d.ts +6 -57
  56. package/dist/inbox.js +24 -380
  57. package/dist/index.d.ts +7 -4
  58. package/dist/index.js +5 -2
  59. package/dist/mcp.d.ts +2 -1
  60. package/dist/mcp.js +40 -70
  61. package/dist/message.d.ts +7 -0
  62. package/dist/message.js +23 -0
  63. package/dist/model.d.ts +15 -91
  64. package/dist/model.js +2 -140
  65. package/dist/neutral.d.ts +72 -0
  66. package/dist/neutral.js +27 -0
  67. package/dist/notifications.d.ts +24 -26
  68. package/dist/notifications.js +39 -143
  69. package/dist/operation-control.d.ts +4 -0
  70. package/dist/operation-control.js +20 -0
  71. package/dist/operation-presentation.d.ts +1 -2
  72. package/dist/operation-presentation.js +1 -7
  73. package/dist/owner.d.ts +2 -2
  74. package/dist/owner.js +1 -1
  75. package/dist/packages/agent-delivery/src/claude-native.d.ts +2 -0
  76. package/dist/packages/agent-delivery/src/claude-native.js +5 -0
  77. package/dist/packages/agent-delivery/src/codex-boundary.d.ts +11 -6
  78. package/dist/packages/agent-delivery/src/codex-boundary.js +31 -40
  79. package/dist/packages/agent-delivery/src/codex-hook.d.ts +17 -12
  80. package/dist/packages/agent-delivery/src/codex-hook.js +26 -39
  81. package/dist/packages/agent-delivery/src/codex.d.ts +3 -0
  82. package/dist/packages/agent-delivery/src/codex.js +41 -4
  83. package/dist/packages/agent-delivery/src/index.d.ts +3 -1
  84. package/dist/packages/agent-delivery/src/index.js +1 -1
  85. package/dist/packages/agent-delivery/src/paseo.js +11 -2
  86. package/dist/packages/agent-delivery/src/types.d.ts +1 -0
  87. package/dist/paseo-delivery.d.ts +5 -5
  88. package/dist/paseo-delivery.js +19 -99
  89. package/dist/paseo.d.ts +1 -1
  90. package/dist/paseo.js +1 -1
  91. package/dist/plugins/opencode/index.d.ts +5 -3
  92. package/dist/plugins/opencode/index.js +99 -21
  93. package/dist/plugins/opencode-shared/delivery.d.ts +23 -0
  94. package/dist/plugins/opencode-shared/delivery.js +109 -0
  95. package/dist/plugins/opencode-v1/index.d.ts +28 -0
  96. package/dist/plugins/opencode-v1/index.js +41 -0
  97. package/dist/plugins/opencode-v1/runtime.d.ts +56 -0
  98. package/dist/plugins/opencode-v1/runtime.js +152 -0
  99. package/dist/plugins/opencode-v1/transport.d.ts +13 -0
  100. package/dist/plugins/opencode-v1/transport.js +50 -0
  101. package/dist/plugins/paseo/shared/card-presentation.d.ts +10 -0
  102. package/dist/plugins/paseo/shared/card-presentation.js +7 -0
  103. package/dist/ports.d.ts +33 -214
  104. package/dist/presentation.d.ts +5 -5
  105. package/dist/presentation.js +1 -0
  106. package/dist/runtime.js +2 -2
  107. package/dist/search.js +1 -1
  108. package/dist/session-lifecycle.d.ts +8 -7
  109. package/dist/session-lifecycle.js +40 -42
  110. package/dist/sqlite-framing.d.ts +8 -0
  111. package/dist/sqlite-framing.js +31 -0
  112. package/dist/sqlite-square.d.ts +16 -26
  113. package/dist/sqlite-square.js +199 -262
  114. package/dist/sqlite-values.d.ts +21 -0
  115. package/dist/sqlite-values.js +78 -0
  116. package/dist/square-api.d.ts +1 -1
  117. package/dist/square-api.js +5 -8
  118. package/dist/square-core.d.ts +0 -1
  119. package/dist/square-domain.d.ts +12 -10
  120. package/dist/square-domain.js +105 -223
  121. package/dist/square-facade.d.ts +25 -76
  122. package/dist/square-location.d.ts +6 -1
  123. package/dist/square-location.js +1 -1
  124. package/dist/square-post.d.ts +53 -0
  125. package/dist/square-post.js +4 -0
  126. package/dist/square-posting.d.ts +13 -0
  127. package/dist/square-posting.js +174 -0
  128. package/dist/square-producer-sqlite.d.ts +11 -0
  129. package/dist/square-producer-sqlite.js +210 -0
  130. package/dist/square-receive.d.ts +2 -3
  131. package/dist/square-sqlite.d.ts +33 -42
  132. package/dist/square-sqlite.js +236 -768
  133. package/dist/square-tools.d.ts +8 -0
  134. package/dist/square-tools.js +39 -0
  135. package/dist/square-values.d.ts +27 -0
  136. package/dist/square-values.js +90 -0
  137. package/dist/views.d.ts +6 -6
  138. package/dist/views.js +14 -9
  139. package/dist/wake-sink.d.ts +4 -11
  140. package/dist/wake-sink.js +8 -32
  141. package/dist/wake-transports.d.ts +4 -0
  142. package/dist/wake-transports.js +11 -0
  143. package/examples/symmetric-domains.mjs +29 -249
  144. package/guides/change-waits.md +13 -53
  145. package/guides/claude-native.md +19 -172
  146. package/guides/codex-delivery.md +55 -78
  147. package/guides/delivery-primitives.md +48 -207
  148. package/guides/operation-cancellation.md +2 -5
  149. package/guides/participant-ownership.md +25 -89
  150. package/guides/pi-native-delivery.md +19 -56
  151. package/guides/pi-tools.md +6 -8
  152. package/guides/row-runtime-delivery-evidence.md +2 -0
  153. package/guides/row-storage-design.md +19 -44
  154. package/guides/square-api.md +113 -538
  155. package/package.json +8 -8
  156. package/plugins/claude/.claude-plugin/plugin.json +1 -1
  157. package/plugins/claude/hooks/hooks.json +1 -1
  158. package/plugins/claude/{hooks/register.js → mods/square.js} +4 -7
  159. package/plugins/claude/types.d.ts +1 -1
  160. package/plugins/codex/.codex-plugin/plugin.json +1 -1
  161. package/plugins/codex/hooks/hooks.json +11 -23
  162. package/plugins/opencode/index.ts +91 -23
  163. package/plugins/opencode-shared/delivery.ts +91 -0
  164. package/plugins/opencode-v1/index.ts +36 -0
  165. package/plugins/opencode-v1/runtime.ts +134 -0
  166. package/plugins/opencode-v1/transport.ts +41 -0
  167. package/plugins/paseo/OVERVIEW.md +5 -5
  168. package/plugins/paseo/README.md +7 -6
  169. package/plugins/paseo/client/markdown.tsx +5 -5
  170. package/plugins/paseo/client/square-message.tsx +28 -24
  171. package/plugins/paseo/client/transform.ts +8 -5
  172. package/plugins/paseo/shared/card-presentation.ts +16 -0
  173. package/plugins/paseo/shared/message.ts +6 -11
  174. package/plugins/pi/square-pi.js +167 -451
  175. package/dist/channel.d.ts +0 -74
  176. package/dist/channel.js +0 -92
  177. package/dist/claude-delivery-status.d.ts +0 -13
  178. package/dist/claude-delivery-status.js +0 -46
  179. package/dist/cmd/notify-once.d.ts +0 -2
  180. package/dist/cmd/notify-once.js +0 -29
  181. package/dist/delivery-attempts.d.ts +0 -52
  182. package/dist/delivery-attempts.js +0 -73
  183. package/dist/delivery-effects.d.ts +0 -139
  184. package/dist/delivery-effects.js +0 -163
  185. package/dist/delivery-health.d.ts +0 -51
  186. package/dist/delivery-health.js +0 -173
  187. package/dist/delivery-operations.d.ts +0 -9
  188. package/dist/delivery-operations.js +0 -168
  189. package/dist/delivery-primitives.d.ts +0 -5
  190. package/dist/delivery-primitives.js +0 -3
  191. package/dist/delivery.d.ts +0 -45
  192. package/dist/delivery.js +0 -106
  193. package/dist/plugins/opencode/delivery.d.ts +0 -19
  194. package/dist/plugins/opencode/delivery.js +0 -238
  195. package/dist/presentation-operations.d.ts +0 -18
  196. package/dist/presentation-operations.js +0 -86
  197. package/dist/square-index.d.ts +0 -16
  198. package/dist/square-index.js +0 -106
  199. package/dist/square-legacy-framing.d.ts +0 -11
  200. package/dist/square-legacy-framing.js +0 -64
  201. package/dist/square-migration-host-ledger.d.ts +0 -26
  202. package/dist/square-migration-host-ledger.js +0 -169
  203. package/dist/square-migration.d.ts +0 -30
  204. package/dist/square-migration.js +0 -599
  205. package/guides/migration.md +0 -156
  206. package/plugins/opencode/delivery.ts +0 -211
@@ -1,64 +0,0 @@
1
- export const FORMAT4_ADDED_OBJECTS = new Set([
2
- 'seats', 'seat_body', 'delivery_evidence', 'delivery_claim_token', 'delivery_activity', 'delivery_cancellations',
3
- ]);
4
- export const FORMAT4_REPLACED_OBJECTS = new Set(['routes', 'route_participant', 'route_session']);
5
- const LEGACY_ROUTES_SQL = `CREATE TABLE routes (
6
- position INTEGER PRIMARY KEY CHECK (position >= 0),
7
- participant_key_json TEXT COLLATE BINARY NOT NULL,
8
- session_json TEXT COLLATE BINARY NOT NULL,
9
- kind TEXT NOT NULL CHECK (kind IN ('opencode-server','codex-queue','claude-native','paseo')),
10
- updated_at REAL NOT NULL,
11
- payload_json TEXT NOT NULL CHECK (json_valid(payload_json))
12
- );
13
- CREATE INDEX route_participant ON routes(participant_key_json, position);
14
- CREATE INDEX route_session ON routes(session_json, position);`;
15
- function normalizedSql(sql) {
16
- return sql.trim().replace(/;$/, '').replace(/\s+/g, ' ').replace(/\s*([(),=])\s*/g, '$1');
17
- }
18
- /** Historical activity framing only; no runtime activity decoder accepts these kinds. */
19
- export function legacyActivitySchema(currentSchemaSql) {
20
- return currentSchemaSql
21
- .replace("kind IN ('join','done','say','read','listen','ignore','unlisten')", "kind IN ('join','done','say','hold','resume','read','listen','ignore','unlisten')")
22
- .replace(' actor_json TEXT COLLATE BINARY NOT NULL,', ' actor_json TEXT COLLATE BINARY,')
23
- .replace(' actor_key_json TEXT COLLATE BINARY NOT NULL,', ' actor_key_json TEXT COLLATE BINARY,')
24
- .replace(" CHECK (kind = 'say' OR (reach IS NULL AND reply_index IS NULL))", " CHECK ((actor_json IS NULL) = (actor_key_json IS NULL)),\n CHECK (kind IN ('hold','resume') OR actor_json IS NOT NULL),\n CHECK (kind = 'say' OR (reach IS NULL AND reply_index IS NULL))");
25
- }
26
- function legacyRowSchema(currentSchemaSql, version) {
27
- const statements = currentSchemaSql.split(';').map((statement) => statement.trim()).filter(Boolean)
28
- .filter((statement) => {
29
- const match = /^(?:CREATE (?:UNIQUE )?TABLE|CREATE (?:UNIQUE )?INDEX)\s+([a-z_]+)/i.exec(statement);
30
- return match === null || !FORMAT4_ADDED_OBJECTS.has(match[1]) && !FORMAT4_REPLACED_OBJECTS.has(match[1]);
31
- });
32
- const legacyStatements = statements.join(';\n')
33
- .replace(' delivery_revision INTEGER NOT NULL CHECK (delivery_revision BETWEEN 0 AND 9007199254740991),\n', '')
34
- .replace(' generation_json TEXT NOT NULL DEFAULT \'""\',\n', '');
35
- const allStatements = [...legacyStatements.split(';').map((statement) => statement.trim()).filter(Boolean),
36
- ...LEGACY_ROUTES_SQL.split(';').map((statement) => statement.trim()).filter(Boolean)];
37
- let schema = allStatements.join(';\n');
38
- if (version === 2) {
39
- schema = schema.replace("kind IN ('join','done','say','hold','resume','read','listen','ignore','unlisten')", "kind IN ('join','done','say','hold','resume','read','listen','ignore')");
40
- }
41
- return schema.split(';').map((statement) => normalizedSql(statement)).filter(Boolean).sort();
42
- }
43
- /**
44
- * Read-only recognition of the exact row framing accepted by explicit migration.
45
- * It inspects identity, owned schema and journal mode only; it never reads row
46
- * contents (including legacy routes), changes pragmas, or performs DDL.
47
- */
48
- export function legacyRowFramingIssue(database, applicationId, version, location, currentSchemaSql) {
49
- const identity = database.prepare('SELECT application_id, user_version FROM pragma_application_id, pragma_user_version').get();
50
- if (identity.application_id !== applicationId)
51
- return 'unrelated SQLite database.';
52
- if (identity.user_version !== version)
53
- return 'unsupported SQLite format version.';
54
- const actual = database.prepare("SELECT sql FROM sqlite_schema WHERE name NOT GLOB 'sqlite_*' AND sql IS NOT NULL").all()
55
- .map((row) => typeof row.sql === 'string' ? normalizedSql(row.sql) : '')
56
- .sort();
57
- const expected = legacyRowSchema(currentSchemaSql, version);
58
- if (actual.length !== expected.length || actual.some((sql, index) => sql !== expected[index]))
59
- return 'unsupported row schema.';
60
- const journalMode = database.prepare('PRAGMA journal_mode').get().journal_mode;
61
- if (journalMode !== (location === ':memory:' ? 'memory' : 'delete'))
62
- return 'unsupported journal mode.';
63
- return undefined;
64
- }
@@ -1,26 +0,0 @@
1
- import { type HarnessCoordinate } from './owner.js';
2
- /** Offline conversion input only; never a runtime ownership or evidence reader. */
3
- export interface LegacyOwner {
4
- readonly participant: string;
5
- readonly coordinate: HarnessCoordinate;
6
- }
7
- export interface LegacyHostData {
8
- readonly owners: readonly LegacyOwner[];
9
- readonly evidence: readonly LegacyDeliveryEvidence[];
10
- }
11
- export interface LegacyDeliveryEvidence {
12
- readonly v: 1;
13
- readonly location: string;
14
- readonly participant: string;
15
- readonly session: string;
16
- readonly activity: string;
17
- readonly kind: 'wake' | 'presentation' | 'lifecycle';
18
- readonly outcome: string;
19
- readonly at?: number;
20
- readonly expiresAt?: number;
21
- readonly attemptN?: number;
22
- readonly claimToken?: string;
23
- readonly [key: string]: unknown;
24
- }
25
- /** One frozen snapshot, latest owners only; no age, expiry, or ownership history inference. */
26
- export declare function readLegacyHostData(location: string, env?: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<LegacyHostData>;
@@ -1,169 +0,0 @@
1
- import { DatabaseSync } from 'node:sqlite';
2
- import fs from 'node:fs';
3
- import os from 'node:os';
4
- import path from 'node:path';
5
- import { pathToFileURL } from 'node:url';
6
- import { canonicalPath } from './canonical-path.js';
7
- import { inSqliteTransaction } from './sqlite-transaction.js';
8
- import { harnessOwner } from './owner.js';
9
- import { nameKey } from './model.js';
10
- const LEDGER_FILENAME = 'host-ledger.sqlite';
11
- const LEDGER_APPLICATION_ID = 0x5351484c;
12
- const LEDGER_VERSION = 2;
13
- const tableSchema = {
14
- host_meta: 'CREATE TABLE host_meta (id INTEGER PRIMARY KEY CHECK(id=1), presence_revision INTEGER NOT NULL, evidence_revision INTEGER NOT NULL)',
15
- host_presence: 'CREATE TABLE host_presence (seq INTEGER PRIMARY KEY AUTOINCREMENT, location_key TEXT NOT NULL, participant_key TEXT NOT NULL, session_key TEXT NOT NULL, channel_key TEXT NOT NULL, effective_at REAL NOT NULL, row_json TEXT NOT NULL)',
16
- host_evidence: 'CREATE TABLE host_evidence (seq INTEGER PRIMARY KEY AUTOINCREMENT, location_key TEXT NOT NULL, participant_key TEXT NOT NULL, session_key TEXT NOT NULL, activity_key TEXT NOT NULL, kind TEXT NOT NULL, outcome TEXT NOT NULL, claim_token_key TEXT, effective_at REAL NOT NULL, row_json TEXT NOT NULL)',
17
- host_native_tokens: "CREATE TABLE host_native_tokens (harness TEXT NOT NULL CHECK(harness='claude'), session_key TEXT NOT NULL, token_key TEXT NOT NULL, PRIMARY KEY(harness,session_key,token_key)) WITHOUT ROWID",
18
- };
19
- const indexes = {
20
- host_presence_identity: ['host_presence', 'location_key', 'participant_key', 'seq'],
21
- host_presence_session: ['host_presence', 'session_key', 'seq'],
22
- host_presence_time: ['host_presence', 'effective_at'],
23
- host_evidence_attention: ['host_evidence', 'location_key', 'participant_key', 'activity_key', 'kind', 'session_key', 'seq'],
24
- host_evidence_kind_session: ['host_evidence', 'kind', 'session_key', 'seq'],
25
- host_evidence_session: ['host_evidence', 'session_key', 'seq'],
26
- host_evidence_token: ['host_evidence', 'location_key', 'participant_key', 'activity_key', 'session_key', 'claim_token_key', 'seq'],
27
- host_evidence_outcome_time: ['host_evidence', 'outcome', 'effective_at'],
28
- host_evidence_time: ['host_evidence', 'effective_at'],
29
- host_evidence_native_token: ['host_evidence', 'session_key', 'claim_token_key', 'seq'],
30
- };
31
- const LEGACY_FILES = ['presence.ndjsonl', 'evidence.ndjsonl'];
32
- function indexSql(name, fields) {
33
- return `CREATE INDEX ${name} ON ${fields[0]} (${fields.slice(1).join(',')})`;
34
- }
35
- function normalizedSql(sql) {
36
- return sql.replace(/\s+/g, '').replace(/;$/, '');
37
- }
38
- function recordKey(value) { return JSON.stringify(value); }
39
- function validateLedger(database) {
40
- const application = database.prepare('PRAGMA application_id').get().application_id;
41
- const version = database.prepare('PRAGMA user_version').get().user_version;
42
- if (application !== LEDGER_APPLICATION_ID || version !== LEDGER_VERSION)
43
- throw invalid('unsupported format.');
44
- if (database.prepare('PRAGMA journal_mode').get().journal_mode !== 'delete')
45
- throw invalid('unsupported journal mode.');
46
- const expected = new Map([
47
- ...Object.entries(tableSchema),
48
- ...Object.entries(indexes).map(([name, fields]) => [name, indexSql(name, fields)]),
49
- ]);
50
- const schema = database.prepare("SELECT name,sql FROM sqlite_schema WHERE name NOT LIKE 'sqlite_%'").all();
51
- if (schema.length !== expected.size || schema.some((row) => typeof row.name !== 'string' || typeof row.sql !== 'string'
52
- || !expected.has(row.name) || normalizedSql(row.sql) !== normalizedSql(expected.get(row.name))))
53
- throw invalid('schema or indexes are malformed.');
54
- const meta = database.prepare('SELECT id,presence_revision,evidence_revision FROM host_meta').all();
55
- if (meta.length !== 1 || meta[0].id !== 1 || ![meta[0].presence_revision, meta[0].evidence_revision].every((value) => Number.isSafeInteger(value) && value >= 0))
56
- throw invalid('revision header is malformed.');
57
- const integrity = database.prepare('PRAGMA integrity_check').all();
58
- if (integrity.length !== 1 || integrity[0].integrity_check !== 'ok')
59
- throw invalid('integrity check failed.');
60
- // Token-only tombstones have no artifact coordinate. Never guess or discard replay protection.
61
- if (database.prepare('SELECT 1 FROM host_native_tokens LIMIT 1').get() !== undefined)
62
- throw invalid('native token tombstones cannot be mapped safely; preserve replay protection and resolve the ledger offline.');
63
- }
64
- function ledgerRoot(env) {
65
- return path.resolve(env.SQUARE_HOST_LEDGER_ROOT
66
- ?? (env.SQUARE_REGISTRY === undefined ? path.join(env.HOME ?? os.homedir(), '.square', 'host-ledger') : path.dirname(env.SQUARE_REGISTRY)));
67
- }
68
- function invalid(detail) {
69
- return new Error(`Invalid legacy host ledger: ${detail}`);
70
- }
71
- function finite(value) {
72
- return typeof value === 'number' && Number.isFinite(value);
73
- }
74
- function decodeEvidence(value) {
75
- if (value === null || typeof value !== 'object' || Array.isArray(value))
76
- throw invalid('evidence record is not an object.');
77
- const row = value;
78
- if (row.v !== 1 || typeof row.location !== 'string' || typeof row.participant !== 'string' || typeof row.session !== 'string'
79
- || typeof row.activity !== 'string' || !['wake', 'presentation', 'lifecycle'].includes(row.kind)
80
- || typeof row.outcome !== 'string')
81
- throw invalid('evidence record fields are malformed.');
82
- if (row.at !== undefined && !finite(row.at))
83
- throw invalid('evidence time is malformed.');
84
- if (row.expiresAt !== undefined && !finite(row.expiresAt))
85
- throw invalid('evidence expiry is malformed.');
86
- if (row.attemptN !== undefined && (!Number.isSafeInteger(row.attemptN) || row.attemptN < 0))
87
- throw invalid('evidence attempt is malformed.');
88
- if (row.claimToken !== undefined && (typeof row.claimToken !== 'string' || row.claimToken.length === 0))
89
- throw invalid('evidence claim token is malformed.');
90
- return row;
91
- }
92
- function record(row) {
93
- if (!Number.isSafeInteger(row.seq) || row.seq < 1 || typeof row.row_json !== 'string')
94
- throw invalid('row framing is malformed.');
95
- let value;
96
- try {
97
- value = JSON.parse(row.row_json);
98
- }
99
- catch {
100
- throw invalid('record JSON is malformed.');
101
- }
102
- if (value === null || typeof value !== 'object' || Array.isArray(value))
103
- throw invalid('record is not an object.');
104
- return value;
105
- }
106
- function projections(row, expected) {
107
- if (Object.entries(expected).some(([key, value]) => row[key] !== value))
108
- throw invalid('record projections are malformed.');
109
- }
110
- /** One frozen snapshot, latest owners only; no age, expiry, or ownership history inference. */
111
- export async function readLegacyHostData(location, env = process.env, signal) {
112
- if (signal?.aborted)
113
- throw signal.reason;
114
- const root = ledgerRoot(env);
115
- const file = path.join(root, LEDGER_FILENAME);
116
- try {
117
- await fs.promises.stat(file);
118
- }
119
- catch (error) {
120
- if (error.code !== 'ENOENT')
121
- throw error;
122
- for (const legacy of LEGACY_FILES) {
123
- try {
124
- await fs.promises.stat(path.join(root, legacy));
125
- throw invalid('legacy line sources require separate host-ledger migration.');
126
- }
127
- catch (nested) {
128
- if (nested.code !== 'ENOENT')
129
- throw nested;
130
- }
131
- }
132
- return { owners: [], evidence: [] };
133
- }
134
- const uri = pathToFileURL(file);
135
- uri.searchParams.set('mode', 'ro');
136
- const database = new DatabaseSync(uri.href);
137
- try {
138
- const canonical = await canonicalPath(location);
139
- return await inSqliteTransaction(database, false, () => validateLedger(database), () => {
140
- const owners = database.prepare(`SELECT * FROM (
141
- SELECT *,row_number() OVER (PARTITION BY participant_key ORDER BY effective_at DESC,seq DESC) AS ordinal
142
- FROM host_presence WHERE location_key=?) WHERE ordinal=1`).all(recordKey(canonical)).map(row => {
143
- const value = record(row);
144
- const at = value.at ?? value.updatedAt;
145
- if (value.v !== 1 || value.location !== canonical || typeof value.participant !== 'string'
146
- || !finite(at))
147
- throw invalid('owner fields are malformed.');
148
- const coordinate = { channel: value.channel, session: value.session, ...(value.agent === undefined ? {} : { agent: value.agent }) };
149
- harnessOwner(coordinate);
150
- projections(row, { location_key: recordKey(canonical), participant_key: recordKey(nameKey(value.participant)),
151
- channel_key: recordKey(coordinate.channel), session_key: recordKey(coordinate.session), effective_at: at });
152
- return { participant: value.participant, coordinate };
153
- });
154
- const evidence = database.prepare("SELECT * FROM host_evidence WHERE location_key=? AND kind IN ('wake','presentation') ORDER BY seq").all(recordKey(canonical)).map(row => {
155
- const value = decodeEvidence(record(row));
156
- if (value.location !== canonical || !finite(value.at))
157
- throw invalid('evidence fields are malformed.');
158
- projections(row, { location_key: recordKey(canonical), participant_key: recordKey(nameKey(value.participant)), session_key: recordKey(value.session),
159
- activity_key: recordKey(value.activity), kind: value.kind, outcome: value.outcome,
160
- claim_token_key: value.claimToken === undefined ? null : recordKey(value.claimToken), effective_at: value.at });
161
- return value;
162
- });
163
- return { owners, evidence };
164
- }, signal);
165
- }
166
- finally {
167
- database.close();
168
- }
169
- }
@@ -1,30 +0,0 @@
1
- import { type SquareState } from './square-sqlite.js';
2
- /** Validate persisted v1 JSON; row codecs share activity and lease acceptance. */
3
- export declare function validateSquareState(value: unknown): SquareState;
4
- export interface MigrationCounts {
5
- readonly activities: number;
6
- readonly receipts: number;
7
- readonly leases: number;
8
- readonly routes: number;
9
- readonly recoveredSeats: number;
10
- readonly unownedStanding: number;
11
- readonly sharedBodySeats: number;
12
- readonly skippedEvidence: number;
13
- }
14
- export interface MigrationOutcome {
15
- readonly status: 'migrated' | 'already-current';
16
- /** Participants standing after the conversion, for the CLI header. */
17
- readonly standing: number;
18
- readonly counts?: MigrationCounts;
19
- }
20
- /**
21
- * Explicit conversion of the supported legacy formats. Row-backed versions 2 and 3 are
22
- * preflighted read-only, then receive ownership/evidence and deferral storage in one
23
- * format-8 transaction. Formats 4/5 gain attachment; format 4 also gains empty deferrals.
24
- * All legacy seats are encoded as opaque owners, preserving format-6 attachment.
25
- * Every source drops obsolete activities and their identity references, clears dangling
26
- * replies and rebuilds derived indices; surviving ids and allocation watermarks remain stable.
27
- * Legacy delivery evidence is copied from HostLedger only when its owner/session mapping is
28
- * unique; no source record is retired. Version 1 is not a supported source for this format transition.
29
- */
30
- export declare function migrateSquareFile(location: string, signal?: AbortSignal, env?: NodeJS.ProcessEnv): Promise<MigrationOutcome>;