@astrosheep/square 0.3.63 → 0.3.65
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 +3 -2
- package/claude-plugin/hooks/hooks.json +1 -22
- package/claude-plugin/hooks/register.js +119 -0
- package/claude-plugin/types.d.ts +7 -0
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/activity-feed.d.ts +1 -10
- package/dist/activity-feed.js +1 -27
- package/dist/activity.js +57 -25
- package/dist/artifact.d.ts +1 -1
- package/dist/artifact.js +24 -25
- package/dist/attention-presentation.js +1 -0
- package/dist/automatic-session.d.ts +3 -1
- package/dist/automatic-session.js +21 -34
- package/dist/boundary-presentation.js +4 -13
- package/dist/canonical-path.d.ts +11 -0
- package/dist/canonical-path.js +47 -0
- package/dist/catch-decisions.js +14 -10
- package/dist/catch-selection.d.ts +6 -0
- package/dist/catch-selection.js +14 -0
- package/dist/claude-delivery.d.ts +11 -0
- package/dist/claude-delivery.js +145 -0
- package/dist/claude-mod.d.ts +8 -0
- package/dist/claude-mod.js +164 -0
- package/dist/cli/context.d.ts +0 -1
- package/dist/cli/context.js +9 -21
- package/dist/cli/harness-command.d.ts +0 -1
- package/dist/cli/harness-command.js +0 -6
- package/dist/cli/observation-commands.d.ts +1 -1
- package/dist/cli/observation-commands.js +31 -58
- package/dist/cli/program.js +20 -18
- package/dist/cli/registry.js +2 -2
- package/dist/cli/square-commands.js +10 -6
- package/dist/codex-boundary-state.d.ts +2 -2
- package/dist/codex-boundary-state.js +4 -4
- package/dist/codex-hook.js +12 -15
- package/dist/codex-queue.d.ts +2 -2
- package/dist/codex-queue.js +7 -5
- package/dist/decisions.d.ts +2 -6
- package/dist/decisions.js +16 -17
- package/dist/delivery-health.d.ts +1 -2
- package/dist/delivery-health.js +4 -5
- package/dist/delivery-operations.d.ts +2 -5
- package/dist/delivery-operations.js +77 -214
- package/dist/delivery.d.ts +25 -47
- package/dist/delivery.js +14 -46
- package/dist/diagnostic-redaction.js +7 -9
- package/dist/file-changes.d.ts +0 -1
- package/dist/file-changes.js +2 -19
- package/dist/harness-claude.js +8 -6
- package/dist/harness-codex.d.ts +0 -2
- package/dist/harness-codex.js +0 -2
- package/dist/harness-links.js +13 -17
- package/dist/harness.js +3 -7
- package/dist/help.js +4 -3
- package/dist/host-ledger-file-adapter.d.ts +17 -8
- package/dist/host-ledger-file-adapter.js +164 -80
- package/dist/host-ledger.d.ts +55 -50
- package/dist/inbox.d.ts +0 -3
- package/dist/inbox.js +88 -50
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/list.js +1 -4
- package/dist/mcp.js +24 -41
- package/dist/mention-parse.js +3 -9
- package/dist/model.d.ts +11 -2
- package/dist/model.js +1 -1
- package/dist/notifications.d.ts +3 -16
- package/dist/notifications.js +41 -122
- package/dist/opencode-delivery.d.ts +14 -0
- package/dist/opencode-delivery.js +171 -0
- package/dist/opencode.d.ts +39 -18
- package/dist/opencode.js +145 -40
- package/dist/packages/agent-delivery/src/claude-auth.d.ts +13 -0
- package/dist/packages/agent-delivery/src/claude-auth.js +75 -0
- package/dist/packages/agent-delivery/src/claude-native.d.ts +28 -0
- package/dist/packages/agent-delivery/src/claude-native.js +68 -0
- package/dist/packages/agent-delivery/src/claude.d.ts +14 -0
- package/dist/packages/agent-delivery/src/claude.js +66 -0
- package/dist/packages/agent-delivery/src/deadline.d.ts +11 -0
- package/dist/packages/agent-delivery/src/deadline.js +41 -0
- package/dist/packages/agent-delivery/src/errors.d.ts +16 -0
- package/dist/packages/agent-delivery/src/errors.js +41 -0
- package/dist/packages/agent-delivery/src/guards.d.ts +6 -0
- package/dist/packages/agent-delivery/src/guards.js +6 -0
- package/dist/packages/agent-delivery/src/index.d.ts +83 -0
- package/dist/packages/agent-delivery/src/index.js +110 -0
- package/dist/packages/agent-delivery/src/local-endpoint.d.ts +26 -0
- package/dist/packages/agent-delivery/src/local-endpoint.js +114 -0
- package/dist/packages/agent-delivery/src/opencode-native.d.ts +33 -0
- package/dist/packages/agent-delivery/src/opencode-native.js +75 -0
- package/dist/packages/agent-delivery/src/opencode.d.ts +14 -0
- package/dist/packages/agent-delivery/src/opencode.js +127 -0
- package/dist/packages/agent-delivery/src/paseo-native.d.ts +58 -0
- package/dist/packages/agent-delivery/src/paseo-native.js +122 -0
- package/dist/packages/agent-delivery/src/paseo.d.ts +19 -0
- package/dist/packages/agent-delivery/src/paseo.js +106 -0
- package/dist/packages/agent-delivery/src/pi-client.d.ts +10 -0
- package/dist/packages/agent-delivery/src/pi-client.js +106 -0
- package/dist/packages/agent-delivery/src/pi-protocol.d.ts +15 -0
- package/dist/packages/agent-delivery/src/pi-protocol.js +50 -0
- package/dist/packages/agent-delivery/src/pi-send.d.ts +23 -0
- package/dist/packages/agent-delivery/src/pi-send.js +4 -0
- package/dist/packages/agent-delivery/src/pi.d.ts +25 -0
- package/dist/packages/agent-delivery/src/pi.js +209 -0
- package/dist/packages/agent-delivery/src/types.d.ts +120 -0
- package/dist/participant-host.js +12 -13
- package/dist/participant-identity.d.ts +21 -0
- package/dist/participant-identity.js +32 -11
- package/dist/paseo-delivery.d.ts +2 -2
- package/dist/paseo-delivery.js +35 -27
- package/dist/paseo-timeline.js +25 -21
- package/dist/paseo.d.ts +2 -2
- package/dist/paseo.js +1 -2
- package/dist/ports.d.ts +7 -20
- package/dist/presentation-operations.js +16 -4
- package/dist/presentation.d.ts +19 -10
- package/dist/presentation.js +99 -177
- package/dist/registry.d.ts +15 -66
- package/dist/registry.js +45 -123
- package/dist/routes.d.ts +1 -28
- package/dist/routes.js +22 -104
- package/dist/runtime.d.ts +3 -9
- package/dist/runtime.js +14 -67
- package/dist/search.d.ts +0 -2
- package/dist/search.js +3 -10
- package/dist/square-actions.js +48 -72
- package/dist/square-application.js +32 -30
- package/dist/square-core.d.ts +3 -0
- package/dist/square-core.js +22 -5
- package/dist/square-facade.d.ts +2 -0
- package/dist/square-file-adapter.d.ts +2 -1
- package/dist/square-file-adapter.js +6 -9
- package/dist/square-projections.d.ts +40 -45
- package/dist/square-projections.js +60 -74
- package/dist/square-state.js +1 -4
- package/dist/square-storage.d.ts +5 -8
- package/dist/square-storage.js +13 -36
- package/dist/square-wiring.d.ts +2 -7
- package/dist/square-wiring.js +6 -24
- package/dist/stream.js +4 -6
- package/dist/time.js +2 -7
- package/dist/views.d.ts +6 -18
- package/dist/views.js +14 -21
- package/dist/wake-attempts.d.ts +2 -56
- package/dist/wake-attempts.js +15 -110
- package/dist/wake-eligibility.d.ts +43 -0
- package/dist/wake-eligibility.js +106 -0
- package/dist/wake-evidence.d.ts +32 -9
- package/dist/wake-evidence.js +29 -24
- package/dist/wake-sink.d.ts +13 -9
- package/dist/wake-sink.js +35 -54
- package/dist/watch.js +13 -21
- package/extensions/square-pi.js +27 -13
- package/guides/change-waits.md +1 -1
- package/guides/claude-native.md +101 -0
- package/guides/host-ledger.md +3 -1
- package/guides/participant.md +14 -7
- package/guides/pi-native-delivery.md +49 -0
- package/package.json +4 -3
- package/dist/claude-hook.d.ts +0 -10
- package/dist/claude-hook.js +0 -60
- package/dist/paseo-connection.d.ts +0 -15
- package/dist/paseo-connection.js +0 -141
- package/dist/presence.d.ts +0 -2
- package/dist/presence.js +0 -24
- package/dist/presented.d.ts +0 -2
- package/dist/presented.js +0 -10
- package/dist/state-cell.d.ts +0 -14
- package/dist/wake-port.d.ts +0 -23
- package/dist/wake-port.js +0 -27
- /package/dist/{state-cell.js → packages/agent-delivery/src/types.js} +0 -0
package/dist/presentation.js
CHANGED
|
@@ -3,19 +3,13 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { participantIdentity } from './participant-identity.js';
|
|
5
5
|
export { participantIdentity } from './participant-identity.js';
|
|
6
|
-
import { audienceIncludes, audienceOf, MAX_IDENTITY_SET_SIZE
|
|
6
|
+
import { audienceIncludes, audienceOf, MAX_IDENTITY_SET_SIZE } from './square-core.js';
|
|
7
7
|
import { perceiveActivity } from './delivery.js';
|
|
8
|
-
import { actId,
|
|
8
|
+
import { actId, sayNumberFor, HELD_WAIT_BUDGET_MS } from './runtime.js';
|
|
9
9
|
import { formatDuration, formatRelativeTime, formatTimestamp } from './time.js';
|
|
10
10
|
import { compareParticipantActivity } from './decisions.js';
|
|
11
11
|
import { grepSnippet } from './search.js';
|
|
12
12
|
import { style } from './tty-style.js';
|
|
13
|
-
function headerLine(squarePath, opts = {}) {
|
|
14
|
-
const count = opts.participantCount ?? 0;
|
|
15
|
-
const heldSuffix = opts.held ? ' — a hand is raised' : '';
|
|
16
|
-
const line = `· ${displayPath(squarePath)} — ${count} in the square${heldSuffix}`;
|
|
17
|
-
return opts.plain === true ? line : style('dim', line);
|
|
18
|
-
}
|
|
19
13
|
export function displayPath(squarePath, cwd = process.cwd()) {
|
|
20
14
|
if (!path.isAbsolute(squarePath))
|
|
21
15
|
return squarePath.split(path.sep).join('/');
|
|
@@ -32,7 +26,10 @@ export function displayPath(squarePath, cwd = process.cwd()) {
|
|
|
32
26
|
return displayed.split(path.sep).join('/');
|
|
33
27
|
}
|
|
34
28
|
export function withPathOutput(squarePath, body = '', opts = {}) {
|
|
35
|
-
|
|
29
|
+
const count = opts.participantCount ?? 0;
|
|
30
|
+
const heldSuffix = opts.held ? ' — a hand is raised' : '';
|
|
31
|
+
const line = `· ${displayPath(squarePath)} — ${count} in the square${heldSuffix}`;
|
|
32
|
+
return [opts.plain === true ? line : style('dim', line), ...(body === '' ? [] : ['', body])].join('\n') + '\n';
|
|
36
33
|
}
|
|
37
34
|
/** The same header/blank/body layout as withPathOutput, for refusal bodies written to stderr. */
|
|
38
35
|
export function formatRefusal(squarePath, bodyLines, opts = {}) {
|
|
@@ -72,35 +69,7 @@ function formatAge(ms) {
|
|
|
72
69
|
return `${Math.max(0, ms)}ms`;
|
|
73
70
|
return `${Math.floor(ms / 1000)}s`;
|
|
74
71
|
}
|
|
75
|
-
function pluralize(count, singular, plural = `${singular}s`) {
|
|
76
|
-
return count === 1 ? singular : plural;
|
|
77
|
-
}
|
|
78
72
|
const PRESENCE_WINDOW_MS = 8 * 60 * 60 * 1000;
|
|
79
|
-
function presenceGlyph(participant) {
|
|
80
|
-
if (participant.state === 'done')
|
|
81
|
-
return '○';
|
|
82
|
-
if (participant.presence === 'watching')
|
|
83
|
-
return '◎';
|
|
84
|
-
if (participant.lastActiveAt !== undefined)
|
|
85
|
-
return '●';
|
|
86
|
-
return '○';
|
|
87
|
-
}
|
|
88
|
-
function styledPresenceGlyph(participant) {
|
|
89
|
-
const glyph = presenceGlyph(participant);
|
|
90
|
-
return glyph === '○' ? style('dim', glyph) : glyph;
|
|
91
|
-
}
|
|
92
|
-
function presenceText(participant, now) {
|
|
93
|
-
if (participant.state === 'done') {
|
|
94
|
-
return participant.lastActiveAt === undefined ? 'stepped out of the square' : `stepped out of the square · ${formatRelativeTime(participant.lastActiveAt, now)}`;
|
|
95
|
-
}
|
|
96
|
-
if (participant.presence === 'watching') {
|
|
97
|
-
const at = participant.lastActiveAt;
|
|
98
|
-
return at === undefined ? 'catching' : `catching · ${formatRelativeTime(at, now)}`;
|
|
99
|
-
}
|
|
100
|
-
if (participant.lastActiveAt === undefined)
|
|
101
|
-
return 'quiet';
|
|
102
|
-
return participant.activityCount > 0 ? `${formatRelativeTime(participant.lastActiveAt, now)}` : `quiet · ${formatRelativeTime(participant.lastActiveAt, now)}`;
|
|
103
|
-
}
|
|
104
73
|
export function renderPresenceLines(participants, now, limit = 5) {
|
|
105
74
|
const recent = participants
|
|
106
75
|
.filter((p) => p.state === 'done' || p.presence === 'watching' || (p.lastActiveAt !== undefined && now - p.lastActiveAt <= PRESENCE_WINDOW_MS))
|
|
@@ -108,16 +77,25 @@ export function renderPresenceLines(participants, now, limit = 5) {
|
|
|
108
77
|
const shown = recent.slice(0, limit);
|
|
109
78
|
if (shown.length === 0)
|
|
110
79
|
return [style('dim', ' ○ nobody nearby')];
|
|
111
|
-
const lines = shown.map((p) =>
|
|
80
|
+
const lines = shown.map((p) => {
|
|
81
|
+
const glyph = p.state === 'done' ? '○' : p.presence === 'watching' ? '◎' : p.lastActiveAt !== undefined ? '●' : '○';
|
|
82
|
+
const text = p.state === 'done'
|
|
83
|
+
? (p.lastActiveAt === undefined ? 'stepped out of the square' : `stepped out of the square · ${formatRelativeTime(p.lastActiveAt, now)}`)
|
|
84
|
+
: p.presence === 'watching'
|
|
85
|
+
? (p.lastActiveAt === undefined ? 'is nearby · catching' : `is nearby · catching · ${formatRelativeTime(p.lastActiveAt, now)}`)
|
|
86
|
+
: p.lastActiveAt === undefined ? 'is nearby · quiet'
|
|
87
|
+
: p.activityCount > 0 ? `is nearby · ${formatRelativeTime(p.lastActiveAt, now)}` : `is nearby · quiet · ${formatRelativeTime(p.lastActiveAt, now)}`;
|
|
88
|
+
return ` ${glyph === '○' ? style('dim', glyph) : glyph} ${participantIdentity(p.name)}${style('dim', ` ${text}`)}`;
|
|
89
|
+
});
|
|
112
90
|
const remaining = recent.length - shown.length;
|
|
113
91
|
if (remaining > 0)
|
|
114
92
|
lines.push(style('dim', ` ○ … ${remaining} more nearby`));
|
|
115
93
|
return lines;
|
|
116
94
|
}
|
|
117
95
|
const EXPRESS_HINTS = [
|
|
118
|
-
'*asterisks* are your body —
|
|
119
|
-
"
|
|
120
|
-
|
|
96
|
+
'*asterisks* are your body — slam a table, shrug, sketch in the air',
|
|
97
|
+
"answer someone's actual words — they're standing right there",
|
|
98
|
+
"say the half-shaped thing — that's what the square is for",
|
|
121
99
|
];
|
|
122
100
|
export function expressHintLine(ownActivityCount) {
|
|
123
101
|
if (ownActivityCount !== 1 && ownActivityCount % 5 !== 0)
|
|
@@ -138,18 +116,14 @@ export function truncateExternalDiagnostic(diagnostic) {
|
|
|
138
116
|
return diagnostic;
|
|
139
117
|
return `${truncateChars(diagnostic, EXTERNAL_DIAGNOSTIC_MAX_CHARS - 1).text}…`;
|
|
140
118
|
}
|
|
141
|
-
function
|
|
119
|
+
function previewBodyFacts(body, maxLen = BODY_PREVIEW_LENGTH) {
|
|
142
120
|
const preview = truncateChars(body, maxLen);
|
|
143
|
-
return
|
|
121
|
+
return {
|
|
122
|
+
text: preview.remaining === 0 ? preview.text : `${preview.text}\n${style('dim', `… ${preview.remaining} more chars`)}`,
|
|
123
|
+
clipped: preview.remaining > 0,
|
|
124
|
+
};
|
|
144
125
|
}
|
|
145
126
|
const UNREAD_PREVIEW_CHARS = 120;
|
|
146
|
-
export function previewActivityBody(body) {
|
|
147
|
-
const compact = body.replace(/\s+/g, ' ').trim();
|
|
148
|
-
if (compact === '')
|
|
149
|
-
return '(empty)';
|
|
150
|
-
const preview = truncateChars(compact, UNREAD_PREVIEW_CHARS);
|
|
151
|
-
return preview.remaining === 0 ? preview.text : `${preview.text}${style('dim', `… (+${preview.remaining} chars)`)}`;
|
|
152
|
-
}
|
|
153
127
|
export function renderRoomChangeText(event) {
|
|
154
128
|
const actor = event.actor ?? 'someone';
|
|
155
129
|
const identity = actor === 'someone' ? actor : participantIdentity(actor);
|
|
@@ -163,34 +137,34 @@ export function renderRoomChangeText(event) {
|
|
|
163
137
|
case 'resume':
|
|
164
138
|
return `${identity} lowered the hand`;
|
|
165
139
|
case 'listen':
|
|
166
|
-
return `${identity}
|
|
140
|
+
return `${identity} turned an ear toward ${participantIdentity(event.target)}`;
|
|
167
141
|
case 'ignore':
|
|
168
|
-
return `${identity}
|
|
142
|
+
return `${identity} turned away from ${participantIdentity(event.target)}`;
|
|
169
143
|
}
|
|
170
144
|
}
|
|
171
145
|
function renderedBody(body, maxChars) {
|
|
172
146
|
if (!body)
|
|
173
|
-
return '';
|
|
174
|
-
return maxChars === undefined ? body :
|
|
147
|
+
return { text: '', clipped: false };
|
|
148
|
+
return maxChars === undefined ? { text: body, clipped: false } : previewBodyFacts(body, maxChars);
|
|
175
149
|
}
|
|
176
150
|
function bodySuffix(body) {
|
|
177
151
|
if (body === '')
|
|
178
152
|
return '';
|
|
179
153
|
return `\n${body.split('\n').map((line) => ` ${line}`).join('\n')}`;
|
|
180
154
|
}
|
|
181
|
-
|
|
155
|
+
function renderEventCliFacts(event, opts = {}) {
|
|
182
156
|
const now = opts.now;
|
|
183
157
|
const maxBody = opts.preview;
|
|
184
158
|
switch (event.kind) {
|
|
185
159
|
case 'join':
|
|
186
|
-
return `· ${renderRoomChangeText(event)}
|
|
160
|
+
return { text: `· ${renderRoomChangeText(event)}`, bodyClipped: false };
|
|
187
161
|
case 'hold':
|
|
188
|
-
return `· ${renderRoomChangeText(event)}
|
|
162
|
+
return { text: `· ${renderRoomChangeText(event)}`, bodyClipped: false };
|
|
189
163
|
case 'resume':
|
|
190
|
-
return `${style('release', '✓')} ${renderRoomChangeText(event)}
|
|
164
|
+
return { text: `${style('release', '✓')} ${renderRoomChangeText(event)}`, bodyClipped: false };
|
|
191
165
|
case 'listen':
|
|
192
166
|
case 'ignore':
|
|
193
|
-
return `· ${renderRoomChangeText(event)}
|
|
167
|
+
return { text: `· ${renderRoomChangeText(event)}`, bodyClipped: false };
|
|
194
168
|
case 'say': {
|
|
195
169
|
const body = renderedBody(event.body, maxBody);
|
|
196
170
|
const mention = opts.mention;
|
|
@@ -199,16 +173,22 @@ export function renderEventCli(event, opts = {}) {
|
|
|
199
173
|
: '';
|
|
200
174
|
const replySuffix = event.reply === undefined ? '' : ` · replies to ${actId(event.reply)}`;
|
|
201
175
|
const meta = ` #${opts.actNumber ?? 1} · ${actId(event)} · ${formatRelativeTime(event.at, now)}${mentionSuffix}${replySuffix}`;
|
|
202
|
-
return `● ${participantIdentity(event.actor)}${style('dim', meta)}${bodySuffix(body)}
|
|
176
|
+
return { text: `● ${participantIdentity(event.actor)}${style('dim', meta)}${bodySuffix(body.text)}`, bodyClipped: body.clipped };
|
|
203
177
|
}
|
|
204
178
|
case 'done': {
|
|
205
179
|
const body = renderedBody(event.body, maxBody);
|
|
206
|
-
return
|
|
180
|
+
return {
|
|
181
|
+
text: `${style('dim', '○')} ${participantIdentity(event.actor)} stepped out of the square — done${style('dim', ` · ${actId(event)} · ${formatRelativeTime(event.at, now)}`)}${bodySuffix(body.text)}`,
|
|
182
|
+
bodyClipped: body.clipped,
|
|
183
|
+
};
|
|
207
184
|
}
|
|
208
185
|
case 'read':
|
|
209
|
-
return '';
|
|
186
|
+
return { text: '', bodyClipped: false };
|
|
210
187
|
}
|
|
211
188
|
}
|
|
189
|
+
export function renderEventCli(event, opts = {}) {
|
|
190
|
+
return renderEventCliFacts(event, opts).text;
|
|
191
|
+
}
|
|
212
192
|
function renderPresenceOnlySay(event, opts = {}) {
|
|
213
193
|
const audience = audienceOf(event);
|
|
214
194
|
const targets = audience.kind === 'bell' ? [] : audience.names;
|
|
@@ -224,19 +204,22 @@ function renderPresenceOnlySay(event, opts = {}) {
|
|
|
224
204
|
].join(' and ')}`;
|
|
225
205
|
return `● ${participantIdentity(event.actor)}${meta}\n${style('dim', ` talked to${dest}`)}`;
|
|
226
206
|
}
|
|
227
|
-
export function
|
|
207
|
+
export function renderAmbientEventFacts(event, viewer, opts = {}) {
|
|
228
208
|
if (event.kind !== 'say')
|
|
229
|
-
return
|
|
209
|
+
return renderEventCliFacts(event, opts);
|
|
230
210
|
if (opts.perception === undefined && opts.squareState === undefined) {
|
|
231
211
|
throw new Error('Ambient say rendering requires a settled perception or SquareState');
|
|
232
212
|
}
|
|
233
213
|
const seen = opts.perception ?? perceiveActivity(opts.squareState, event, viewer);
|
|
234
214
|
if (seen === 'presence') {
|
|
235
215
|
const presence = renderPresenceOnlySay(event, opts);
|
|
236
|
-
const body = opts.presencePreview === undefined ? '' : renderedBody(event.body, opts.presencePreview);
|
|
237
|
-
return `${presence}${bodySuffix(body)}
|
|
216
|
+
const body = opts.presencePreview === undefined ? { text: '', clipped: false } : renderedBody(event.body, opts.presencePreview);
|
|
217
|
+
return { text: `${presence}${bodySuffix(body.text)}`, bodyClipped: body.clipped };
|
|
238
218
|
}
|
|
239
|
-
return
|
|
219
|
+
return renderEventCliFacts(event, opts);
|
|
220
|
+
}
|
|
221
|
+
export function renderAmbientEvent(event, viewer, opts = {}) {
|
|
222
|
+
return renderAmbientEventFacts(event, viewer, opts).text;
|
|
240
223
|
}
|
|
241
224
|
function draftSavedLines(draftPath) {
|
|
242
225
|
return draftPath === undefined ? [] : [style('dim', `· draft kept: ${draftPath}`)];
|
|
@@ -256,14 +239,16 @@ function renderUnreadSummary(opts) {
|
|
|
256
239
|
if (preview.perception === 'presence') {
|
|
257
240
|
return style('dim', ` · ${participantIdentity(item.name)} spoke — ${formatAge(item.latestActivityAgeMs)} ago · ${rendered.replace(/\n/g, ' ')}`);
|
|
258
241
|
}
|
|
259
|
-
|
|
242
|
+
const compact = preview.act.body.replace(/\s+/g, ' ').trim();
|
|
243
|
+
const bodyPreview = compact === '' ? { text: '(empty)', remaining: 0 } : truncateChars(compact, UNREAD_PREVIEW_CHARS);
|
|
244
|
+
const bodyText = bodyPreview.remaining === 0 ? bodyPreview.text : `${bodyPreview.text}${style('dim', `… (+${bodyPreview.remaining} chars)`)}`;
|
|
245
|
+
return style('dim', ` · ${participantIdentity(item.name)} spoke — ${formatAge(item.latestActivityAgeMs)} ago · "${bodyText}"`);
|
|
260
246
|
}),
|
|
261
247
|
]),
|
|
262
248
|
...(remainingSummaries === 0 ? [] : [style('dim', ` · ${remainingSummaries} more participants have unread activity`)]),
|
|
263
|
-
...opts.roomChanges.map((act) => style('dim', ` · ${renderRoomChangeText(act)}`)),
|
|
264
249
|
];
|
|
265
250
|
}
|
|
266
|
-
export function renderPendingFeed(history, publicItems,
|
|
251
|
+
export function renderPendingFeed(history, publicItems, viewer = '', squareState) {
|
|
267
252
|
const lines = [];
|
|
268
253
|
for (const act of publicItems) {
|
|
269
254
|
const rendered = renderAmbientEvent(act, viewer, {
|
|
@@ -273,19 +258,13 @@ export function renderPendingFeed(history, publicItems, roomChanges, viewer = ''
|
|
|
273
258
|
if (rendered !== '')
|
|
274
259
|
lines.push(rendered);
|
|
275
260
|
}
|
|
276
|
-
const publicIndexes = new Set(publicItems.map((item) => item.index));
|
|
277
|
-
for (const act of roomChanges) {
|
|
278
|
-
if (publicIndexes.has(act.index))
|
|
279
|
-
continue;
|
|
280
|
-
lines.push(`· ${renderRoomChangeText(act)}`);
|
|
281
|
-
}
|
|
282
261
|
return lines.join('\n\n');
|
|
283
262
|
}
|
|
284
263
|
export function renderActivityBlocked(opts) {
|
|
285
264
|
const readNowCommand = `${participantCommandPrefix(opts.squarePath, opts.name)} catch --now`;
|
|
286
265
|
return withPathOutput(opts.squarePath, [
|
|
287
266
|
`${style('blocked', '✕')} your activity doesn't land — the square moved behind your back`,
|
|
288
|
-
...renderUnreadSummary({ activitySummaries: opts.activitySummaries,
|
|
267
|
+
...renderUnreadSummary({ activitySummaries: opts.activitySummaries, viewer: opts.name }),
|
|
289
268
|
...draftSavedLines(opts.draftPath),
|
|
290
269
|
`${readNowCommand}`,
|
|
291
270
|
' · take it in, then retry:',
|
|
@@ -306,18 +285,27 @@ export function renderActivityUncertain(opts) {
|
|
|
306
285
|
`${commandPrefix(opts.squarePath)} history${opts.landedId === undefined ? ' --limit 10' : ` --at ${opts.landedId}`} --no-truncate`,
|
|
307
286
|
], opts);
|
|
308
287
|
}
|
|
288
|
+
/** A blank or whitespace hold reason is absent, never an empty sensory line. */
|
|
289
|
+
function holdReasonLines(reason) {
|
|
290
|
+
const text = reason?.trim() ?? '';
|
|
291
|
+
return text === '' ? [] : [style('dim', ` · ${text}`)];
|
|
292
|
+
}
|
|
293
|
+
function heldMainLine(holder, styled) {
|
|
294
|
+
const glyph = styled ? style('blocked', '✕') : '✕';
|
|
295
|
+
const who = holder === undefined ? 'a hand is raised' : `${participantIdentity(holder)} has a hand raised`;
|
|
296
|
+
return `${glyph} ${who} — voices drop, yours too`;
|
|
297
|
+
}
|
|
309
298
|
export function renderExpressWaiting(opts) {
|
|
310
299
|
if (opts.reason === 'throttled') {
|
|
311
300
|
return [
|
|
312
|
-
'✕ the square is packed',
|
|
313
|
-
` ·
|
|
301
|
+
'✕ the square is packed — shoulder to shoulder',
|
|
302
|
+
` · a lull opens in ${formatDuration(opts.delayMs)}`,
|
|
314
303
|
' · --no-wait saves a draft and returns now',
|
|
315
304
|
].join('\n');
|
|
316
305
|
}
|
|
317
|
-
const holder = opts.holder === undefined ? 'a hand is raised' : `${participantIdentity(opts.holder)} raised a hand`;
|
|
318
306
|
return [
|
|
319
|
-
|
|
320
|
-
...(opts.holdReason
|
|
307
|
+
heldMainLine(opts.holder, false),
|
|
308
|
+
...holdReasonLines(opts.holdReason),
|
|
321
309
|
` · your activity is waiting — after ${formatDuration(HELD_WAIT_BUDGET_MS)} it saves a draft and stops`,
|
|
322
310
|
' · --no-wait saves a draft and returns now',
|
|
323
311
|
].join('\n');
|
|
@@ -326,31 +314,19 @@ export function renderExpressNoWait(opts) {
|
|
|
326
314
|
const retryCommand = opts.retryCommand;
|
|
327
315
|
const lines = opts.reason === 'throttled'
|
|
328
316
|
? [
|
|
329
|
-
`${style('blocked', '✕')} the square is packed`,
|
|
330
|
-
` ·
|
|
317
|
+
`${style('blocked', '✕')} the square is packed — shoulder to shoulder`,
|
|
318
|
+
` · a lull opens in ${formatDuration(opts.delayMs)}`,
|
|
331
319
|
...draftSavedLines(opts.draftPath),
|
|
332
320
|
`${withDraftInput(retryCommand, opts.draftPath)}`,
|
|
333
321
|
]
|
|
334
322
|
: [
|
|
335
|
-
|
|
336
|
-
|
|
323
|
+
heldMainLine(opts.holder, true),
|
|
324
|
+
...holdReasonLines(opts.holdReason),
|
|
337
325
|
...draftSavedLines(opts.draftPath),
|
|
338
326
|
`${withDraftInput(retryCommand, opts.draftPath)}`,
|
|
339
327
|
];
|
|
340
328
|
return withPathOutput(opts.squarePath, lines.join('\n'), { participantCount: opts.participantCount, held: opts.held });
|
|
341
329
|
}
|
|
342
|
-
export function renderPublicTail(squareState, events, lastN, now, viewer = '') {
|
|
343
|
-
const publicItems = publicActs(events);
|
|
344
|
-
const selected = lastN == null ? publicItems : publicItems.slice(-lastN);
|
|
345
|
-
const preview = lastN == null ? undefined : BODY_PREVIEW_LENGTH;
|
|
346
|
-
return selected
|
|
347
|
-
.map((event) => renderAmbientEvent(event, viewer, { now, preview, actNumber: event.kind === 'say' ? sayNumberFor(events, event) : undefined, squareState }))
|
|
348
|
-
.filter(Boolean)
|
|
349
|
-
.join('\n\n');
|
|
350
|
-
}
|
|
351
|
-
function lastPresenceAnchor(squareState, name, landed) {
|
|
352
|
-
return presenceAnchor(squareState, name, landed);
|
|
353
|
-
}
|
|
354
330
|
export function renderPresenceAnchor(names) {
|
|
355
331
|
const visibleNames = names.slice(0, MAX_IDENTITY_SET_SIZE);
|
|
356
332
|
const participants = visibleNames.map((name) => participantIdentity(name)).join(', ');
|
|
@@ -358,45 +334,7 @@ export function renderPresenceAnchor(names) {
|
|
|
358
334
|
const suffix = remaining === 0 ? '' : ` and ${remaining} more`;
|
|
359
335
|
return style('dim', names.length === 1 ? `→ ${participants} was here` : `→ ${participants}${suffix} were here`);
|
|
360
336
|
}
|
|
361
|
-
export function renderActivitiesView(squareState, visible, lastN, noTruncate, squarePath, viewer = '', mode = 'ambient') {
|
|
362
|
-
const publicVisible = visible.filter((act) => act.kind === 'say' || act.kind === 'done');
|
|
363
|
-
const shown = lastN == null ? publicVisible : publicVisible.slice(-lastN);
|
|
364
|
-
const previewLen = noTruncate ? undefined : BODY_PREVIEW_LENGTH;
|
|
365
|
-
const markers = new Map();
|
|
366
|
-
const landed = replayLandedAudiences(squareState.acts);
|
|
367
|
-
for (const participant of rosterNames(squareState)) {
|
|
368
|
-
const anchor = lastPresenceAnchor(squareState, participant, landed);
|
|
369
|
-
if (anchor >= 0)
|
|
370
|
-
markers.set(anchor, [...(markers.get(anchor) ?? []), participant]);
|
|
371
|
-
}
|
|
372
|
-
const chunks = [];
|
|
373
|
-
for (const act of shown) {
|
|
374
|
-
const opts = {
|
|
375
|
-
preview: previewLen,
|
|
376
|
-
actNumber: act.kind === 'say' ? sayNumberFor(squareState.acts, act) : undefined,
|
|
377
|
-
};
|
|
378
|
-
const rendered = mode === 'archive'
|
|
379
|
-
? renderEventCli(act, opts)
|
|
380
|
-
: renderAmbientEvent(act, viewer, { ...opts, squareState });
|
|
381
|
-
if (rendered !== '')
|
|
382
|
-
chunks.push(rendered);
|
|
383
|
-
const participants = markers.get(act.index);
|
|
384
|
-
if (participants !== undefined)
|
|
385
|
-
chunks.push(renderPresenceAnchor(participants));
|
|
386
|
-
}
|
|
387
|
-
if (chunks.length === 0)
|
|
388
|
-
return 'latest\n ○ no public activity in this view';
|
|
389
|
-
if (previewLen !== undefined) {
|
|
390
|
-
const truncated = shown.some((act) => act.kind === 'say' && act.body.length > previewLen && (mode === 'archive' || perceiveActivity(squareState, act, viewer) === 'full'));
|
|
391
|
-
if (truncated)
|
|
392
|
-
chunks.push(`${commandPrefix(squarePath)} history --no-truncate`);
|
|
393
|
-
}
|
|
394
|
-
return chunks.join('\n\n');
|
|
395
|
-
}
|
|
396
337
|
const GREP_PREVIEW_CHARS = 160;
|
|
397
|
-
function highlightGrepMatch(text) {
|
|
398
|
-
return style('match', text);
|
|
399
|
-
}
|
|
400
338
|
export function renderGrepActivitiesView(visible, totalMatches, noTruncate, squarePath, pattern, fixed = false, perception) {
|
|
401
339
|
const publicVisible = visible.filter((act) => act.kind === 'say' || act.kind === 'done');
|
|
402
340
|
if (totalMatches === 0)
|
|
@@ -418,14 +356,14 @@ export function renderGrepActivitiesView(visible, totalMatches, noTruncate, squa
|
|
|
418
356
|
}
|
|
419
357
|
const snippet = grepSnippet(rawBody, pattern, GREP_PREVIEW_CHARS, fixed);
|
|
420
358
|
if (snippet === undefined) {
|
|
421
|
-
const preview =
|
|
359
|
+
const preview = previewBodyFacts(rawBody, GREP_PREVIEW_CHARS).text;
|
|
422
360
|
chunks.push(`${header}${preview === '' ? '' : `\n ${preview}`}`);
|
|
423
361
|
continue;
|
|
424
362
|
}
|
|
425
363
|
const clippedBefore = snippet.beforeOmitted > 0;
|
|
426
364
|
const clippedAfter = snippet.afterOmitted > 0;
|
|
427
365
|
truncated ||= clippedBefore || clippedAfter;
|
|
428
|
-
const text = `${clippedBefore ? '… ' : ''}${snippet.before}${
|
|
366
|
+
const text = `${clippedBefore ? '… ' : ''}${snippet.before}${style('match', snippet.match)}${snippet.after}${clippedAfter ? ' …' : ''}`;
|
|
429
367
|
const omitted = clippedBefore || clippedAfter
|
|
430
368
|
? `\n${style('dim', ` · ${snippet.beforeOmitted} chars before · ${snippet.afterOmitted} chars after`)}`
|
|
431
369
|
: '';
|
|
@@ -439,18 +377,16 @@ export function renderGrepActivitiesView(visible, totalMatches, noTruncate, squa
|
|
|
439
377
|
}
|
|
440
378
|
return chunks.join('\n\n');
|
|
441
379
|
}
|
|
442
|
-
function
|
|
443
|
-
|
|
380
|
+
export function renderActivityLimit(opts) {
|
|
381
|
+
// The cap wording lives inside the count: the speaker is simply spent.
|
|
382
|
+
const spoken = opts.count !== undefined && opts.hardCap !== undefined ? ` — ${opts.count}/${opts.hardCap} spoken` : '';
|
|
444
383
|
const doneCommand = `${participantCommandPrefix(opts.squarePath, opts.name)} done`;
|
|
445
|
-
return [
|
|
446
|
-
`${style('blocked', '✕')}
|
|
384
|
+
return withPathOutput(opts.squarePath, [
|
|
385
|
+
`${style('blocked', '✕')} nothing left in you${spoken}`,
|
|
447
386
|
...draftSavedLines(opts.draftPath),
|
|
448
387
|
' · your draft stays unsent; done only steps out',
|
|
449
388
|
doneCommand,
|
|
450
|
-
].join('\n');
|
|
451
|
-
}
|
|
452
|
-
export function renderActivityLimit(opts) {
|
|
453
|
-
return withPathOutput(opts.squarePath, renderActivityLimitBody(opts), { participantCount: opts.participantCount, held: opts.held });
|
|
389
|
+
].join('\n'), { participantCount: opts.participantCount, held: opts.held });
|
|
454
390
|
}
|
|
455
391
|
export function renderWatchAlreadyActive(opts) {
|
|
456
392
|
return [
|
|
@@ -480,53 +416,39 @@ export function renderWatchStatus(opts) {
|
|
|
480
416
|
case 'stale':
|
|
481
417
|
case 'empty-now': {
|
|
482
418
|
const prefix = participantCommandPrefix(opts.squarePath, opts.name);
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
419
|
+
// Quiet graduates with the idle length; an empty catch has no idle budget to report.
|
|
420
|
+
const idleMs = opts.idleMs;
|
|
421
|
+
const quiet = idleMs !== undefined && idleMs >= 60 * 60 * 1000
|
|
422
|
+
? style('dim', `○ dust lies thick — ${formatDuration(idleMs)} of quiet`)
|
|
423
|
+
: idleMs !== undefined && idleMs >= 60 * 1000
|
|
424
|
+
? style('dim', `○ dust settles on the flagstones — ${formatDuration(idleMs)} of quiet`)
|
|
425
|
+
: style('dim', '○ only footsteps in the square — nothing new for you');
|
|
426
|
+
// The quiet report never repeats the catch just run.
|
|
427
|
+
const hints = [`${prefix} catch --idle 30m`];
|
|
486
428
|
return [
|
|
487
429
|
quiet,
|
|
488
|
-
...(opts.showCatchHint === false
|
|
489
|
-
? []
|
|
490
|
-
: [`${prefix} catch --idle 30m`, ` glance: ${prefix} catch --now`]),
|
|
430
|
+
...(opts.showCatchHint === false ? [] : hints),
|
|
491
431
|
...presenceLines,
|
|
492
432
|
].join('\n');
|
|
493
433
|
}
|
|
494
434
|
case 'quorum':
|
|
495
435
|
return [`${style('release', '✓')} everyone else has left — the square is yours alone`, `${participantCommandPrefix(opts.squarePath, opts.name)} done`].join('\n');
|
|
496
|
-
case 'capped':
|
|
497
|
-
|
|
436
|
+
case 'capped': {
|
|
437
|
+
const spoken = opts.hardCap === undefined || opts.hardCap === null
|
|
438
|
+
? ''
|
|
439
|
+
: ` — ${opts.ownActivityCount ?? 0}/${opts.hardCap} spoken`;
|
|
440
|
+
return [`${style('blocked', '✕')} nothing left in you${spoken}`, `${participantCommandPrefix(opts.squarePath, opts.name)} done`].join('\n');
|
|
441
|
+
}
|
|
498
442
|
}
|
|
499
443
|
}
|
|
500
|
-
function renderRoomChanges(changes) {
|
|
501
|
-
if (changes.length === 0)
|
|
502
|
-
return '';
|
|
503
|
-
return [`${style('changed', '▲')} while your back was turned`, ...changes.map((act) => ` · ${renderRoomChangeText(act)}`)].join('\n');
|
|
504
|
-
}
|
|
505
444
|
export function renderDoctorClean() {
|
|
506
445
|
return '✓ no problems found';
|
|
507
446
|
}
|
|
508
447
|
export function renderDoctorUnfixable(reason) {
|
|
509
448
|
return ['✕ unreadable artifact', ` · ${truncateExternalDiagnostic(reason)}`].join('\n');
|
|
510
449
|
}
|
|
511
|
-
export function renderWatchOutput(history, publicItems,
|
|
450
|
+
export function renderWatchOutput(history, publicItems, opts) {
|
|
512
451
|
const sections = [];
|
|
513
|
-
if (opts.stalePartial) {
|
|
514
|
-
const prefix = participantCommandPrefix(opts.squarePath, opts.viewer);
|
|
515
|
-
const quiet = opts.idleMs === undefined
|
|
516
|
-
? '○ only footsteps in the square — nothing new for you'
|
|
517
|
-
: `○ ${formatDuration(opts.idleMs)} of quiet — nothing else for you`;
|
|
518
|
-
sections.push([
|
|
519
|
-
quiet,
|
|
520
|
-
...(opts.showCatchHint === false
|
|
521
|
-
? []
|
|
522
|
-
: [`${prefix} catch --idle 30m`, ` glance: ${prefix} catch --now`]),
|
|
523
|
-
].join('\n'));
|
|
524
|
-
}
|
|
525
|
-
const publicIndexes = new Set(publicItems.map((item) => item.index));
|
|
526
|
-
const presenceChanges = roomChanges.filter(({ index }) => !publicIndexes.has(index));
|
|
527
|
-
const room = renderRoomChanges(presenceChanges);
|
|
528
|
-
if (room !== '')
|
|
529
|
-
sections.push(room);
|
|
530
452
|
if (publicItems.length > 0) {
|
|
531
453
|
const rendered = publicItems
|
|
532
454
|
.map((act) => renderAmbientEvent(act, opts.viewer, {
|
package/dist/registry.d.ts
CHANGED
|
@@ -1,51 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
import { type
|
|
3
|
-
import type { HostLedgerPort, PresenceRecord } from './host-ledger.js';
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
sessionId: string;
|
|
7
|
-
name: string;
|
|
8
|
-
squarePath: string;
|
|
9
|
-
channel: SessionChannel;
|
|
10
|
-
child: boolean;
|
|
11
|
-
route?: PresenceRecord['route'];
|
|
12
|
-
updatedAt: number;
|
|
13
|
-
epoch: number;
|
|
14
|
-
}
|
|
15
|
-
export interface RegistryWriteOptions {
|
|
16
|
-
channel?: SessionChannel;
|
|
17
|
-
child?: boolean;
|
|
18
|
-
route?: PresenceRecord['route'];
|
|
19
|
-
at?: number;
|
|
20
|
-
env?: NodeJS.ProcessEnv;
|
|
21
|
-
}
|
|
22
|
-
type PresenceWithEpoch = PresenceRecord & {
|
|
23
|
-
readonly epoch?: number;
|
|
24
|
-
};
|
|
25
|
-
export declare function registryPath(env?: NodeJS.ProcessEnv): string;
|
|
26
|
-
export declare function canonicalSquarePath(squarePath: string): Promise<string>;
|
|
27
|
-
export declare function presenceEpoch(record: PresenceWithEpoch | undefined): number;
|
|
28
|
-
/** Runs `fn` inside the ownership claim critical section, under the same lock as claims and finalize. */
|
|
29
|
-
export declare function withOwnershipClaimLock<T>(env: NodeJS.ProcessEnv, fn: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
30
|
-
export declare function recordJoin(sessionId: string, name: string, squarePath: string, options?: RegistryWriteOptions): Promise<void>;
|
|
31
|
-
export declare function recordDone(sessionId: string, name: string, squarePath: string, options?: RegistryWriteOptions): Promise<void>;
|
|
32
|
-
export declare function readActiveBindings(now?: number, env?: NodeJS.ProcessEnv): Promise<RegistryBinding[]>;
|
|
33
|
-
export declare function lookupSessionBindings(sessionId: string, now?: number, env?: NodeJS.ProcessEnv): Promise<RegistryBinding[]>;
|
|
34
|
-
export declare function lookupSession(sessionId: string, now?: number, env?: NodeJS.ProcessEnv): Promise<Array<{
|
|
35
|
-
name: string;
|
|
36
|
-
squarePath: string;
|
|
37
|
-
}>>;
|
|
38
|
-
export declare function lookupParticipant(squarePath: string, name: string, now?: number, env?: NodeJS.ProcessEnv): Promise<RegistryBinding[]>;
|
|
39
|
-
export declare function localParticipantOwner(squarePath: string, name: string, env?: NodeJS.ProcessEnv, now?: number): Promise<string | undefined>;
|
|
40
|
-
export declare function localParticipantName(squarePath: string, env?: NodeJS.ProcessEnv): Promise<string | undefined>;
|
|
1
|
+
/** Participant ownership and local session identity on the host ledger. */
|
|
2
|
+
import { type FileHostLedgerPort } from './host-ledger-file-adapter.js';
|
|
3
|
+
import type { HostLedgerPort, PresenceChannel, PresenceRecord } from './host-ledger.js';
|
|
4
|
+
export declare function presenceEpoch(record: PresenceRecord | undefined): number;
|
|
5
|
+
export declare function localParticipantName(squarePath: string, hostLedger: HostLedgerPort, env?: NodeJS.ProcessEnv): Promise<string | undefined>;
|
|
41
6
|
export declare function squareAssignedParticipantName(env?: NodeJS.ProcessEnv): string | undefined;
|
|
42
|
-
export type CurrentParticipantBinding = Readonly<{
|
|
43
|
-
created: boolean;
|
|
44
|
-
sessionId: string;
|
|
45
|
-
}>;
|
|
46
7
|
export type OwnershipClaim = {
|
|
47
8
|
readonly status: 'acquired' | 'owned';
|
|
48
|
-
readonly record:
|
|
9
|
+
readonly record: PresenceRecord;
|
|
49
10
|
readonly sessionId: string;
|
|
50
11
|
readonly epoch: number;
|
|
51
12
|
} | undefined;
|
|
@@ -62,43 +23,31 @@ export type TakeoverRunResult<T> = {
|
|
|
62
23
|
readonly status: 'busy';
|
|
63
24
|
readonly epoch: number;
|
|
64
25
|
};
|
|
65
|
-
export declare function readParticipantOwner(squarePath: string, name: string,
|
|
66
|
-
export declare function sessionOwnsParticipant(squarePath: string, name: string, sessionId: string,
|
|
67
|
-
export declare function releaseSessionParticipantClaim(
|
|
68
|
-
export declare function claimSessionParticipant(squarePath: string, name: string, env?: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<OwnershipClaim>;
|
|
26
|
+
export declare function readParticipantOwner(squarePath: string, name: string, hostLedger: HostLedgerPort): Promise<PresenceRecord | undefined>;
|
|
27
|
+
export declare function sessionOwnsParticipant(squarePath: string, name: string, sessionId: string, hostLedger: HostLedgerPort, expectedEpoch?: number): Promise<boolean>;
|
|
28
|
+
export declare function releaseSessionParticipantClaim(hostLedger: HostLedgerPort, claim: OwnershipClaim): Promise<void>;
|
|
29
|
+
export declare function claimSessionParticipant(squarePath: string, name: string, hostLedger: HostLedgerPort, env?: NodeJS.ProcessEnv, signal?: AbortSignal): Promise<OwnershipClaim>;
|
|
69
30
|
/**
|
|
70
31
|
* Fenced takeover: the ownership claim and the lifecycle run as one critical section under the
|
|
71
|
-
*
|
|
32
|
+
* claim lock, so no second takeover can interleave between claim and commit. The claim
|
|
72
33
|
* persists nothing until the lifecycle commits: standing owner rows stay authoritative through
|
|
73
34
|
* the lifecycle (a self-takeover can therefore never clobber its own standing row). On success
|
|
74
35
|
* the standing rows are replaced by the new owner's row at the claim epoch; on refusal, rows
|
|
75
36
|
* carrying the claim token (session + channel + claim epoch) are withdrawn and the captured
|
|
76
37
|
* standing rows are restored exactly.
|
|
77
38
|
*/
|
|
78
|
-
export declare function claimSessionTakeover<T>(squarePath: string, name: string, env: NodeJS.ProcessEnv | undefined, opts: {
|
|
39
|
+
export declare function claimSessionTakeover<T>(squarePath: string, name: string, hostLedger: HostLedgerPort, env: NodeJS.ProcessEnv | undefined, opts: {
|
|
79
40
|
readonly expectedEpoch?: number;
|
|
80
41
|
readonly expectedSession?: string;
|
|
81
42
|
} | undefined, lifecycle: (claim: TakeoverClaimToken) => Promise<T>, signal?: AbortSignal): Promise<TakeoverRunResult<T>>;
|
|
82
|
-
export declare function releaseSessionParticipant(squarePath: string, name: string, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
83
|
-
export declare function bindCurrentParticipant(squarePath: string, name: string, env?: NodeJS.ProcessEnv): Promise<CurrentParticipantBinding>;
|
|
84
|
-
export declare function unbindCurrentParticipant(squarePath: string, name: string, env?: NodeJS.ProcessEnv): Promise<boolean>;
|
|
85
|
-
export interface RegistryPruneResult {
|
|
86
|
-
removed: number;
|
|
87
|
-
kept: number;
|
|
88
|
-
}
|
|
89
|
-
export declare function pruneRegistry(readActs: (squarePath: string) => StoredAct[] | undefined | Promise<StoredAct[] | undefined>, now?: number): Promise<RegistryPruneResult>;
|
|
43
|
+
export declare function releaseSessionParticipant(squarePath: string, name: string, hostLedger: HostLedgerPort, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
90
44
|
export interface LocalSessionIdentity {
|
|
91
45
|
sessionId: string;
|
|
92
|
-
channel:
|
|
46
|
+
channel: PresenceChannel;
|
|
93
47
|
child: boolean;
|
|
94
48
|
paseoAgentId?: string;
|
|
95
49
|
}
|
|
96
50
|
export declare function localSessionIdentities(env?: NodeJS.ProcessEnv): LocalSessionIdentity[];
|
|
97
51
|
export declare function hasAutomaticDeliveryIdentity(env?: NodeJS.ProcessEnv): boolean;
|
|
98
|
-
export declare function recordLocalJoin(name: string, squarePath: string, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
99
|
-
export declare function recordLocalDone(name: string, squarePath: string, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
100
|
-
export declare function recordSessionJoin(sessionId: string, name: string, squarePath: string, channel: SessionChannel, env?: NodeJS.ProcessEnv): Promise<string>;
|
|
101
|
-
export declare function recordSessionDone(sessionId: string, name: string, squarePath: string, channel: SessionChannel, env?: NodeJS.ProcessEnv): Promise<boolean>;
|
|
102
52
|
/** Bind the host ledger to the caller's captured environment. */
|
|
103
|
-
export declare function hostLedgerForEnv(env?: NodeJS.ProcessEnv):
|
|
104
|
-
export {};
|
|
53
|
+
export declare function hostLedgerForEnv(env?: NodeJS.ProcessEnv): FileHostLedgerPort;
|