@astrosheep/square 0.3.12 → 0.3.13
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/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/codex-plugin/hooks/hooks.json +9 -0
- package/dist/activity-feed.d.ts +14 -0
- package/dist/activity-feed.js +5 -5
- package/dist/activity.d.ts +9 -0
- package/dist/activity.js +111 -90
- package/dist/artifact.d.ts +20 -0
- package/dist/artifact.js +10 -29
- package/dist/automatic-session.d.ts +5 -0
- package/dist/automatic-session.js +86 -0
- package/dist/boundary-presentation.d.ts +5 -0
- package/dist/boundary-presentation.js +5 -4
- package/dist/claude-hook.d.ts +9 -0
- package/dist/claude-hook.js +35 -3
- package/dist/cli/context.d.ts +35 -0
- package/dist/cli/context.js +25 -30
- package/dist/cli/harness-command.d.ts +28 -0
- package/dist/cli/harness-command.js +29 -14
- package/dist/cli/maintenance-commands.d.ts +7 -0
- package/dist/cli/maintenance-commands.js +3 -3
- package/dist/cli/meta-commands.d.ts +5 -0
- package/dist/cli/observation-commands.d.ts +20 -0
- package/dist/cli/observation-commands.js +155 -128
- package/dist/cli/program.d.ts +2 -0
- package/dist/cli/program.js +2 -12
- package/dist/cli/registry.d.ts +9 -0
- package/dist/cli/registry.js +1 -2
- package/dist/cli/square-commands.d.ts +34 -0
- package/dist/cli/square-commands.js +81 -74
- package/dist/cmd/notify-once.d.ts +2 -0
- package/dist/codex-hook.d.ts +10 -0
- package/dist/codex-hook.js +35 -3
- package/dist/decisions.d.ts +92 -0
- package/dist/decisions.js +83 -77
- package/dist/delivery-health.d.ts +21 -0
- package/dist/delivery-health.js +40 -34
- package/dist/delivery.d.ts +81 -0
- package/dist/delivery.js +60 -22
- package/dist/file-lock.d.ts +6 -0
- package/dist/harness-claude.d.ts +19 -0
- package/dist/harness-claude.js +8 -3
- package/dist/harness-codex.d.ts +29 -0
- package/dist/harness-codex.js +2 -2
- package/dist/harness-links.d.ts +17 -0
- package/dist/harness-links.js +2 -2
- package/dist/harness-pi.d.ts +11 -0
- package/dist/harness-pi.js +2 -2
- package/dist/harness-stage.d.ts +6 -0
- package/dist/harness.d.ts +20 -0
- package/dist/harness.js +5 -3
- package/dist/help.d.ts +6 -0
- package/dist/help.js +6 -5
- package/dist/identity.d.ts +13 -0
- package/dist/inbox.d.ts +2 -0
- package/dist/inbox.js +15 -19
- package/dist/index.d.ts +13 -0
- package/dist/index.js +31 -69
- package/dist/landing.d.ts +10 -0
- package/dist/landing.js +95 -0
- package/dist/list.d.ts +1 -0
- package/dist/list.js +40 -18
- package/dist/model.d.ts +147 -0
- package/dist/model.js +12 -2
- package/dist/notifications.d.ts +30 -0
- package/dist/notifications.js +75 -91
- package/dist/open-square.d.ts +11 -0
- package/dist/open-square.js +4 -0
- package/dist/participant-identity.d.ts +1 -0
- package/dist/participant-identity.js +3 -0
- package/dist/paseo-connection.d.ts +15 -0
- package/dist/paseo-delivery.d.ts +14 -0
- package/dist/paseo-state.d.ts +11 -0
- package/dist/paseo-timeline.d.ts +16 -0
- package/dist/presence.d.ts +3 -0
- package/dist/presence.js +42 -0
- package/dist/presentation.d.ts +91 -0
- package/dist/presentation.js +33 -29
- package/dist/presented.d.ts +11 -0
- package/dist/registry.d.ts +58 -0
- package/dist/registry.js +36 -3
- package/dist/routes.d.ts +42 -0
- package/dist/runtime.d.ts +45 -0
- package/dist/runtime.js +42 -34
- package/dist/search.d.ts +11 -0
- package/dist/square-core.d.ts +111 -0
- package/dist/square-core.js +7 -0
- package/dist/square-facade.d.ts +86 -0
- package/dist/square-facade.js +1 -0
- package/dist/square-file-adapter.d.ts +18 -0
- package/dist/square-file-adapter.js +70 -0
- package/dist/square-storage.d.ts +20 -0
- package/dist/square-storage.js +171 -0
- package/dist/square-wiring.d.ts +19 -0
- package/dist/square-wiring.js +70 -0
- package/dist/square.d.ts +2 -0
- package/dist/state-cell.d.ts +14 -0
- package/dist/state-cell.js +1 -0
- package/dist/stream.d.ts +3 -0
- package/dist/stream.js +19 -23
- package/dist/time.d.ts +6 -0
- package/dist/views.d.ts +95 -0
- package/dist/views.js +81 -0
- package/dist/wake-attempts.d.ts +39 -0
- package/dist/wake-evidence.d.ts +12 -0
- package/dist/wake-evidence.js +7 -10
- package/dist/wake-port.d.ts +20 -0
- package/dist/wake-sink.d.ts +12 -0
- package/dist/wakes.d.ts +40 -0
- package/dist/wakes.js +62 -0
- package/dist/watch.d.ts +2 -0
- package/dist/watch.js +89 -210
- package/extensions/square-opencode.js +27 -1
- package/extensions/square-pi.js +13 -0
- package/package.json +5 -2
- package/skills/brainstorm/SKILL.md +26 -26
- package/skills/square/.claude-plugin/plugin.json +1 -1
- package/skills/square/SKILL.md +47 -29
- package/skills/square/hooks/hooks.json +9 -0
- package/skills/square-feedback/SKILL.md +2 -2
- package/dist/compact.js +0 -26
- package/dist/square-application.js +0 -193
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { runCodexHook } from '../codex-hook.js';
|
|
4
|
-
import { coreActivities, coreParticipants, coreStatus } from '../decisions.js';
|
|
1
|
+
import { runClaudeHookAsync } from '../claude-hook.js';
|
|
2
|
+
import { runCodexHookAsync } from '../codex-hook.js';
|
|
5
3
|
import { sessionInbox } from '../inbox.js';
|
|
6
4
|
import { sweepPendingNotifications } from '../notifications.js';
|
|
7
5
|
import { cmdListSquares } from '../list.js';
|
|
8
|
-
import { sameName } from '../model.js';
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { actId, inSquareCount, nowMs, sayNumberFor } from '../runtime.js';
|
|
6
|
+
import { parseActivityId, sameName } from '../model.js';
|
|
7
|
+
import { commandPrefix, participantCommandPrefix, participantIdentity, renderGrepActivitiesView, renderEventCli, renderAmbientEvent, withPathOutput, } from '../presentation.js';
|
|
8
|
+
import { actId, nowMs } from '../runtime.js';
|
|
12
9
|
import { cmdStream, cmdStreamNdjson } from '../stream.js';
|
|
13
10
|
import { formatRelativeTime, formatTimestamp, parseTimeOrRelative } from '../time.js';
|
|
14
11
|
import { cmdWatch } from '../watch.js';
|
|
12
|
+
import { openSquare } from '../square-file-adapter.js';
|
|
13
|
+
import { closeOpenSquare } from '../open-square.js';
|
|
14
|
+
import { historyPresentation, participantsPresentation, statusPresentation } from '../views.js';
|
|
15
15
|
import { fail, parseDurationMs, parseNameList, parseNonNegativeInteger, readStdinSync, requireParticipant, requireValue, usage, } from './context.js';
|
|
16
16
|
export const listCommand = {
|
|
17
17
|
parse: (argv) => argv,
|
|
18
|
-
execute(argv, context) {
|
|
19
|
-
cmdListSquares(argv, () => usage(context.command));
|
|
18
|
+
async execute(argv, context) {
|
|
19
|
+
await cmdListSquares(argv, () => usage(context.command));
|
|
20
20
|
},
|
|
21
21
|
present: () => { },
|
|
22
22
|
};
|
|
@@ -117,7 +117,7 @@ function parseHistory(argv, context) {
|
|
|
117
117
|
let before;
|
|
118
118
|
let after;
|
|
119
119
|
let afterIndex;
|
|
120
|
-
|
|
120
|
+
const atIndexes = [];
|
|
121
121
|
let beforeContext;
|
|
122
122
|
let afterContext;
|
|
123
123
|
let mention;
|
|
@@ -125,10 +125,8 @@ function parseHistory(argv, context) {
|
|
|
125
125
|
let full = false;
|
|
126
126
|
let grep;
|
|
127
127
|
let fixed;
|
|
128
|
-
let ids;
|
|
129
128
|
let order;
|
|
130
129
|
let format;
|
|
131
|
-
let countOnly = false;
|
|
132
130
|
let json = false;
|
|
133
131
|
const participants = [];
|
|
134
132
|
for (let index = 0; index < argv.length; index++) {
|
|
@@ -166,7 +164,10 @@ function parseHistory(argv, context) {
|
|
|
166
164
|
index += 1;
|
|
167
165
|
}
|
|
168
166
|
else if (flag === '--at') {
|
|
169
|
-
|
|
167
|
+
const values = requireValue(argv, index, flag).split(',');
|
|
168
|
+
if (values.some((value) => value === ''))
|
|
169
|
+
fail(`Invalid ${flag}: expected an activity id like act/12`);
|
|
170
|
+
atIndexes.push(...values.map((value) => parseActRef(value, flag)));
|
|
170
171
|
index += 1;
|
|
171
172
|
}
|
|
172
173
|
else if (flag === '-B') {
|
|
@@ -199,14 +200,6 @@ function parseHistory(argv, context) {
|
|
|
199
200
|
fixed = requireValue(argv, index, flag);
|
|
200
201
|
index += 1;
|
|
201
202
|
}
|
|
202
|
-
else if (flag === '--ids') {
|
|
203
|
-
ids = requireValue(argv, index, flag)
|
|
204
|
-
.split(',')
|
|
205
|
-
.map((item) => item.trim())
|
|
206
|
-
.filter(Boolean)
|
|
207
|
-
.map((item) => parseActRef(item, flag));
|
|
208
|
-
index += 1;
|
|
209
|
-
}
|
|
210
203
|
else if (flag === '--order') {
|
|
211
204
|
const value = requireValue(argv, index, flag);
|
|
212
205
|
if (value !== 'asc' && value !== 'desc')
|
|
@@ -218,8 +211,6 @@ function parseHistory(argv, context) {
|
|
|
218
211
|
format = requireValue(argv, index, flag).split(',').map((item) => item.trim()).filter(Boolean);
|
|
219
212
|
index += 1;
|
|
220
213
|
}
|
|
221
|
-
else if (flag === '--count')
|
|
222
|
-
countOnly = true;
|
|
223
214
|
else if (flag === '--json')
|
|
224
215
|
json = true;
|
|
225
216
|
else
|
|
@@ -231,7 +222,7 @@ function parseHistory(argv, context) {
|
|
|
231
222
|
fail('--grep and --fixed cannot be combined.');
|
|
232
223
|
if (grep === '' || fixed === '')
|
|
233
224
|
fail('--grep and --fixed require non-empty text.');
|
|
234
|
-
if (!lastNExplicit && (
|
|
225
|
+
if (!lastNExplicit && (atIndexes.length > 0 || pending))
|
|
235
226
|
lastN = null;
|
|
236
227
|
return {
|
|
237
228
|
lastN,
|
|
@@ -239,7 +230,7 @@ function parseHistory(argv, context) {
|
|
|
239
230
|
before,
|
|
240
231
|
after,
|
|
241
232
|
afterIndex,
|
|
242
|
-
|
|
233
|
+
atIndexes: atIndexes.length === 0 ? undefined : atIndexes,
|
|
243
234
|
beforeContext,
|
|
244
235
|
afterContext,
|
|
245
236
|
mention,
|
|
@@ -248,14 +239,12 @@ function parseHistory(argv, context) {
|
|
|
248
239
|
full,
|
|
249
240
|
grep,
|
|
250
241
|
fixed,
|
|
251
|
-
ids,
|
|
252
242
|
order,
|
|
253
243
|
format,
|
|
254
|
-
countOnly,
|
|
255
244
|
json,
|
|
256
245
|
};
|
|
257
246
|
}
|
|
258
|
-
function renderFields(
|
|
247
|
+
function renderFields(sayNumbers, item, fields) {
|
|
259
248
|
return fields.map((field) => {
|
|
260
249
|
switch (field) {
|
|
261
250
|
case 'id': return actId(item.index);
|
|
@@ -265,13 +254,13 @@ function renderFields(doc, item, fields) {
|
|
|
265
254
|
case 'at': return formatTimestamp(item.at);
|
|
266
255
|
case 'kind': return item.kind;
|
|
267
256
|
case 'body': return 'body' in item && typeof item.body === 'string' ? item.body.replace(/\s+/g, ' ').trim() : '';
|
|
268
|
-
case 'number': return item.kind === 'say' ? String(
|
|
257
|
+
case 'number': return item.kind === 'say' ? String(sayNumbers[item.index]) : '';
|
|
269
258
|
case 'reply': return item.kind === 'say' && item.reply !== undefined ? actId(item.reply) : '';
|
|
270
259
|
default: return '';
|
|
271
260
|
}
|
|
272
261
|
}).join('\t');
|
|
273
262
|
}
|
|
274
|
-
function jsonLine(
|
|
263
|
+
function jsonLine(sayNumbers, item) {
|
|
275
264
|
const act = item;
|
|
276
265
|
return JSON.stringify({
|
|
277
266
|
id: actId(item.index),
|
|
@@ -281,122 +270,160 @@ function jsonLine(doc, item) {
|
|
|
281
270
|
at: act.at,
|
|
282
271
|
ts: formatTimestamp(act.at),
|
|
283
272
|
body: 'body' in act && typeof act.body === 'string' ? act.body : '',
|
|
284
|
-
number: act.kind === 'say' ?
|
|
273
|
+
number: act.kind === 'say' ? sayNumbers[act.index] : null,
|
|
285
274
|
reach: act.kind === 'say' ? act.reach ?? null : null,
|
|
286
275
|
reply: act.kind === 'say' && act.reply !== undefined ? actId(act.reply) : null,
|
|
287
276
|
});
|
|
288
277
|
}
|
|
278
|
+
function renderHistoryProjection(projection, visible, full, squarePath, viewer, mode) {
|
|
279
|
+
const shown = visible.filter((activity) => activity.kind === 'say' || activity.kind === 'done');
|
|
280
|
+
const preview = full ? undefined : 200;
|
|
281
|
+
const chunks = [];
|
|
282
|
+
for (const activity of shown) {
|
|
283
|
+
const options = {
|
|
284
|
+
preview,
|
|
285
|
+
actNumber: activity.kind === 'say' ? projection.sayNumbers[activity.index] : undefined,
|
|
286
|
+
};
|
|
287
|
+
const rendered = mode === 'archive'
|
|
288
|
+
? renderEventCli(activity, options)
|
|
289
|
+
: renderAmbientEvent(activity, viewer, options);
|
|
290
|
+
if (rendered !== '')
|
|
291
|
+
chunks.push(rendered);
|
|
292
|
+
for (const name of projection.presenceAnchors[activity.index] ?? [])
|
|
293
|
+
chunks.push(`→ ${participantIdentity(name)} was here`);
|
|
294
|
+
}
|
|
295
|
+
if (chunks.length === 0)
|
|
296
|
+
return 'latest\n ○ no public activity in this view';
|
|
297
|
+
if (preview !== undefined && shown.some((activity) => activity.kind === 'say' && activity.body.length > preview && (mode === 'archive' || activity.perception === 'full'))) {
|
|
298
|
+
chunks.push(`» ${commandPrefix(squarePath)} history --full`);
|
|
299
|
+
}
|
|
300
|
+
return chunks.join('\n\n');
|
|
301
|
+
}
|
|
289
302
|
export const historyCommand = {
|
|
290
303
|
parse(argv, context) { return parseHistory(argv, context); },
|
|
291
|
-
execute(options, context) {
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
304
|
+
async execute(options, context) {
|
|
305
|
+
const square = await openSquare(context.squarePath, { clock: nowMs });
|
|
306
|
+
try {
|
|
307
|
+
const projection = await historyPresentation(square, options);
|
|
308
|
+
let events = [...projection.activities];
|
|
309
|
+
const searching = options.grep !== undefined || options.fixed !== undefined;
|
|
310
|
+
const totalMatches = searching ? events.length : 0;
|
|
311
|
+
if (options.lastN != null) {
|
|
312
|
+
events = options.order === 'desc'
|
|
313
|
+
? events.slice(0, options.lastN)
|
|
314
|
+
: events.slice(-options.lastN);
|
|
315
|
+
}
|
|
316
|
+
if (options.json)
|
|
317
|
+
return events.map((item) => jsonLine(projection.sayNumbers, item)).join('\n') + (events.length > 0 ? '\n' : '');
|
|
318
|
+
if (options.format !== undefined && options.format.length > 0) {
|
|
319
|
+
return events.map((item) => renderFields(projection.sayNumbers, item, options.format)).join('\n') + (events.length > 0 ? '\n' : '');
|
|
320
|
+
}
|
|
321
|
+
const pattern = options.grep ?? options.fixed;
|
|
322
|
+
const anonymous = options.viewer === undefined;
|
|
323
|
+
const archive = (options.atIndexes !== undefined && options.atIndexes.length > 0)
|
|
324
|
+
|| (options.lastN == null && options.full === true)
|
|
325
|
+
|| anonymous;
|
|
326
|
+
const output = pattern === undefined || pattern === ''
|
|
327
|
+
? renderHistoryProjection(projection, events, options.full === true || anonymous, context.squarePath, options.viewer ?? '', archive ? 'archive' : 'ambient')
|
|
328
|
+
: renderGrepActivitiesView(events, totalMatches, options.full, context.squarePath, pattern, options.fixed !== undefined);
|
|
329
|
+
return withPathOutput(context.squarePath, output, { participantCount: projection.participantCount });
|
|
300
330
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (options.json)
|
|
304
|
-
return events.map((item) => jsonLine(doc, item)).join('\n') + (events.length > 0 ? '\n' : '');
|
|
305
|
-
if (options.format !== undefined && options.format.length > 0) {
|
|
306
|
-
return events.map((item) => renderFields(doc, item, options.format)).join('\n') + (events.length > 0 ? '\n' : '');
|
|
331
|
+
finally {
|
|
332
|
+
await closeOpenSquare(square);
|
|
307
333
|
}
|
|
308
|
-
const pattern = options.grep ?? options.fixed;
|
|
309
|
-
const archive = options.atIndex != null
|
|
310
|
-
|| (options.ids !== undefined && options.ids.length > 0)
|
|
311
|
-
|| (options.lastN == null && options.full === true);
|
|
312
|
-
const output = pattern === undefined || pattern === ''
|
|
313
|
-
? renderActivitiesView(doc, events, null, options.full, context.squarePath, options.viewer ?? '', archive ? 'archive' : 'ambient')
|
|
314
|
-
: renderGrepActivitiesView(events, totalMatches, options.full, context.squarePath, pattern, options.fixed !== undefined);
|
|
315
|
-
return withPathOutput(context.squarePath, output, { participantCount: inSquareCount(doc) });
|
|
316
334
|
},
|
|
317
335
|
present: (result) => process.stdout.write(result),
|
|
318
336
|
};
|
|
319
337
|
export const participantsCommand = {
|
|
320
338
|
parse(argv, context) { if (argv.length > 0)
|
|
321
339
|
usage(context.command); return undefined; },
|
|
322
|
-
execute(_intent, context) {
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
340
|
+
async execute(_intent, context) {
|
|
341
|
+
const square = await openSquare(context.squarePath, { clock: nowMs });
|
|
342
|
+
try {
|
|
343
|
+
const now = nowMs();
|
|
344
|
+
const participants = await participantsPresentation(square);
|
|
345
|
+
const lines = participants.map((participant) => {
|
|
346
|
+
const glyph = participant.state === 'done' ? '○' : participant.presence === 'watching' ? '◎' : participant.activityCount > 0 ? '●' : '○';
|
|
347
|
+
const state = participant.state === 'done' ? 'done' : participant.presence === 'watching' ? 'catching' : participant.state;
|
|
348
|
+
const last = participant.lastActiveAt === undefined ? '—' : formatRelativeTime(participant.lastActiveAt, now);
|
|
349
|
+
return ` ${glyph} ${participantIdentity(participant.name)} · ${state} · ${participant.activityCount} ${participant.activityCount === 1 ? 'activity' : 'activities'} · ${last}`;
|
|
350
|
+
});
|
|
351
|
+
const participantCount = participants.filter((participant) => participant.state === 'active').length;
|
|
352
|
+
return withPathOutput(context.squarePath, ['participants', ...lines].join('\n'), {
|
|
353
|
+
participantCount,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
finally {
|
|
357
|
+
await closeOpenSquare(square);
|
|
358
|
+
}
|
|
336
359
|
},
|
|
337
360
|
present: (result) => process.stdout.write(result),
|
|
338
361
|
};
|
|
339
362
|
export const statusCommand = {
|
|
340
363
|
parse(argv, context) { if (argv.length > 0)
|
|
341
364
|
usage(context.command); return undefined; },
|
|
342
|
-
execute(_intent, context) {
|
|
343
|
-
const
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
async execute(_intent, context) {
|
|
366
|
+
const square = await openSquare(context.squarePath, { clock: nowMs });
|
|
367
|
+
try {
|
|
368
|
+
const presentation = await statusPresentation(square);
|
|
369
|
+
const result = presentation.status;
|
|
370
|
+
const active = result.participants.filter((participant) => participant.state === 'active').sort((a, b) => {
|
|
371
|
+
const aViewer = context.name !== undefined && sameName(a.name, context.name);
|
|
372
|
+
const bViewer = context.name !== undefined && sameName(b.name, context.name);
|
|
373
|
+
if (aViewer !== bViewer)
|
|
374
|
+
return aViewer ? -1 : 1;
|
|
375
|
+
return (b.lastActiveAt ?? -Infinity) - (a.lastActiveAt ?? -Infinity) || a.name.localeCompare(b.name);
|
|
376
|
+
});
|
|
377
|
+
const people = active.length === 0 ? [' ○ nobody in the square'] : active.map((participant) => {
|
|
378
|
+
const glyph = participant.presence === 'watching'
|
|
379
|
+
? '◎'
|
|
380
|
+
: participant.activityCount > 0 ? '●' : '○';
|
|
381
|
+
const summary = participant.activityCount > 0
|
|
382
|
+
? `${participant.activityCount} ${participant.activityCount === 1 ? 'activity' : 'activities'} · ${participant.lastActiveAt === undefined
|
|
383
|
+
? 'just now'
|
|
384
|
+
: formatRelativeTime(participant.lastActiveAt, result.now)}`
|
|
385
|
+
: `quiet · ${participant.lastActiveAt === undefined ? '—' : formatRelativeTime(participant.lastActiveAt, result.now)}`;
|
|
386
|
+
const showAttention = context.name === undefined || sameName(participant.name, context.name);
|
|
387
|
+
const attention = !showAttention
|
|
388
|
+
? ''
|
|
389
|
+
: participant.pendingMentionCount > 0
|
|
390
|
+
? `${participant.pendingMentionCount} mention${participant.pendingMentionCount === 1 ? '' : 's'} waiting`
|
|
391
|
+
: participant.unreadActivityCount > 0
|
|
392
|
+
? `${participant.unreadActivityCount} change${participant.unreadActivityCount === 1 ? '' : 's'} waiting`
|
|
393
|
+
: 'caught up';
|
|
394
|
+
return ` ${glyph} ${participantIdentity(participant.name)} · ${summary}${attention === '' ? '' : ` · ${attention}`}`;
|
|
395
|
+
});
|
|
396
|
+
const cap = result.hardCap === null ? 'unlimited' : String(result.hardCap);
|
|
397
|
+
const hold = result.holdActive
|
|
398
|
+
? `· ${result.holdActor === undefined ? 'someone' : participantIdentity(result.holdActor)} raised a hand${result.holdReason ? ` — ${result.holdReason}` : ''} · ${result.holdAt === undefined
|
|
358
399
|
? 'just now'
|
|
359
|
-
: formatRelativeTime(
|
|
360
|
-
:
|
|
361
|
-
const
|
|
362
|
-
const attention = !showAttention
|
|
400
|
+
: formatRelativeTime(result.holdAt, result.now)}`
|
|
401
|
+
: undefined;
|
|
402
|
+
const visible = result.latestAct === undefined
|
|
363
403
|
? ''
|
|
364
|
-
:
|
|
365
|
-
|
|
366
|
-
:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
:
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
const latest = visible === ''
|
|
387
|
-
? [result.latestAct === undefined
|
|
388
|
-
? ' ○ no public activity yet'
|
|
389
|
-
: ' · latest activity is private to another participant']
|
|
390
|
-
: [` ${visible.replace(/\n/g, '\n ')}`];
|
|
391
|
-
if (visible.includes('more chars') && result.latestAct !== undefined) {
|
|
392
|
-
const prefix = context.name === undefined ? commandPrefix(context.squarePath) : participantCommandPrefix(context.squarePath, context.name);
|
|
393
|
-
latest.push(`» ${prefix} history --at ${actId(result.latestAct)} -C 2 --full`);
|
|
404
|
+
: renderAmbientEvent(result.latestAct, context.name ?? '', {
|
|
405
|
+
now: result.now,
|
|
406
|
+
preview: 200,
|
|
407
|
+
actNumber: presentation.latestActNumber,
|
|
408
|
+
});
|
|
409
|
+
const latest = visible === ''
|
|
410
|
+
? [result.latestAct === undefined
|
|
411
|
+
? ' ○ no public activity yet'
|
|
412
|
+
: ' · latest activity is private to another participant']
|
|
413
|
+
: [` ${visible.replace(/\n/g, '\n ')}`];
|
|
414
|
+
if (visible.includes('more chars') && result.latestAct !== undefined) {
|
|
415
|
+
const prefix = context.name === undefined ? commandPrefix(context.squarePath) : participantCommandPrefix(context.squarePath, context.name);
|
|
416
|
+
latest.push(`» ${prefix} history --at ${actId(result.latestAct)} -C 2 --full`);
|
|
417
|
+
}
|
|
418
|
+
const output = [
|
|
419
|
+
`${result.activeCount} active · ${result.doneCount} done · cap ${cap} · throttle ${result.throttlePerMinute === undefined ? 'none' : `${result.throttlePerMinute}/min`}`,
|
|
420
|
+
...(hold === undefined ? [] : ['', hold]), '', 'around the square', ...people, '', 'latest', ...latest,
|
|
421
|
+
].join('\n');
|
|
422
|
+
return withPathOutput(context.squarePath, output, { participantCount: result.activeCount, held: result.holdActive });
|
|
423
|
+
}
|
|
424
|
+
finally {
|
|
425
|
+
await closeOpenSquare(square);
|
|
394
426
|
}
|
|
395
|
-
const output = [
|
|
396
|
-
`${result.activeCount} active · ${result.doneCount} done · cap ${cap} · throttle ${result.throttlePerMinute === undefined ? 'none' : `${result.throttlePerMinute}/min`}`,
|
|
397
|
-
...(hold === undefined ? [] : ['', hold]), '', 'around the square', ...people, '', 'latest', ...latest,
|
|
398
|
-
].join('\n');
|
|
399
|
-
return withPathOutput(context.squarePath, output, { participantCount: result.activeCount, held: result.holdActive });
|
|
400
427
|
},
|
|
401
428
|
present: (result) => process.stdout.write(result),
|
|
402
429
|
};
|
|
@@ -418,8 +445,8 @@ export const inboxCommand = {
|
|
|
418
445
|
fail('inbox requires --for-session <session-id>.');
|
|
419
446
|
return { sessionId, json };
|
|
420
447
|
},
|
|
421
|
-
execute(intent) {
|
|
422
|
-
const inbox = sessionInbox(intent.sessionId);
|
|
448
|
+
async execute(intent) {
|
|
449
|
+
const inbox = await sessionInbox(intent.sessionId);
|
|
423
450
|
return intent.json ? `${JSON.stringify(inbox)}\n` : inbox.map((membership) => `${membership.name}\t${membership.squarePath}\t${membership.notifications.length}\n`).join('');
|
|
424
451
|
},
|
|
425
452
|
present: (result) => process.stdout.write(result),
|
|
@@ -432,5 +459,5 @@ function hookCommand(runHook) {
|
|
|
432
459
|
present: (result) => process.stdout.write(result),
|
|
433
460
|
};
|
|
434
461
|
}
|
|
435
|
-
export const claudeHookCommand = hookCommand(
|
|
436
|
-
export const codexHookCommand = hookCommand(
|
|
462
|
+
export const claudeHookCommand = hookCommand(runClaudeHookAsync);
|
|
463
|
+
export const codexHookCommand = hookCommand(runCodexHookAsync);
|
package/dist/cli/program.js
CHANGED
|
@@ -1,15 +1,9 @@
|
|
|
1
1
|
import { helpRequest } from '../help.js';
|
|
2
|
-
import {
|
|
2
|
+
import { isSquareError } from '../model.js';
|
|
3
3
|
import { defaultContext, parseGlobalArgs } from './context.js';
|
|
4
4
|
import { executeRegisteredCommand, findCommand } from './registry.js';
|
|
5
|
-
function isMutatingCommand(command, argv) {
|
|
6
|
-
void argv;
|
|
7
|
-
if (['build', 'join', 'catch', 'express', 'done', 'hold', 'resume', 'compact'].includes(command))
|
|
8
|
-
return true;
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
5
|
function handleSquareError(error) {
|
|
12
|
-
if (error
|
|
6
|
+
if (isSquareError(error)) {
|
|
13
7
|
process.stderr.write(`${error.message}\n`);
|
|
14
8
|
process.exit(error.code === 'not_found' ? 1 : 2);
|
|
15
9
|
}
|
|
@@ -33,10 +27,6 @@ export async function runCli(rawArgs = process.argv.slice(2)) {
|
|
|
33
27
|
process.stderr.write(`unknown command: ${command}\nrun 'square' for usage\n`);
|
|
34
28
|
process.exit(2);
|
|
35
29
|
}
|
|
36
|
-
if (!parsed.explicitSquarePath && parsed.multipleSquares && isMutatingCommand(command, parsed.args.slice(1))) {
|
|
37
|
-
process.stderr.write('✕ more than one square is active here; choose the path before changing or consuming activity.\n» square list\n');
|
|
38
|
-
process.exit(2);
|
|
39
|
-
}
|
|
40
30
|
await executeRegisteredCommand(command, parsed.args.slice(1), defaultContext(command, parsed.squarePath, parsed.name));
|
|
41
31
|
}
|
|
42
32
|
catch (error) {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CommandContext, type CommandSpec } from './context.js';
|
|
2
|
+
export interface RegisteredCommand {
|
|
3
|
+
names: readonly string[];
|
|
4
|
+
spec: CommandSpec<any, any>;
|
|
5
|
+
}
|
|
6
|
+
/** Every public command is an executable adapter, including aliases and utility commands. */
|
|
7
|
+
export declare const commandRegistry: readonly RegisteredCommand[];
|
|
8
|
+
export declare function findCommand(name: string): RegisteredCommand | undefined;
|
|
9
|
+
export declare function executeRegisteredCommand(name: string, argv: string[], context: CommandContext): Promise<void>;
|
package/dist/cli/registry.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildCommand,
|
|
1
|
+
import { buildCommand, doneCommand, expressCommand, holdCommand, joinCommand, resumeCommand } from './square-commands.js';
|
|
2
2
|
import { doctorCommand } from './maintenance-commands.js';
|
|
3
3
|
import { harnessCommand, installCommand, uninstallCommand } from './harness-command.js';
|
|
4
4
|
import { helpCommand, versionCommand } from './meta-commands.js';
|
|
@@ -20,7 +20,6 @@ export const commandRegistry = [
|
|
|
20
20
|
{ names: ['install'], spec: installCommand },
|
|
21
21
|
{ names: ['uninstall'], spec: uninstallCommand },
|
|
22
22
|
{ names: ['harness'], spec: harnessCommand },
|
|
23
|
-
{ names: ['compact'], spec: compactCommand },
|
|
24
23
|
{ names: ['doctor'], spec: doctorCommand },
|
|
25
24
|
{ names: ['history'], spec: historyCommand },
|
|
26
25
|
{ names: ['status'], spec: statusCommand },
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type BuildOptions, type HardCap, type Reach } from '../model.js';
|
|
2
|
+
import { type CommandSpec } from './context.js';
|
|
3
|
+
interface BuildIntent {
|
|
4
|
+
options: BuildOptions & {
|
|
5
|
+
hardCap: HardCap;
|
|
6
|
+
};
|
|
7
|
+
snippet: string;
|
|
8
|
+
}
|
|
9
|
+
interface JoinIntent {
|
|
10
|
+
name: string;
|
|
11
|
+
lastN: number | null;
|
|
12
|
+
kick: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface ActivityIntent {
|
|
15
|
+
name: string;
|
|
16
|
+
activity: string;
|
|
17
|
+
force: boolean;
|
|
18
|
+
noWait: boolean;
|
|
19
|
+
reach?: Reach;
|
|
20
|
+
reply?: number;
|
|
21
|
+
}
|
|
22
|
+
interface BodyIntent {
|
|
23
|
+
name: string;
|
|
24
|
+
body?: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const buildCommand: CommandSpec<BuildIntent, string>;
|
|
27
|
+
export declare const joinCommand: CommandSpec<JoinIntent, string>;
|
|
28
|
+
export declare const expressCommand: CommandSpec<ActivityIntent>;
|
|
29
|
+
export declare const doneCommand: CommandSpec<BodyIntent, string>;
|
|
30
|
+
export declare const holdCommand: CommandSpec<BodyIntent, string>;
|
|
31
|
+
export declare const resumeCommand: CommandSpec<{
|
|
32
|
+
name: string;
|
|
33
|
+
}, string>;
|
|
34
|
+
export {};
|