@astrosheep/square 0.3.50 → 0.3.52
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/claude-plugin/.claude-plugin/plugin.json +1 -1
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/attention-presentation.d.ts +1 -1
- package/dist/attention-presentation.js +23 -8
- package/dist/boundary-presentation.js +18 -27
- package/dist/cli/observation-commands.js +1 -7
- package/dist/decisions.d.ts +1 -1
- package/dist/decisions.js +15 -16
- package/dist/inbox.d.ts +1 -0
- package/dist/inbox.js +1 -1
- package/dist/presentation.js +8 -10
- package/dist/square-core.js +3 -3
- package/dist/views.js +1 -1
- package/package.json +2 -1
|
@@ -7,8 +7,8 @@ export interface AttentionPreview {
|
|
|
7
7
|
actor: string;
|
|
8
8
|
route: DirectedNotificationRoute;
|
|
9
9
|
body: string;
|
|
10
|
-
compact?: boolean;
|
|
11
10
|
}
|
|
12
11
|
export declare function previewAttentionBody(body: string): string;
|
|
12
|
+
export declare function attentionBodyIsClipped(body: string): boolean;
|
|
13
13
|
export declare function displayAttentionPath(squarePath: string): string;
|
|
14
14
|
export declare function renderAttentionPreview(attention: AttentionPreview): string;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
|
-
import { notificationMessageId } from './delivery.js';
|
|
3
|
-
import { participantIdentity } from './presentation.js';
|
|
4
2
|
import { formatActivityId } from './square-core.js';
|
|
3
|
+
import { participantCommandPrefix } from './presentation.js';
|
|
5
4
|
export const ATTENTION_BODY_MAX = 200;
|
|
6
5
|
export function previewAttentionBody(body) {
|
|
7
6
|
const compact = body.replace(/\r\n/g, '\n');
|
|
@@ -9,6 +8,9 @@ export function previewAttentionBody(body) {
|
|
|
9
8
|
return compact;
|
|
10
9
|
return `${compact.slice(0, ATTENTION_BODY_MAX).trimEnd()}…`;
|
|
11
10
|
}
|
|
11
|
+
export function attentionBodyIsClipped(body) {
|
|
12
|
+
return body.replace(/\r\n/g, '\n').length > ATTENTION_BODY_MAX;
|
|
13
|
+
}
|
|
12
14
|
export function displayAttentionPath(squarePath) {
|
|
13
15
|
return squarePath.startsWith(homedir())
|
|
14
16
|
? `~${squarePath.slice(homedir().length)}`
|
|
@@ -16,12 +18,25 @@ export function displayAttentionPath(squarePath) {
|
|
|
16
18
|
}
|
|
17
19
|
export function renderAttentionPreview(attention) {
|
|
18
20
|
const attentionKind = attention.route === 'bell' ? 'bell' : 'attention';
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
:
|
|
22
|
-
|
|
21
|
+
const attributes = {
|
|
22
|
+
location: displayAttentionPath(attention.squarePath),
|
|
23
|
+
id: formatActivityId(attention.actIndex),
|
|
24
|
+
from: attention.actor,
|
|
25
|
+
to: attention.recipient,
|
|
26
|
+
kind: attentionKind,
|
|
27
|
+
};
|
|
23
28
|
return [
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
'<square-activity',
|
|
30
|
+
...Object.entries(attributes).map(([key, value]) => ` ${key}="${escapeAttribute(value)}"`),
|
|
31
|
+
'>',
|
|
32
|
+
previewAttentionBody(attention.body),
|
|
33
|
+
'</square-activity>',
|
|
34
|
+
...(attentionBodyIsClipped(attention.body)
|
|
35
|
+
? [`» ${participantCommandPrefix(attention.squarePath, attention.recipient)} catch --id ${formatActivityId(attention.actIndex)}`]
|
|
36
|
+
: []),
|
|
26
37
|
].join('\n');
|
|
27
38
|
}
|
|
39
|
+
function escapeAttribute(value) {
|
|
40
|
+
return value.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<').replace(/>/g, '>')
|
|
41
|
+
.replace(/\r/g, ' ').replace(/\n/g, ' ').replace(/\t/g, '	');
|
|
42
|
+
}
|
|
@@ -6,8 +6,10 @@ import { withFileLock } from './file-lock.js';
|
|
|
6
6
|
import { openSquare } from './square-file-adapter.js';
|
|
7
7
|
import { closeOpenSquare } from './open-square.js';
|
|
8
8
|
import { presentPending } from './presentation-operations.js';
|
|
9
|
-
import { sessionInbox } from './inbox.js';
|
|
10
|
-
import { renderAttentionPreview } from './attention-presentation.js';
|
|
9
|
+
import { hostLedgerForEnv, sessionInbox } from './inbox.js';
|
|
10
|
+
import { attentionBodyIsClipped, renderAttentionPreview } from './attention-presentation.js';
|
|
11
|
+
import { presentationSuppressesWake, projectPresentationEvidence } from './square-projections.js';
|
|
12
|
+
import { formatActivityId } from './square-core.js';
|
|
11
13
|
const CONTEXT_MAX = 1200;
|
|
12
14
|
const presentationLocks = new Map();
|
|
13
15
|
function pendingCount(inbox) {
|
|
@@ -34,10 +36,6 @@ function frameBoundary(lines) {
|
|
|
34
36
|
return `\n${lines.join('\n')}\n`;
|
|
35
37
|
}
|
|
36
38
|
function renderBoundary(inbox) {
|
|
37
|
-
const count = pendingCount(inbox);
|
|
38
|
-
const noun = count === 1 ? 'notification' : 'notifications';
|
|
39
|
-
const header = `<system-reminder source="square">You have ${count} Square ${noun}.`;
|
|
40
|
-
const footer = ['</system-reminder>'];
|
|
41
39
|
const queued = inbox.flatMap((membership) => membership.notifications.map((notification) => ({ membership, notification })));
|
|
42
40
|
const blocks = [];
|
|
43
41
|
const complete = [];
|
|
@@ -55,15 +53,7 @@ function renderBoundary(inbox) {
|
|
|
55
53
|
}),
|
|
56
54
|
].join('\n');
|
|
57
55
|
const omittedAfter = omitted + queued.length - index - 1;
|
|
58
|
-
const prospective = frameBoundary([
|
|
59
|
-
header,
|
|
60
|
-
...blocks,
|
|
61
|
-
block,
|
|
62
|
-
...(omittedAfter > 0
|
|
63
|
-
? [`… ${omittedAfter} ${omittedAfter === 1 ? 'notification' : 'notifications'} omitted.`]
|
|
64
|
-
: []),
|
|
65
|
-
...footer,
|
|
66
|
-
]);
|
|
56
|
+
const prospective = frameBoundary([...blocks, block, ...(omittedAfter > 0 ? [`… ${omittedAfter} ${omittedAfter === 1 ? 'notification' : 'notifications'} omitted.`] : [])]);
|
|
67
57
|
if (prospective.length > CONTEXT_MAX) {
|
|
68
58
|
omitted += 1;
|
|
69
59
|
continue;
|
|
@@ -72,20 +62,11 @@ function renderBoundary(inbox) {
|
|
|
72
62
|
complete.push({
|
|
73
63
|
membership,
|
|
74
64
|
actIndexes: [notification.actIndex],
|
|
75
|
-
|
|
76
|
-
// preview had to clip the body. Keep clipped items from being replayed.
|
|
77
|
-
markSeen: true,
|
|
65
|
+
markSeen: !attentionBodyIsClipped(notification.body),
|
|
78
66
|
});
|
|
79
67
|
}
|
|
80
68
|
return {
|
|
81
|
-
context: frameBoundary([
|
|
82
|
-
header,
|
|
83
|
-
...blocks,
|
|
84
|
-
...(omitted > 0
|
|
85
|
-
? [`… ${omitted} ${omitted === 1 ? 'notification' : 'notifications'} omitted.`]
|
|
86
|
-
: []),
|
|
87
|
-
...footer,
|
|
88
|
-
]),
|
|
69
|
+
context: frameBoundary([...blocks, ...(omitted > 0 ? [`… ${omitted} ${omitted === 1 ? 'notification' : 'notifications'} omitted.`] : [])]),
|
|
89
70
|
complete,
|
|
90
71
|
};
|
|
91
72
|
}
|
|
@@ -93,7 +74,17 @@ async function presentPendingAtBoundaryUnlocked(sessionId, present, lookup = ses
|
|
|
93
74
|
const inbox = await lookup(sessionId, env);
|
|
94
75
|
if (signal?.aborted)
|
|
95
76
|
return undefined;
|
|
96
|
-
const
|
|
77
|
+
const hostLedger = hostLedgerForEnv(env);
|
|
78
|
+
const pending = [];
|
|
79
|
+
for (const membership of pendingAtBoundary(inbox)) {
|
|
80
|
+
const evidence = await projectPresentationEvidence({ hostLedger, location: membership.squarePath, participant: membership.name, sessionId });
|
|
81
|
+
const notifications = membership.notifications.filter((notification) => !presentationSuppressesWake(evidence.filter((row) => row.activity === formatActivityId(notification.actIndex))));
|
|
82
|
+
if (notifications.length > 0)
|
|
83
|
+
pending.push({ ...membership, notifications });
|
|
84
|
+
}
|
|
85
|
+
if (pending.length === 0 || signal?.aborted)
|
|
86
|
+
return undefined;
|
|
87
|
+
const delivered = renderBoundary(pending);
|
|
97
88
|
if (delivered.context === '')
|
|
98
89
|
return undefined;
|
|
99
90
|
let result;
|
|
@@ -467,13 +467,7 @@ export const statusCommand = {
|
|
|
467
467
|
try {
|
|
468
468
|
const presentation = await statusPresentation(square);
|
|
469
469
|
const result = presentation.status;
|
|
470
|
-
const active = result.participants.filter((participant) => participant.state === 'active')
|
|
471
|
-
const aViewer = context.name !== undefined && sameName(a.name, context.name);
|
|
472
|
-
const bViewer = context.name !== undefined && sameName(b.name, context.name);
|
|
473
|
-
if (aViewer !== bViewer)
|
|
474
|
-
return aViewer ? -1 : 1;
|
|
475
|
-
return (b.lastActiveAt ?? -Infinity) - (a.lastActiveAt ?? -Infinity) || a.name.localeCompare(b.name);
|
|
476
|
-
});
|
|
470
|
+
const active = result.participants.filter((participant) => participant.state === 'active');
|
|
477
471
|
const people = active.length === 0 ? [' ○ nobody in the square'] : active.slice(0, STATUS_PARTICIPANT_PREVIEW_LIMIT).map((participant) => {
|
|
478
472
|
const glyph = participant.presence === 'watching'
|
|
479
473
|
? '◎'
|
package/dist/decisions.d.ts
CHANGED
|
@@ -90,11 +90,11 @@ export interface ParticipantStatus {
|
|
|
90
90
|
activityCount: number;
|
|
91
91
|
lastActiveAt: number | undefined;
|
|
92
92
|
presence: CorePresenceState;
|
|
93
|
-
presenceAt: number | undefined;
|
|
94
93
|
unreadActivityCount: number;
|
|
95
94
|
pendingMentionCount: number;
|
|
96
95
|
}
|
|
97
96
|
export type CorePresenceState = 'never-joined' | 'active' | 'watching' | 'done';
|
|
97
|
+
export declare function compareParticipantActivity(a: Pick<ParticipantStatus, 'name' | 'lastActiveAt'>, b: Pick<ParticipantStatus, 'name' | 'lastActiveAt'>): number;
|
|
98
98
|
export interface StatusResult {
|
|
99
99
|
hardCap: HardCap;
|
|
100
100
|
throttlePerMinute: number | undefined;
|
package/dist/decisions.js
CHANGED
|
@@ -212,23 +212,23 @@ export function coreResume(squareState, actor, now) {
|
|
|
212
212
|
requireStanding(squareState, act);
|
|
213
213
|
return act;
|
|
214
214
|
}
|
|
215
|
-
function
|
|
216
|
-
|
|
217
|
-
return { state: 'done', lastAt: snapshot.lastActiveAt };
|
|
218
|
-
const cursorAt = squareState.acts.findLast((act) => act.index <= delivery.cursorFor(name))?.at;
|
|
219
|
-
const lease = freshWatchLease(squareState, name, now);
|
|
220
|
-
if (lease !== undefined)
|
|
221
|
-
return { state: 'watching', lastAt: cursorAt ?? lease.heartbeatAt };
|
|
222
|
-
const lastAt = cursorAt ?? (snapshot?.joined ? snapshot.lastActiveAt : undefined);
|
|
223
|
-
return lastAt === undefined
|
|
224
|
-
? { state: 'never-joined', lastAt: undefined }
|
|
225
|
-
: { state: 'active', lastAt };
|
|
215
|
+
export function compareParticipantActivity(a, b) {
|
|
216
|
+
return (b.lastActiveAt ?? -Infinity) - (a.lastActiveAt ?? -Infinity) || a.name.localeCompare(b.name);
|
|
226
217
|
}
|
|
227
218
|
function buildParticipantStatuses(squareState, now, state = foldedState(squareState), suppliedDelivery) {
|
|
228
219
|
const delivery = suppliedDelivery ?? deriveDeliveryModel(squareState);
|
|
229
220
|
return state.participants.map((snapshot) => {
|
|
230
221
|
const participant = snapshot.name;
|
|
231
|
-
|
|
222
|
+
let lastActiveAt = snapshot.lastActiveAt;
|
|
223
|
+
// Receipt time is evidence of catching; the consumed activity's time is not.
|
|
224
|
+
if (snapshot.joined) {
|
|
225
|
+
for (const observation of Object.values(squareState.runtime.observations[participant] ?? {})) {
|
|
226
|
+
if (observation.state === 'seen')
|
|
227
|
+
lastActiveAt = Math.max(lastActiveAt ?? -Infinity, observation.at);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
const presence = snapshot.done ? 'done' : !snapshot.joined ? 'never-joined'
|
|
231
|
+
: freshWatchLease(squareState, participant, now) !== undefined ? 'watching' : 'active';
|
|
232
232
|
const participantStatus = snapshot?.done ? 'done' : snapshot?.joined ? 'active' : 'not joined';
|
|
233
233
|
const consumedThrough = delivery.cursorFor(participant);
|
|
234
234
|
let unreadActivityCount = 0;
|
|
@@ -245,13 +245,12 @@ function buildParticipantStatuses(squareState, now, state = foldedState(squareSt
|
|
|
245
245
|
state: participantStatus,
|
|
246
246
|
listening: listeningTo(state, participant),
|
|
247
247
|
activityCount: snapshot?.activityCount ?? 0,
|
|
248
|
-
lastActiveAt
|
|
249
|
-
presence
|
|
250
|
-
presenceAt: presence.lastAt,
|
|
248
|
+
lastActiveAt,
|
|
249
|
+
presence,
|
|
251
250
|
unreadActivityCount,
|
|
252
251
|
pendingMentionCount: snapshot?.joined ? delivery.pendingFor(participant).length : 0,
|
|
253
252
|
};
|
|
254
|
-
});
|
|
253
|
+
}).sort(compareParticipantActivity);
|
|
255
254
|
}
|
|
256
255
|
export function coreStatus(squareState, now, delivery) {
|
|
257
256
|
const state = foldedState(squareState);
|
package/dist/inbox.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type InboxMembership } from './model.js';
|
|
2
|
+
export declare function hostLedgerForEnv(env: NodeJS.ProcessEnv): import("./host-ledger.js").HostLedgerPort;
|
|
2
3
|
export interface PendingWaitOptions {
|
|
3
4
|
signal?: AbortSignal;
|
|
4
5
|
/** Ephemeral watcher de-duplication; never persisted or used by delivery derivation. */
|
package/dist/inbox.js
CHANGED
|
@@ -4,7 +4,7 @@ import { waitForSquareChanges } from './square-file-adapter.js';
|
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { createHostLedgerPort } from './host-ledger-file-adapter.js';
|
|
6
6
|
import { projectPresentation, projectSessionBindings } from './square-projections.js';
|
|
7
|
-
function hostLedgerForEnv(env) {
|
|
7
|
+
export function hostLedgerForEnv(env) {
|
|
8
8
|
const root = env.SQUARE_REGISTRY === undefined ? undefined : path.dirname(env.SQUARE_REGISTRY);
|
|
9
9
|
return createHostLedgerPort({
|
|
10
10
|
userPath: env.SQUARE_HOST_LEDGER_USER ?? root,
|
package/dist/presentation.js
CHANGED
|
@@ -7,6 +7,7 @@ import { audienceIncludes, audienceOf, MAX_IDENTITY_SET_SIZE } from './square-co
|
|
|
7
7
|
import { perceiveActivity } from './delivery.js';
|
|
8
8
|
import { actId, publicActs, readCursor, rosterNames, sayNumberFor } from './runtime.js';
|
|
9
9
|
import { formatDuration, formatRelativeTime, formatTimestamp } from './time.js';
|
|
10
|
+
import { compareParticipantActivity } from './decisions.js';
|
|
10
11
|
import { grepSnippet } from './search.js';
|
|
11
12
|
function headerLine(squarePath, opts = {}) {
|
|
12
13
|
const count = opts.participantCount ?? 0;
|
|
@@ -56,7 +57,7 @@ function presenceGlyph(participant) {
|
|
|
56
57
|
return '○';
|
|
57
58
|
if (participant.presence === 'watching')
|
|
58
59
|
return '◎';
|
|
59
|
-
if (participant.
|
|
60
|
+
if (participant.lastActiveAt !== undefined)
|
|
60
61
|
return '●';
|
|
61
62
|
return '○';
|
|
62
63
|
}
|
|
@@ -65,19 +66,17 @@ function presenceText(participant, now) {
|
|
|
65
66
|
return participant.lastActiveAt === undefined ? 'stepped out of the square' : `stepped out of the square · ${formatRelativeTime(participant.lastActiveAt, now)}`;
|
|
66
67
|
}
|
|
67
68
|
if (participant.presence === 'watching') {
|
|
68
|
-
const at = participant.
|
|
69
|
+
const at = participant.lastActiveAt;
|
|
69
70
|
return at === undefined ? 'catching' : `catching · ${formatRelativeTime(at, now)}`;
|
|
70
71
|
}
|
|
71
|
-
if (participant.
|
|
72
|
+
if (participant.lastActiveAt === undefined)
|
|
72
73
|
return 'quiet';
|
|
73
|
-
return participant.activityCount > 0 ? `${formatRelativeTime(participant.
|
|
74
|
+
return participant.activityCount > 0 ? `${formatRelativeTime(participant.lastActiveAt, now)}` : `quiet · ${formatRelativeTime(participant.lastActiveAt, now)}`;
|
|
74
75
|
}
|
|
75
76
|
export function renderPresenceLines(participants, now, limit = 5) {
|
|
76
77
|
const recent = participants
|
|
77
|
-
.
|
|
78
|
-
.
|
|
79
|
-
.sort((a, b) => b.at - a.at || a.p.name.localeCompare(b.p.name))
|
|
80
|
-
.map(({ p }) => p);
|
|
78
|
+
.filter((p) => p.state === 'done' || p.presence === 'watching' || (p.lastActiveAt !== undefined && now - p.lastActiveAt <= PRESENCE_WINDOW_MS))
|
|
79
|
+
.sort(compareParticipantActivity);
|
|
81
80
|
const shown = recent.slice(0, limit);
|
|
82
81
|
if (shown.length === 0)
|
|
83
82
|
return [' ○ nobody nearby'];
|
|
@@ -90,8 +89,7 @@ export function renderPresenceLines(participants, now, limit = 5) {
|
|
|
90
89
|
const EXPRESS_HINTS = [
|
|
91
90
|
'*asterisks* are your body — *slams table*, *sketches in the air*, *shrugs*',
|
|
92
91
|
"you're standing in a square — words and gestures both land",
|
|
93
|
-
'
|
|
94
|
-
'@ only who you need — step back with catch --mention',
|
|
92
|
+
'the square is for conversation — share thoughts and engage with others, beyond status updates and empty acknowledgments',
|
|
95
93
|
];
|
|
96
94
|
export function expressHintLine(ownActivityCount) {
|
|
97
95
|
if (ownActivityCount !== 1 && ownActivityCount % 5 !== 0)
|
package/dist/square-core.js
CHANGED
|
@@ -150,19 +150,20 @@ function applyActivity(accumulator, act) {
|
|
|
150
150
|
const { state, byKey, ordered } = accumulator;
|
|
151
151
|
const actor = actorOf(act);
|
|
152
152
|
const snapshot = actor === undefined ? undefined : touchParticipant(byKey, ordered, actor);
|
|
153
|
+
if (snapshot !== undefined && act.at !== undefined) {
|
|
154
|
+
snapshot.lastActiveAt = Math.max(snapshot.lastActiveAt ?? -Infinity, act.at);
|
|
155
|
+
}
|
|
153
156
|
switch (act.kind) {
|
|
154
157
|
case 'join':
|
|
155
158
|
if (snapshot !== undefined) {
|
|
156
159
|
snapshot.joined = true;
|
|
157
160
|
snapshot.done = false;
|
|
158
|
-
snapshot.lastActiveAt = act.at ?? snapshot.lastActiveAt;
|
|
159
161
|
}
|
|
160
162
|
break;
|
|
161
163
|
case 'done':
|
|
162
164
|
if (snapshot !== undefined) {
|
|
163
165
|
snapshot.joined = false;
|
|
164
166
|
snapshot.done = true;
|
|
165
|
-
snapshot.lastActiveAt = act.at ?? snapshot.lastActiveAt;
|
|
166
167
|
state.listening.delete(nameKey(snapshot.name));
|
|
167
168
|
}
|
|
168
169
|
break;
|
|
@@ -195,7 +196,6 @@ function applyActivity(accumulator, act) {
|
|
|
195
196
|
case 'say':
|
|
196
197
|
if (snapshot !== undefined) {
|
|
197
198
|
snapshot.activityCount += 1;
|
|
198
|
-
snapshot.lastActiveAt = act.at ?? snapshot.lastActiveAt;
|
|
199
199
|
}
|
|
200
200
|
pushThrottleAt(state, act.at);
|
|
201
201
|
if (act.reach === 'bell')
|
package/dist/views.js
CHANGED
|
@@ -68,7 +68,7 @@ export async function activityPresentation(square, name) { const { state } = awa
|
|
|
68
68
|
export async function entryPresentation(square, name, lastN = 10) { const { state } = await square.artifact.read(); const known = resolveRosterName(state, name) ?? name; const publicActivities = state.acts.filter((activity) => activity.kind === 'say' || activity.kind === 'done'); return { joined: isCurrentlyJoined(state.acts, known), scene: state.warmup.join('\n').trim(), context: state.preamble.join('\n').trim(), joinContext: (state.preamble.at(-1) === '---' ? state.preamble.slice(0, -1) : state.preamble).join('\n').trim(), recentActivities: lastN === null ? publicActivities : publicActivities.slice(-lastN), state, sayNumbers: sayNumbers(state), participantCount: inSquareCount(state) }; }
|
|
69
69
|
export async function historyPresentation(square, options) { const { state } = await square.artifact.read(); const delivery = deriveDeliveryModel(state); return { activities: coreActivities(state, options, delivery), sayNumbers: sayNumbers(state), presenceAnchors: anchors(state, delivery), participantCount: inSquareCount(state) }; }
|
|
70
70
|
export async function participantsPresentation(square) { const { state } = await square.artifact.read(); const delivery = deriveDeliveryModel(state); return coreParticipants(state, square.clock(), delivery); }
|
|
71
|
-
export async function listPresentation(square) { const { state } = await square.artifact.read(); return { context: state.preamble, participants:
|
|
71
|
+
export async function listPresentation(square) { const { state } = await square.artifact.read(); return { context: state.preamble, participants: coreParticipants(state, square.clock()).filter((participant) => participant.state === 'active').map((participant) => participant.name), activities: state.acts.filter((activity) => activity.kind === 'say').length }; }
|
|
72
72
|
export async function statusPresentation(square) { const { state } = await square.artifact.read(); const delivery = deriveDeliveryModel(state); const status = coreStatus(state, square.clock(), delivery); return { state, status, ...(status.latestAct?.kind === 'say' ? { latestActNumber: countSays(state.acts, status.latestAct.actor) } : {}) }; }
|
|
73
73
|
export async function eventPresentation(square, id) { const { state } = await square.artifact.read(); const activity = state.acts.find((candidate) => candidate.index === parseRequiredActivityId(id)); if (activity === undefined)
|
|
74
74
|
throw new SquareError('invalid_args', `Unknown activity id: ${id}`); return { activity, participantCount: inSquareCount(state), held: currentHold(state.acts).active }; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/square",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.52",
|
|
4
4
|
"description": "A shared public square where agents join, catch activity, express, and step out when done.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"clean": "node --input-type=module -e \"import fs from 'node:fs'; fs.rmSync('dist',{recursive:true,force:true})\"",
|
|
19
19
|
"build": "npm run clean && tsc && node --input-type=module -e \"import fs from 'node:fs'; fs.chmodSync('dist/square.js',0o755)\"",
|
|
20
20
|
"verify-release": "node test/release.test.js",
|
|
21
|
+
"release": "npm version patch && npm publish && git push --follow-tags",
|
|
21
22
|
"prepublishOnly": "npm run build && npm run verify-release",
|
|
22
23
|
"test": "npm run build && node --test test/*.test.js",
|
|
23
24
|
"test:cli-process": "npm run build && node --test test/process/square-cli-render.test.js"
|