@astrosheep/square 0.3.77 → 0.3.79

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 (76) hide show
  1. package/dist/attention-presentation.d.ts +3 -1
  2. package/dist/attention-presentation.js +45 -13
  3. package/dist/automatic-session.js +1 -1
  4. package/dist/boundary-presentation.js +4 -6
  5. package/dist/claude-mod.js +1 -1
  6. package/dist/cli/catch-presentation.d.ts +2 -2
  7. package/dist/cli/catch-presentation.js +3 -3
  8. package/dist/cli/context.d.ts +11 -1
  9. package/dist/cli/context.js +14 -3
  10. package/dist/cli/express-presentation.d.ts +6 -5
  11. package/dist/cli/express-presentation.js +35 -30
  12. package/dist/cli/maintenance-commands.js +8 -8
  13. package/dist/cli/mcp-server-command.js +1 -1
  14. package/dist/cli/observation-commands.d.ts +4 -4
  15. package/dist/cli/observation-commands.js +20 -16
  16. package/dist/cli/program.d.ts +1 -1
  17. package/dist/cli/program.js +13 -7
  18. package/dist/cli/square-commands.js +35 -23
  19. package/dist/decisions.d.ts +9 -4
  20. package/dist/decisions.js +17 -8
  21. package/dist/delivery.d.ts +1 -1
  22. package/dist/help.js +15 -2
  23. package/dist/host-ledger-migration.js +2 -6
  24. package/dist/host-ledger-sqlite.js +2 -2
  25. package/dist/inbox.js +3 -3
  26. package/dist/index.d.ts +1 -2
  27. package/dist/index.js +1 -2
  28. package/dist/ledger-maintenance.d.ts +1 -1
  29. package/dist/ledger-maintenance.js +1 -1
  30. package/dist/list.d.ts +3 -3
  31. package/dist/list.js +1 -1
  32. package/dist/mcp.d.ts +2 -2
  33. package/dist/mcp.js +12 -7
  34. package/dist/mention-parse.d.ts +2 -8
  35. package/dist/mention-parse.js +6 -9
  36. package/dist/model.d.ts +5 -1
  37. package/dist/notifications.js +24 -8
  38. package/dist/participant-host.js +5 -0
  39. package/dist/plugins/opencode/index.js +1 -1
  40. package/dist/square-actions.d.ts +22 -9
  41. package/dist/square-actions.js +27 -19
  42. package/dist/square-api.d.ts +43 -0
  43. package/dist/square-api.js +471 -0
  44. package/dist/square-facade.d.ts +124 -203
  45. package/dist/square-sqlite.d.ts +2 -8
  46. package/dist/square-sqlite.js +3 -11
  47. package/dist/square-tools.d.ts +4 -3
  48. package/dist/square-tools.js +22 -16
  49. package/dist/stream.d.ts +2 -2
  50. package/dist/views.d.ts +16 -12
  51. package/dist/views.js +13 -27
  52. package/guides/application-demand-optimization.md +5 -0
  53. package/guides/application-facade-delivery-evidence.md +6 -1
  54. package/guides/claude-native.md +3 -1
  55. package/guides/mcp-connection-lifetime.md +2 -2
  56. package/guides/mcp.md +1 -1
  57. package/guides/migration.md +2 -1
  58. package/guides/operation-cancellation.md +2 -0
  59. package/guides/primitive-catch-consolidation.md +5 -0
  60. package/guides/primitive-history-consolidation.md +5 -0
  61. package/guides/primitive-status-consolidation.md +5 -0
  62. package/guides/primitive-storage-consolidation.md +5 -0
  63. package/guides/row-storage-design.md +2 -2
  64. package/guides/square-api.md +107 -0
  65. package/package.json +1 -1
  66. package/plugins/claude/.claude-plugin/plugin.json +1 -1
  67. package/plugins/claude/skills/square/SKILL.md +3 -3
  68. package/plugins/codex/.codex-plugin/plugin.json +1 -1
  69. package/plugins/opencode/index.ts +1 -1
  70. package/plugins/paseo/client/markdown.tsx +16 -6
  71. package/plugins/pi/square-pi.js +70 -30
  72. package/skills/square/SKILL.md +3 -3
  73. package/dist/square-application.d.ts +0 -38
  74. package/dist/square-application.js +0 -683
  75. package/guides/application-boundary.md +0 -32
  76. package/guides/application-facade-design.md +0 -98
@@ -1,10 +1,8 @@
1
1
  import type { ActivityId, Perception, Reach } from './square-core.js';
2
2
  import type { StoredAct } from './model.js';
3
3
  import type { HostLedgerPort, WakeTransportPort, DeliveryResult, SquareResourceOwner } from './ports.js';
4
- import type { DiagnoseResult } from './artifact.js';
5
- import type { MigrationOutcome } from './square-migration.js';
6
4
  export type { ActivityId, Perception, Reach } from './square-core.js';
7
- /** The existing indexed domain event, including read and historical actorless lifecycle records. */
5
+ /** Indexed archive event, including read and historical actorless lifecycle records. */
8
6
  export type ArchiveRecord = Readonly<StoredAct>;
9
7
  export interface Activity {
10
8
  readonly id: ActivityId;
@@ -20,35 +18,57 @@ export interface Activity {
20
18
  export interface PerceivedActivity extends Activity {
21
19
  readonly perception: Perception;
22
20
  }
23
- export interface ExpressOptions {
21
+ /** Request extra facts for rendering, without changing operation semantics. */
22
+ export interface ObservationOptions {
23
+ readonly observe?: boolean;
24
+ }
25
+ export interface ExpressOptions extends ObservationOptions {
24
26
  readonly force?: boolean;
25
27
  readonly mentions?: readonly string[];
26
28
  readonly reach?: Reach;
27
29
  readonly reply?: ActivityId;
28
30
  readonly noMention?: boolean;
31
+ readonly noWait?: boolean;
32
+ readonly requireExplicitReach?: boolean;
29
33
  }
30
- export interface ExpressResult {
34
+ export interface ActivityResult {
31
35
  readonly activity: Activity;
32
36
  readonly delivery?: DeliveryResult;
37
+ }
38
+ export interface ExpressResult extends ActivityResult {
39
+ readonly waited: boolean;
33
40
  /** The replied-to author was not standing when the reply landed. */
34
41
  readonly replyAuthorNotHere?: string;
42
+ /** Body @name tokens with no standing match at landing; never stored on the activity. */
43
+ readonly unmatchedMentions?: readonly string[];
44
+ readonly observation?: ExpressObservation;
35
45
  }
36
- export interface ListenerChangeData {
46
+ export interface ListenerChangeResult {
37
47
  readonly activity: Activity | null;
48
+ readonly observation?: ListenerObservation;
38
49
  }
39
- export type ListenerChangeResult = ListenerChangeData;
40
- export interface CatchOptions {
50
+ export interface ListeningResult {
51
+ readonly listening: readonly string[];
52
+ readonly observation?: SquareObservation;
53
+ }
54
+ export interface LifecycleResult extends ActivityResult {
55
+ readonly observation?: LifecycleObservation;
56
+ }
57
+ export interface CatchOptions extends ObservationOptions {
41
58
  readonly id?: ActivityId;
42
59
  readonly idle?: number;
43
60
  readonly from?: readonly string[];
44
61
  readonly mention?: boolean;
45
62
  readonly limit?: number;
63
+ readonly replace?: boolean;
46
64
  }
47
65
  export interface CatchResult {
48
66
  readonly activities: readonly PerceivedActivity[];
49
67
  readonly consumedThrough: ActivityId | null;
50
68
  readonly idleExpired: boolean;
51
69
  readonly remaining: number;
70
+ readonly status?: CatchTerminalStatus;
71
+ readonly observation?: CatchObservation;
52
72
  }
53
73
  export interface CatchWaitStart {
54
74
  readonly idleMs: number;
@@ -69,8 +89,23 @@ export interface OperationControl {
69
89
  readonly signal?: AbortSignal;
70
90
  readonly onProgress?: (progress: OperationProgress) => void;
71
91
  }
72
- export interface HistoryQuery {
73
- readonly limit?: number;
92
+ export interface OperationFailureDetail {
93
+ readonly operation: 'express' | 'join' | 'catch' | 'history' | 'other';
94
+ readonly subject?: 'caller' | 'filter' | 'recipient';
95
+ readonly participant?: string;
96
+ readonly expressEffect?: 'unsent' | 'landed' | 'unknown';
97
+ readonly landedId?: ActivityId;
98
+ readonly historyBounds?: {
99
+ readonly maxLimit: number;
100
+ readonly totalMatches: number;
101
+ };
102
+ }
103
+ export interface OperationError extends Error {
104
+ readonly operation?: OperationFailureDetail;
105
+ }
106
+ export interface HistoryQuery extends ObservationOptions {
107
+ /** Ten by default; null explicitly reads the full archive. */
108
+ readonly limit?: number | null;
74
109
  readonly order?: 'asc' | 'desc';
75
110
  readonly before?: ActivityId;
76
111
  readonly after?: ActivityId;
@@ -78,6 +113,14 @@ export interface HistoryQuery {
78
113
  readonly fixed?: string;
79
114
  readonly from?: readonly string[];
80
115
  readonly mention?: string;
116
+ readonly since?: number;
117
+ readonly at?: readonly ActivityId[];
118
+ readonly contextBefore?: number;
119
+ readonly contextAfter?: number;
120
+ }
121
+ export interface HistoryResult {
122
+ readonly activities: readonly Activity[];
123
+ readonly observation?: HistoryObservation;
81
124
  }
82
125
  export interface ParticipantStatus {
83
126
  readonly name: string;
@@ -98,132 +141,61 @@ export interface SquareSnapshot {
98
141
  readonly participants: readonly ParticipantStatus[];
99
142
  delivered(name: string, id: ActivityId): boolean;
100
143
  }
101
- export type SquareSource = {
102
- path: string;
103
- };
104
144
  export interface OpenOptions {
105
- clock?: () => number;
106
- hostLedger?: HostLedgerPort;
107
- wakeTransport?: WakeTransportPort;
108
- env?: NodeJS.ProcessEnv;
109
- }
110
- export interface SquareAtInput extends SquareSource, OpenOptions {
145
+ readonly clock?: () => number;
146
+ readonly hostLedger?: HostLedgerPort;
147
+ readonly wakeTransport?: WakeTransportPort;
148
+ readonly env?: NodeJS.ProcessEnv;
111
149
  }
112
- export interface SquareBuildInput extends SquareSource, OpenOptions {
113
- markdown: string;
114
- hardCap?: number | null;
115
- throttlePerMinute?: number;
116
- }
117
- /** Optional fence for owner-scoped lifecycle actions. */
118
- export interface OwnershipFenceOptions {
119
- readonly expectedEpoch?: number;
150
+ export interface SquareLocation {
151
+ readonly path?: string;
152
+ readonly cwd?: string;
153
+ readonly env?: NodeJS.ProcessEnv;
120
154
  }
121
- export interface Participant {
122
- readonly name: string;
123
- express(body: string, options?: ExpressOptions, control?: OperationControl): Promise<ExpressResult>;
124
- listen(target: string, control?: OperationControl): Promise<ListenerChangeResult>;
125
- ignore(target: string, control?: OperationControl): Promise<ListenerChangeResult>;
126
- listening(control?: OperationControl): Promise<readonly string[]>;
127
- catch(options?: CatchOptions, control?: OperationControl): Promise<CatchResult>;
128
- history(query?: HistoryQuery, control?: OperationControl): Promise<Activity[]>;
129
- hold(reason?: string, control?: OperationControl): Promise<ExpressResult>;
130
- resume(control?: OperationControl): Promise<ExpressResult>;
131
- /** Leave without a message. Only an omitted or empty body is accepted. */
132
- done(body?: string, control?: OperationControl): Promise<ExpressResult>;
133
- }
134
- export interface SquareApplicationContext extends Readonly<OpenOptions> {
135
- readonly cwd: string;
136
- readonly env: NodeJS.ProcessEnv;
137
- readonly squarePath?: string;
155
+ export interface SquareAtInput extends SquareLocation, OpenOptions {
138
156
  readonly participant?: string;
139
- /** Borrow the owner's connection for the configured square. The caller owns its lifetime;
140
- * without an owner, each operation opens and closes its own connection. */
157
+ /** A caller-owned connection; closing this Square never closes its owner. */
141
158
  readonly resources?: SquareResourceOwner;
142
159
  }
143
- /** Data-only callers do not request or pay for presentation work. */
144
- export interface ApplicationOutcome<Data, Projection, Presentation extends boolean = true> {
145
- readonly data: Data;
146
- readonly projection: Presentation extends true ? Projection : undefined;
147
- }
148
- export interface ApplicationFailureDetail {
149
- readonly operation: 'express' | 'join' | 'catch' | 'history' | 'other';
150
- readonly subject?: 'caller' | 'filter' | 'recipient';
151
- readonly participant?: string;
152
- readonly expressEffect?: 'unsent' | 'landed' | 'unknown';
153
- readonly landedId?: ActivityId;
154
- readonly historyBounds?: {
155
- readonly maxLimit: number;
156
- readonly totalMatches: number;
157
- };
158
- }
159
- export interface ApplicationError extends Error {
160
- readonly operation?: ApplicationFailureDetail;
161
- }
162
- export interface SquareContextProjection {
163
- readonly location: string;
164
- readonly standingCount: number;
165
- readonly held: boolean;
166
- readonly now: number;
167
- readonly participant?: string;
168
- readonly automaticDeliveryAvailable: boolean;
169
- }
170
- export interface BuildApplicationInput {
160
+ export interface SquareBuildInput extends SquareAtInput {
171
161
  readonly markdown: string;
172
162
  readonly hardCap?: number | null;
173
163
  readonly throttlePerMinute?: number;
174
164
  readonly template?: string;
175
165
  readonly force?: boolean;
176
166
  }
177
- export interface BuildApplicationData {
178
- readonly location: string;
179
- readonly hardCap: number | null;
180
- readonly throttlePerMinute?: number;
181
- }
182
- export interface JoinApplicationOptions {
167
+ export interface JoinOptions extends ObservationOptions {
183
168
  readonly takeover?: boolean;
184
169
  readonly last?: number;
185
170
  }
186
- export interface JoinApplicationData {
187
- readonly participant: string;
171
+ export interface JoinResult {
172
+ readonly participant: Participant;
188
173
  readonly activity: Activity | null;
189
174
  readonly kind: 'joined' | 'reconnected' | 'taken-over';
190
- /** Known joined-or-done participants, NOT the current standing count. */
175
+ /** Known joined-or-done participants, not the current standing count. */
191
176
  readonly participantCount: number;
177
+ readonly observation?: JoinObservation;
192
178
  }
193
- export interface ExpressApplicationOptions extends ExpressOptions {
194
- readonly noWait?: boolean;
195
- readonly requireExplicitReach?: boolean;
196
- }
197
- export interface ExpressApplicationData {
198
- readonly activity: Activity;
199
- readonly waited: boolean;
200
- readonly replyAuthorNotHere?: string;
179
+ /** Optional fence for owner-scoped lifecycle actions. */
180
+ export interface OwnershipFenceOptions {
181
+ readonly expectedEpoch?: number;
201
182
  }
202
- export interface CatchApplicationOptions extends CatchOptions {
203
- readonly replace?: boolean;
183
+ export interface Participant {
184
+ readonly name: string;
185
+ express(body: string, options?: ExpressOptions, control?: OperationControl): Promise<ExpressResult>;
186
+ listen(target: string, options?: ObservationOptions, control?: OperationControl): Promise<ListenerChangeResult>;
187
+ ignore(target: string, options?: ObservationOptions, control?: OperationControl): Promise<ListenerChangeResult>;
188
+ listening(options?: ObservationOptions, control?: OperationControl): Promise<ListeningResult>;
189
+ catch(options?: CatchOptions, control?: OperationControl): Promise<CatchResult>;
190
+ history(query?: HistoryQuery, control?: OperationControl): Promise<HistoryResult>;
191
+ hold(reason?: string, options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
192
+ resume(options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
193
+ /** Leave without a message. Only an omitted or empty body is accepted. */
194
+ done(body?: string, options?: ObservationOptions, control?: OperationControl): Promise<LifecycleResult>;
204
195
  }
205
196
  export type CatchTerminalStatus = 'already-active' | 'replaced' | 'capped' | 'quorum';
206
197
  export type CatchStopStatus = CatchTerminalStatus | 'empty-now' | 'stale';
207
- export interface CatchApplicationData extends CatchResult {
208
- readonly status?: CatchTerminalStatus;
209
- }
210
- export interface HistoryApplicationQuery extends HistoryQuery {
211
- readonly since?: number;
212
- readonly at?: readonly ActivityId[];
213
- readonly contextBefore?: number;
214
- readonly contextAfter?: number;
215
- }
216
- export interface HistoryApplicationData {
217
- readonly activities: readonly Activity[];
218
- }
219
- export interface ListeningData {
220
- readonly listening: readonly string[];
221
- }
222
- export interface LifecycleData {
223
- readonly activity: Activity;
224
- }
225
198
  export type ParticipantPresence = 'never-joined' | 'active' | 'watching' | 'done';
226
- /** Canonical public participant fields; status excludes never-joined roster entries. */
227
199
  export interface ParticipantSummary {
228
200
  readonly name: string;
229
201
  readonly state: 'active' | 'done' | 'not joined';
@@ -234,7 +206,10 @@ export interface ParticipantSummary {
234
206
  readonly unreadActivityCount: number;
235
207
  readonly pendingMentionCount: number;
236
208
  }
237
- export interface StatusApplicationData {
209
+ export interface StatusOptions extends ObservationOptions {
210
+ readonly viewer?: string;
211
+ }
212
+ export interface StatusResult {
238
213
  readonly hardCap: number | null;
239
214
  readonly activeCount: number;
240
215
  readonly doneCount: number;
@@ -247,13 +222,13 @@ export interface StatusApplicationData {
247
222
  readonly at?: number;
248
223
  } | null;
249
224
  readonly latestActivity?: Activity;
225
+ readonly observation?: StatusObservation;
250
226
  }
251
- export interface ParticipantsApplicationData {
227
+ export interface ParticipantsResult {
252
228
  readonly participants: readonly ParticipantSummary[];
229
+ readonly observation?: ParticipantsObservation;
253
230
  }
254
- export type DiagnosisApplicationData = DiagnoseResult;
255
- export type MigrationApplicationData = MigrationOutcome;
256
- export interface DiscoveryApplicationOptions {
231
+ export interface DiscoveryOptions {
257
232
  readonly depth?: number;
258
233
  readonly limit?: number;
259
234
  readonly after?: string;
@@ -265,21 +240,14 @@ export interface SquareListItem {
265
240
  readonly participants: readonly string[];
266
241
  readonly activities: number;
267
242
  }
268
- export interface DiscoveryApplicationData {
243
+ export interface DiscoveryResult {
269
244
  readonly items: readonly SquareListItem[];
270
245
  readonly stopped: boolean;
271
- /** All discovered squares before applying the cursor or page limit. */
272
246
  readonly total: number;
273
247
  readonly remaining: number;
274
248
  readonly next?: string;
275
249
  }
276
- export interface DiscoveryProjection {
277
- readonly cwd: string;
278
- readonly now: number;
279
- readonly depth: number;
280
- readonly limit: number;
281
- }
282
- export interface InboxApplicationOptions {
250
+ export interface InboxOptions {
283
251
  readonly limit?: number;
284
252
  }
285
253
  export interface InboxMembershipSummary {
@@ -287,16 +255,11 @@ export interface InboxMembershipSummary {
287
255
  readonly squarePath: string;
288
256
  readonly pending: number;
289
257
  }
290
- export interface InboxApplicationData {
258
+ export interface InboxResult {
291
259
  readonly rows: readonly InboxMembershipSummary[];
292
260
  readonly total: number;
293
261
  }
294
- export interface InboxProjection {
295
- readonly sessionId: string;
296
- readonly now: number;
297
- readonly limit: number;
298
- }
299
- export interface RecoveryApplicationData {
262
+ export interface RecoveryResult {
300
263
  readonly participant?: string;
301
264
  readonly standingCount?: number;
302
265
  readonly held?: boolean;
@@ -306,7 +269,6 @@ export interface RecoveryApplicationData {
306
269
  readonly roster?: readonly string[];
307
270
  readonly activitySummaries?: readonly UnreadActivitySummary[];
308
271
  }
309
- export type RecoveryProjection = RecoveryApplicationData & Partial<SquareContextProjection>;
310
272
  export type StreamStart = {
311
273
  readonly kind: 'tail';
312
274
  readonly last: number;
@@ -314,11 +276,11 @@ export type StreamStart = {
314
276
  readonly kind: 'after';
315
277
  readonly after: number;
316
278
  };
317
- export interface StreamApplicationOptions {
279
+ export interface StreamOptions {
318
280
  readonly recipient?: string;
319
281
  readonly start?: StreamStart;
320
282
  }
321
- export type StreamApplicationRecord = ArchiveRecord & {
283
+ export type StreamRecord = ArchiveRecord & {
322
284
  readonly seq: number;
323
285
  readonly square: string;
324
286
  readonly route?: string;
@@ -336,33 +298,13 @@ export interface UnreadActivitySummary {
336
298
  readonly latestActivityAgeMs: number;
337
299
  readonly previews: readonly UnreadActivityPreview[];
338
300
  }
339
- /** Selected-row observations. participantCount in these existing concern DTOs is a standing count. */
340
- export interface RecoveryObservation {
341
- readonly name: string;
342
- readonly roster: readonly string[];
343
- readonly activitySummaries: readonly UnreadActivitySummary[];
344
- readonly participantCount: number;
345
- readonly held: boolean;
346
- readonly holdReason?: string;
347
- readonly ownActivityCount: number;
348
- readonly hardCap: number | null;
349
- }
350
301
  export interface EntryPresentation {
351
- readonly joined: boolean;
352
302
  readonly joinedBefore: boolean;
353
303
  readonly scene: string;
354
- readonly context: string;
355
304
  readonly joinContext: string;
356
305
  readonly recentActivities: readonly ArchiveRecord[];
357
306
  readonly perceptions: Readonly<Record<number, Perception>>;
358
307
  readonly sayNumbers: Readonly<Record<number, number>>;
359
- readonly participantCount: number;
360
- readonly held: boolean;
361
- }
362
- export interface HistoryContinuation {
363
- readonly direction: 'before' | 'after';
364
- readonly cursor: ActivityId;
365
- readonly limit: number;
366
308
  }
367
309
  export interface ListPresentation {
368
310
  readonly context: readonly string[];
@@ -370,7 +312,6 @@ export interface ListPresentation {
370
312
  readonly activities: number;
371
313
  }
372
314
  export interface PresenceClassification {
373
- /** Names in canonical data, watching first, then recent signs of life; no presentation clipping. */
374
315
  readonly orderedHereNames: readonly string[];
375
316
  readonly lingeringCount: number;
376
317
  readonly classificationByName: Readonly<Record<string, 'here' | 'lingering' | 'done' | 'not-joined'>>;
@@ -387,54 +328,61 @@ export interface StreamProjection {
387
328
  readonly cursor: number;
388
329
  readonly hasMore: boolean;
389
330
  }
390
- export interface EntryProjection extends SquareContextProjection, EntryPresentation {
331
+ export interface SquareObservation {
332
+ readonly location: string;
333
+ readonly standingCount: number;
334
+ readonly held: boolean;
335
+ readonly now: number;
336
+ readonly participant?: string;
337
+ readonly automaticDeliveryAvailable: boolean;
338
+ }
339
+ export interface JoinObservation extends SquareObservation {
340
+ readonly entry?: EntryPresentation;
341
+ /** The receipt succeeded, but optional recent-history/context enrichment was unavailable. */
342
+ readonly enrichmentUnavailable?: true;
391
343
  }
392
- export interface ExpressionObservation extends Pick<SquareContextProjection, 'standingCount' | 'held' | 'now'> {
344
+ export interface ExpressionObservation extends Pick<SquareObservation, 'standingCount' | 'held' | 'now'> {
393
345
  readonly ownActivityCount: number;
394
346
  readonly hardCap: number | null;
395
347
  }
396
- export interface ExpressProjection extends SquareContextProjection, ExpressionObservation {
348
+ export interface ExpressObservation extends SquareObservation, ExpressionObservation {
397
349
  readonly participant: string;
398
350
  readonly pendingPublic: readonly ArchiveRecord[];
399
351
  readonly sayNumbers: Readonly<Record<number, number>>;
400
352
  readonly perceptions: Readonly<Record<number, Perception>>;
401
353
  readonly reentry?: Activity;
402
- readonly delivery?: DeliveryResult;
403
354
  }
404
- export interface CatchProjection extends SquareContextProjection, ExpressionObservation {
355
+ export interface CatchObservation extends SquareObservation, ExpressionObservation {
405
356
  readonly participant: string;
406
357
  readonly sayNumbers: Readonly<Record<number, number>>;
407
- /** Optional nearby presence is not a commit-time selection fact. */
408
358
  readonly presence?: CatchPresence;
409
359
  readonly stop?: CatchStopStatus;
410
360
  readonly waitStarted?: boolean;
411
361
  readonly replaced?: boolean;
412
362
  readonly enrichmentUnavailable?: true;
413
363
  }
414
- export interface HistoryProjection extends SquareContextProjection {
364
+ export interface HistoryContinuation {
365
+ readonly direction: 'before' | 'after';
366
+ readonly cursor: ActivityId;
367
+ readonly limit: number;
368
+ }
369
+ export interface HistoryObservation extends SquareObservation {
415
370
  readonly activities: readonly ArchiveRecord[];
416
371
  readonly sayNumbers: Readonly<Record<number, number>>;
417
372
  readonly presenceAnchors: Readonly<Record<number, readonly string[]>>;
418
373
  readonly totalMatches: number;
419
- /** Ordinary terminal history visibility and stable continuation are owner policy. */
420
374
  readonly visibleActivities: readonly ArchiveRecord[];
421
375
  readonly continuation?: HistoryContinuation;
422
376
  }
423
- export interface ListenerProjection extends SquareContextProjection {
377
+ export interface ListenerObservation extends SquareObservation {
424
378
  readonly participant: string;
425
379
  readonly target: string;
426
380
  readonly requestedTarget: string;
427
381
  }
428
- export interface EventPresentation {
382
+ export interface LifecycleObservation extends SquareObservation {
429
383
  readonly activity: ArchiveRecord;
430
- readonly participantCount: number;
431
- readonly held: boolean;
432
- }
433
- export interface LifecycleProjection extends SquareContextProjection, EventPresentation {
434
- readonly delivery?: DeliveryResult;
435
384
  }
436
- export interface StatusProjection extends SquareContextProjection, PresenceClassification {
437
- /** Full roster size, including never-joined names omitted from status data. */
385
+ export interface StatusObservation extends SquareObservation, PresenceClassification {
438
386
  readonly knownParticipantCount: number;
439
387
  readonly latestActNumber?: number;
440
388
  readonly latestPerception?: Perception;
@@ -446,32 +394,5 @@ export interface StatusProjection extends SquareContextProjection, PresenceClass
446
394
  readonly attentionNames: readonly string[];
447
395
  readonly viewer: string;
448
396
  }
449
- export interface ParticipantsProjection extends SquareContextProjection, PresenceClassification {
450
- }
451
- export interface SquareApplication<Presentation extends boolean = true> {
452
- now(): number;
453
- build(input: BuildApplicationInput, control?: OperationControl): Promise<ApplicationOutcome<BuildApplicationData, SquareContextProjection, Presentation>>;
454
- join(options?: JoinApplicationOptions, control?: OperationControl): Promise<ApplicationOutcome<JoinApplicationData, EntryProjection, Presentation>>;
455
- express(body: string, options?: ExpressApplicationOptions, control?: OperationControl): Promise<ApplicationOutcome<ExpressApplicationData, ExpressProjection, Presentation>>;
456
- catch(options?: CatchApplicationOptions, control?: OperationControl): Promise<ApplicationOutcome<CatchApplicationData, CatchProjection, Presentation>>;
457
- history(query?: HistoryApplicationQuery, control?: OperationControl): Promise<ApplicationOutcome<HistoryApplicationData, HistoryProjection, Presentation>>;
458
- listen(target: string, control?: OperationControl): Promise<ApplicationOutcome<ListenerChangeData, ListenerProjection, Presentation>>;
459
- ignore(target: string, control?: OperationControl): Promise<ApplicationOutcome<ListenerChangeData, ListenerProjection, Presentation>>;
460
- listening(control?: OperationControl): Promise<ApplicationOutcome<ListeningData, SquareContextProjection, Presentation>>;
461
- hold(reason?: string, control?: OperationControl): Promise<ApplicationOutcome<LifecycleData, LifecycleProjection, Presentation>>;
462
- resume(control?: OperationControl): Promise<ApplicationOutcome<LifecycleData, LifecycleProjection, Presentation>>;
463
- done(body?: string, control?: OperationControl): Promise<ApplicationOutcome<LifecycleData, LifecycleProjection, Presentation>>;
464
- status(viewer?: string, control?: OperationControl): Promise<ApplicationOutcome<StatusApplicationData, StatusProjection, Presentation>>;
465
- participants(control?: OperationControl): Promise<ApplicationOutcome<ParticipantsApplicationData, ParticipantsProjection, Presentation>>;
466
- diagnose(control?: OperationControl): Promise<ApplicationOutcome<DiagnosisApplicationData, Partial<SquareContextProjection>, Presentation>>;
467
- migrate(control?: OperationControl): Promise<ApplicationOutcome<MigrationApplicationData, Partial<SquareContextProjection>, Presentation>>;
468
- discover(options: DiscoveryApplicationOptions, control?: OperationControl): Promise<ApplicationOutcome<DiscoveryApplicationData, DiscoveryProjection, Presentation>>;
469
- inbox(sessionId: string, options?: InboxApplicationOptions, control?: OperationControl): Promise<ApplicationOutcome<InboxApplicationData, InboxProjection, Presentation>>;
470
- recovery(control?: OperationControl): Promise<ApplicationOutcome<RecoveryApplicationData, RecoveryProjection, Presentation>>;
471
- stream(options: StreamApplicationOptions, control?: OperationControl): AsyncIterable<StreamApplicationRecord>;
472
- }
473
- export type JoinApplicationResult = JoinApplicationData;
474
- export type ExpressApplicationResult = ExpressApplicationData;
475
- export type ApplicationStatus = StatusApplicationData;
476
- export type ApplicationStatusProjection = StatusProjection;
477
- export type ApplicationParticipants = ParticipantsApplicationData;
397
+ export interface ParticipantsObservation extends SquareObservation, PresenceClassification {
398
+ }
@@ -25,17 +25,11 @@ export interface LegacyFraming {
25
25
  readonly userVersion: number;
26
26
  readonly journalMode: string;
27
27
  }
28
- /**
29
- * The one recovery command for an owned legacy artifact, with a shell-quoted
30
- * path. Kept beside framing recognition so the refusal and migration
31
- * instruction cannot drift apart. This codec stays free of the renderer.
32
- */
33
- export declare function migrationRecoveryCommand(location: string): string;
34
28
  /**
35
29
  * Read-only legacy framing: application id, format version, journal mode and the
36
30
  * exact owned snapshot schema. It decodes no snapshot payload, writes no pragma
37
- * and runs no DDL, so ordinary open can establish ownership before offering
38
- * the migration command. Anything else is unrelated or unsupported, not repaired.
31
+ * and runs no DDL, so ordinary open can establish ownership before requiring
32
+ * migration. Anything else is unrelated or unsupported, not repaired.
39
33
  */
40
34
  export declare function validateLegacyFraming(database: DatabaseSync, applicationId: number, location?: string): LegacyFraming;
41
35
  export declare const SCHEMA_SQL = "CREATE TABLE square_meta (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n revision INTEGER NOT NULL CHECK (revision BETWEEN 0 AND 9007199254740991),\n next_act_index INTEGER NOT NULL CHECK (next_act_index BETWEEN 0 AND 9007199254740991),\n hard_cap INTEGER CHECK (hard_cap BETWEEN 1 AND 9007199254740991),\n throttle_per_minute INTEGER CHECK (throttle_per_minute BETWEEN 1 AND 9007199254740991),\n preamble_json TEXT NOT NULL CHECK (json_valid(preamble_json)),\n warmup_json TEXT NOT NULL CHECK (json_valid(warmup_json))\n);\nCREATE TABLE activities (\n act_index INTEGER PRIMARY KEY CHECK (act_index BETWEEN 0 AND 9007199254740991),\n at REAL NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('join','done','say','hold','resume','read','listen','ignore')),\n actor_json TEXT COLLATE BINARY,\n actor_key_json TEXT COLLATE BINARY,\n reach TEXT CHECK (reach = 'bell'),\n reply_index INTEGER CHECK (reply_index >= 0 AND reply_index < act_index),\n payload_json TEXT NOT NULL CHECK (json_valid(payload_json)),\n 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))\n);\nCREATE INDEX activity_kind_index ON activities(kind, act_index);\nCREATE INDEX activity_actor_index ON activities(actor_key_json, act_index);\nCREATE INDEX activity_say_actor_index ON activities(actor_key_json, act_index) WHERE kind='say';\nCREATE INDEX activity_say_time ON activities(at, act_index) WHERE kind='say';\nCREATE INDEX activity_bell_actor_time ON activities(actor_key_json, at, act_index) WHERE kind='say' AND reach='bell';\n\nCREATE TABLE receipts (\n owner_json TEXT COLLATE BINARY NOT NULL,\n act_index INTEGER NOT NULL CHECK (act_index BETWEEN 0 AND 9007199254740991),\n at REAL NOT NULL,\n PRIMARY KEY (owner_json, act_index)\n) WITHOUT ROWID;\nCREATE INDEX receipt_owner_time ON receipts(owner_json, at);\nCREATE TABLE catch_leases (\n owner_json TEXT COLLATE BINARY PRIMARY KEY NOT NULL,\n lease_id_json TEXT NOT NULL,\n heartbeat_at REAL NOT NULL,\n expires_at REAL NOT NULL CHECK (expires_at >= heartbeat_at),\n filter_json TEXT CHECK (filter_json IS NULL OR json_valid(filter_json))\n) WITHOUT ROWID;\n\nCREATE TABLE routes (\n position INTEGER PRIMARY KEY CHECK (position >= 0),\n participant_key_json TEXT COLLATE BINARY NOT NULL,\n session_json TEXT COLLATE BINARY NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('opencode-server','codex-queue','claude-native','paseo')),\n updated_at REAL NOT NULL,\n payload_json TEXT NOT NULL CHECK (json_valid(payload_json))\n);\nCREATE INDEX route_participant ON routes(participant_key_json, position);\nCREATE INDEX route_session ON routes(session_json, position);\n\nCREATE TABLE participants (\n name_key_json TEXT COLLATE BINARY PRIMARY KEY NOT NULL,\n name_json TEXT NOT NULL,\n first_index INTEGER NOT NULL UNIQUE,\n joined INTEGER NOT NULL CHECK (joined IN (0,1)),\n done INTEGER NOT NULL CHECK (done IN (0,1)),\n say_count INTEGER NOT NULL CHECK (say_count >= 0),\n last_active_at REAL,\n last_join_index INTEGER,\n CHECK (NOT (joined=1 AND done=1))\n) WITHOUT ROWID;\nCREATE TABLE attention (\n listener_key_json TEXT COLLATE BINARY NOT NULL,\n target_key_json TEXT COLLATE BINARY NOT NULL,\n target_json TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('listen','ignore')),\n since_index INTEGER NOT NULL,\n PRIMARY KEY (listener_key_json, target_key_json)\n) WITHOUT ROWID;\nCREATE INDEX attention_target ON attention(target_key_json, kind, listener_key_json);\nCREATE TABLE landed_audience (\n act_index INTEGER NOT NULL,\n recipient_key_json TEXT COLLATE BINARY NOT NULL,\n recipient_order INTEGER NOT NULL CHECK (recipient_order >= 0),\n route TEXT NOT NULL CHECK (route IN ('mention','reply','attention','bell')),\n PRIMARY KEY (act_index, recipient_key_json),\n UNIQUE (act_index, recipient_order)\n) WITHOUT ROWID;\nCREATE INDEX audience_recipient ON landed_audience(recipient_key_json, act_index);";
@@ -13,19 +13,11 @@ const V1_SNAPSHOT_COLUMNS = [
13
13
  { cid: 1, name: 'revision', type: 'INTEGER', notnull: 1, dflt_value: null, pk: 0, hidden: 0 },
14
14
  { cid: 2, name: 'state', type: 'TEXT', notnull: 1, dflt_value: null, pk: 0, hidden: 0 },
15
15
  ];
16
- /**
17
- * The one recovery command for an owned legacy artifact, with a shell-quoted
18
- * path. Kept beside framing recognition so the refusal and migration
19
- * instruction cannot drift apart. This codec stays free of the renderer.
20
- */
21
- export function migrationRecoveryCommand(location) {
22
- return `square --location '${location.replace(/'/g, `'\\''`)}' migrate`;
23
- }
24
16
  /**
25
17
  * Read-only legacy framing: application id, format version, journal mode and the
26
18
  * exact owned snapshot schema. It decodes no snapshot payload, writes no pragma
27
- * and runs no DDL, so ordinary open can establish ownership before offering
28
- * the migration command. Anything else is unrelated or unsupported, not repaired.
19
+ * and runs no DDL, so ordinary open can establish ownership before requiring
20
+ * migration. Anything else is unrelated or unsupported, not repaired.
29
21
  */
30
22
  export function validateLegacyFraming(database, applicationId, location = '') {
31
23
  const identity = database.prepare('SELECT application_id, user_version FROM pragma_application_id, pragma_user_version').get();
@@ -328,7 +320,7 @@ export function validateSqliteHeader(db, location = '') {
328
320
  requireFact(identity.application_id === APPLICATION_ID, 'unrelated SQLite database.');
329
321
  if (identity.user_version === 1) {
330
322
  validateLegacyFraming(db, APPLICATION_ID, location);
331
- throw new SquareError('invalid_args', `Square artifact needs migration.\n${migrationRecoveryCommand(location)}`, { reason: 'migration_required' });
323
+ throw new SquareError('invalid_args', `Square artifact at ${location} needs migration.\nStop sessions using it, back it up, then migrate and verify before restarting.`, { reason: 'migration_required' });
332
324
  }
333
325
  requireFact(identity.user_version === 2, 'unsupported SQLite format version.');
334
326
  const actual = db.prepare("SELECT sql FROM sqlite_schema WHERE name NOT GLOB 'sqlite_*' AND sql IS NOT NULL").all().map(r => normalizedSql(string(r.sql))).sort();
@@ -1,12 +1,13 @@
1
1
  import { z } from 'zod/v4';
2
- import type { ApplicationOutcome, OperationControl, SquareApplication } from './square-facade.js';
2
+ import type { Square } from './square-api.js';
3
+ import type { OperationControl } from './square-facade.js';
3
4
  type JsonObject = Record<string, unknown>;
4
- type Outcome = Promise<ApplicationOutcome<object, unknown, false>>;
5
+ type Outcome = Promise<object>;
5
6
  interface ToolDefinition {
6
7
  name: string;
7
8
  description: string;
8
9
  inputSchema: z.ZodObject<z.ZodRawShape>;
9
- run(app: SquareApplication<false>, args: JsonObject, control: OperationControl): Outcome;
10
+ run(square: Square, args: JsonObject, control: OperationControl): Outcome;
10
11
  }
11
12
  export declare const SQUARE_TOOL_INSTRUCTIONS = "The catch tool consumes activities. Use history with act/<index> cursors for read-only archive access.";
12
13
  export declare const SQUARE_TOOLS: readonly ToolDefinition[];