@astrosheep/square 0.3.56 → 0.3.57

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.56",
3
+ "version": "0.3.57",
4
4
  "description": "Native Claude Code turn-boundary delivery for Square participants",
5
5
  "author": {
6
6
  "name": "Square"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.56",
3
+ "version": "0.3.57",
4
4
  "description": "Shared Square activity with reliable participant attention at Codex boundaries.",
5
5
  "author": {
6
6
  "name": "Square"
package/dist/activity.js CHANGED
@@ -3,7 +3,7 @@ import fs from 'node:fs';
3
3
  import path from 'node:path';
4
4
  import { setTimeout as sleep } from 'node:timers/promises';
5
5
  import { SquareError, isSquareError, validateName } from './model.js';
6
- import { expressHintLine, renderActivityBlocked, renderActivityLimit, renderExpressNoWait, renderExpressWaiting, renderPendingFeed, withPathOutput, } from './presentation.js';
6
+ import { expressHintLine, renderActivityBlocked, renderActivityLimit, renderExpressNoWait, renderExpressWaiting, renderPendingFeed, joinRecoveryCommand, withPathOutput, } from './presentation.js';
7
7
  import { nowMs, SLEEP_MS } from './runtime.js';
8
8
  import { openSquare } from './square-file-adapter.js';
9
9
  import { closeOpenSquare } from './open-square.js';
@@ -55,6 +55,8 @@ export async function cmdActivity(squarePath, name, activity, resolveBody, opts)
55
55
  const draftPath = saveActivityDraft(squarePath, name, rawInput);
56
56
  process.stderr.write(err.message + '\n');
57
57
  process.stderr.write(`draft kept: ${draftPath}\n`);
58
+ if (/^Unknown participant/.test(err.message))
59
+ process.stderr.write(`${joinRecoveryCommand(squarePath, name)}\n`);
58
60
  process.exit(2);
59
61
  }
60
62
  process.stderr.write(err.message + '\n');
@@ -1,13 +1,20 @@
1
1
  import { helpRequest } from '../help.js';
2
2
  import { isSquareError } from '../model.js';
3
- import { commandPrefix } from '../presentation.js';
3
+ import { joinRecoveryCommand, participantsRecoveryCommand } from '../presentation.js';
4
4
  import { defaultContext, parseGlobalArgs } from './context.js';
5
5
  import { executeRegisteredCommand, findCommand } from './registry.js';
6
- function handleSquareError(error, squarePath) {
6
+ function handleSquareError(error, squarePath, name) {
7
7
  if (isSquareError(error)) {
8
8
  process.stderr.write(`${error.message}\n`);
9
- if (squarePath !== undefined && /^(Unknown participant|Unknown mention target)/.test(error.message)) {
10
- process.stderr.write(`» ${commandPrefix(squarePath)} participants\n`);
9
+ if (squarePath !== undefined && /^Unknown participant/.test(error.message)) {
10
+ // The caller's name has never joined this square; only a join admits it.
11
+ if (name !== undefined)
12
+ process.stderr.write(`${joinRecoveryCommand(squarePath, name)}\n`);
13
+ else
14
+ process.stderr.write(`${participantsRecoveryCommand(squarePath)}\n`);
15
+ }
16
+ else if (squarePath !== undefined && /^Unknown mention target/.test(error.message)) {
17
+ process.stderr.write(`${participantsRecoveryCommand(squarePath)}\n`);
11
18
  }
12
19
  process.exit(error.code === 'not_found' ? 1 : 2);
13
20
  }
@@ -16,6 +23,7 @@ function handleSquareError(error, squarePath) {
16
23
  /** Parse global flags, select an executable adapter, and leave all command work to the registry. */
17
24
  export async function runCli(rawArgs = process.argv.slice(2)) {
18
25
  let squarePath;
26
+ let requestedName;
19
27
  try {
20
28
  const requestedHelp = helpRequest(rawArgs);
21
29
  if (requestedHelp !== undefined) {
@@ -24,6 +32,7 @@ export async function runCli(rawArgs = process.argv.slice(2)) {
24
32
  }
25
33
  const parsed = await parseGlobalArgs(rawArgs);
26
34
  squarePath = parsed.squarePath;
35
+ requestedName = parsed.name;
27
36
  if (parsed.args.length === 0 || parsed.args[0] === '--help' || parsed.args[0] === '-h') {
28
37
  await executeRegisteredCommand('help', [], defaultContext('help', parsed.squarePath, parsed.name));
29
38
  return;
@@ -36,6 +45,6 @@ export async function runCli(rawArgs = process.argv.slice(2)) {
36
45
  await executeRegisteredCommand(command, parsed.args.slice(1), defaultContext(command, parsed.squarePath, parsed.name));
37
46
  }
38
47
  catch (error) {
39
- handleSquareError(error, squarePath);
48
+ handleSquareError(error, squarePath, requestedName);
40
49
  }
41
50
  }
@@ -49,6 +49,9 @@ export declare function withPathOutput(squarePath: string, body?: string, opts?:
49
49
  export declare function quoteShell(value: string): string;
50
50
  export declare function commandPrefix(squarePath: string): string;
51
51
  export declare function participantCommandPrefix(squarePath: string, name: string): string;
52
+ /** Blocked actions end with a full copy-pasteable recovery command. */
53
+ export declare function joinRecoveryCommand(squarePath: string, name: string): string;
54
+ export declare function participantsRecoveryCommand(squarePath: string): string;
52
55
  export declare function renderPresenceLines(participants: ParticipantStatus[], now: number, limit?: number): string[];
53
56
  export declare function expressHintLine(ownActivityCount: number): string | undefined;
54
57
  export declare function truncateChars(body: string, maxChars: number): {
@@ -41,6 +41,13 @@ export function commandPrefix(squarePath) {
41
41
  export function participantCommandPrefix(squarePath, name) {
42
42
  return `square --location ${quoteShell(path.resolve(squarePath))} --as ${quoteShell(name)}`;
43
43
  }
44
+ /** Blocked actions end with a full copy-pasteable recovery command. */
45
+ export function joinRecoveryCommand(squarePath, name) {
46
+ return `» ${participantCommandPrefix(squarePath, name)} join`;
47
+ }
48
+ export function participantsRecoveryCommand(squarePath) {
49
+ return `» ${commandPrefix(squarePath)} participants`;
50
+ }
44
51
  function formatAge(ms) {
45
52
  if (ms === undefined)
46
53
  return '(none)';
package/dist/watch.js CHANGED
@@ -6,7 +6,7 @@ import { closeOpenSquare } from './open-square.js';
6
6
  import { openParticipant } from './square-wiring.js';
7
7
  import { resolveParticipant, watchPresentation } from './views.js';
8
8
  import { acquireWatchLease, ownsWatchLease, pulseWatchLease, releaseWatchLease } from './wakes.js';
9
- import { renderWatchForceTakeover, renderWatchAlreadyActive, renderWatchReplaceMissing, renderWatchOutput, renderWatchReplaced, renderWatchStatus, participantCommandPrefix, withPathOutput, } from './presentation.js';
9
+ import { renderWatchForceTakeover, renderWatchAlreadyActive, renderWatchReplaceMissing, renderWatchOutput, renderWatchReplaced, renderWatchStatus, participantCommandPrefix, joinRecoveryCommand, participantsRecoveryCommand, withPathOutput, } from './presentation.js';
10
10
  import { hasAutomaticDeliveryIdentity } from './registry.js';
11
11
  import { parseActivityId } from './square-core.js';
12
12
  function watchStatusExitCode(status) {
@@ -150,6 +150,18 @@ export async function cmdWatch(squarePath, name, opts) {
150
150
  try {
151
151
  square = await openSquare(squarePath, { clock: nowMs });
152
152
  name = (await resolveParticipant(square, name)).name;
153
+ }
154
+ catch (err) {
155
+ if (isSquareError(err)) {
156
+ process.stderr.write(err.message + '\n');
157
+ // The caller's own name has never joined; only a join admits it.
158
+ if (/^Unknown participant/.test(err.message))
159
+ process.stderr.write(`${joinRecoveryCommand(squarePath, name)}\n`);
160
+ process.exit(err.code === 'not_found' ? 1 : 2);
161
+ }
162
+ throw err;
163
+ }
164
+ try {
153
165
  if (opts.mention !== undefined)
154
166
  opts = { ...opts, mention: (await resolveParticipant(square, opts.mention)).name };
155
167
  if (opts.participants !== undefined && opts.participants.length > 0) {
@@ -157,8 +169,12 @@ export async function cmdWatch(squarePath, name, opts) {
157
169
  }
158
170
  }
159
171
  catch (err) {
172
+ await closeOpenSquare(square).catch(() => undefined);
160
173
  if (isSquareError(err)) {
161
174
  process.stderr.write(err.message + '\n');
175
+ // A filter target is unknown, not the caller; the roster is the useful next read.
176
+ if (/^(Unknown participant|Unknown mention target)/.test(err.message))
177
+ process.stderr.write(`${participantsRecoveryCommand(squarePath)}\n`);
162
178
  process.exit(err.code === 'not_found' ? 1 : 2);
163
179
  }
164
180
  throw err;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/square",
3
- "version": "0.3.56",
3
+ "version": "0.3.57",
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": {