@astrosheep/square 0.3.12 → 0.3.13

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 (121) hide show
  1. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  2. package/codex-plugin/hooks/hooks.json +9 -0
  3. package/dist/activity-feed.d.ts +14 -0
  4. package/dist/activity-feed.js +5 -5
  5. package/dist/activity.d.ts +9 -0
  6. package/dist/activity.js +111 -90
  7. package/dist/artifact.d.ts +20 -0
  8. package/dist/artifact.js +10 -29
  9. package/dist/automatic-session.d.ts +5 -0
  10. package/dist/automatic-session.js +86 -0
  11. package/dist/boundary-presentation.d.ts +5 -0
  12. package/dist/boundary-presentation.js +5 -4
  13. package/dist/claude-hook.d.ts +9 -0
  14. package/dist/claude-hook.js +35 -3
  15. package/dist/cli/context.d.ts +35 -0
  16. package/dist/cli/context.js +25 -30
  17. package/dist/cli/harness-command.d.ts +28 -0
  18. package/dist/cli/harness-command.js +29 -14
  19. package/dist/cli/maintenance-commands.d.ts +7 -0
  20. package/dist/cli/maintenance-commands.js +3 -3
  21. package/dist/cli/meta-commands.d.ts +5 -0
  22. package/dist/cli/observation-commands.d.ts +20 -0
  23. package/dist/cli/observation-commands.js +155 -128
  24. package/dist/cli/program.d.ts +2 -0
  25. package/dist/cli/program.js +2 -12
  26. package/dist/cli/registry.d.ts +9 -0
  27. package/dist/cli/registry.js +1 -2
  28. package/dist/cli/square-commands.d.ts +34 -0
  29. package/dist/cli/square-commands.js +81 -74
  30. package/dist/cmd/notify-once.d.ts +2 -0
  31. package/dist/codex-hook.d.ts +10 -0
  32. package/dist/codex-hook.js +35 -3
  33. package/dist/decisions.d.ts +92 -0
  34. package/dist/decisions.js +83 -77
  35. package/dist/delivery-health.d.ts +21 -0
  36. package/dist/delivery-health.js +40 -34
  37. package/dist/delivery.d.ts +81 -0
  38. package/dist/delivery.js +60 -22
  39. package/dist/file-lock.d.ts +6 -0
  40. package/dist/harness-claude.d.ts +19 -0
  41. package/dist/harness-claude.js +8 -3
  42. package/dist/harness-codex.d.ts +29 -0
  43. package/dist/harness-codex.js +2 -2
  44. package/dist/harness-links.d.ts +17 -0
  45. package/dist/harness-links.js +2 -2
  46. package/dist/harness-pi.d.ts +11 -0
  47. package/dist/harness-pi.js +2 -2
  48. package/dist/harness-stage.d.ts +6 -0
  49. package/dist/harness.d.ts +20 -0
  50. package/dist/harness.js +5 -3
  51. package/dist/help.d.ts +6 -0
  52. package/dist/help.js +6 -5
  53. package/dist/identity.d.ts +13 -0
  54. package/dist/inbox.d.ts +2 -0
  55. package/dist/inbox.js +15 -19
  56. package/dist/index.d.ts +13 -0
  57. package/dist/index.js +31 -69
  58. package/dist/landing.d.ts +10 -0
  59. package/dist/landing.js +95 -0
  60. package/dist/list.d.ts +1 -0
  61. package/dist/list.js +40 -18
  62. package/dist/model.d.ts +147 -0
  63. package/dist/model.js +12 -2
  64. package/dist/notifications.d.ts +30 -0
  65. package/dist/notifications.js +75 -91
  66. package/dist/open-square.d.ts +11 -0
  67. package/dist/open-square.js +4 -0
  68. package/dist/participant-identity.d.ts +1 -0
  69. package/dist/participant-identity.js +3 -0
  70. package/dist/paseo-connection.d.ts +15 -0
  71. package/dist/paseo-delivery.d.ts +14 -0
  72. package/dist/paseo-state.d.ts +11 -0
  73. package/dist/paseo-timeline.d.ts +16 -0
  74. package/dist/presence.d.ts +3 -0
  75. package/dist/presence.js +42 -0
  76. package/dist/presentation.d.ts +91 -0
  77. package/dist/presentation.js +33 -29
  78. package/dist/presented.d.ts +11 -0
  79. package/dist/registry.d.ts +58 -0
  80. package/dist/registry.js +36 -3
  81. package/dist/routes.d.ts +42 -0
  82. package/dist/runtime.d.ts +45 -0
  83. package/dist/runtime.js +42 -34
  84. package/dist/search.d.ts +11 -0
  85. package/dist/square-core.d.ts +111 -0
  86. package/dist/square-core.js +7 -0
  87. package/dist/square-facade.d.ts +86 -0
  88. package/dist/square-facade.js +1 -0
  89. package/dist/square-file-adapter.d.ts +18 -0
  90. package/dist/square-file-adapter.js +70 -0
  91. package/dist/square-storage.d.ts +20 -0
  92. package/dist/square-storage.js +171 -0
  93. package/dist/square-wiring.d.ts +19 -0
  94. package/dist/square-wiring.js +70 -0
  95. package/dist/square.d.ts +2 -0
  96. package/dist/state-cell.d.ts +14 -0
  97. package/dist/state-cell.js +1 -0
  98. package/dist/stream.d.ts +3 -0
  99. package/dist/stream.js +19 -23
  100. package/dist/time.d.ts +6 -0
  101. package/dist/views.d.ts +95 -0
  102. package/dist/views.js +81 -0
  103. package/dist/wake-attempts.d.ts +39 -0
  104. package/dist/wake-evidence.d.ts +12 -0
  105. package/dist/wake-evidence.js +7 -10
  106. package/dist/wake-port.d.ts +20 -0
  107. package/dist/wake-sink.d.ts +12 -0
  108. package/dist/wakes.d.ts +40 -0
  109. package/dist/wakes.js +62 -0
  110. package/dist/watch.d.ts +2 -0
  111. package/dist/watch.js +89 -210
  112. package/extensions/square-opencode.js +27 -1
  113. package/extensions/square-pi.js +13 -0
  114. package/package.json +5 -2
  115. package/skills/brainstorm/SKILL.md +26 -26
  116. package/skills/square/.claude-plugin/plugin.json +1 -1
  117. package/skills/square/SKILL.md +47 -29
  118. package/skills/square/hooks/hooks.json +9 -0
  119. package/skills/square-feedback/SKILL.md +2 -2
  120. package/dist/compact.js +0 -26
  121. package/dist/square-application.js +0 -193
@@ -3,29 +3,24 @@ import { randomUUID } from 'node:crypto';
3
3
  import { homedir } from 'node:os';
4
4
  import { setTimeout as sleep } from 'node:timers/promises';
5
5
  import { fileURLToPath } from 'node:url';
6
- import { loadSquare } from './artifact.js';
7
- import { deriveDeliveryModel, isDeliveryDelivered, leaseOwnsNotification, planActNotifications, } from './delivery.js';
6
+ import { leaseOwnsNotification, planActNotifications, } from './delivery.js';
8
7
  import { sessionInbox } from './inbox.js';
9
8
  import { hasPresentedAttention } from './presented.js';
10
- import { nameKey, SquareError } from './model.js';
11
- import { SLEEP_MS, matchesMentionTarget, resolveRosterName, rosterNames } from './runtime.js';
12
- import { formatActivityId, parseActivityId } from './square-core.js';
9
+ import { SquareError } from './model.js';
10
+ import { SLEEP_MS, matchesMentionTarget } from './runtime.js';
11
+ import { parseActivityId } from './square-core.js';
13
12
  import { PaseoAdapter } from './paseo-delivery.js';
14
- import { quoteShell } from './presentation.js';
13
+ import { participantIdentity, quoteShell } from './presentation.js';
15
14
  import { lookupParticipant } from './registry.js';
16
- import { isCurrentlyJoined } from './runtime.js';
17
- import { execute } from './square-application.js';
15
+ import { openSquare } from './square-file-adapter.js';
16
+ import { closeOpenSquare } from './open-square.js';
17
+ import { entryPresentation, notificationDelivered, notificationForAct, pendingDeliveries, resolveParticipant } from './views.js';
18
+ import { claimNotificationLease, releaseNotificationLease, transitionNotificationLease } from './wakes.js';
18
19
  import { nextWakeAttemptNumber, recordRecoveredUnknown, recordWakeAttempt, } from './wake-attempts.js';
19
- import { joinedRecipients, wakeEvidence, wakeIsEligible } from './wake-evidence.js';
20
+ import { wakeEvidence, wakeIsEligible } from './wake-evidence.js';
20
21
  import { WakePort } from './wake-port.js';
21
22
  const NOTIFY_LEASE_MS = 5 * 60 * 1000;
22
23
  export { planActNotifications, matchesMentionTarget };
23
- function known(doc, name) {
24
- const value = resolveRosterName(doc, name);
25
- if (value === undefined)
26
- throw new SquareError('invalid_args', `Unknown participant "${name}". Expected one of: ${rosterNames(doc).join(', ')}.`);
27
- return value;
28
- }
29
24
  export { notificationMessageId } from './delivery.js';
30
25
  export function wakeGraceMs(env = process.env) {
31
26
  const value = Number.parseInt(env.SQUARE_NOTIFY_DELIVERY_WAIT_MS ?? '5000', 10);
@@ -43,7 +38,7 @@ function renderWakePayload(request) {
43
38
  : request.squarePath;
44
39
  return [
45
40
  '<system-reminder source="square">',
46
- `${request.route === 'bell' ? 'Bell' : 'Mention'} from @${request.actor} in \`${display}\``,
41
+ `${request.route === 'bell' ? 'Bell' : 'Mention'} from ${participantIdentity(request.actor)} in \`${display}\``,
47
42
  'The native adapter will present it at the next boundary. If no native wake is available, pull from the square yourself.',
48
43
  `\`${catchCommand(request.squarePath, request.recipient)}\``,
49
44
  '</system-reminder>',
@@ -52,7 +47,7 @@ function renderWakePayload(request) {
52
47
  async function waitForCatch(route, request, body) {
53
48
  const binding = lookupParticipant(request.squarePath, request.recipient)
54
49
  .find((item) => item.ownerId === route.ownerId);
55
- const activeCatch = binding && sessionInbox(binding.sessionId)
50
+ const activeCatch = binding && (await sessionInbox(binding.sessionId))
56
51
  .find((item) => item.name === request.recipient)?.catchLease;
57
52
  if (!activeCatch || !leaseOwnsNotification(activeCatch, {
58
53
  actor: request.actor,
@@ -62,12 +57,11 @@ async function waitForCatch(route, request, body) {
62
57
  return false;
63
58
  const deadline = Date.now() + 180_000;
64
59
  while (Date.now() < deadline) {
65
- const doc = loadSquare(request.squarePath);
66
- if (isDeliveryDelivered(doc, request.recipient, request.actIndex))
60
+ if (await hasDeliveredNotification(request.squarePath, request.recipient, request.actIndex))
67
61
  return true;
68
62
  const currentBinding = lookupParticipant(request.squarePath, request.recipient)
69
63
  .find((item) => item.ownerId === route.ownerId);
70
- const lease = currentBinding && sessionInbox(currentBinding.sessionId)
64
+ const lease = currentBinding && (await sessionInbox(currentBinding.sessionId))
71
65
  .find((item) => item.name === request.recipient)?.catchLease;
72
66
  if (!lease || lease.expiresAt <= Date.now())
73
67
  return false;
@@ -83,58 +77,45 @@ function notificationIndex(ref) {
83
77
  throw new Error(`Invalid act ref: ${ref}`);
84
78
  return index;
85
79
  }
86
- export function hasDeliveredNotification(squarePath, name, ref) {
87
- const doc = loadSquare(squarePath);
88
- return isDeliveryDelivered(doc, known(doc, name), notificationIndex(ref));
80
+ export async function hasDeliveredNotification(squarePath, name, ref) {
81
+ const square = await openSquare(squarePath);
82
+ try {
83
+ const recipient = (await resolveParticipant(square, name)).name;
84
+ return notificationDelivered(square, recipient, notificationIndex(ref));
85
+ }
86
+ finally {
87
+ await closeOpenSquare(square);
88
+ }
89
89
  }
90
- export function hasAttentionNotification(squarePath, name, ref, env = process.env) {
91
- const doc = loadSquare(squarePath);
92
- const recipient = known(doc, name);
93
- const index = notificationIndex(ref);
94
- return isDeliveryDelivered(doc, recipient, index) || hasPresentedAttention(squarePath, recipient, index, env);
90
+ export async function hasAttentionNotification(squarePath, name, ref, env = process.env) {
91
+ const square = await openSquare(squarePath);
92
+ try {
93
+ const recipient = (await resolveParticipant(square, name)).name;
94
+ const index = notificationIndex(ref);
95
+ return await notificationDelivered(square, recipient, index) || hasPresentedAttention(squarePath, recipient, index, env);
96
+ }
97
+ finally {
98
+ await closeOpenSquare(square);
99
+ }
95
100
  }
96
101
  export async function waitForDeliveredNotification(squarePath, name, ref, opts = {}) {
97
102
  const deadline = Date.now() + (opts.timeoutMs ?? 30000);
98
103
  while (Date.now() <= deadline) {
99
- if (hasDeliveredNotification(squarePath, name, ref))
104
+ if (await hasDeliveredNotification(squarePath, name, ref))
100
105
  return true;
101
106
  await sleep(Math.min(SLEEP_MS, Math.max(1, deadline - Date.now())));
102
107
  }
103
108
  return false;
104
109
  }
105
- function notifyLeaseKey(recipient, actIndex) {
106
- return JSON.stringify([formatActivityId(actIndex), nameKey(recipient)]);
107
- }
108
- async function claimNotifyLease(squarePath, recipient, actIndex) {
109
- const at = Date.now();
110
- const committed = await execute(squarePath, {
111
- type: 'claim-notify',
112
- key: notifyLeaseKey(recipient, actIndex),
113
- leaseId: randomUUID(),
114
- at,
115
- expiresAt: at + NOTIFY_LEASE_MS,
116
- });
117
- return committed.result;
110
+ async function claimNotifyLease(square, recipient, actIndex) {
111
+ const leaseId = randomUUID();
112
+ return claimNotificationLease(square, recipient, actIndex, leaseId, NOTIFY_LEASE_MS);
118
113
  }
119
- async function transitionNotifyLease(squarePath, recipient, actIndex, leaseId, phase, routeKind, attemptN) {
120
- const at = Date.now();
121
- const committed = await execute(squarePath, {
122
- type: 'transition-notify',
123
- key: notifyLeaseKey(recipient, actIndex),
124
- leaseId,
125
- expiresAt: at + NOTIFY_LEASE_MS,
126
- phase,
127
- ...(routeKind === undefined ? {} : { routeKind }),
128
- ...(attemptN === undefined ? {} : { attemptN }),
129
- });
130
- return committed.result.updated;
114
+ async function transitionNotifyLease(square, recipient, actIndex, leaseId, phase, routeKind, attemptN) {
115
+ return transitionNotificationLease(square, recipient, actIndex, leaseId, phase, NOTIFY_LEASE_MS, routeKind, attemptN);
131
116
  }
132
- function releaseNotifyLease(squarePath, recipient, actIndex, leaseId) {
133
- return execute(squarePath, {
134
- type: 'release-notify',
135
- key: notifyLeaseKey(recipient, actIndex),
136
- leaseId,
137
- });
117
+ async function releaseNotifyLease(square, recipient, actIndex, leaseId) {
118
+ await releaseNotificationLease(square, recipient, actIndex, leaseId);
138
119
  }
139
120
  async function processNotification(squarePath, notification, opts) {
140
121
  const env = opts.env ?? process.env;
@@ -145,23 +126,27 @@ async function processNotification(squarePath, notification, opts) {
145
126
  recipient: notification.recipient,
146
127
  };
147
128
  const initialAt = now();
148
- if (!wakeIsEligible(wakeEvidence(squarePath, notification.recipient, notification.item.index, initialAt, env)))
129
+ if (!wakeIsEligible(await wakeEvidence(squarePath, notification.recipient, notification.item.index, initialAt, env)))
149
130
  return;
150
- const claim = await claimNotifyLease(squarePath, notification.recipient, notification.item.index);
151
- if (claim.type === 'busy')
131
+ const square = await openSquare(squarePath, { clock: now });
132
+ const claim = await claimNotifyLease(square, notification.recipient, notification.item.index);
133
+ if (claim.type === 'busy' || claim.type === 'delivered') {
134
+ await closeOpenSquare(square);
152
135
  return;
136
+ }
153
137
  if (claim.type === 'ambiguous') {
154
138
  const recovered = recordRecoveredUnknown(attention, claim.lease, env);
155
139
  if (recovered !== undefined) {
156
- await releaseNotifyLease(squarePath, notification.recipient, notification.item.index, claim.lease.leaseId);
140
+ await releaseNotifyLease(square, notification.recipient, notification.item.index, claim.lease.leaseId);
157
141
  }
142
+ await closeOpenSquare(square);
158
143
  return;
159
144
  }
160
145
  const { leaseId } = claim;
161
146
  let releaseLease = true;
162
147
  try {
163
148
  const dispatchAt = now();
164
- const evidence = wakeEvidence(squarePath, notification.recipient, notification.item.index, dispatchAt, env);
149
+ const evidence = await wakeEvidence(squarePath, notification.recipient, notification.item.index, dispatchAt, env);
165
150
  if (!wakeIsEligible(evidence))
166
151
  return;
167
152
  const port = new WakePort(opts.adapters ?? [new PaseoAdapter()]);
@@ -178,22 +163,21 @@ async function processNotification(squarePath, notification, opts) {
178
163
  if (await waitForCatch(route, request, notification.item.body))
179
164
  return false;
180
165
  const currentAt = now();
181
- const latest = loadSquare(squarePath);
182
- if (!isCurrentlyJoined(latest.acts, notification.recipient))
166
+ if (!(await entryPresentation(square, notification.recipient)).joined)
183
167
  return false;
184
- const current = wakeEvidence(squarePath, notification.recipient, notification.item.index, currentAt, env);
168
+ const current = await wakeEvidence(squarePath, notification.recipient, notification.item.index, currentAt, env);
185
169
  if (!wakeIsEligible(current))
186
170
  return false;
187
171
  if (!current.attemptableRoutes.some((candidate) => candidate.ownerId === route.ownerId && candidate.kind === route.kind && candidate.sessionId === route.sessionId))
188
172
  return false;
189
- const dispatching = await transitionNotifyLease(squarePath, notification.recipient, notification.item.index, leaseId, 'dispatching', route.kind, attemptN);
173
+ const dispatching = await transitionNotifyLease(square, notification.recipient, notification.item.index, leaseId, 'dispatching', route.kind, attemptN);
190
174
  if (dispatching)
191
175
  releaseLease = false;
192
176
  return dispatching;
193
177
  },
194
178
  record: async (route, attemptN, outcome) => {
195
179
  if (outcome.outcome === 'failed') {
196
- await transitionNotifyLease(squarePath, notification.recipient, notification.item.index, leaseId, 'claimed');
180
+ await transitionNotifyLease(square, notification.recipient, notification.item.index, leaseId, 'claimed');
197
181
  releaseLease = true;
198
182
  }
199
183
  recordWakeAttempt({
@@ -213,47 +197,47 @@ async function processNotification(squarePath, notification, opts) {
213
197
  }
214
198
  finally {
215
199
  if (releaseLease) {
216
- await releaseNotifyLease(squarePath, notification.recipient, notification.item.index, leaseId);
200
+ await releaseNotifyLease(square, notification.recipient, notification.item.index, leaseId);
217
201
  }
202
+ await closeOpenSquare(square);
218
203
  }
219
204
  }
220
205
  export async function processActNotificationsOnce(squarePath, actIndex, opts = {}) {
221
- const doc = loadSquare(squarePath);
222
- const item = doc.acts.find((candidate) => candidate.index === actIndex);
223
- if (item === undefined)
224
- return;
225
- const notifications = planActNotifications(doc, item);
206
+ const square = await openSquare(squarePath);
207
+ const notifications = await notificationForAct(square, actIndex).finally(() => closeOpenSquare(square));
226
208
  await Promise.all(notifications.map((notification) => processNotification(squarePath, notification, opts)));
227
209
  }
228
210
  function launchWorker(workerPath, args) {
229
211
  const child = spawn(process.execPath, [workerPath, ...args], { detached: true, stdio: 'ignore', env: process.env });
230
212
  child.unref();
231
213
  }
232
- /** Start one detached worker only when this act contains directed attention. */
233
- export async function dispatchActNotifications(squarePath, item, opts = {}) {
234
- const env = opts.env ?? process.env;
235
- if (env.SQUARE_DISABLE_PASEO_WAKE === '1')
236
- return;
237
- const doc = loadSquare(squarePath);
238
- if (planActNotifications(doc, item).length === 0)
239
- return;
240
- (opts.launchWorker ?? launchWorker)(fileURLToPath(new URL('./cmd/notify-once.js', import.meta.url)), ['--location', squarePath, '--act-index', String(item.index)]);
214
+ export function wakeNotifierForSquare(squarePath, env = process.env) {
215
+ return {
216
+ wake(recipients, activity) {
217
+ if (env.SQUARE_DISABLE_PASEO_WAKE === '1' || recipients.length === 0)
218
+ return;
219
+ const actIndex = parseActivityId(activity.id);
220
+ if (actIndex === undefined)
221
+ return;
222
+ launchWorker(fileURLToPath(new URL('./cmd/notify-once.js', import.meta.url)), ['--location', squarePath, '--act-index', String(actIndex)]);
223
+ },
224
+ };
241
225
  }
242
226
  /** Reconsider old pending attention at a bounded action boundary using the existing worker. */
243
- export function sweepPendingNotifications(squarePath, opts = {}) {
227
+ export async function sweepPendingNotifications(squarePath, opts = {}) {
244
228
  const env = opts.env ?? process.env;
245
229
  if (env.SQUARE_DISABLE_PASEO_WAKE === '1')
246
230
  return [];
247
231
  const now = opts.now ?? Date.now();
248
232
  const limit = opts.limit ?? 8;
249
- const doc = loadSquare(squarePath);
250
- const model = deriveDeliveryModel(doc);
233
+ const square = await openSquare(squarePath, { clock: () => now });
234
+ const pending = await pendingDeliveries(square).finally(() => closeOpenSquare(square));
251
235
  const indexes = new Set();
252
- for (const recipient of joinedRecipients(doc)) {
253
- for (const note of model.pendingFor(recipient)) {
236
+ for (const delivery of pending) {
237
+ for (const note of delivery.notifications) {
254
238
  if (now - note.item.at <= wakeGraceMs(env))
255
239
  continue;
256
- if (!wakeIsEligible(wakeEvidence(squarePath, recipient, note.item.index, now, env)))
240
+ if (!wakeIsEligible(await wakeEvidence(squarePath, delivery.recipient, note.item.index, now, env)))
257
241
  continue;
258
242
  indexes.add(note.item.index);
259
243
  }
@@ -0,0 +1,11 @@
1
+ import type { StateCell } from './state-cell.js';
2
+ import type { WakeNotifier } from './square-facade.js';
3
+ /** Private binding assembled by storage and consumed by the four concerns. */
4
+ export interface OpenSquare {
5
+ readonly cell: StateCell;
6
+ readonly clock: () => number;
7
+ readonly notifier?: WakeNotifier;
8
+ readonly location: string;
9
+ }
10
+ /** Package-private lifecycle boundary for bound squares. */
11
+ export declare function closeOpenSquare(square: OpenSquare): Promise<void>;
@@ -0,0 +1,4 @@
1
+ /** Package-private lifecycle boundary for bound squares. */
2
+ export function closeOpenSquare(square) {
3
+ return square.cell.close();
4
+ }
@@ -0,0 +1 @@
1
+ export declare function participantIdentity(name: string): string;
@@ -0,0 +1,3 @@
1
+ export function participantIdentity(name) {
2
+ return `@${name}`;
3
+ }
@@ -0,0 +1,15 @@
1
+ import { DaemonClient } from '@getpaseo/client/internal/daemon-client';
2
+ export type PaseoDaemonTarget = {
3
+ type: 'tcp';
4
+ url: string;
5
+ password?: string;
6
+ } | {
7
+ type: 'ipc';
8
+ url: string;
9
+ socketPath: string;
10
+ password?: string;
11
+ };
12
+ /** Match the host precedence used by the Paseo CLI for local daemon connections. */
13
+ export declare function paseoDaemonHosts(env?: NodeJS.ProcessEnv): string[];
14
+ export declare function resolvePaseoDaemonTarget(host: string, env?: NodeJS.ProcessEnv): PaseoDaemonTarget;
15
+ export declare function connectPaseoDaemon(env?: NodeJS.ProcessEnv, connectTimeoutMs?: number): Promise<DaemonClient>;
@@ -0,0 +1,14 @@
1
+ import { type WakeAdapter, type WakeDispatchResult } from './delivery.js';
2
+ import { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
3
+ import { sendPaseoWake } from './wake-sink.js';
4
+ export interface PaseoAdapterOptions {
5
+ discover?: typeof discoverPaseoAgents;
6
+ waitForBoundary?: typeof waitForPaseoWakeBoundary;
7
+ sendWake?: typeof sendPaseoWake;
8
+ }
9
+ export declare class PaseoAdapter implements WakeAdapter {
10
+ private readonly opts;
11
+ readonly kind: "paseo";
12
+ constructor(opts?: PaseoAdapterOptions);
13
+ dispatch(address: Readonly<Record<string, string>>, payload: string, beforeSend: () => Promise<boolean>): Promise<WakeDispatchResult>;
14
+ }
@@ -0,0 +1,11 @@
1
+ export interface PaseoAgent {
2
+ id: string;
3
+ name: string;
4
+ status: string;
5
+ cwd?: string;
6
+ }
7
+ export declare function discoverPaseoAgents(timeoutMs?: number): {
8
+ agents: PaseoAgent[];
9
+ error?: string;
10
+ };
11
+ export declare function waitForPaseoWakeBoundary(agent: Pick<PaseoAgent, 'id' | 'status'>): Promise<boolean>;
@@ -0,0 +1,16 @@
1
+ export type PaseoToolStatus = 'running' | 'completed' | 'failed';
2
+ export interface PaseoToolCallSnapshot {
3
+ callId: string;
4
+ status: PaseoToolStatus;
5
+ }
6
+ export interface PaseoTimelineSnapshot {
7
+ agentStatus: string;
8
+ toolCalls: PaseoToolCallSnapshot[];
9
+ }
10
+ export interface WaitForPaseoToolBoundaryOptions {
11
+ pollIntervalMs?: number;
12
+ timeoutMs?: number;
13
+ readSnapshot?: (agentId: string) => Promise<PaseoTimelineSnapshot>;
14
+ delay?: (ms: number) => Promise<void>;
15
+ }
16
+ export declare function waitForPaseoToolBoundary(agentId: string, opts?: WaitForPaseoToolBoundaryOptions): Promise<boolean>;
@@ -0,0 +1,3 @@
1
+ import type { OpenSquare } from './open-square.js';
2
+ import type { CatchOptions, CatchResult } from './square-facade.js';
3
+ export declare function catchUp(square: OpenSquare, name: string, options?: CatchOptions): Promise<CatchResult>;
@@ -0,0 +1,42 @@
1
+ import { extractMentions, formatActivityId, perceive } from './square-core.js';
2
+ import { ackPeerDelta, deliveryDelta, filteredRoomChanges, matchesFeedFilter, peerPublicActs } from './activity-feed.js';
3
+ import { markDeliveredNotifications } from './delivery.js';
4
+ import { SquareError } from './model.js';
5
+ import { resolveKnownName } from './decisions.js';
6
+ import { readCursor } from './runtime.js';
7
+ function expose(activity, viewer) {
8
+ if (activity.kind === 'read' || activity.actor === undefined)
9
+ throw new Error(`Cannot expose stored activity ${formatActivityId(activity.index)}`);
10
+ const perception = perceive(activity, viewer);
11
+ const result = { id: formatActivityId(activity.index), at: activity.at, kind: activity.kind, actor: activity.actor, mentions: activity.kind === 'say' ? extractMentions(activity.body) : [], ...('body' in activity && activity.body !== undefined ? { body: activity.body } : {}), ...(activity.kind === 'say' && activity.reply !== undefined ? { reply: formatActivityId(activity.reply) } : {}) };
12
+ if (perception === 'full' || !('body' in result))
13
+ return { ...result, perception };
14
+ const { body: _body, ...withoutBody } = result;
15
+ return { ...withoutBody, perception };
16
+ }
17
+ export async function catchUp(square, name, options = {}) {
18
+ const idle = options.idle ?? 0;
19
+ if (!Number.isFinite(idle) || idle < 0)
20
+ throw new SquareError('invalid_args', 'Catch idle duration must be a non-negative number');
21
+ const deadline = Date.now() + idle;
22
+ while (true) {
23
+ const attempt = await square.cell.transact((state, version) => {
24
+ const at = square.clock();
25
+ const viewer = resolveKnownName(state, name);
26
+ const delta = deliveryDelta(state, viewer);
27
+ const filter = { ...(options.from === undefined ? {} : { participants: [...options.from] }), ...(options.mention === true ? { mention: viewer } : {}) };
28
+ const delivered = [...peerPublicActs(delta, viewer).filter((activity) => matchesFeedFilter(activity, filter)), ...filteredRoomChanges(delta, viewer, filter)]
29
+ .filter((activity, index, activities) => activities.findIndex((candidate) => candidate.index === activity.index) === index)
30
+ .sort((left, right) => left.index - right.index);
31
+ const cursorChanged = ackPeerDelta(state, viewer, delta, at);
32
+ const receiptsChanged = markDeliveredNotifications(state, viewer, delivered, at);
33
+ const cursor = readCursor(state, viewer);
34
+ return { ...(cursorChanged || receiptsChanged ? { state } : {}), result: { version, caught: { activities: delivered.map((activity) => expose(activity, viewer)), consumedThrough: cursor < 0 ? null : formatActivityId(cursor), idleExpired: false } } };
35
+ });
36
+ if (attempt.caught.activities.length > 0 || idle === 0)
37
+ return attempt.caught;
38
+ const remaining = deadline - Date.now();
39
+ if (remaining <= 0 || !await square.cell.changed(attempt.version, remaining))
40
+ return { ...attempt.caught, idleExpired: true };
41
+ }
42
+ }
@@ -0,0 +1,91 @@
1
+ import { type StoredAct, type SquareState, type PublicAct, type RoomChangeAct } from './model.js';
2
+ export { participantIdentity } from './participant-identity.js';
3
+ import type { UnreadActivitySummary, ParticipantStatus } from './decisions.js';
4
+ export type WatchStatus = 'stale' | 'empty-now' | 'quorum' | 'capped';
5
+ interface HeaderOptions {
6
+ participantCount?: number;
7
+ held?: boolean;
8
+ }
9
+ interface ParticipantOutputOptions {
10
+ squarePath: string;
11
+ name: string;
12
+ participantCount?: number;
13
+ held?: boolean;
14
+ }
15
+ interface ActivityLimitOptions extends ParticipantOutputOptions {
16
+ count?: number;
17
+ hardCap?: number;
18
+ draftPath?: string;
19
+ }
20
+ interface ActivityBlockedOptions extends ParticipantOutputOptions {
21
+ forceCommand: string;
22
+ activitySummaries: UnreadActivitySummary[];
23
+ unreadRoomChanges: RoomChangeAct[];
24
+ draftPath?: string;
25
+ }
26
+ interface ExpressWaitingOptions {
27
+ reason: 'throttled' | 'held';
28
+ delayMs?: number;
29
+ }
30
+ interface ExpressNoWaitOptions extends ParticipantOutputOptions {
31
+ reason: 'throttled' | 'held';
32
+ delayMs?: number;
33
+ holdReason?: string;
34
+ draftPath?: string;
35
+ }
36
+ interface WatchStatusOptions extends ParticipantOutputOptions {
37
+ status: WatchStatus;
38
+ idleMs?: number;
39
+ presence?: {
40
+ participants: ParticipantStatus[];
41
+ now: number;
42
+ };
43
+ showCatchHint?: boolean;
44
+ }
45
+ export declare function displayPath(squarePath: string, cwd?: string): string;
46
+ export declare function withPathOutput(squarePath: string, body?: string, opts?: HeaderOptions): string;
47
+ export declare function quoteShell(value: string): string;
48
+ export declare function commandPrefix(squarePath: string): string;
49
+ export declare function participantCommandPrefix(squarePath: string, name: string): string;
50
+ export declare function renderPresenceLines(participants: ParticipantStatus[], now: number, limit?: number): string[];
51
+ export declare function expressHintLine(ownActivityCount: number): string | undefined;
52
+ export declare function truncateChars(body: string, maxChars: number): {
53
+ text: string;
54
+ remaining: number;
55
+ };
56
+ export declare function previewActivityBody(body: string): string;
57
+ export declare function renderRoomChangeText(event: RoomChangeAct): string;
58
+ export declare function renderEventCli(event: StoredAct, opts?: {
59
+ now?: number;
60
+ preview?: number;
61
+ actNumber?: number;
62
+ mention?: string;
63
+ }): string;
64
+ export declare function renderAmbientEvent(event: StoredAct, viewer: string, opts?: {
65
+ now?: number;
66
+ preview?: number;
67
+ actNumber?: number;
68
+ mention?: string;
69
+ }): string;
70
+ export declare function renderPendingFeed(history: StoredAct[], publicItems: PublicAct[], roomChanges: RoomChangeAct[], viewer?: string): string;
71
+ export declare function renderActivityBlocked(opts: ActivityBlockedOptions): string;
72
+ export declare function renderExpressWaiting(opts: ExpressWaitingOptions): string;
73
+ export declare function renderExpressNoWait(opts: ExpressNoWaitOptions): string;
74
+ export declare function renderPublicTail(events: StoredAct[], lastN: number | null | undefined, now?: number, viewer?: string): string;
75
+ export declare function renderActivitiesView(squareState: SquareState, visible: StoredAct[], lastN: number | null | undefined, full: boolean | undefined, squarePath: string, viewer?: string, mode?: 'ambient' | 'archive'): string;
76
+ export declare function renderGrepActivitiesView(visible: StoredAct[], totalMatches: number, full: boolean | undefined, squarePath: string, pattern: string, fixed?: boolean): string;
77
+ export declare function renderActivityLimit(opts: ActivityLimitOptions): string;
78
+ export declare function renderWatchAlreadyActive(opts: ParticipantOutputOptions): string;
79
+ export declare function renderWatchForceTakeover(_opts: ParticipantOutputOptions): string;
80
+ export declare function renderWatchReplaced(_opts: ParticipantOutputOptions): string;
81
+ export declare function renderWatchStatus(opts: WatchStatusOptions): string;
82
+ export declare function renderDoctorClean(): string;
83
+ export declare function renderDoctorUnfixable(reason: string): string;
84
+ export declare function renderWatchOutput(history: StoredAct[], publicItems: PublicAct[], roomChanges: RoomChangeAct[], opts: {
85
+ squarePath: string;
86
+ stalePartial?: boolean;
87
+ idleMs?: number;
88
+ mention?: string;
89
+ viewer: string;
90
+ showCatchHint?: boolean;
91
+ }): string;