@astrosheep/square 0.3.106 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/activity-feed.js +1 -1
- package/dist/artifact-store.d.ts +41 -0
- package/dist/artifact-store.js +272 -0
- package/dist/artifact.d.ts +6 -12
- package/dist/artifact.js +43 -344
- package/dist/attention-presentation.d.ts +13 -7
- package/dist/attention-presentation.js +29 -68
- package/dist/boundary-presentation.d.ts +3 -16
- package/dist/boundary-presentation.js +29 -109
- package/dist/card-presentation.d.ts +1 -0
- package/dist/card-presentation.js +2 -0
- package/dist/catch-decisions.d.ts +2 -2
- package/dist/catch-decisions.js +7 -3
- package/dist/catch-selection.d.ts +8 -0
- package/dist/catch-selection.js +5 -0
- package/dist/claude-delivery.d.ts +14 -12
- package/dist/claude-delivery.js +42 -142
- package/dist/claude-mcp-context.js +2 -2
- package/dist/claude-mod.js +28 -140
- package/dist/claude-transport.d.ts +5 -0
- package/dist/claude-transport.js +34 -0
- package/dist/cli/context.d.ts +2 -2
- package/dist/cli/context.js +7 -10
- package/dist/cli/maintenance-commands.d.ts +0 -4
- package/dist/cli/maintenance-commands.js +2 -29
- package/dist/cli/observation-commands.d.ts +2 -0
- package/dist/cli/observation-commands.js +12 -2
- package/dist/cli/program.js +1 -1
- package/dist/cli/registry.js +4 -3
- package/dist/codex-address.d.ts +2 -2
- package/dist/codex-boundary-state.d.ts +1 -5
- package/dist/codex-boundary-state.js +0 -4
- package/dist/codex-hook.d.ts +7 -10
- package/dist/codex-hook.js +69 -33
- package/dist/codex-queue.d.ts +10 -11
- package/dist/codex-queue.js +32 -34
- package/dist/codex-watch.d.ts +2 -0
- package/dist/codex-watch.js +100 -0
- package/dist/decisions.js +3 -3
- package/dist/delivery-deferral.d.ts +1 -19
- package/dist/delivery-deferral.js +1 -29
- package/dist/delivery-frame.d.ts +7 -0
- package/dist/delivery-frame.js +11 -0
- package/dist/delivery-ledger-sqlite.d.ts +97 -0
- package/dist/delivery-ledger-sqlite.js +496 -0
- package/dist/delivery-ledger.d.ts +196 -0
- package/dist/delivery-ledger.js +268 -0
- package/dist/delivery-lifetime.d.ts +6 -0
- package/dist/delivery-lifetime.js +45 -0
- package/dist/harness-links.js +61 -7
- package/dist/harness.js +12 -17
- package/dist/help.js +3 -6
- package/dist/http-delivery.d.ts +5 -9
- package/dist/http-delivery.js +20 -79
- package/dist/inbox.d.ts +6 -57
- package/dist/inbox.js +24 -380
- package/dist/index.d.ts +7 -4
- package/dist/index.js +5 -2
- package/dist/mcp.d.ts +2 -1
- package/dist/mcp.js +40 -70
- package/dist/message.d.ts +7 -0
- package/dist/message.js +23 -0
- package/dist/model.d.ts +15 -91
- package/dist/model.js +2 -140
- package/dist/neutral.d.ts +72 -0
- package/dist/neutral.js +27 -0
- package/dist/notifications.d.ts +24 -26
- package/dist/notifications.js +39 -143
- package/dist/operation-control.d.ts +4 -0
- package/dist/operation-control.js +20 -0
- package/dist/operation-presentation.d.ts +1 -2
- package/dist/operation-presentation.js +1 -7
- package/dist/owner.d.ts +2 -2
- package/dist/owner.js +1 -1
- package/dist/packages/agent-delivery/src/claude-native.d.ts +2 -0
- package/dist/packages/agent-delivery/src/claude-native.js +5 -0
- package/dist/packages/agent-delivery/src/codex-boundary.d.ts +11 -6
- package/dist/packages/agent-delivery/src/codex-boundary.js +31 -40
- package/dist/packages/agent-delivery/src/codex-hook.d.ts +17 -12
- package/dist/packages/agent-delivery/src/codex-hook.js +26 -39
- package/dist/packages/agent-delivery/src/codex.d.ts +3 -0
- package/dist/packages/agent-delivery/src/codex.js +41 -4
- package/dist/packages/agent-delivery/src/index.d.ts +3 -1
- package/dist/packages/agent-delivery/src/index.js +1 -1
- package/dist/packages/agent-delivery/src/paseo.js +11 -2
- package/dist/packages/agent-delivery/src/types.d.ts +1 -0
- package/dist/paseo-delivery.d.ts +5 -5
- package/dist/paseo-delivery.js +19 -99
- package/dist/paseo.d.ts +1 -1
- package/dist/paseo.js +1 -1
- package/dist/plugins/opencode/index.d.ts +5 -3
- package/dist/plugins/opencode/index.js +99 -21
- package/dist/plugins/opencode-shared/delivery.d.ts +23 -0
- package/dist/plugins/opencode-shared/delivery.js +109 -0
- package/dist/plugins/opencode-v1/index.d.ts +28 -0
- package/dist/plugins/opencode-v1/index.js +41 -0
- package/dist/plugins/opencode-v1/runtime.d.ts +56 -0
- package/dist/plugins/opencode-v1/runtime.js +152 -0
- package/dist/plugins/opencode-v1/transport.d.ts +13 -0
- package/dist/plugins/opencode-v1/transport.js +50 -0
- package/dist/plugins/paseo/shared/card-presentation.d.ts +10 -0
- package/dist/plugins/paseo/shared/card-presentation.js +7 -0
- package/dist/ports.d.ts +33 -214
- package/dist/presentation.d.ts +5 -5
- package/dist/presentation.js +1 -0
- package/dist/runtime.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-lifecycle.d.ts +8 -7
- package/dist/session-lifecycle.js +40 -42
- package/dist/sqlite-framing.d.ts +8 -0
- package/dist/sqlite-framing.js +31 -0
- package/dist/sqlite-square.d.ts +16 -26
- package/dist/sqlite-square.js +199 -262
- package/dist/sqlite-values.d.ts +21 -0
- package/dist/sqlite-values.js +78 -0
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +5 -8
- package/dist/square-core.d.ts +0 -1
- package/dist/square-domain.d.ts +12 -10
- package/dist/square-domain.js +105 -223
- package/dist/square-facade.d.ts +25 -76
- package/dist/square-location.d.ts +6 -1
- package/dist/square-location.js +1 -1
- package/dist/square-post.d.ts +53 -0
- package/dist/square-post.js +4 -0
- package/dist/square-posting.d.ts +13 -0
- package/dist/square-posting.js +174 -0
- package/dist/square-producer-sqlite.d.ts +11 -0
- package/dist/square-producer-sqlite.js +210 -0
- package/dist/square-receive.d.ts +2 -3
- package/dist/square-sqlite.d.ts +33 -42
- package/dist/square-sqlite.js +236 -768
- package/dist/square-tools.d.ts +8 -0
- package/dist/square-tools.js +39 -0
- package/dist/square-values.d.ts +27 -0
- package/dist/square-values.js +90 -0
- package/dist/views.d.ts +6 -6
- package/dist/views.js +14 -9
- package/dist/wake-sink.d.ts +4 -11
- package/dist/wake-sink.js +8 -32
- package/dist/wake-transports.d.ts +4 -0
- package/dist/wake-transports.js +11 -0
- package/examples/symmetric-domains.mjs +29 -249
- package/guides/change-waits.md +13 -53
- package/guides/claude-native.md +19 -172
- package/guides/codex-delivery.md +55 -78
- package/guides/delivery-primitives.md +48 -207
- package/guides/operation-cancellation.md +2 -5
- package/guides/participant-ownership.md +25 -89
- package/guides/pi-native-delivery.md +19 -56
- package/guides/pi-tools.md +6 -8
- package/guides/row-runtime-delivery-evidence.md +2 -0
- package/guides/row-storage-design.md +19 -44
- package/guides/square-api.md +113 -538
- package/package.json +8 -8
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/hooks.json +1 -1
- package/plugins/claude/{hooks/register.js → mods/square.js} +4 -7
- package/plugins/claude/types.d.ts +1 -1
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/codex/hooks/hooks.json +11 -23
- package/plugins/opencode/index.ts +91 -23
- package/plugins/opencode-shared/delivery.ts +91 -0
- package/plugins/opencode-v1/index.ts +36 -0
- package/plugins/opencode-v1/runtime.ts +134 -0
- package/plugins/opencode-v1/transport.ts +41 -0
- package/plugins/paseo/OVERVIEW.md +5 -5
- package/plugins/paseo/README.md +7 -6
- package/plugins/paseo/client/markdown.tsx +5 -5
- package/plugins/paseo/client/square-message.tsx +28 -24
- package/plugins/paseo/client/transform.ts +8 -5
- package/plugins/paseo/shared/card-presentation.ts +16 -0
- package/plugins/paseo/shared/message.ts +6 -11
- package/plugins/pi/square-pi.js +167 -451
- package/dist/channel.d.ts +0 -74
- package/dist/channel.js +0 -92
- package/dist/claude-delivery-status.d.ts +0 -13
- package/dist/claude-delivery-status.js +0 -46
- package/dist/cmd/notify-once.d.ts +0 -2
- package/dist/cmd/notify-once.js +0 -29
- package/dist/delivery-attempts.d.ts +0 -52
- package/dist/delivery-attempts.js +0 -73
- package/dist/delivery-effects.d.ts +0 -139
- package/dist/delivery-effects.js +0 -163
- package/dist/delivery-health.d.ts +0 -51
- package/dist/delivery-health.js +0 -173
- package/dist/delivery-operations.d.ts +0 -9
- package/dist/delivery-operations.js +0 -168
- package/dist/delivery-primitives.d.ts +0 -5
- package/dist/delivery-primitives.js +0 -3
- package/dist/delivery.d.ts +0 -45
- package/dist/delivery.js +0 -106
- package/dist/plugins/opencode/delivery.d.ts +0 -19
- package/dist/plugins/opencode/delivery.js +0 -238
- package/dist/presentation-operations.d.ts +0 -18
- package/dist/presentation-operations.js +0 -86
- package/dist/square-index.d.ts +0 -16
- package/dist/square-index.js +0 -106
- package/dist/square-legacy-framing.d.ts +0 -11
- package/dist/square-legacy-framing.js +0 -64
- package/dist/square-migration-host-ledger.d.ts +0 -26
- package/dist/square-migration-host-ledger.js +0 -169
- package/dist/square-migration.d.ts +0 -30
- package/dist/square-migration.js +0 -599
- package/guides/migration.md +0 -156
- package/plugins/opencode/delivery.ts +0 -211
package/dist/channel.d.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { type HarnessSessionChannel } from './participant-identity.js';
|
|
2
|
-
import type { SquareResourceOwner, WakeTransportPort } from './ports.js';
|
|
3
|
-
import type { ActivityId, ChannelSendInput, ChannelSendResult, DeliveryDeferral, HeldSeat, MetadataMatch, OperationControl, Owner, Participant, WakeAddress, PendingOptions, PendingResult, AckResult } from './square-facade.js';
|
|
4
|
-
export { harnessOwner, decodeHarnessOwner, localUserOwner } from './owner.js';
|
|
5
|
-
export type { ActivityDelivery, ActivityMetadata, ActivityQuery, ActivitySearch, ActivityCursor, ChannelTruncate, PerceivedActivity, PendingOptions, PendingResult, AckResult } from './square-facade.js';
|
|
6
|
-
export type { ActivityId, ChannelSendInput, ChannelSendResult, DeliveryDeferral, HeldSeat, MetadataMatch, OperationControl, Owner, WakeAddress, SquareResourceOwner, WakeTransportPort, HarnessSessionChannel };
|
|
7
|
-
export interface ResolvedHarnessSession {
|
|
8
|
-
readonly channel: HarnessSessionChannel;
|
|
9
|
-
readonly sessionId: string;
|
|
10
|
-
readonly agentId?: string;
|
|
11
|
-
readonly owner: Owner;
|
|
12
|
-
readonly wakeAddress?: WakeAddress;
|
|
13
|
-
}
|
|
14
|
-
export declare function resolveHarnessSession(env?: NodeJS.ProcessEnv): ResolvedHarnessSession | undefined;
|
|
15
|
-
export interface ChannelOpenInput {
|
|
16
|
-
readonly path: string;
|
|
17
|
-
readonly cwd?: string;
|
|
18
|
-
readonly env?: NodeJS.ProcessEnv;
|
|
19
|
-
readonly clock?: () => number;
|
|
20
|
-
readonly wakeTransport?: WakeTransportPort | false;
|
|
21
|
-
readonly resources?: SquareResourceOwner;
|
|
22
|
-
}
|
|
23
|
-
export interface ChannelCreateInput extends ChannelOpenInput {
|
|
24
|
-
readonly force?: boolean;
|
|
25
|
-
readonly description?: string;
|
|
26
|
-
}
|
|
27
|
-
type EndpointOptions = {
|
|
28
|
-
readonly owner: Owner;
|
|
29
|
-
readonly wakeAddress?: WakeAddress;
|
|
30
|
-
};
|
|
31
|
-
type EndpointIdentity = {
|
|
32
|
-
readonly owner: Owner;
|
|
33
|
-
readonly generation: ActivityId;
|
|
34
|
-
};
|
|
35
|
-
/** A scoped direct-messaging vocabulary over the shared Square resource. */
|
|
36
|
-
export declare class Channel {
|
|
37
|
-
private readonly square;
|
|
38
|
-
private constructor();
|
|
39
|
-
get location(): string;
|
|
40
|
-
static open(input: ChannelOpenInput, control?: OperationControl): Promise<Channel>;
|
|
41
|
-
static create(input: ChannelCreateInput, control?: OperationControl): Promise<Channel>;
|
|
42
|
-
static inMemory(input?: Omit<ChannelCreateInput, 'path' | 'resources' | 'force'>): Channel;
|
|
43
|
-
attach(name: string, options: EndpointOptions & {
|
|
44
|
-
readonly takeover?: boolean;
|
|
45
|
-
}, control?: OperationControl): Promise<ChannelEndpoint>;
|
|
46
|
-
reattach(name: string, options: EndpointOptions, control?: OperationControl): Promise<ChannelEndpoint | null>;
|
|
47
|
-
endpoint(name: string, options: {
|
|
48
|
-
readonly owner: Owner;
|
|
49
|
-
}): Promise<ChannelEndpoint>;
|
|
50
|
-
endpointsOf(owner: Owner): Promise<readonly HeldSeat[]>;
|
|
51
|
-
detach(name: string, identity: EndpointIdentity): Promise<true | null>;
|
|
52
|
-
remove(name: string, identity: EndpointIdentity): Promise<boolean>;
|
|
53
|
-
cancelDeliveries(name: string, identity: EndpointIdentity): Promise<boolean>;
|
|
54
|
-
send(input: ChannelSendInput, control?: OperationControl): Promise<ChannelSendResult>;
|
|
55
|
-
close(): Promise<void>;
|
|
56
|
-
}
|
|
57
|
-
/** Captures one recipient generation through its existing Participant handle. */
|
|
58
|
-
export declare class ChannelEndpoint {
|
|
59
|
-
private readonly channel;
|
|
60
|
-
private readonly participant;
|
|
61
|
-
constructor(channel: Channel, participant: Participant);
|
|
62
|
-
get name(): string;
|
|
63
|
-
get generation(): ActivityId;
|
|
64
|
-
pending(options?: PendingOptions, control?: OperationControl): Promise<PendingResult>;
|
|
65
|
-
ack(ids: readonly ActivityId[], control?: OperationControl): Promise<AckResult>;
|
|
66
|
-
leave(control?: OperationControl): Promise<void>;
|
|
67
|
-
deferDelivery(input: Readonly<{
|
|
68
|
-
match: MetadataMatch;
|
|
69
|
-
durationMs: number;
|
|
70
|
-
}>, control?: OperationControl): Promise<DeliveryDeferral>;
|
|
71
|
-
renewDeliveryDeferral(id: string, durationMs: number, control?: OperationControl): Promise<DeliveryDeferral | null>;
|
|
72
|
-
releaseDeliveryDeferral(id: string, control?: OperationControl): Promise<boolean>;
|
|
73
|
-
send(input: Omit<ChannelSendInput, 'from'>, control?: OperationControl): Promise<ChannelSendResult>;
|
|
74
|
-
}
|
package/dist/channel.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { codexWakeAddress } from './codex-address.js';
|
|
2
|
-
import { SquareError } from './model.js';
|
|
3
|
-
import { harnessOwner } from './owner.js';
|
|
4
|
-
import { harnessSessionSources } from './participant-identity.js';
|
|
5
|
-
import { Square } from './square-api.js';
|
|
6
|
-
import { squareLocation } from './square-location.js';
|
|
7
|
-
export { harnessOwner, decodeHarnessOwner, localUserOwner } from './owner.js';
|
|
8
|
-
export function resolveHarnessSession(env = process.env) {
|
|
9
|
-
for (const { variable, channel } of harnessSessionSources) {
|
|
10
|
-
const sessionId = env[variable]?.trim();
|
|
11
|
-
if (!sessionId)
|
|
12
|
-
continue;
|
|
13
|
-
const agentId = channel === 'claude-code' && env.CLAUDE_CODE_CHILD_SESSION?.trim() === '1'
|
|
14
|
-
? env.CLAUDE_CODE_AGENT_ID?.trim() || undefined : undefined;
|
|
15
|
-
const wakeAddress = channel === 'codex' ? codexWakeAddress(sessionId, env)
|
|
16
|
-
: channel === 'paseo' ? { kind: 'paseo', address: { agentId: sessionId } } : undefined;
|
|
17
|
-
return { channel, sessionId, ...(agentId === undefined ? {} : { agentId }),
|
|
18
|
-
owner: harnessOwner({ channel, session: sessionId, ...(agentId === undefined ? {} : { agent: agentId }) }),
|
|
19
|
-
...(wakeAddress === undefined ? {} : { wakeAddress }) };
|
|
20
|
-
}
|
|
21
|
-
return undefined;
|
|
22
|
-
}
|
|
23
|
-
function explicitLocation(input) {
|
|
24
|
-
if (typeof input?.path !== 'string' || input.path.trim() === '')
|
|
25
|
-
throw new SquareError('invalid_args', 'Channel path is required.');
|
|
26
|
-
return squareLocation(input);
|
|
27
|
-
}
|
|
28
|
-
/** A scoped direct-messaging vocabulary over the shared Square resource. */
|
|
29
|
-
export class Channel {
|
|
30
|
-
square;
|
|
31
|
-
constructor(square) {
|
|
32
|
-
this.square = square;
|
|
33
|
-
}
|
|
34
|
-
get location() { return this.square.location; }
|
|
35
|
-
static async open(input, control) {
|
|
36
|
-
const path = explicitLocation(input);
|
|
37
|
-
return new Channel(await Square.at({ ...input, path }, control));
|
|
38
|
-
}
|
|
39
|
-
static async create(input, control) {
|
|
40
|
-
const path = explicitLocation(input);
|
|
41
|
-
return new Channel(await Square.build({ ...input, path, hardCap: null, markdown: input.description ?? '# Channel\n' }, control));
|
|
42
|
-
}
|
|
43
|
-
static inMemory(input = {}) {
|
|
44
|
-
return new Channel(Square.inMemory({ ...input, hardCap: null, markdown: input.description ?? '# Channel\n' }));
|
|
45
|
-
}
|
|
46
|
-
async attach(name, options, control) {
|
|
47
|
-
return new ChannelEndpoint(this, (await this.square.join(name, options, control)).participant);
|
|
48
|
-
}
|
|
49
|
-
async reattach(name, options, control) {
|
|
50
|
-
const participant = await this.square.reattach(name, options, control);
|
|
51
|
-
return participant === null ? null : new ChannelEndpoint(this, participant);
|
|
52
|
-
}
|
|
53
|
-
async endpoint(name, options) {
|
|
54
|
-
return new ChannelEndpoint(this, await this.square.participant(name, options));
|
|
55
|
-
}
|
|
56
|
-
endpointsOf(owner) { return this.square.seatsOf(owner); }
|
|
57
|
-
detach(name, identity) { return this.square.detach(name, identity); }
|
|
58
|
-
async remove(name, identity) { return await this.square.endHeld(name, identity) !== null; }
|
|
59
|
-
cancelDeliveries(name, identity) { return this.square.cancelDeliveries(name, identity); }
|
|
60
|
-
send(input, control) { return this.square.send(input, control); }
|
|
61
|
-
close() { return this.square.close(); }
|
|
62
|
-
}
|
|
63
|
-
/** Captures one recipient generation through its existing Participant handle. */
|
|
64
|
-
export class ChannelEndpoint {
|
|
65
|
-
channel;
|
|
66
|
-
participant;
|
|
67
|
-
constructor(channel, participant) {
|
|
68
|
-
this.channel = channel;
|
|
69
|
-
this.participant = participant;
|
|
70
|
-
}
|
|
71
|
-
get name() { return this.participant.name; }
|
|
72
|
-
get generation() { return this.participant.generation; }
|
|
73
|
-
pending(options, control) {
|
|
74
|
-
return this.participant.pending(options, control);
|
|
75
|
-
}
|
|
76
|
-
ack(ids, control) {
|
|
77
|
-
return this.participant.ack(ids, control);
|
|
78
|
-
}
|
|
79
|
-
async leave(control) { await this.participant.done(undefined, {}, control); }
|
|
80
|
-
deferDelivery(input, control) {
|
|
81
|
-
return this.participant.deferDelivery(input, control);
|
|
82
|
-
}
|
|
83
|
-
renewDeliveryDeferral(id, durationMs, control) {
|
|
84
|
-
return this.participant.renewDeliveryDeferral(id, durationMs, control);
|
|
85
|
-
}
|
|
86
|
-
releaseDeliveryDeferral(id, control) {
|
|
87
|
-
return this.participant.releaseDeliveryDeferral(id, control);
|
|
88
|
-
}
|
|
89
|
-
send(input, control) {
|
|
90
|
-
return this.channel.send({ ...input, from: this.name }, control);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export interface ClaudeDeliveryObservation {
|
|
2
|
-
readonly eventId: string;
|
|
3
|
-
readonly messageId: string;
|
|
4
|
-
readonly state: 'held' | 'released' | 'dropped';
|
|
5
|
-
readonly reason?: string;
|
|
6
|
-
readonly observedAt: number;
|
|
7
|
-
}
|
|
8
|
-
export interface ClaudeDeliveryStatus extends ClaudeDeliveryObservation {
|
|
9
|
-
readonly provider: 'claude';
|
|
10
|
-
readonly sessionId: string;
|
|
11
|
-
}
|
|
12
|
-
/** This receiver-owned observation is not a model tool and grants no delivery authority. */
|
|
13
|
-
export declare function recordClaudeDeliveryStatus(input: ClaudeDeliveryStatus, env?: NodeJS.ProcessEnv): Promise<boolean>;
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { createArtifactPort } from './artifact.js';
|
|
2
|
-
import { decodeHarnessOwner } from './owner.js';
|
|
3
|
-
import { indexedSquareEntries } from './square-index.js';
|
|
4
|
-
const holdReasons = new Set(['explicit-setting', 'managed-setting', 'repo-setting', 'invalid-setting', 'bypass-default', 'mode-unknown', 'mode-mismatch', 'no-mode-asserted']);
|
|
5
|
-
const dropReasons = new Set(['expired', 'refused', 'dropped', 'discarded']);
|
|
6
|
-
const uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
7
|
-
/** This receiver-owned observation is not a model tool and grants no delivery authority. */
|
|
8
|
-
export async function recordClaudeDeliveryStatus(input, env = process.env) {
|
|
9
|
-
if (!input || input.provider !== 'claude' || typeof input.sessionId !== 'string' || !input.sessionId
|
|
10
|
-
|| typeof input.messageId !== 'string' || !uuid.test(input.messageId)
|
|
11
|
-
|| typeof input.eventId !== 'string' || !uuid.test(input.eventId)
|
|
12
|
-
|| !Number.isFinite(input.observedAt) || input.observedAt < 0
|
|
13
|
-
|| !['held', 'released', 'dropped'].includes(input.state)
|
|
14
|
-
|| (input.state === 'held' ? !holdReasons.has(input.reason ?? '')
|
|
15
|
-
: input.state === 'dropped' ? !dropReasons.has(input.reason ?? '') : input.reason !== undefined))
|
|
16
|
-
return false;
|
|
17
|
-
const paths = new Set((await indexedSquareEntries({}, env)).filter(entry => {
|
|
18
|
-
const coordinate = decodeHarnessOwner(entry.owner);
|
|
19
|
-
return coordinate?.channel === 'claude-code' && coordinate.session === input.sessionId;
|
|
20
|
-
}).map(entry => entry.location));
|
|
21
|
-
for (const location of paths) {
|
|
22
|
-
const artifact = createArtifactPort(location);
|
|
23
|
-
try {
|
|
24
|
-
const { value: match } = await artifact.read((facts) => facts.roster().flatMap((participant) => {
|
|
25
|
-
const seat = facts.seat(participant.name);
|
|
26
|
-
if (seat === undefined || seat.attachment !== 'attached' || seat.wakeAddress?.kind !== 'claude-native'
|
|
27
|
-
|| seat.wakeAddress.address.sessionId !== input.sessionId)
|
|
28
|
-
return [];
|
|
29
|
-
const evidence = facts.deliveryEvidence(seat.participant, seat.generation).find((row) => row.correlation?.harness === 'claude' && row.correlation.messageId === input.messageId && row.claimToken !== undefined);
|
|
30
|
-
return evidence === undefined ? [] : [{ seat, evidence }];
|
|
31
|
-
}));
|
|
32
|
-
if (match.length === 0)
|
|
33
|
-
continue;
|
|
34
|
-
const { seat, evidence } = match[0];
|
|
35
|
-
const ref = { participant: seat.participant, owner: seat.owner, generation: seat.generation };
|
|
36
|
-
return (await artifact.transactAs({ kind: 'participant', seat: ref }, (facts) => facts.observeNativeDelivery({ seat: ref, claimToken: evidence.claimToken, observation: {
|
|
37
|
-
eventId: input.eventId, messageId: input.messageId, state: input.state,
|
|
38
|
-
...(input.reason === undefined ? {} : { reason: input.reason }), observedAt: input.observedAt,
|
|
39
|
-
} }))).value;
|
|
40
|
-
}
|
|
41
|
-
finally {
|
|
42
|
-
await artifact.close();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return false;
|
|
46
|
-
}
|
package/dist/cmd/notify-once.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { resolve } from 'node:path';
|
|
3
|
-
import { setTimeout as sleep } from 'node:timers/promises';
|
|
4
|
-
import { processActNotificationsOnce, wakeGraceMs } from '../notifications.js';
|
|
5
|
-
function args(argv) {
|
|
6
|
-
let squarePath;
|
|
7
|
-
let actIndex;
|
|
8
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
9
|
-
if (argv[index] === '--location' && argv[index + 1] !== undefined)
|
|
10
|
-
squarePath = resolve(argv[++index]);
|
|
11
|
-
else if (argv[index] === '--act-index' && /^\d+$/.test(argv[index + 1] ?? ''))
|
|
12
|
-
actIndex = Number(argv[++index]);
|
|
13
|
-
else
|
|
14
|
-
throw new Error(`Unknown notify-once argument: ${argv[index]}`);
|
|
15
|
-
}
|
|
16
|
-
if (squarePath === undefined || actIndex === undefined)
|
|
17
|
-
throw new Error('notify-once requires --location and --act-index.');
|
|
18
|
-
return { squarePath, actIndex };
|
|
19
|
-
}
|
|
20
|
-
async function main() {
|
|
21
|
-
if (process.env.SQUARE_DISABLE_PASEO_WAKE === '1')
|
|
22
|
-
return;
|
|
23
|
-
const { squarePath, actIndex } = args(process.argv.slice(2));
|
|
24
|
-
await sleep(wakeGraceMs());
|
|
25
|
-
await processActNotificationsOnce(squarePath, actIndex);
|
|
26
|
-
}
|
|
27
|
-
main().catch(() => {
|
|
28
|
-
process.exitCode = 0;
|
|
29
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export type DeliveryPurpose = 'dispatch' | 'presentation';
|
|
2
|
-
export type AttemptOutcome = 'dispatching' | 'accepted' | 'failed' | 'unknown' | 'released' | 'presented' | 'clipped';
|
|
3
|
-
export interface Attempt<D> {
|
|
4
|
-
readonly purpose: DeliveryPurpose;
|
|
5
|
-
readonly token: string;
|
|
6
|
-
readonly ordinal: number;
|
|
7
|
-
readonly outcome: AttemptOutcome;
|
|
8
|
-
readonly at: number;
|
|
9
|
-
readonly expiresAt?: number;
|
|
10
|
-
readonly data: D;
|
|
11
|
-
}
|
|
12
|
-
/** One item/recipient/authority/purpose series, bound inside the caller's transaction.
|
|
13
|
-
* The caller owns token uniqueness, isolation and rollback; replacements retain coordinates.
|
|
14
|
-
*/
|
|
15
|
-
export interface AttemptRows<D> {
|
|
16
|
-
list(): readonly Attempt<D>[];
|
|
17
|
-
byToken(token: string): Attempt<D> | undefined;
|
|
18
|
-
insert(attempt: Attempt<D>): void;
|
|
19
|
-
replace(attempt: Attempt<D>): void;
|
|
20
|
-
}
|
|
21
|
-
export type AttemptClaim<D> = {
|
|
22
|
-
readonly status: 'acquired';
|
|
23
|
-
readonly token: string;
|
|
24
|
-
readonly ordinal: number;
|
|
25
|
-
} | {
|
|
26
|
-
readonly status: 'busy' | 'terminal';
|
|
27
|
-
readonly evidence: Attempt<D>;
|
|
28
|
-
readonly interrupted?: true;
|
|
29
|
-
};
|
|
30
|
-
export declare function claimAttempt<D>(rows: AttemptRows<D>, input: {
|
|
31
|
-
purpose: DeliveryPurpose;
|
|
32
|
-
token: string;
|
|
33
|
-
at: number;
|
|
34
|
-
leaseMs: number;
|
|
35
|
-
data: D;
|
|
36
|
-
}): AttemptClaim<D>;
|
|
37
|
-
export declare function prepareAttempt<D>(rows: AttemptRows<D>, input: {
|
|
38
|
-
token: string;
|
|
39
|
-
data: D;
|
|
40
|
-
}): boolean;
|
|
41
|
-
export declare function settleAttempt<D>(rows: AttemptRows<D>, input: {
|
|
42
|
-
token: string;
|
|
43
|
-
outcome: Exclude<AttemptOutcome, 'dispatching'>;
|
|
44
|
-
at: number;
|
|
45
|
-
data: D;
|
|
46
|
-
}): boolean;
|
|
47
|
-
type Custody = Pick<Attempt<unknown>, 'purpose' | 'outcome' | 'expiresAt'>;
|
|
48
|
-
/** Presentation custody suppresses dispatch independently of dispatch acceptance. */
|
|
49
|
-
export declare function presentationBlocksDispatch(attempts: readonly Custody[], now: number): boolean;
|
|
50
|
-
/** An expired dispatch is uncertain, not permission for automatic replay. */
|
|
51
|
-
export declare function automaticDispatchEligible(attempts: readonly Custody[], now: number): boolean;
|
|
52
|
-
export {};
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
function finite(value) {
|
|
2
|
-
if (typeof value !== 'number' || !Number.isFinite(value))
|
|
3
|
-
throw new RangeError('time must be finite');
|
|
4
|
-
}
|
|
5
|
-
function token(value) {
|
|
6
|
-
if (typeof value !== 'string' || value.length === 0)
|
|
7
|
-
throw new TypeError('token must be nonempty');
|
|
8
|
-
}
|
|
9
|
-
export function claimAttempt(rows, input) {
|
|
10
|
-
if (input.purpose !== 'dispatch' && input.purpose !== 'presentation')
|
|
11
|
-
throw new TypeError('unsupported purpose');
|
|
12
|
-
token(input.token);
|
|
13
|
-
finite(input.at);
|
|
14
|
-
if (!Number.isSafeInteger(input.leaseMs) || input.leaseMs <= 0)
|
|
15
|
-
throw new RangeError('leaseMs must be a positive safe integer');
|
|
16
|
-
const expiresAt = input.at + input.leaseMs;
|
|
17
|
-
finite(expiresAt);
|
|
18
|
-
const attempts = rows.list();
|
|
19
|
-
const terminal = attempts.find(row => row.outcome === 'unknown'
|
|
20
|
-
|| row.outcome === (input.purpose === 'dispatch' ? 'accepted' : 'presented'));
|
|
21
|
-
if (terminal !== undefined)
|
|
22
|
-
return { status: 'terminal', evidence: terminal };
|
|
23
|
-
const dispatching = attempts.find(row => row.outcome === 'dispatching');
|
|
24
|
-
if (dispatching !== undefined) {
|
|
25
|
-
if (dispatching.expiresAt === undefined || dispatching.expiresAt > input.at)
|
|
26
|
-
return { status: 'busy', evidence: dispatching };
|
|
27
|
-
const { expiresAt: _expiry, ...previous } = dispatching;
|
|
28
|
-
const evidence = { ...previous, outcome: 'unknown', at: input.at };
|
|
29
|
-
rows.replace(evidence);
|
|
30
|
-
return { status: 'terminal', evidence, interrupted: true };
|
|
31
|
-
}
|
|
32
|
-
const ordinal = (attempts[0]?.ordinal ?? -1) + 1;
|
|
33
|
-
if (!Number.isSafeInteger(ordinal) || ordinal < 0)
|
|
34
|
-
throw new RangeError('attempt ordinal exhausted');
|
|
35
|
-
rows.insert({ purpose: input.purpose, token: input.token, ordinal, outcome: 'dispatching', at: input.at, expiresAt, data: input.data });
|
|
36
|
-
return { status: 'acquired', token: input.token, ordinal };
|
|
37
|
-
}
|
|
38
|
-
export function prepareAttempt(rows, input) {
|
|
39
|
-
token(input.token);
|
|
40
|
-
const previous = rows.byToken(input.token);
|
|
41
|
-
if (previous?.outcome !== 'dispatching')
|
|
42
|
-
return false;
|
|
43
|
-
rows.replace({ ...previous, data: input.data });
|
|
44
|
-
return true;
|
|
45
|
-
}
|
|
46
|
-
export function settleAttempt(rows, input) {
|
|
47
|
-
token(input.token);
|
|
48
|
-
finite(input.at);
|
|
49
|
-
if (!['accepted', 'failed', 'unknown', 'released', 'presented', 'clipped'].includes(input.outcome))
|
|
50
|
-
throw new TypeError('unsupported completion');
|
|
51
|
-
const previous = rows.byToken(input.token);
|
|
52
|
-
if (previous === undefined)
|
|
53
|
-
return false;
|
|
54
|
-
if (previous.outcome === 'accepted' && input.outcome === 'accepted')
|
|
55
|
-
return true;
|
|
56
|
-
if (previous.outcome !== 'dispatching' && !(previous.outcome === 'unknown' && input.outcome === 'accepted'))
|
|
57
|
-
return false;
|
|
58
|
-
const { expiresAt: _expiry, ...retained } = previous;
|
|
59
|
-
rows.replace({ ...retained, outcome: input.outcome, at: input.at, data: input.data });
|
|
60
|
-
return true;
|
|
61
|
-
}
|
|
62
|
-
/** Presentation custody suppresses dispatch independently of dispatch acceptance. */
|
|
63
|
-
export function presentationBlocksDispatch(attempts, now) {
|
|
64
|
-
finite(now);
|
|
65
|
-
return attempts.some(row => row.purpose === 'presentation'
|
|
66
|
-
&& (row.outcome === 'presented' || row.outcome === 'clipped' || row.outcome === 'unknown'
|
|
67
|
-
|| row.outcome === 'dispatching'));
|
|
68
|
-
}
|
|
69
|
-
/** An expired dispatch is uncertain, not permission for automatic replay. */
|
|
70
|
-
export function automaticDispatchEligible(attempts, now) {
|
|
71
|
-
return !presentationBlocksDispatch(attempts, now) && !attempts.some(row => row.purpose === 'dispatch'
|
|
72
|
-
&& (row.outcome === 'accepted' || row.outcome === 'unknown' || row.outcome === 'dispatching'));
|
|
73
|
-
}
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
export interface EffectClaim {
|
|
2
|
-
readonly token: string;
|
|
3
|
-
readonly ordinal: number;
|
|
4
|
-
}
|
|
5
|
-
/** Bound to one captured item/recipient/authority/purpose, not an encoded series key. */
|
|
6
|
-
export interface EffectPort<C> {
|
|
7
|
-
/** The caller's existing atomic claim operation. Undefined means no custody acquired. */
|
|
8
|
-
claim(signal?: AbortSignal): Promise<EffectClaim | undefined>;
|
|
9
|
-
/** Pre-effect policy only. Rejection means unverifiable/not current. */
|
|
10
|
-
current(signal?: AbortSignal): Promise<boolean>;
|
|
11
|
-
/**
|
|
12
|
-
* No request signal: persistence has its own bounded lifetime. For presentation,
|
|
13
|
-
* `presented` MUST complete the attempt and record ALL captured full-consumption
|
|
14
|
-
* receipts in ONE atomic transaction (rollback both on error). `clipped`, `failed`,
|
|
15
|
-
* `unknown` and `released` complete the attempt without full-consumption receipts.
|
|
16
|
-
* No post-effect currentness/deferral/cancellation veto; captured authority still fences.
|
|
17
|
-
*/
|
|
18
|
-
settle(claim: EffectClaim, completion: C): Promise<boolean>;
|
|
19
|
-
}
|
|
20
|
-
export type Persistence = {
|
|
21
|
-
readonly status: 'recorded';
|
|
22
|
-
} | {
|
|
23
|
-
readonly status: 'not-recorded';
|
|
24
|
-
} | {
|
|
25
|
-
readonly status: 'error';
|
|
26
|
-
readonly error: unknown;
|
|
27
|
-
};
|
|
28
|
-
export interface Settlement<C> {
|
|
29
|
-
readonly completion: C;
|
|
30
|
-
readonly persistence: Persistence;
|
|
31
|
-
}
|
|
32
|
-
export interface DispatchOutcome {
|
|
33
|
-
readonly outcome: 'accepted' | 'failed' | 'unknown' | 'not-capable';
|
|
34
|
-
readonly data?: unknown;
|
|
35
|
-
}
|
|
36
|
-
export type DispatchCompletion = {
|
|
37
|
-
readonly outcome: 'accepted' | 'failed' | 'unknown';
|
|
38
|
-
readonly reason: 'returned';
|
|
39
|
-
readonly data?: unknown;
|
|
40
|
-
} | {
|
|
41
|
-
readonly outcome: 'unknown';
|
|
42
|
-
readonly reason: 'threw';
|
|
43
|
-
readonly error: unknown;
|
|
44
|
-
} | {
|
|
45
|
-
readonly outcome: 'unknown';
|
|
46
|
-
readonly reason: 'timeout';
|
|
47
|
-
} | {
|
|
48
|
-
readonly outcome: 'released';
|
|
49
|
-
readonly reason: 'not-current';
|
|
50
|
-
readonly phase: 'initial' | 'final';
|
|
51
|
-
} | {
|
|
52
|
-
readonly outcome: 'released';
|
|
53
|
-
readonly reason: 'not-capable';
|
|
54
|
-
readonly data?: unknown;
|
|
55
|
-
} | {
|
|
56
|
-
readonly outcome: 'released';
|
|
57
|
-
readonly reason: 'cancelled';
|
|
58
|
-
};
|
|
59
|
-
export interface DispatchContext {
|
|
60
|
-
readonly claim: EffectClaim;
|
|
61
|
-
readonly timeoutMs: number;
|
|
62
|
-
readonly deadline: number;
|
|
63
|
-
readonly signal?: AbortSignal;
|
|
64
|
-
/** Policy only. Sender MUST recheck deadline/cancellation after this await before I/O. */
|
|
65
|
-
beforeSend(): Promise<boolean>;
|
|
66
|
-
}
|
|
67
|
-
export interface DispatchReport {
|
|
68
|
-
readonly observation: {
|
|
69
|
-
readonly kind: 'not-invoked';
|
|
70
|
-
} | {
|
|
71
|
-
readonly kind: 'returned';
|
|
72
|
-
readonly result: DispatchOutcome;
|
|
73
|
-
} | {
|
|
74
|
-
readonly kind: 'threw';
|
|
75
|
-
readonly error: unknown;
|
|
76
|
-
} | {
|
|
77
|
-
readonly kind: 'timeout';
|
|
78
|
-
};
|
|
79
|
-
readonly settlement?: Settlement<DispatchCompletion>;
|
|
80
|
-
}
|
|
81
|
-
/** Timer bounds the external attempt only, not claim/currentness/persistence. No automatic retry. */
|
|
82
|
-
export declare function dispatchEffect(port: EffectPort<DispatchCompletion>, send: (context: DispatchContext) => Promise<DispatchOutcome>, options: {
|
|
83
|
-
readonly timeoutMs: number;
|
|
84
|
-
readonly signal?: AbortSignal;
|
|
85
|
-
}): Promise<DispatchReport>;
|
|
86
|
-
export type PresentationCompletion = {
|
|
87
|
-
readonly outcome: 'presented' | 'clipped';
|
|
88
|
-
readonly reason: 'returned';
|
|
89
|
-
} | {
|
|
90
|
-
readonly outcome: 'failed' | 'unknown';
|
|
91
|
-
readonly reason: 'threw';
|
|
92
|
-
readonly error: unknown;
|
|
93
|
-
} | {
|
|
94
|
-
readonly outcome: 'released';
|
|
95
|
-
readonly reason: 'not-current' | 'cancelled' | 'unused';
|
|
96
|
-
};
|
|
97
|
-
export interface PresentationWork<P> {
|
|
98
|
-
readonly payload: P;
|
|
99
|
-
readonly coverage: 'full' | 'clipped';
|
|
100
|
-
readonly port: EffectPort<PresentationCompletion>;
|
|
101
|
-
}
|
|
102
|
-
declare const preparedBrand: unique symbol;
|
|
103
|
-
export interface PreparedPresentation<P> {
|
|
104
|
-
readonly [preparedBrand]: true;
|
|
105
|
-
readonly payload: P;
|
|
106
|
-
eligible(signal?: AbortSignal): Promise<boolean>;
|
|
107
|
-
release(): Promise<Settlement<PresentationCompletion>>;
|
|
108
|
-
}
|
|
109
|
-
export interface PresentationControl {
|
|
110
|
-
readonly signal?: AbortSignal;
|
|
111
|
-
/** Default unknown; throwing or invalid classifiers also stay unknown. */
|
|
112
|
-
readonly classifyError?: (error: unknown) => 'failed' | 'unknown';
|
|
113
|
-
}
|
|
114
|
-
export interface PresentationReport<P, R> {
|
|
115
|
-
readonly observation: {
|
|
116
|
-
readonly kind: 'not-invoked';
|
|
117
|
-
} | {
|
|
118
|
-
readonly kind: 'returned';
|
|
119
|
-
readonly value: R;
|
|
120
|
-
} | {
|
|
121
|
-
readonly kind: 'threw';
|
|
122
|
-
readonly error: unknown;
|
|
123
|
-
readonly outcome: 'failed' | 'unknown';
|
|
124
|
-
};
|
|
125
|
-
readonly settlements: readonly {
|
|
126
|
-
readonly prepared: PreparedPresentation<P>;
|
|
127
|
-
readonly result: Settlement<PresentationCompletion>;
|
|
128
|
-
}[];
|
|
129
|
-
}
|
|
130
|
-
export declare function preparePresentation<P>(work: PresentationWork<P>, control?: {
|
|
131
|
-
readonly signal?: AbortSignal;
|
|
132
|
-
}): Promise<PreparedPresentation<P> | undefined>;
|
|
133
|
-
export declare function presentPrepared<P, R>(prepared: PreparedPresentation<P>, sink: (payload: P) => R | Promise<R>, control?: PresentationControl): Promise<PresentationReport<P, R>>;
|
|
134
|
-
/** Takes all local custody synchronously, then owns eligibility/effect/settlement/cleanup. */
|
|
135
|
-
export declare function presentPreparedBatch<P, B, R>(prepared: readonly PreparedPresentation<P>[], render: (eligible: readonly PreparedPresentation<P>[]) => {
|
|
136
|
-
readonly payload: B;
|
|
137
|
-
readonly included: readonly PreparedPresentation<P>[];
|
|
138
|
-
}, sink: (payload: B) => R | Promise<R>, control?: PresentationControl): Promise<PresentationReport<P, R>>;
|
|
139
|
-
export {};
|