@astrosheep/square 0.3.78 → 0.3.80
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/attention-presentation.d.ts +2 -0
- package/dist/attention-presentation.js +39 -4
- package/dist/automatic-session.js +1 -1
- package/dist/boundary-presentation.js +4 -7
- package/dist/claude-mod.js +1 -1
- package/dist/cli/catch-presentation.d.ts +2 -2
- package/dist/cli/catch-presentation.js +3 -3
- package/dist/cli/context.d.ts +11 -1
- package/dist/cli/context.js +14 -3
- package/dist/cli/express-presentation.d.ts +6 -5
- package/dist/cli/express-presentation.js +42 -43
- package/dist/cli/maintenance-commands.js +6 -6
- package/dist/cli/mcp-server-command.js +1 -1
- package/dist/cli/observation-commands.d.ts +4 -4
- package/dist/cli/observation-commands.js +20 -16
- package/dist/cli/program.d.ts +1 -1
- package/dist/cli/program.js +5 -5
- package/dist/cli/square-commands.js +35 -23
- package/dist/decisions.d.ts +3 -5
- package/dist/decisions.js +10 -9
- package/dist/delivery.d.ts +1 -1
- package/dist/help.js +15 -2
- package/dist/inbox.js +3 -3
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/ledger-maintenance.d.ts +1 -1
- package/dist/ledger-maintenance.js +1 -1
- package/dist/list.d.ts +3 -3
- package/dist/list.js +1 -1
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +12 -7
- package/dist/mention-parse.d.ts +2 -8
- package/dist/mention-parse.js +6 -9
- package/dist/model.d.ts +2 -2
- package/dist/notifications.js +24 -8
- package/dist/participant-host.js +5 -0
- package/dist/plugins/opencode/index.js +1 -1
- package/dist/square-actions.d.ts +22 -9
- package/dist/square-actions.js +26 -19
- package/dist/square-api.d.ts +43 -0
- package/dist/square-api.js +471 -0
- package/dist/square-facade.d.ts +123 -203
- package/dist/square-tools.d.ts +4 -3
- package/dist/square-tools.js +21 -15
- package/dist/stream.d.ts +2 -2
- package/dist/views.d.ts +16 -12
- package/dist/views.js +13 -27
- package/guides/application-demand-optimization.md +5 -0
- package/guides/application-facade-delivery-evidence.md +7 -2
- package/guides/mcp-connection-lifetime.md +2 -2
- package/guides/mcp.md +1 -1
- package/guides/operation-cancellation.md +2 -0
- package/guides/primitive-catch-consolidation.md +5 -0
- package/guides/primitive-history-consolidation.md +5 -0
- package/guides/primitive-status-consolidation.md +5 -0
- package/guides/primitive-storage-consolidation.md +5 -0
- package/guides/row-storage-design.md +1 -1
- package/guides/square-api.md +107 -0
- package/package.json +1 -1
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/skills/square/SKILL.md +4 -4
- package/plugins/codex/.codex-plugin/plugin.json +1 -1
- package/plugins/opencode/index.ts +1 -1
- package/plugins/paseo/client/markdown.tsx +16 -6
- package/plugins/pi/square-pi.js +7 -6
- package/skills/square/SKILL.md +4 -4
- package/dist/square-application.d.ts +0 -38
- package/dist/square-application.js +0 -683
- package/guides/application-boundary.md +0 -32
- package/guides/application-facade-design.md +0 -98
package/dist/square-actions.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { type StoredAct } from './model.js';
|
|
1
2
|
import type { WakeTransportPort } from './ports.js';
|
|
2
|
-
import type { Activity, CatchOptions, ExpressOptions, ExpressResult, ExpressionObservation,
|
|
3
|
+
import type { Activity, ActivityResult, CatchOptions, ExpressOptions, ExpressResult, ExpressionObservation, OperationControl, OwnershipFenceOptions, SquareObservation } from './square-facade.js';
|
|
3
4
|
import { type CatchSelection } from './catch-decisions.js';
|
|
4
5
|
import { type HostContext } from './participant-host.js';
|
|
5
6
|
export interface OperationContext extends HostContext {
|
|
@@ -8,6 +9,7 @@ export interface OperationContext extends HostContext {
|
|
|
8
9
|
export type { OwnershipFenceOptions };
|
|
9
10
|
export declare function catchUp(square: OperationContext, name: string, options?: CatchOptions, control?: OperationControl): Promise<CatchSelection>;
|
|
10
11
|
export declare function catchUp(square: OperationContext, name: string, options: CatchOptions, control: OperationControl | undefined, leaseId: string): Promise<CatchSelection | null>;
|
|
12
|
+
type LandingContext = Pick<SquareObservation, 'standingCount' | 'held' | 'now'>;
|
|
11
13
|
export declare function join(square: OperationContext, name: string, control?: OperationControl, admission?: {
|
|
12
14
|
readonly requireKnown?: boolean;
|
|
13
15
|
}): Promise<{
|
|
@@ -15,28 +17,39 @@ export declare function join(square: OperationContext, name: string, control?: O
|
|
|
15
17
|
readonly activity: Activity | null;
|
|
16
18
|
readonly participantCount: number;
|
|
17
19
|
readonly reconnected: boolean;
|
|
20
|
+
readonly observation: LandingContext;
|
|
18
21
|
}>;
|
|
19
22
|
/** Takeover holds the host CAS fence across the single done+join artifact transaction. */
|
|
20
|
-
export declare function takeover(square: OperationContext, name: string,
|
|
23
|
+
export declare function takeover(square: OperationContext, name: string, control?: OperationControl): Promise<{
|
|
21
24
|
readonly name: string;
|
|
22
25
|
readonly activities: readonly Activity[];
|
|
23
26
|
readonly participantCount: number;
|
|
24
27
|
readonly epoch?: number;
|
|
28
|
+
readonly observation: LandingContext;
|
|
25
29
|
}>;
|
|
26
30
|
export declare function implicitJoin(square: OperationContext, name: string, control?: OperationControl): Promise<{
|
|
27
31
|
readonly name: string;
|
|
28
32
|
readonly state: 'joined' | 'active' | 'done';
|
|
29
33
|
readonly activity: Activity | null;
|
|
30
34
|
}>;
|
|
31
|
-
export interface ExpressCommittedResult extends ExpressResult {
|
|
35
|
+
export interface ExpressCommittedResult extends Omit<ExpressResult, 'waited' | 'observation'> {
|
|
32
36
|
readonly observation: ExpressionObservation;
|
|
33
37
|
}
|
|
34
38
|
export declare function express(square: OperationContext, name: string, body: string, options?: ExpressOptions, control?: OperationControl): Promise<ExpressCommittedResult>;
|
|
35
|
-
export
|
|
36
|
-
|
|
39
|
+
export interface ListenerCommittedResult {
|
|
40
|
+
readonly activity: Activity | null;
|
|
41
|
+
readonly observation: LandingContext;
|
|
42
|
+
}
|
|
43
|
+
export declare function listen(square: OperationContext, actor: string, target: string, control?: OperationControl): Promise<ListenerCommittedResult>;
|
|
44
|
+
export declare function ignore(square: OperationContext, actor: string, target: string, control?: OperationControl): Promise<ListenerCommittedResult>;
|
|
37
45
|
export declare function listening(square: OperationContext, actor: string, control?: OperationControl): Promise<readonly string[]>;
|
|
38
|
-
export
|
|
39
|
-
|
|
46
|
+
export interface LifecycleCommittedResult extends ActivityResult {
|
|
47
|
+
readonly observation: LandingContext & {
|
|
48
|
+
readonly activity: StoredAct;
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export declare function done(square: OperationContext, name: string, body?: string, fence?: OwnershipFenceOptions, control?: OperationControl): Promise<LifecycleCommittedResult>;
|
|
52
|
+
export declare function endOwnedSession(square: OperationContext, name: string, sessionId: string, expectedEpoch?: number): Promise<ActivityResult | null>;
|
|
40
53
|
export declare function retireEndedSessionRoutes(square: OperationContext, sessionId: string): Promise<void>;
|
|
41
|
-
export declare function hold(square: OperationContext, name: string, reason?: string, control?: OperationControl): Promise<
|
|
42
|
-
export declare function resume(square: OperationContext, name: string, control?: OperationControl): Promise<
|
|
54
|
+
export declare function hold(square: OperationContext, name: string, reason?: string, control?: OperationControl): Promise<LifecycleCommittedResult>;
|
|
55
|
+
export declare function resume(square: OperationContext, name: string, control?: OperationControl): Promise<LifecycleCommittedResult>;
|
package/dist/square-actions.js
CHANGED
|
@@ -40,21 +40,23 @@ export async function join(square, name, control, admission = {}) {
|
|
|
40
40
|
const preview = (await square.artifact.read((facts) => {
|
|
41
41
|
// Express may reenter a known participant, but must never create a new name.
|
|
42
42
|
const selected = admission.requireKnown ? resolveKnownName(facts, name) : name;
|
|
43
|
+
const now = square.clock();
|
|
43
44
|
return {
|
|
44
|
-
...decideJoin(facts, selected,
|
|
45
|
+
...decideJoin(facts, selected, now),
|
|
45
46
|
participantCount: facts.roster().filter((p) => p.joined || p.done).length,
|
|
47
|
+
observation: { standingCount: inSquareCount(facts), held: facts.hold().active, now },
|
|
46
48
|
};
|
|
47
49
|
}, control?.signal)).value;
|
|
48
50
|
name = preview.joinedName;
|
|
49
51
|
if (preview.joinAct === undefined) {
|
|
50
52
|
if (hostLedger === undefined)
|
|
51
|
-
return { name: preview.joinedName, activity: null, participantCount: preview.participantCount, reconnected: false };
|
|
53
|
+
return { name: preview.joinedName, activity: null, participantCount: preview.participantCount, reconnected: false, observation: preview.observation };
|
|
52
54
|
const identity = processIdentity(square.env ?? process.env);
|
|
53
55
|
const owner = await readParticipantOwner(square.location, preview.joinedName, hostLedger);
|
|
54
56
|
if (owner?.session === identity.session)
|
|
55
57
|
return {
|
|
56
58
|
name: preview.joinedName, activity: null, participantCount: preview.participantCount,
|
|
57
|
-
reconnected: identity.channel !== 'unknown',
|
|
59
|
+
reconnected: identity.channel !== 'unknown', observation: preview.observation,
|
|
58
60
|
};
|
|
59
61
|
// Missing or foreign owner must pass CAS, not become a silent reconnect.
|
|
60
62
|
}
|
|
@@ -80,6 +82,7 @@ export async function join(square, name, control, admission = {}) {
|
|
|
80
82
|
return {
|
|
81
83
|
name: decision.joinedName, stored,
|
|
82
84
|
participantCount: facts.roster().filter((p) => p.joined || p.done).length,
|
|
85
|
+
observation: { standingCount: inSquareCount(facts), held: facts.hold().active, now },
|
|
83
86
|
};
|
|
84
87
|
}, control?.signal)).value;
|
|
85
88
|
}
|
|
@@ -91,11 +94,11 @@ export async function join(square, name, control, admission = {}) {
|
|
|
91
94
|
await publishCommittedIdentity(square, committed.name, epoch);
|
|
92
95
|
return {
|
|
93
96
|
name: committed.name, activity: committed.stored === null ? null : toPublicActivity(committed.stored),
|
|
94
|
-
participantCount: committed.participantCount, reconnected: false,
|
|
97
|
+
participantCount: committed.participantCount, reconnected: false, observation: committed.observation,
|
|
95
98
|
};
|
|
96
99
|
}
|
|
97
100
|
/** Takeover holds the host CAS fence across the single done+join artifact transaction. */
|
|
98
|
-
export async function takeover(square, name,
|
|
101
|
+
export async function takeover(square, name, control) {
|
|
99
102
|
throwIfAborted(control);
|
|
100
103
|
validateName(name);
|
|
101
104
|
const hostLedger = square.hostLedger;
|
|
@@ -113,6 +116,7 @@ export async function takeover(square, name, _oldSessionIds = [], control) {
|
|
|
113
116
|
return {
|
|
114
117
|
name: joinedName, stored: [storedDone, storedJoin],
|
|
115
118
|
participantCount: facts.roster().filter((p) => p.joined || p.done).length,
|
|
119
|
+
observation: { standingCount: inSquareCount(facts), held: facts.hold().active, now },
|
|
116
120
|
};
|
|
117
121
|
}, control?.signal)).value;
|
|
118
122
|
};
|
|
@@ -131,11 +135,11 @@ export async function takeover(square, name, _oldSessionIds = [], control) {
|
|
|
131
135
|
}, control?.signal);
|
|
132
136
|
if (outcome.status === 'busy')
|
|
133
137
|
throw new SquareError('already_joined', `${participantIdentity(name)} already stands here — another session holds the name`);
|
|
134
|
-
return { name: outcome.result.name, activities: outcome.result.stored.map(toPublicActivity), participantCount: outcome.result.participantCount, epoch: outcome.epoch };
|
|
138
|
+
return { name: outcome.result.name, activities: outcome.result.stored.map(toPublicActivity), participantCount: outcome.result.participantCount, epoch: outcome.epoch, observation: outcome.result.observation };
|
|
135
139
|
}
|
|
136
140
|
const committed = await commitLifecycle();
|
|
137
141
|
await publishCommittedIdentity(square, committed.name);
|
|
138
|
-
return { name: committed.name, activities: committed.stored.map(toPublicActivity), participantCount: committed.participantCount };
|
|
142
|
+
return { name: committed.name, activities: committed.stored.map(toPublicActivity), participantCount: committed.participantCount, observation: committed.observation };
|
|
139
143
|
}
|
|
140
144
|
export async function implicitJoin(square, name, control) {
|
|
141
145
|
throwIfAborted(control);
|
|
@@ -185,14 +189,16 @@ export async function express(square, name, body, options = {}, control) {
|
|
|
185
189
|
}
|
|
186
190
|
catch (error) {
|
|
187
191
|
if (isSquareError(error))
|
|
188
|
-
error.facts = {
|
|
192
|
+
error.facts = {
|
|
193
|
+
...error.facts, reason: 'invalid_reply', activityId: options.reply,
|
|
194
|
+
};
|
|
189
195
|
throw error;
|
|
190
196
|
}
|
|
191
197
|
});
|
|
192
198
|
const committed = (await square.artifact.transact((facts) => {
|
|
193
199
|
// Selected-row decoding is storage work, not evidence that admission safely refused.
|
|
194
200
|
const proposed = decideAct(facts, { name, body, force: options.force ?? false, now, mentions: options.mentions,
|
|
195
|
-
...(options.reach === undefined ? {} : { reach: options.reach }), ...(options.noMention === undefined ? {} : { noMention: options.noMention }), ...(
|
|
201
|
+
...(options.reach === undefined ? {} : { reach: options.reach }), ...(options.noMention === undefined ? {} : { noMention: options.noMention }), ...(reply === undefined ? {} : { reply }) });
|
|
196
202
|
const holder = proposed.type === 'held' ? facts.hold().actor : undefined;
|
|
197
203
|
const decision = rejectUnsentActivity(() => {
|
|
198
204
|
const decision = proposed;
|
|
@@ -216,6 +222,7 @@ export async function express(square, name, body, options = {}, control) {
|
|
|
216
222
|
standingCount: inSquareCount(facts), held: facts.hold().active, now,
|
|
217
223
|
ownActivityCount: facts.participant(name).sayCount, hardCap: facts.header().hardCap,
|
|
218
224
|
},
|
|
225
|
+
...(decision.unmatchedMentions === undefined ? {} : { unmatchedMentions: decision.unmatchedMentions }),
|
|
219
226
|
...(decision.replyAuthorNotHere === undefined ? {} : { replyAuthorNotHere: decision.replyAuthorNotHere }),
|
|
220
227
|
};
|
|
221
228
|
}, control?.signal)).value;
|
|
@@ -224,19 +231,18 @@ export async function express(square, name, body, options = {}, control) {
|
|
|
224
231
|
? await deliverPending({ artifact: square.artifact, hostLedger: square.hostLedger, transport: square.wakeTransport, location: square.location, activity: committed.stored.index, now })
|
|
225
232
|
.catch(() => ({ attempted: 0, accepted: 0, failed: 0, unknown: 0, notCapable: 1 }))
|
|
226
233
|
: { attempted: 0, accepted: 0, failed: 0, unknown: 0, notCapable: 1 };
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
...(committed.replyAuthorNotHere === undefined ? {} : { replyAuthorNotHere: committed.replyAuthorNotHere }),
|
|
230
|
-
};
|
|
234
|
+
const { stored, observation, ...metadata } = committed;
|
|
235
|
+
return { activity: toPublicActivity(stored), delivery, observation, ...metadata };
|
|
231
236
|
}
|
|
232
237
|
async function landListenerChange(square, verb, actor, target, control) {
|
|
233
238
|
throwIfAborted(control);
|
|
234
239
|
const now = square.clock();
|
|
235
|
-
const
|
|
240
|
+
const committed = (await square.artifact.transact((facts) => {
|
|
236
241
|
const act = verb === 'listen' ? coreListen(facts, actor, target, now) : coreIgnore(facts, actor, target, now);
|
|
237
|
-
|
|
242
|
+
const stored = act === undefined ? null : facts.land(act);
|
|
243
|
+
return { stored, observation: { standingCount: inSquareCount(facts), held: facts.hold().active, now } };
|
|
238
244
|
}, control?.signal)).value;
|
|
239
|
-
return { activity: stored === null ? null : toPublicActivity(stored) };
|
|
245
|
+
return { activity: committed.stored === null ? null : toPublicActivity(committed.stored), observation: committed.observation };
|
|
240
246
|
}
|
|
241
247
|
export function listen(square, actor, target, control) { return landListenerChange(square, 'listen', actor, target, control); }
|
|
242
248
|
export function ignore(square, actor, target, control) { return landListenerChange(square, 'ignore', actor, target, control); }
|
|
@@ -256,7 +262,9 @@ async function landCore(square, verb, actor, body = '', fence = {}, control) {
|
|
|
256
262
|
const result = facts.land(verb === 'done' ? coreDone(facts, actor, body, now) : verb === 'hold' ? coreHold(facts, actor, body, now) : coreResume(facts, actor, now));
|
|
257
263
|
if (session !== undefined)
|
|
258
264
|
dropEndedSessionWakeRoutes(facts, square.location, session, { expectedEpoch: fence.expectedEpoch, force: true, participant: actor });
|
|
259
|
-
return result
|
|
265
|
+
return { activity: toPublicActivity(result), observation: {
|
|
266
|
+
activity: result, standingCount: inSquareCount(facts), held: facts.hold().active, now,
|
|
267
|
+
} };
|
|
260
268
|
}, control?.signal)).value;
|
|
261
269
|
for (const row of owners)
|
|
262
270
|
await hostLedger.removePresenceIfUnchanged(row).catch((error) => {
|
|
@@ -264,8 +272,7 @@ async function landCore(square, verb, actor, body = '', fence = {}, control) {
|
|
|
264
272
|
});
|
|
265
273
|
return stored;
|
|
266
274
|
};
|
|
267
|
-
|
|
268
|
-
return { activity: toPublicActivity(stored) };
|
|
275
|
+
return hostLedger === undefined ? commitAndCleanup() : hostLedger.withClaimLock(commitAndCleanup, control?.signal);
|
|
269
276
|
}
|
|
270
277
|
export function done(square, name, body = '', fence = {}, control) { return landCore(square, 'done', name, body, fence, control); }
|
|
271
278
|
function liveClaimedParticipants(rows, sessionId) {
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ActivityResult, HistoryQuery, HistoryResult, JoinOptions, JoinResult, ObservationOptions, OperationControl, Participant, SquareAtInput, SquareBuildInput, SquareLocation, StatusOptions, StatusResult, ParticipantsResult, RecoveryResult, DiscoveryOptions, InboxOptions, InboxResult, StreamOptions } from './square-facade.js';
|
|
2
|
+
export type * from './square-facade.js';
|
|
3
|
+
export { createSquareResourceOwner } from './open-square.js';
|
|
4
|
+
export { formatActivityId, parseActivityId, MAX_IDENTITY_SET_SIZE } from './square-core.js';
|
|
5
|
+
export { CATCH_DEFAULT_LIMIT, CATCH_MAX_LIMIT } from './catch-decisions.js';
|
|
6
|
+
export { HELD_WAIT_BUDGET_MS } from './runtime.js';
|
|
7
|
+
export { HISTORY_DEFAULT_LIMIT, HISTORY_MAX_LIMIT } from './views.js';
|
|
8
|
+
export { DEFAULT_LIST_DEPTH, MAX_LIST_DEPTH, DEFAULT_LIST_LIMIT, MAX_LIST_LIMIT } from './list.js';
|
|
9
|
+
export declare function squareLocation(input: SquareLocation): string;
|
|
10
|
+
export declare function squareClock(env: NodeJS.ProcessEnv, clock?: () => number): () => number;
|
|
11
|
+
/** One concrete square resource. Request handles may borrow a server-owned connection. */
|
|
12
|
+
export declare class Square {
|
|
13
|
+
readonly location: string;
|
|
14
|
+
private readonly square;
|
|
15
|
+
private readonly defaultParticipant?;
|
|
16
|
+
private readonly transport;
|
|
17
|
+
private constructor();
|
|
18
|
+
static at(input: SquareAtInput, control?: OperationControl): Promise<Square>;
|
|
19
|
+
static build(input: SquareBuildInput, control?: OperationControl): Promise<Square>;
|
|
20
|
+
static inMemory(input: Omit<SquareBuildInput, 'path' | 'resources'>): Square;
|
|
21
|
+
private handle;
|
|
22
|
+
participant(requested?: string): Promise<Participant>;
|
|
23
|
+
join(requested?: string, options?: JoinOptions, control?: OperationControl): Promise<JoinResult>;
|
|
24
|
+
doneOwnedSession(name: string, body: string, expectedEpoch: number, control?: OperationControl): Promise<ActivityResult>;
|
|
25
|
+
implicitJoin(name: string, control?: OperationControl): Promise<{
|
|
26
|
+
readonly state: 'joined' | 'active' | 'done';
|
|
27
|
+
readonly participant?: Participant;
|
|
28
|
+
}>;
|
|
29
|
+
snapshot(control?: OperationControl): Promise<import("./square-facade.js").SquareSnapshot>;
|
|
30
|
+
history(query?: HistoryQuery, control?: OperationControl): Promise<HistoryResult>;
|
|
31
|
+
status(options?: StatusOptions, control?: OperationControl): Promise<StatusResult>;
|
|
32
|
+
participants(options?: ObservationOptions, control?: OperationControl): Promise<ParticipantsResult>;
|
|
33
|
+
recovery(requested?: string, control?: OperationControl): Promise<RecoveryResult>;
|
|
34
|
+
stream(options: StreamOptions, control?: OperationControl): AsyncIterable<import("./square-facade.js").StreamRecord>;
|
|
35
|
+
recognize(env: NodeJS.ProcessEnv): Promise<Participant | null>;
|
|
36
|
+
close(): Promise<void>;
|
|
37
|
+
endOwnedSession(name: string, sessionId: string, expectedEpoch?: number): Promise<ActivityResult | null>;
|
|
38
|
+
retireEndedSessionRoutes(sessionId: string): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
export declare function diagnoseSquare(input: SquareLocation, control?: OperationControl): Promise<import("./artifact.js").DiagnoseResult>;
|
|
41
|
+
export declare function migrateSquare(input: SquareLocation, control?: OperationControl): Promise<import("./square-migration.js").MigrationOutcome>;
|
|
42
|
+
export declare function discover(input: SquareAtInput, options?: DiscoveryOptions, control?: OperationControl): Promise<import("./square-facade.js").DiscoveryResult>;
|
|
43
|
+
export declare function inbox(input: SquareAtInput, sessionId: string, options?: InboxOptions, control?: OperationControl): Promise<InboxResult>;
|