@astrosheep/square 0.3.85 → 0.3.87
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.
- package/dist/artifact.d.ts +6 -1
- package/dist/artifact.js +79 -10
- package/dist/boundary-presentation.d.ts +5 -4
- package/dist/boundary-presentation.js +21 -25
- package/dist/catch-decisions.js +2 -1
- package/dist/claude-delivery-status.d.ts +8 -2
- package/dist/claude-delivery-status.js +26 -10
- package/dist/claude-delivery.d.ts +8 -4
- package/dist/claude-delivery.js +114 -104
- package/dist/claude-mcp-context.js +2 -2
- package/dist/claude-mod.js +119 -105
- package/dist/cli/context.d.ts +3 -1
- package/dist/cli/context.js +25 -1
- package/dist/cli/express-presentation.d.ts +3 -1
- package/dist/cli/express-presentation.js +15 -12
- package/dist/cli/mcp-server-command.js +2 -2
- package/dist/cli/observation-commands.js +2 -1
- package/dist/cli/registry.js +0 -2
- package/dist/cli/square-commands.d.ts +4 -2
- package/dist/cli/square-commands.js +21 -6
- package/dist/codex-hook.d.ts +3 -3
- package/dist/codex-hook.js +4 -4
- package/dist/codex-queue.d.ts +5 -6
- package/dist/codex-queue.js +9 -5
- package/dist/decisions.d.ts +3 -2
- package/dist/decisions.js +18 -6
- package/dist/delivery-health.d.ts +32 -2
- package/dist/delivery-health.js +108 -45
- package/dist/delivery-operations.d.ts +1 -2
- package/dist/delivery-operations.js +155 -196
- package/dist/delivery.d.ts +14 -23
- package/dist/delivery.js +48 -18
- package/dist/file-lock.d.ts +8 -1
- package/dist/file-lock.js +2 -0
- package/dist/help.js +12 -14
- package/dist/hints.js +2 -3
- package/dist/inbox.d.ts +35 -9
- package/dist/inbox.js +228 -144
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -3
- package/dist/list.js +9 -4
- package/dist/mcp.js +12 -1
- package/dist/model.d.ts +39 -5
- package/dist/model.js +84 -0
- package/dist/notifications.d.ts +8 -6
- package/dist/notifications.js +56 -143
- package/dist/operation-presentation.js +12 -14
- package/dist/participant-identity.d.ts +0 -3
- package/dist/participant-identity.js +0 -31
- package/dist/paseo-delivery.d.ts +5 -6
- package/dist/paseo-delivery.js +13 -8
- package/dist/paseo.d.ts +1 -1
- package/dist/paseo.js +1 -1
- package/dist/plugins/opencode/delivery.d.ts +8 -3
- package/dist/plugins/opencode/delivery.js +187 -132
- package/dist/plugins/opencode/index.js +12 -38
- package/dist/ports.d.ts +112 -40
- package/dist/presentation-operations.d.ts +1 -1
- package/dist/presentation-operations.js +51 -35
- package/dist/presentation.d.ts +0 -1
- package/dist/presentation.js +18 -13
- package/dist/seats.d.ts +7 -0
- package/dist/seats.js +27 -0
- package/dist/session-lifecycle.d.ts +2 -2
- package/dist/session-lifecycle.js +10 -12
- package/dist/sqlite-square.d.ts +53 -0
- package/dist/sqlite-square.js +602 -0
- package/dist/square-api.d.ts +12 -41
- package/dist/square-api.js +26 -474
- package/dist/square-backend.d.ts +13 -0
- package/dist/square-core.d.ts +3 -2
- package/dist/square-domain.d.ts +12 -5
- package/dist/square-domain.js +163 -7
- package/dist/square-facade.d.ts +16 -10
- package/dist/square-index.d.ts +24 -0
- package/dist/square-index.js +131 -0
- package/dist/square-legacy-framing.d.ts +9 -0
- package/dist/square-legacy-framing.js +56 -0
- package/dist/square-location.d.ts +15 -0
- package/dist/square-location.js +76 -0
- package/dist/square-migration-host-ledger.d.ts +26 -0
- package/dist/square-migration-host-ledger.js +168 -0
- package/dist/square-migration.d.ts +5 -5
- package/dist/square-migration.js +373 -71
- package/dist/square-sqlite.d.ts +9 -9
- package/dist/square-sqlite.js +329 -79
- package/dist/square-stdio.d.ts +22 -0
- package/dist/square-stdio.js +222 -0
- package/dist/square-tools.js +30 -3
- package/dist/stdio-server.d.ts +3 -0
- package/dist/stdio-server.js +192 -0
- package/dist/stream.d.ts +3 -2
- package/dist/stream.js +9 -10
- package/dist/views.d.ts +9 -14
- package/dist/views.js +50 -70
- package/dist/wakes.d.ts +6 -5
- package/dist/wakes.js +20 -17
- package/guides/application-facade-delivery-evidence.md +1 -1
- package/guides/backends.md +180 -0
- package/guides/claude-native.md +9 -9
- package/guides/mcp.md +1 -1
- package/guides/migration.md +107 -67
- package/guides/row-storage-design.md +1 -1
- package/guides/square-api.md +69 -30
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/register.js +1 -1
- package/plugins/claude/skills/square/SKILL.md +7 -7
- package/plugins/claude/types.d.ts +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/opencode/delivery.ts +170 -118
- package/plugins/opencode/index.ts +12 -30
- package/plugins/pi/square-pi.js +58 -20
- package/skills/square/SKILL.md +7 -7
- package/dist/cli/ledger-command.d.ts +0 -12
- package/dist/cli/ledger-command.js +0 -72
- package/dist/host-ledger-file-adapter.d.ts +0 -47
- package/dist/host-ledger-file-adapter.js +0 -384
- package/dist/host-ledger-migration.d.ts +0 -27
- package/dist/host-ledger-migration.js +0 -264
- package/dist/host-ledger-root.d.ts +0 -2
- package/dist/host-ledger-root.js +0 -9
- package/dist/host-ledger-sqlite.d.ts +0 -65
- package/dist/host-ledger-sqlite.js +0 -368
- package/dist/host-ledger.d.ts +0 -195
- package/dist/ledger-maintenance.d.ts +0 -30
- package/dist/ledger-maintenance.js +0 -110
- package/dist/open-square.d.ts +0 -36
- package/dist/open-square.js +0 -81
- package/dist/participant-host.d.ts +0 -22
- package/dist/participant-host.js +0 -92
- package/dist/registry.d.ts +0 -55
- package/dist/registry.js +0 -123
- package/dist/routes.d.ts +0 -39
- package/dist/routes.js +0 -99
- package/dist/square-actions.d.ts +0 -56
- package/dist/square-actions.js +0 -353
- package/dist/square-projections.d.ts +0 -31
- package/dist/square-projections.js +0 -64
- package/dist/wake-attempts.d.ts +0 -10
- package/dist/wake-attempts.js +0 -39
- package/dist/wake-eligibility.d.ts +0 -53
- package/dist/wake-eligibility.js +0 -123
- package/dist/wake-evidence.d.ts +0 -33
- package/dist/wake-evidence.js +0 -32
- package/guides/host-ledger.md +0 -58
- package/guides/indexed-host-ledger-performance.md +0 -39
- /package/dist/{host-ledger.js → square-backend.js} +0 -0
package/dist/model.js
CHANGED
|
@@ -1,6 +1,90 @@
|
|
|
1
1
|
// Shared model and constants for Square.
|
|
2
2
|
export { formatActivityId, parseActivityId } from './square-core.js';
|
|
3
3
|
export const WAKE_ROUTE_KINDS = ['opencode-server', 'codex-queue', 'claude-native', 'paseo'];
|
|
4
|
+
export const ACTIVITY_METADATA_MAX_BYTES = 16 * 1024;
|
|
5
|
+
export const ACTIVITY_METADATA_MAX_DEPTH = 256;
|
|
6
|
+
/** Validate the bounded, lossless JSON object carried by a say. */
|
|
7
|
+
export function validateActivityMetadata(value) {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
return undefined;
|
|
10
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
11
|
+
throw new SquareError('invalid_args', 'Activity metadata must be a non-null JSON object.');
|
|
12
|
+
const visiting = new Set();
|
|
13
|
+
const stack = [{ value, depth: 0 }];
|
|
14
|
+
while (stack.length > 0) {
|
|
15
|
+
const frame = stack.pop();
|
|
16
|
+
if (frame.exit !== undefined) {
|
|
17
|
+
visiting.delete(frame.exit);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const item = frame.value;
|
|
21
|
+
if (item === null || typeof item === 'boolean' || typeof item === 'string')
|
|
22
|
+
continue;
|
|
23
|
+
if (typeof item === 'number') {
|
|
24
|
+
if (!Number.isFinite(item))
|
|
25
|
+
throw new SquareError('invalid_args', 'Activity metadata must contain only finite JSON values.');
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (typeof item !== 'object')
|
|
29
|
+
throw new SquareError('invalid_args', 'Activity metadata must contain only JSON values.');
|
|
30
|
+
if (frame.depth > ACTIVITY_METADATA_MAX_DEPTH)
|
|
31
|
+
throw new SquareError('invalid_args', `Activity metadata nesting cannot exceed ${ACTIVITY_METADATA_MAX_DEPTH} levels.`);
|
|
32
|
+
if (visiting.has(item))
|
|
33
|
+
throw new SquareError('invalid_args', 'Activity metadata cannot contain a cycle.');
|
|
34
|
+
visiting.add(item);
|
|
35
|
+
stack.push({ value: item, depth: frame.depth, exit: item });
|
|
36
|
+
if (Array.isArray(item)) {
|
|
37
|
+
if (Object.getOwnPropertySymbols(item).length > 0 || Object.keys(item).length !== item.length)
|
|
38
|
+
throw new SquareError('invalid_args', 'Activity metadata arrays must be dense JSON arrays.');
|
|
39
|
+
const names = Object.getOwnPropertyNames(item);
|
|
40
|
+
if (names.some(name => name !== 'length' && (!/^(0|[1-9]\d*)$/.test(name) || Number(name) >= item.length)))
|
|
41
|
+
throw new SquareError('invalid_args', 'Activity metadata arrays must contain only indexed values.');
|
|
42
|
+
for (const key of Object.keys(item).reverse()) {
|
|
43
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, key);
|
|
44
|
+
if (descriptor === undefined || !('value' in descriptor))
|
|
45
|
+
throw new SquareError('invalid_args', 'Activity metadata cannot contain accessors.');
|
|
46
|
+
stack.push({ value: descriptor.value, depth: frame.depth + 1 });
|
|
47
|
+
}
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
const prototype = Object.getPrototypeOf(item);
|
|
51
|
+
if (prototype !== Object.prototype && prototype !== null)
|
|
52
|
+
throw new SquareError('invalid_args', 'Activity metadata must contain only plain JSON objects.');
|
|
53
|
+
if (Object.getOwnPropertySymbols(item).length > 0)
|
|
54
|
+
throw new SquareError('invalid_args', 'Activity metadata cannot contain symbol keys.');
|
|
55
|
+
const names = Object.getOwnPropertyNames(item);
|
|
56
|
+
if (names.some(name => !Object.prototype.propertyIsEnumerable.call(item, name)))
|
|
57
|
+
throw new SquareError('invalid_args', 'Activity metadata cannot contain non-enumerable properties.');
|
|
58
|
+
for (const name of names.reverse()) {
|
|
59
|
+
const descriptor = Object.getOwnPropertyDescriptor(item, name);
|
|
60
|
+
if (!('value' in descriptor))
|
|
61
|
+
throw new SquareError('invalid_args', 'Activity metadata cannot contain accessors.');
|
|
62
|
+
stack.push({ value: descriptor.value, depth: frame.depth + 1 });
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let serialized;
|
|
66
|
+
try {
|
|
67
|
+
serialized = JSON.stringify(value);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new SquareError('invalid_args', 'Activity metadata must contain only lossless JSON values.');
|
|
71
|
+
}
|
|
72
|
+
if (serialized === undefined || Buffer.byteLength(serialized, 'utf8') > ACTIVITY_METADATA_MAX_BYTES)
|
|
73
|
+
throw new SquareError('invalid_args', `Activity metadata cannot exceed ${ACTIVITY_METADATA_MAX_BYTES} UTF-8 bytes.`);
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
export function activityMetadataHasContent(metadata) {
|
|
77
|
+
return metadata !== undefined && Object.keys(metadata).length > 0;
|
|
78
|
+
}
|
|
79
|
+
export function sameBody(left, right) {
|
|
80
|
+
return left.channel === right.channel && left.session === right.session && left.agent === right.agent;
|
|
81
|
+
}
|
|
82
|
+
export function validateBody(body) {
|
|
83
|
+
if (!body || typeof body.channel !== 'string' || !body.channel || typeof body.session !== 'string' || !body.session
|
|
84
|
+
|| (body.agent !== undefined && (typeof body.agent !== 'string' || !body.agent))) {
|
|
85
|
+
throw new SquareError('invalid_args', 'A participant write requires an explicit channel and session body.');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
4
88
|
export function isWakeRouteKind(value) {
|
|
5
89
|
return typeof value === 'string' && WAKE_ROUTE_KINDS.includes(value);
|
|
6
90
|
}
|
package/dist/notifications.d.ts
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type WakeRouteKind } from './model.js';
|
|
2
2
|
import type { WakeTransportPort } from './ports.js';
|
|
3
3
|
export type { PlannedNotification } from './delivery.js';
|
|
4
4
|
export declare const PRIVILEGED_HOOK_BUDGET_MS = 3000;
|
|
5
5
|
export declare function wakeGraceMs(env?: NodeJS.ProcessEnv): number;
|
|
6
|
+
export type WakeTransports = Readonly<Partial<Record<WakeRouteKind, WakeTransportPort>>>;
|
|
6
7
|
interface ProcessNotificationOptions {
|
|
7
|
-
|
|
8
|
+
transports?: WakeTransports;
|
|
8
9
|
env?: NodeJS.ProcessEnv;
|
|
9
10
|
now?: () => number;
|
|
10
11
|
}
|
|
11
|
-
|
|
12
|
-
export declare function createDefaultWakeTransport(
|
|
13
|
-
|
|
12
|
+
/** Concrete transports use wall time; semantic state time belongs to Square operations. */
|
|
13
|
+
export declare function createDefaultWakeTransport(env?: NodeJS.ProcessEnv, suppliedTransports?: WakeTransports): Promise<WakeTransportPort>;
|
|
14
|
+
/** Route selection only: all implementations receive the same request and final gate. */
|
|
15
|
+
export declare function createWakeTransport(transports: WakeTransports): WakeTransportPort;
|
|
14
16
|
export declare function processActNotificationsOnce(squarePath: string, actIndex: number, opts?: ProcessNotificationOptions): Promise<import("./ports.js").DeliveryResult>;
|
|
15
17
|
/** Privileged hook fallback: sweep indexed squares plus the current cwd's local squares within one boundary budget. */
|
|
16
|
-
export declare function sweepPrivilegedPending(cwd: string, env?: NodeJS.ProcessEnv,
|
|
18
|
+
export declare function sweepPrivilegedPending(cwd: string, env?: NodeJS.ProcessEnv, suppliedTransports?: WakeTransports, deadline?: number, signal?: AbortSignal): Promise<void>;
|
|
17
19
|
export interface SweepPendingNotificationsOptions {
|
|
18
20
|
env?: NodeJS.ProcessEnv;
|
|
19
21
|
now?: number;
|
package/dist/notifications.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
|
-
import { hostLedgerRoot } from './host-ledger-root.js';
|
|
2
1
|
import path from 'node:path';
|
|
3
2
|
import fs from 'node:fs';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { closeOpenSquare } from './open-square.js';
|
|
3
|
+
import { indexedSquareEntries } from './square-index.js';
|
|
4
|
+
import { InternalSquareError, SquareError } from './model.js';
|
|
5
|
+
import { createArtifactPort } from './artifact.js';
|
|
8
6
|
import { deliverPending, sweepPending } from './delivery-operations.js';
|
|
9
|
-
import { projectWakeEvidence } from './wake-eligibility.js';
|
|
10
|
-
import { pendingHead } from './delivery.js';
|
|
11
|
-
import { parseActivityId } from './square-core.js';
|
|
12
|
-
import { canonicalPath } from './canonical-path.js';
|
|
13
|
-
import { createHostLedgerPort } from './host-ledger-file-adapter.js';
|
|
14
7
|
export const PRIVILEGED_HOOK_BUDGET_MS = 3000;
|
|
15
8
|
export function wakeGraceMs(env = process.env) {
|
|
16
9
|
const value = Number.parseInt(env.SQUARE_NOTIFY_DELIVERY_WAIT_MS ?? '5000', 10);
|
|
@@ -19,161 +12,75 @@ export function wakeGraceMs(env = process.env) {
|
|
|
19
12
|
}
|
|
20
13
|
return value;
|
|
21
14
|
}
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
/** Concrete transports use wall time; semantic state time belongs to Square operations. */
|
|
16
|
+
export async function createDefaultWakeTransport(env = process.env, suppliedTransports) {
|
|
17
|
+
if (suppliedTransports !== undefined)
|
|
18
|
+
return createWakeTransport(suppliedTransports);
|
|
19
|
+
const transports = {};
|
|
24
20
|
try {
|
|
25
|
-
const {
|
|
26
|
-
|
|
21
|
+
const { CodexQueueTransport } = await import('./codex-queue.js');
|
|
22
|
+
transports['codex-queue'] = new CodexQueueTransport({ env });
|
|
27
23
|
}
|
|
28
|
-
catch {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
catch {
|
|
36
|
-
// Paseo is an optional integration; a core-only install simply has no Paseo adapter.
|
|
24
|
+
catch { /* core-only builds may omit Codex */ }
|
|
25
|
+
if (env.SQUARE_DISABLE_PASEO_WAKE !== '1') {
|
|
26
|
+
try {
|
|
27
|
+
const { PaseoWakeTransport } = await import('./paseo-delivery.js');
|
|
28
|
+
transports.paseo = new PaseoWakeTransport();
|
|
29
|
+
}
|
|
30
|
+
catch { /* Paseo is optional */ }
|
|
37
31
|
}
|
|
38
|
-
return adapters;
|
|
39
|
-
}
|
|
40
|
-
export async function createDefaultWakeTransport(hostLedger, clock, env = process.env, suppliedAdapters) {
|
|
41
|
-
const adapters = suppliedAdapters ?? await defaultWakeAdapters(env);
|
|
42
32
|
const { createClaudeWakeTransport } = await import('./claude-delivery.js');
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
async function observeWakeRequest(request, hostLedger, now) {
|
|
46
|
-
let square;
|
|
47
|
-
try {
|
|
48
|
-
const location = await canonicalPath(request.location);
|
|
49
|
-
square = await openSquare(location, { hostLedger });
|
|
50
|
-
const { value: facts } = await square.artifact.read((facts) => {
|
|
51
|
-
const index = parseActivityId(request.activity);
|
|
52
|
-
const head = index === undefined ? undefined : pendingHead(facts, request.participant, index);
|
|
53
|
-
return { routes: facts.routes(), pending: head === undefined ? [] : [head] };
|
|
54
|
-
});
|
|
55
|
-
const eligibility = await projectWakeEvidence({ ...facts, hostLedger, location, now });
|
|
56
|
-
return { ...eligibility.currentness({ ...request, location }), observationAvailable: true };
|
|
57
|
-
}
|
|
58
|
-
catch {
|
|
59
|
-
return { current: false, activityPending: false, sessionBound: false, routePublished: false,
|
|
60
|
-
selectedOwner: false, cancelled: false, presented: false, observationAvailable: false };
|
|
61
|
-
}
|
|
62
|
-
finally {
|
|
63
|
-
if (square !== undefined)
|
|
64
|
-
await closeOpenSquare(square);
|
|
65
|
-
}
|
|
33
|
+
transports['claude-native'] = createClaudeWakeTransport(env);
|
|
34
|
+
return createWakeTransport(transports);
|
|
66
35
|
}
|
|
67
|
-
|
|
36
|
+
/** Route selection only: all implementations receive the same request and final gate. */
|
|
37
|
+
export function createWakeTransport(transports) {
|
|
38
|
+
const missing = (kind) => ({ outcome: 'not-capable', diagnostic: `no transport for ${kind}` });
|
|
68
39
|
return {
|
|
69
|
-
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
return
|
|
73
|
-
const adapter = adapters.find((candidate) => candidate.kind === route.kind);
|
|
74
|
-
if (adapter === undefined)
|
|
75
|
-
return { outcome: 'not-capable', diagnostic: `no adapter for ${route.kind}` };
|
|
76
|
-
const probe = adapter.probe;
|
|
77
|
-
if (probe === undefined)
|
|
78
|
-
return true;
|
|
40
|
+
async probe(route) {
|
|
41
|
+
const transport = transports[route.kind];
|
|
42
|
+
if (transport === undefined)
|
|
43
|
+
return missing(route.kind);
|
|
79
44
|
try {
|
|
80
|
-
return await probe
|
|
45
|
+
return await transport.probe?.(route) ?? true;
|
|
81
46
|
}
|
|
82
47
|
catch (error) {
|
|
83
48
|
return { outcome: 'not-capable', diagnostic: error instanceof Error ? error.message : String(error) };
|
|
84
49
|
}
|
|
85
50
|
},
|
|
86
|
-
attempt:
|
|
87
|
-
|
|
88
|
-
const finalGate = beforeSend ?? (async () => {
|
|
89
|
-
revalidation = await observeWakeRequest(request, hostLedger, clock());
|
|
90
|
-
return revalidation.current;
|
|
91
|
-
});
|
|
92
|
-
const native = nativePorts[request.route.kind];
|
|
93
|
-
if (native !== undefined)
|
|
94
|
-
return native.attempt(request, timeoutMs, finalGate);
|
|
95
|
-
const adapter = adapters.find((candidate) => candidate.kind === request.route.kind);
|
|
96
|
-
if (adapter === undefined)
|
|
97
|
-
return { outcome: 'not-capable', diagnostic: `no adapter for ${request.route.kind}` };
|
|
98
|
-
try {
|
|
99
|
-
const location = await canonicalPath(request.location);
|
|
100
|
-
const square = await openSquare(location, { hostLedger }).catch(() => undefined);
|
|
101
|
-
if (square === undefined)
|
|
102
|
-
return { outcome: 'not-capable', diagnostic: `Square is unavailable at ${location}` };
|
|
103
|
-
let payload;
|
|
104
|
-
try {
|
|
105
|
-
const index = parseActivityId(request.activity);
|
|
106
|
-
payload = (await square.artifact.read((facts) => {
|
|
107
|
-
const head = index === undefined ? undefined : pendingHead(facts, request.participant, index);
|
|
108
|
-
const item = index === undefined ? undefined : facts.activity(index);
|
|
109
|
-
if (!head || item?.kind !== 'say')
|
|
110
|
-
return undefined;
|
|
111
|
-
return renderSquareReminder([renderAttentionPreview({
|
|
112
|
-
squarePath: location, recipient: request.participant, actIndex: item.index,
|
|
113
|
-
actor: item.actor, route: head.route, body: item.body,
|
|
114
|
-
})]);
|
|
115
|
-
})).value;
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
await closeOpenSquare(square);
|
|
119
|
-
}
|
|
120
|
-
if (payload === undefined)
|
|
121
|
-
return { outcome: 'not-capable', diagnostic: 'No pending Square activity to preview.' };
|
|
122
|
-
const result = await adapter.dispatch(request.route.address, payload, finalGate, timeoutMs, request);
|
|
123
|
-
if (result.outcome !== 'gate-rejected')
|
|
124
|
-
return result;
|
|
125
|
-
if (revalidation !== undefined && !revalidation.current) {
|
|
126
|
-
return {
|
|
127
|
-
outcome: 'failed',
|
|
128
|
-
signature: 'pre_send_revalidation_failed',
|
|
129
|
-
message: revalidation.observationAvailable
|
|
130
|
-
? 'Wake was not sent because current attention, session binding, or route no longer matches.'
|
|
131
|
-
: 'Wake was not sent because current Square delivery state could not be verified.',
|
|
132
|
-
diagnostic: revalidation,
|
|
133
|
-
unavailable: true,
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
return { outcome: 'unknown', diagnostic: 'wake dispatch cancelled' };
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
return { outcome: 'unknown', diagnostic: error instanceof Error ? error.message : String(error) };
|
|
140
|
-
}
|
|
141
|
-
},
|
|
51
|
+
attempt: (request, timeoutMs, beforeSend) => transports[request.route.kind]?.attempt(request, timeoutMs, beforeSend)
|
|
52
|
+
?? Promise.resolve(missing(request.route.kind)),
|
|
142
53
|
};
|
|
143
54
|
}
|
|
144
55
|
export async function processActNotificationsOnce(squarePath, actIndex, opts = {}) {
|
|
145
56
|
const env = opts.env ?? process.env;
|
|
146
57
|
const now = opts.now ?? Date.now;
|
|
147
|
-
const
|
|
148
|
-
const hostLedger = createHostLedgerPort({
|
|
149
|
-
rootPath: ledgerRoot,
|
|
150
|
-
});
|
|
151
|
-
const square = await openSquare(squarePath, { clock: now, hostLedger, env });
|
|
58
|
+
const artifact = createArtifactPort(squarePath);
|
|
152
59
|
try {
|
|
153
|
-
|
|
60
|
+
await artifact.read(facts => facts.header());
|
|
61
|
+
const transport = await createDefaultWakeTransport(env, opts.transports);
|
|
154
62
|
try {
|
|
155
|
-
return await deliverPending({ artifact
|
|
63
|
+
return await deliverPending({ artifact, transport, location: squarePath, activity: actIndex, timeoutMs: Number(env.SQUARE_NOTIFY_DELIVERY_WAIT_MS ?? 5000), now: now() });
|
|
156
64
|
}
|
|
157
65
|
catch {
|
|
158
66
|
return { attempted: 0, accepted: 0, failed: 0, unknown: 0, notCapable: 1 };
|
|
159
67
|
}
|
|
160
68
|
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
if (error instanceof InternalSquareError && error.code === 'not_found')
|
|
71
|
+
throw new SquareError('unavailable', `Square is unavailable at ${squarePath}`);
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
161
74
|
finally {
|
|
162
|
-
await
|
|
75
|
+
await artifact.close();
|
|
163
76
|
}
|
|
164
77
|
}
|
|
165
78
|
/** Privileged hook fallback: sweep indexed squares plus the current cwd's local squares within one boundary budget. */
|
|
166
|
-
export async function sweepPrivilegedPending(cwd, env = process.env,
|
|
79
|
+
export async function sweepPrivilegedPending(cwd, env = process.env, suppliedTransports, deadline = Date.now() + PRIVILEGED_HOOK_BUDGET_MS, signal) {
|
|
167
80
|
const remainingMs = () => Math.max(0, deadline - Date.now());
|
|
168
81
|
if (remainingMs() === 0 || signal?.aborted)
|
|
169
82
|
return;
|
|
170
|
-
const
|
|
171
|
-
const hostLedger = createHostLedgerPort({ rootPath: root });
|
|
172
|
-
let indexed = [];
|
|
173
|
-
try {
|
|
174
|
-
indexed = await hostLedger.listPresence({ now: Date.now() });
|
|
175
|
-
}
|
|
176
|
-
catch { /* capability is best effort */ }
|
|
83
|
+
const indexed = await indexedSquareEntries({}, env).catch(() => []);
|
|
177
84
|
const paths = new Set(indexed.map((binding) => binding.location));
|
|
178
85
|
try {
|
|
179
86
|
for (const entry of await fs.promises.readdir(path.join(cwd, '.square'))) {
|
|
@@ -184,29 +91,30 @@ export async function sweepPrivilegedPending(cwd, env = process.env, suppliedAda
|
|
|
184
91
|
catch { /* no local square directory */ }
|
|
185
92
|
if (remainingMs() === 0 || signal?.aborted)
|
|
186
93
|
return;
|
|
187
|
-
const transport = await createDefaultWakeTransport(
|
|
94
|
+
const transport = await createDefaultWakeTransport(env, suppliedTransports);
|
|
188
95
|
for (const squarePath of paths) {
|
|
189
96
|
if (remainingMs() === 0 || signal?.aborted)
|
|
190
97
|
break;
|
|
191
98
|
try {
|
|
192
|
-
const
|
|
99
|
+
const artifact = createArtifactPort(squarePath, undefined, signal);
|
|
193
100
|
try {
|
|
101
|
+
await artifact.read(facts => facts.header(), signal);
|
|
194
102
|
if (remainingMs() === 0 || signal?.aborted)
|
|
195
103
|
break;
|
|
196
104
|
const limit = Number.parseInt(env.SQUARE_NOTIFY_SWEEP_LIMIT ?? '8', 10);
|
|
197
105
|
const graceMs = 0;
|
|
198
|
-
const selected = await sweepPending({ artifact
|
|
106
|
+
const selected = await sweepPending({ artifact, location: squarePath, now: Date.now(), graceMs, limit: Number.isFinite(limit) && limit > 0 ? limit : 8 }).catch(() => []);
|
|
199
107
|
for (const actIndex of selected) {
|
|
200
108
|
const remaining = remainingMs();
|
|
201
109
|
if (remaining === 0 || signal?.aborted)
|
|
202
110
|
break;
|
|
203
111
|
const configured = Number(env.SQUARE_NOTIFY_DELIVERY_WAIT_MS ?? 5000);
|
|
204
112
|
const timeoutMs = Math.max(1, Math.min(Number.isFinite(configured) && configured > 0 ? configured : 5000, remaining));
|
|
205
|
-
await deliverPending({ artifact
|
|
113
|
+
await deliverPending({ artifact, transport, location: squarePath, activity: actIndex, timeoutMs, now: Date.now() }).catch(() => undefined);
|
|
206
114
|
}
|
|
207
115
|
}
|
|
208
116
|
finally {
|
|
209
|
-
await
|
|
117
|
+
await artifact.close();
|
|
210
118
|
}
|
|
211
119
|
}
|
|
212
120
|
catch { /* stale index entries are ignored by the hook */ }
|
|
@@ -219,14 +127,19 @@ export async function sweepPendingNotifications(squarePath, opts = {}) {
|
|
|
219
127
|
return [];
|
|
220
128
|
const now = opts.now ?? Date.now();
|
|
221
129
|
const limit = opts.limit ?? 8;
|
|
222
|
-
const
|
|
223
|
-
const square = await openSquare(squarePath, { clock: () => now, hostLedger, env });
|
|
130
|
+
const artifact = createArtifactPort(squarePath);
|
|
224
131
|
let selected;
|
|
225
132
|
try {
|
|
226
|
-
|
|
133
|
+
await artifact.read(facts => facts.header());
|
|
134
|
+
selected = await sweepPending({ artifact, location: squarePath, now, graceMs: wakeGraceMs(env), limit });
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
if (error instanceof InternalSquareError && error.code === 'not_found')
|
|
138
|
+
throw new SquareError('unavailable', `Square is unavailable at ${squarePath}`);
|
|
139
|
+
throw error;
|
|
227
140
|
}
|
|
228
141
|
finally {
|
|
229
|
-
await
|
|
142
|
+
await artifact.close();
|
|
230
143
|
}
|
|
231
144
|
if (opts.dispatchCandidate !== undefined) {
|
|
232
145
|
for (const actIndex of selected)
|
|
@@ -19,9 +19,9 @@ export function renderJoinResult(data) {
|
|
|
19
19
|
actNumber: event.kind === 'say' ? entry.sayNumbers[event.index] : undefined,
|
|
20
20
|
perception: entry.perceptions[event.index],
|
|
21
21
|
})).filter(Boolean).join('\n\n');
|
|
22
|
-
const fallback = after.automaticDeliveryAvailable ? [] : [
|
|
22
|
+
const fallback = after.automaticDeliveryAvailable ? ['', '· when someone calls you, you’ll hear them here'] : [
|
|
23
23
|
'', `${participantCommandPrefix(after.location, name)} catch --idle 30m`,
|
|
24
|
-
'
|
|
24
|
+
' · stay within earshot — keep this catch open for new activity',
|
|
25
25
|
];
|
|
26
26
|
const entryLine = data.kind === 'joined' ? '● you stepped into the square'
|
|
27
27
|
: data.kind === 'reconnected' ? '● you are already in the square'
|
|
@@ -31,7 +31,6 @@ export function renderJoinResult(data) {
|
|
|
31
31
|
? '*the flagstones are where you left them. so is your shadow.*' : entry.scene;
|
|
32
32
|
return withPathOutput(after.location, [
|
|
33
33
|
entryLine, '',
|
|
34
|
-
"· carved into the fountain's edge: every word here lands on a real ear — speak when someone needs it.",
|
|
35
34
|
...(entryScene === '' ? [] : ['', entryScene]),
|
|
36
35
|
...(isRejoin || !entry?.joinContext ? [] : ['', style('dim', 'context'), entry.joinContext]),
|
|
37
36
|
...(after.enrichmentUnavailable ? [' · joined; recent activity and context are unavailable right now'] : []),
|
|
@@ -59,13 +58,12 @@ export function renderExpression(squarePath, data) {
|
|
|
59
58
|
? `● you ring the bell — everyone turns · ${activity.id}${style('dim', capCount)}`
|
|
60
59
|
: `● ${activity.mentions.length > 0
|
|
61
60
|
? `you walk over to ${activity.mentions.map((target) => participantIdentity(target)).join(', ')}`
|
|
62
|
-
: isGestureOnly(activity.body ?? '') ? 'your gesture lands' : 'your words land'} — ${activity.id}${style('dim', capCount)}`;
|
|
61
|
+
: activity.metadata !== undefined && (activity.body ?? '').trim() === '' ? 'structured activity lands' : isGestureOnly(activity.body ?? '') ? 'your gesture lands' : 'your words land'} — ${activity.id}${style('dim', capCount)}`;
|
|
63
62
|
const replyNotice = data.replyAuthorNotHere === undefined ? ''
|
|
64
63
|
: `\n○ ${participantIdentity(data.replyAuthorNotHere)} isn't in the square right now — the reply landed without reaching them`;
|
|
65
64
|
const unmatchedNotice = data.unmatchedMentions?.length
|
|
66
65
|
? `\n · ${data.unmatchedMentions.map((token) => `@${token} isn't standing here`).join('; ')} — ${activity.mentions.length === 0 && activity.reply === undefined ? 'activity landed bare' : 'left as literal text'}` : '';
|
|
67
|
-
return withPathOutput(projection.location ?? squarePath, (
|
|
68
|
-
+ confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') + replyNotice + unmatchedNotice + pending, { participantCount: projection.standingCount, held: projection.held });
|
|
66
|
+
return withPathOutput(projection.location ?? squarePath, confirmation + (data.hint ? `\n${style('dim', `· ${data.hint}`)}` : '') + replyNotice + unmatchedNotice + pending, { participantCount: projection.standingCount, held: projection.held });
|
|
69
67
|
}
|
|
70
68
|
function continuationCommand(squarePath, name, options) {
|
|
71
69
|
const args = ['--now'];
|
|
@@ -103,7 +101,7 @@ export function renderCatchOutcome(squarePath, data, options = {}) {
|
|
|
103
101
|
perception: activity.perception, mention: options.mention ? name : undefined,
|
|
104
102
|
})).filter(Boolean).join('\n\n');
|
|
105
103
|
const remaining = data.remaining === 0 ? ''
|
|
106
|
-
:
|
|
104
|
+
: `· ${data.remaining} matching ${data.remaining === 1 ? 'activity remains' : 'activities remain'}\n${continuationCommand(location, name, options)}`;
|
|
107
105
|
const terminal = stop === undefined ? '' : renderWatchStatus({
|
|
108
106
|
...statusOptions, status: stop,
|
|
109
107
|
...(stop === 'stale' && options.idle !== undefined ? { idleMs: options.idle } : {}),
|
|
@@ -136,9 +134,9 @@ function renderHistoryProjection(projection, visible, noTruncate, squarePath) {
|
|
|
136
134
|
}
|
|
137
135
|
}
|
|
138
136
|
if (chunks.length === 0)
|
|
139
|
-
return '
|
|
140
|
-
if (preview !== undefined && shown.some((activity) => activity.kind === 'say' && activity.body
|
|
141
|
-
chunks.push(`${commandPrefix(squarePath)} history --no-truncate`);
|
|
137
|
+
return '○ no activity matches this history query';
|
|
138
|
+
if (preview !== undefined && shown.some((activity) => activity.kind === 'say' && (activity.body?.length ?? 0) > preview)) {
|
|
139
|
+
chunks.push(`${commandPrefix(squarePath)} history --at ${shown.map((activity) => formatActivityId(activity.index)).join(',')} --no-truncate`);
|
|
142
140
|
}
|
|
143
141
|
if (anchored.length > 0)
|
|
144
142
|
chunks.push(renderPresenceAnchor(anchored));
|
|
@@ -203,7 +201,7 @@ export function renderParticipantsResult(squarePath, data, limit = PARTICIPANTS_
|
|
|
203
201
|
const tail = participants.length <= limit
|
|
204
202
|
? []
|
|
205
203
|
: [
|
|
206
|
-
style('dim', `
|
|
204
|
+
style('dim', ` · ${lines.length} of ${participants.length} participants shown`),
|
|
207
205
|
...(participants.length <= PARTICIPANTS_MAX_LIMIT ? [
|
|
208
206
|
`${participantsLimitCommand(squarePath, participants.length)}`,
|
|
209
207
|
] : []),
|
|
@@ -315,10 +313,10 @@ export function renderListenerChange(squarePath, verb, data) {
|
|
|
315
313
|
const target = participantIdentity(projection.target);
|
|
316
314
|
const action = data.activity !== null
|
|
317
315
|
? verb === 'listen' ? `${actor} turns an ear toward ${target}`
|
|
318
|
-
: verb === 'ignore' ? `${actor} turns away from ${target}`
|
|
319
|
-
: `${actor} stops listening to ${target}`
|
|
316
|
+
: verb === 'ignore' ? `${actor} turns away from ${target} — only bells will reach you from them`
|
|
317
|
+
: `${actor} stops listening to ${target} — direct mentions and replies still reach you unless ignored`
|
|
320
318
|
: verb === 'listen' ? `${actor} already turns an ear toward ${target}`
|
|
321
|
-
: verb === 'ignore' ? `${actor}
|
|
319
|
+
: verb === 'ignore' ? `${actor} already ignores ${target} — only bells will reach you from them`
|
|
322
320
|
: `${actor} is not listening to ${target}`;
|
|
323
321
|
return withPathOutput(squarePath, `${data.activity === null ? '○' : '·'} ${action}`, {
|
|
324
322
|
participantCount: projection.standingCount, held: projection.held,
|
|
@@ -23,6 +23,3 @@ export declare function firstHarnessSession(env?: NodeJS.ProcessEnv): {
|
|
|
23
23
|
readonly sessionId: string;
|
|
24
24
|
readonly channel: HarnessSessionChannel;
|
|
25
25
|
} | undefined;
|
|
26
|
-
export declare function automaticParticipant(provider: AutomaticProvider, sessionId: string, env: NodeJS.ProcessEnv): string;
|
|
27
|
-
/** Compute the current harness participant without reading a Square or registry artifact. */
|
|
28
|
-
export declare function squareAssignedParticipantName(env?: NodeJS.ProcessEnv): string | undefined;
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { createHash } from 'node:crypto';
|
|
2
|
-
import { validateName } from './model.js';
|
|
3
1
|
export function participantIdentity(name) {
|
|
4
2
|
return `@${name}`;
|
|
5
3
|
}
|
|
@@ -38,32 +36,3 @@ export function firstHarnessSession(env = process.env) {
|
|
|
38
36
|
}
|
|
39
37
|
return undefined;
|
|
40
38
|
}
|
|
41
|
-
export function automaticParticipant(provider, sessionId, env) {
|
|
42
|
-
const configured = env.SQUARE_PARTICIPANT_NAME?.trim();
|
|
43
|
-
if (configured) {
|
|
44
|
-
validateName(configured);
|
|
45
|
-
return configured;
|
|
46
|
-
}
|
|
47
|
-
const digest = createHash('sha256').update(sessionId, 'utf8').digest('hex').slice(0, 12);
|
|
48
|
-
return `${provider}-${digest}`;
|
|
49
|
-
}
|
|
50
|
-
/** Compute the current harness participant without reading a Square or registry artifact. */
|
|
51
|
-
export function squareAssignedParticipantName(env = process.env) {
|
|
52
|
-
const configured = env.SQUARE_PARTICIPANT_NAME?.trim();
|
|
53
|
-
if (configured) {
|
|
54
|
-
validateName(configured);
|
|
55
|
-
return configured;
|
|
56
|
-
}
|
|
57
|
-
// Every native provider contributes its own name without deduping session ids first: equal ids
|
|
58
|
-
// in different providers are different coordinates and must stay ambiguous.
|
|
59
|
-
const names = new Set();
|
|
60
|
-
for (const source of harnessSessionSources) {
|
|
61
|
-
if (source.provider === undefined)
|
|
62
|
-
continue;
|
|
63
|
-
const sessionId = env[source.variable]?.trim();
|
|
64
|
-
if (!sessionId)
|
|
65
|
-
continue;
|
|
66
|
-
names.add(automaticParticipant(source.provider, sessionId, env));
|
|
67
|
-
}
|
|
68
|
-
return names.size === 1 ? [...names][0] : undefined;
|
|
69
|
-
}
|
package/dist/paseo-delivery.d.ts
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { WakeRequest, WakeOutcome, WakeTransportPort } from './ports.js';
|
|
2
2
|
import { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
3
3
|
import { sendPaseoWake } from './wake-sink.js';
|
|
4
|
-
export interface
|
|
4
|
+
export interface PaseoWakeTransportOptions {
|
|
5
5
|
discover?: typeof discoverPaseoAgents;
|
|
6
6
|
waitForBoundary?: typeof waitForPaseoWakeBoundary;
|
|
7
7
|
sendWake?: typeof sendPaseoWake;
|
|
8
8
|
}
|
|
9
|
-
export declare class
|
|
9
|
+
export declare class PaseoWakeTransport implements WakeTransportPort {
|
|
10
10
|
private readonly opts;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
dispatch(address: Readonly<Record<string, string>>, payload: string, beforeSend: () => Promise<boolean>, timeoutMs?: number, context?: WakeDispatchContext): Promise<WakeAdapterResult>;
|
|
11
|
+
constructor(opts?: PaseoWakeTransportOptions);
|
|
12
|
+
attempt(request: WakeRequest, timeoutMs: number, beforeSend: () => Promise<boolean>): Promise<WakeOutcome>;
|
|
14
13
|
}
|
package/dist/paseo-delivery.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { wakePreview } from './delivery.js';
|
|
1
2
|
import { DeliveryError } from './packages/agent-delivery/src/index.js';
|
|
2
3
|
import { resolvePaseoDaemon } from './packages/agent-delivery/src/paseo-native.js';
|
|
3
4
|
import { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
|
@@ -14,13 +15,13 @@ function diagnostic(phase, address, code) {
|
|
|
14
15
|
passwordPresent: Boolean(process.env.PASEO_PASSWORD),
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
|
-
export class
|
|
18
|
+
export class PaseoWakeTransport {
|
|
18
19
|
opts;
|
|
19
|
-
kind = 'paseo';
|
|
20
20
|
constructor(opts = {}) {
|
|
21
21
|
this.opts = opts;
|
|
22
22
|
}
|
|
23
|
-
async
|
|
23
|
+
async attempt(request, timeoutMs, beforeSend) {
|
|
24
|
+
const address = request.route.address;
|
|
24
25
|
const deadline = Date.now() + timeoutMs;
|
|
25
26
|
const remainingMs = () => Math.max(0, deadline - Date.now());
|
|
26
27
|
const budgetUnavailable = () => ({
|
|
@@ -41,6 +42,10 @@ export class PaseoAdapter {
|
|
|
41
42
|
diagnostic: diagnostic('selection', address, 'invalid_address'),
|
|
42
43
|
};
|
|
43
44
|
}
|
|
45
|
+
const payload = request.artifact === undefined ? undefined
|
|
46
|
+
: (await request.artifact.read((facts) => wakePreview(facts, request))).value;
|
|
47
|
+
if (payload === undefined)
|
|
48
|
+
return { outcome: 'not-capable', diagnostic: 'No pending Square activity to preview.' };
|
|
44
49
|
let remaining = remainingMs();
|
|
45
50
|
if (remaining === 0)
|
|
46
51
|
return budgetUnavailable();
|
|
@@ -84,7 +89,7 @@ export class PaseoAdapter {
|
|
|
84
89
|
};
|
|
85
90
|
}
|
|
86
91
|
if (!(await beforeSend()))
|
|
87
|
-
return { outcome: '
|
|
92
|
+
return { outcome: 'not-capable' };
|
|
88
93
|
remaining = remainingMs();
|
|
89
94
|
if (remaining === 0)
|
|
90
95
|
return budgetUnavailable();
|
|
@@ -92,10 +97,10 @@ export class PaseoAdapter {
|
|
|
92
97
|
await (this.opts.sendWake ?? sendPaseoWake)({
|
|
93
98
|
agentId,
|
|
94
99
|
prompt: payload,
|
|
95
|
-
location:
|
|
96
|
-
participant:
|
|
97
|
-
activity:
|
|
98
|
-
...(
|
|
100
|
+
location: request.location,
|
|
101
|
+
participant: request.participant,
|
|
102
|
+
activity: request.activity,
|
|
103
|
+
...(request.attemptN === undefined ? {} : { attemptN: request.attemptN }),
|
|
99
104
|
}, { timeoutMs: remaining });
|
|
100
105
|
return { outcome: 'accepted' };
|
|
101
106
|
}
|
package/dist/paseo.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Optional Paseo integration. Importing this entry requires the Paseo peer dependencies. */
|
|
2
|
-
export {
|
|
2
|
+
export { PaseoWakeTransport } from './paseo-delivery.js';
|
|
3
3
|
export { paseoWakeMessageId, sendPaseoWake } from './wake-sink.js';
|
|
4
4
|
export type { PaseoWakeRequest } from './wake-sink.js';
|
|
5
5
|
export { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|
package/dist/paseo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
/** Optional Paseo integration. Importing this entry requires the Paseo peer dependencies. */
|
|
2
|
-
export {
|
|
2
|
+
export { PaseoWakeTransport } from './paseo-delivery.js';
|
|
3
3
|
export { paseoWakeMessageId, sendPaseoWake } from './wake-sink.js';
|
|
4
4
|
export { discoverPaseoAgents, waitForPaseoWakeBoundary } from './paseo-state.js';
|