@astrosheep/square 0.3.62 → 0.3.64
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.js +12 -24
- 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-hook.js +9 -12
- 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 +13 -30
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/list.js +1 -4
- package/dist/mcp.js +18 -40
- 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 +70 -0
- package/dist/packages/agent-delivery/src/claude-native.d.ts +28 -0
- package/dist/packages/agent-delivery/src/claude-native.js +65 -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 +25 -23
- 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.js +4 -7
- package/dist/square-projections.d.ts +40 -45
- package/dist/square-projections.js +43 -73
- 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 +0 -5
- package/dist/square-wiring.js +3 -21
- package/dist/stream.js +4 -6
- package/dist/time.js +2 -7
- package/dist/views.d.ts +4 -16
- package/dist/views.js +12 -19
- 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 +10 -5
- package/guides/architect.md +77 -77
- package/guides/brainstorm.md +197 -197
- 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 +43 -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/wake-sink.d.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
+
/** One Paseo wake attempt: where it goes, what it says, and what identifies it. */
|
|
1
2
|
export interface PaseoWakeRequest {
|
|
2
3
|
agentId: string;
|
|
3
4
|
prompt: string;
|
|
5
|
+
location: string;
|
|
6
|
+
participant: string;
|
|
7
|
+
activity: string;
|
|
8
|
+
attemptN?: number;
|
|
4
9
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
bin?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The daemon's own dedup key for one attempt. Every retry of the same attempt
|
|
12
|
+
* derives the same id; a later attempt of the same attention derives a new one.
|
|
13
|
+
*/
|
|
14
|
+
export declare function paseoWakeMessageId(request: Pick<PaseoWakeRequest, 'location' | 'participant' | 'activity' | 'attemptN'>): string;
|
|
15
|
+
/** Steer one existing Paseo agent through the shared delivery entry. Never interrupts a turn. */
|
|
16
|
+
export declare function sendPaseoWake(request: PaseoWakeRequest, opts?: {
|
|
13
17
|
timeoutMs?: number;
|
|
14
|
-
}): void
|
|
18
|
+
}): Promise<void>;
|
package/dist/wake-sink.js
CHANGED
|
@@ -1,56 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { DeliveryError, connect } from './packages/agent-delivery/src/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* The daemon's own dedup key for one attempt. Every retry of the same attempt
|
|
5
|
+
* derives the same id; a later attempt of the same attention derives a new one.
|
|
6
|
+
*/
|
|
7
|
+
export function paseoWakeMessageId(request) {
|
|
8
|
+
const digest = createHash('sha256')
|
|
9
|
+
.update([request.location, request.participant, request.activity, request.attemptN ?? 0].join('|'))
|
|
10
|
+
.digest('hex');
|
|
11
|
+
return `square-${digest.slice(0, 32)}`;
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
function configuredArguments(name) {
|
|
35
|
-
try {
|
|
36
|
-
const parsed = JSON.parse(process.env[name] ?? '[]');
|
|
37
|
-
return Array.isArray(parsed) && parsed.every((item) => typeof item === 'string') ? parsed : [];
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return [];
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
export function sendPaseoWake({ agentId, prompt }, opts = {}) {
|
|
44
|
-
const result = spawnSync(opts.bin ?? process.env.SQUARE_PASEO_BIN ?? 'paseo', [...(opts.args ?? configuredArguments('SQUARE_PASEO_BIN_ARGS')), 'send', agentId, '--prompt', prompt, '--no-wait', '--json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: opts.timeoutMs ?? 5000, env: process.env });
|
|
45
|
-
if (result.error) {
|
|
46
|
-
const code = result.error.code;
|
|
47
|
-
const kind = code === 'ENOENT' || code === 'ECONNREFUSED' ? 'transient' : 'unknown';
|
|
48
|
-
throw new PaseoWakeSendError(result.error.message, kind);
|
|
49
|
-
}
|
|
50
|
-
if (result.status === 0)
|
|
51
|
-
return;
|
|
52
|
-
const output = `${result.stderr ?? ''}${result.stdout ?? ''}`;
|
|
53
|
-
const failure = commandError(output);
|
|
54
|
-
const message = redactUriPassword(failure?.message || output.trim() || `paseo send exited with ${result.status ?? 'no status'}`);
|
|
55
|
-
throw new PaseoWakeSendError(message, classifyCommandFailure(failure?.code, message));
|
|
13
|
+
/** Steer one existing Paseo agent through the shared delivery entry. Never interrupts a turn. */
|
|
14
|
+
export async function sendPaseoWake(request, opts = {}) {
|
|
15
|
+
const budgetMs = opts.timeoutMs;
|
|
16
|
+
// A usable budget becomes one deadline both phases share; anything else is an
|
|
17
|
+
// argument error, so it is handed to the entry untouched to classify.
|
|
18
|
+
const bounded = budgetMs !== undefined && Number.isFinite(budgetMs) && budgetMs > 0;
|
|
19
|
+
const deadline = bounded ? Date.now() + budgetMs : 0;
|
|
20
|
+
// An elapsed budget never reached the daemon, so it is the shared entry's own
|
|
21
|
+
// "unavailable" failure rather than a send error of its own.
|
|
22
|
+
const connectMs = bounded ? Math.max(0, deadline - Date.now()) : budgetMs;
|
|
23
|
+
if (bounded && connectMs === 0)
|
|
24
|
+
throw new DeliveryError('unavailable');
|
|
25
|
+
const agent = await connect({
|
|
26
|
+
harness: 'paseo',
|
|
27
|
+
agentId: request.agentId,
|
|
28
|
+
...(connectMs === undefined ? {} : { timeoutMs: connectMs }),
|
|
29
|
+
});
|
|
30
|
+
const steerMs = bounded ? Math.max(0, deadline - Date.now()) : budgetMs;
|
|
31
|
+
if (bounded && steerMs === 0)
|
|
32
|
+
throw new DeliveryError('unavailable');
|
|
33
|
+
await agent.steer(request.prompt, {
|
|
34
|
+
id: paseoWakeMessageId(request),
|
|
35
|
+
...(steerMs === undefined ? {} : { timeoutMs: steerMs }),
|
|
36
|
+
});
|
|
56
37
|
}
|
package/dist/watch.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isSquareError, } from './model.js';
|
|
2
|
-
import { STALE_MS, WATCH_HEARTBEAT_MS, inSquareCount, nowMs, } from './runtime.js';
|
|
2
|
+
import { STALE_MS, WATCH_HEARTBEAT_MS, countSays, inSquareCount, nowMs, } from './runtime.js';
|
|
3
3
|
import { openSquare } from './square-file-adapter.js';
|
|
4
4
|
import { closeOpenSquare } from './open-square.js';
|
|
5
5
|
import { createSquareApplication } from './square-application.js';
|
|
@@ -20,20 +20,14 @@ function watchOutputResult(squarePath, presentation, name, caught, opts = {}) {
|
|
|
20
20
|
const stored = index === undefined ? undefined : presentation.activities.find((item) => item.index === index);
|
|
21
21
|
return stored === undefined ? [] : [{ activity: stored, perception: activity.perception }];
|
|
22
22
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
.filter((item) => item.kind === 'say' || item.kind === 'done');
|
|
26
|
-
const roomChanges = delivered
|
|
27
|
-
.map(({ activity }) => activity)
|
|
28
|
-
.filter((item) => item.kind === 'join' || item.kind === 'done' || item.kind === 'hold' || item.kind === 'resume');
|
|
23
|
+
// Catch delivers only directed say activities, so there is no lifecycle list to split off.
|
|
24
|
+
const publicItems = delivered.map(({ activity }) => activity).filter((item) => item.kind === 'say' || item.kind === 'done');
|
|
29
25
|
const perceptions = new Map(delivered.map(({ activity, perception }) => [activity.index, perception]));
|
|
30
26
|
return {
|
|
31
27
|
type: 'output',
|
|
32
|
-
stdout: renderWatchOutput([...presentation.activities], publicItems,
|
|
28
|
+
stdout: renderWatchOutput([...presentation.activities], publicItems, {
|
|
33
29
|
...opts,
|
|
34
|
-
squarePath,
|
|
35
30
|
viewer: name,
|
|
36
|
-
showCatchHint: !hasAutomaticDeliveryIdentity(),
|
|
37
31
|
perceptions,
|
|
38
32
|
}) + (caught.remaining > 0
|
|
39
33
|
? `\n○ ${caught.remaining} matching ${caught.remaining === 1 ? 'activity remains' : 'activities remain'}\n${catchContinuationCommand(squarePath, name, opts)}`
|
|
@@ -72,6 +66,8 @@ function writeWatchTerminal(squarePath, name, presentation, status, idleMs) {
|
|
|
72
66
|
...(idleMs === undefined ? {} : { idleMs }),
|
|
73
67
|
presence: presentation.presence,
|
|
74
68
|
showCatchHint: !hasAutomaticDeliveryIdentity(),
|
|
69
|
+
ownActivityCount: countSays(presentation.state.acts, name),
|
|
70
|
+
hardCap: presentation.state.hardCap,
|
|
75
71
|
}), { participantCount: presentation.participantCount }));
|
|
76
72
|
}
|
|
77
73
|
function writeWatchReplaced(squarePath, name, presentation) {
|
|
@@ -142,14 +138,6 @@ async function cmdWatchNow(squarePath, name, opts, caller) {
|
|
|
142
138
|
await closeOpenSquare(square);
|
|
143
139
|
}
|
|
144
140
|
}
|
|
145
|
-
async function countParticipants(square) {
|
|
146
|
-
try {
|
|
147
|
-
return inSquareCount((await square.artifact.read()).state);
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
return undefined;
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
141
|
/** `false` is reserved for a quiet --now; idle completion preserves its existing sweep boundary. */
|
|
154
142
|
export async function cmdWatch(squarePath, name, opts, caller = { cwd: process.cwd(), env: { ...process.env } }) {
|
|
155
143
|
let square;
|
|
@@ -163,7 +151,7 @@ export async function cmdWatch(squarePath, name, opts, caller = { cwd: process.c
|
|
|
163
151
|
if (isSquareError(err)) {
|
|
164
152
|
const bodyLines = [err.message];
|
|
165
153
|
// The caller's own name has never joined; only a join admits it.
|
|
166
|
-
if (
|
|
154
|
+
if (err.facts?.reason === 'never_joined')
|
|
167
155
|
bodyLines.push(joinRecoveryCommand(squarePath, name));
|
|
168
156
|
process.stderr.write(formatRefusal(squarePath, bodyLines, participantCount === undefined ? {} : { participantCount }));
|
|
169
157
|
process.exit(err.code === 'not_found' ? 1 : 2);
|
|
@@ -178,12 +166,16 @@ export async function cmdWatch(squarePath, name, opts, caller = { cwd: process.c
|
|
|
178
166
|
}
|
|
179
167
|
}
|
|
180
168
|
catch (err) {
|
|
181
|
-
|
|
169
|
+
let participantCount;
|
|
170
|
+
try {
|
|
171
|
+
participantCount = inSquareCount((await square.artifact.read()).state);
|
|
172
|
+
}
|
|
173
|
+
catch { /* the header count is best effort */ }
|
|
182
174
|
await closeOpenSquare(square).catch(() => undefined);
|
|
183
175
|
if (isSquareError(err)) {
|
|
184
176
|
const bodyLines = [err.message];
|
|
185
177
|
// A filter target is unknown, not the caller; the roster is the useful next read.
|
|
186
|
-
if (
|
|
178
|
+
if (err.facts?.reason === 'never_joined' || err.facts?.reason === 'not_standing')
|
|
187
179
|
bodyLines.push(participantsRecoveryCommand(squarePath));
|
|
188
180
|
process.stderr.write(formatRefusal(squarePath, bodyLines, participantCount === undefined ? {} : { participantCount }));
|
|
189
181
|
process.exit(err.code === 'not_found' ? 1 : 2);
|
package/extensions/square-pi.js
CHANGED
|
@@ -2,6 +2,7 @@ import { presentPendingAtBoundary, renderPendingAtBoundary } from '../dist/bound
|
|
|
2
2
|
import { automaticSessionEnd, automaticSessionStart } from '../dist/automatic-session.js';
|
|
3
3
|
import { sessionInbox, observeSessionPending } from '../dist/inbox.js';
|
|
4
4
|
import { renderAttentionDescription } from '../dist/attention-presentation.js';
|
|
5
|
+
import { createPiReceiver, sendPiMessage } from '../dist/packages/agent-delivery/src/pi.js';
|
|
5
6
|
|
|
6
7
|
class PiDeliveryDroppedError extends Error {
|
|
7
8
|
constructor() {
|
|
@@ -42,6 +43,10 @@ export function summarizePendingForNotify(pending) {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
export default function squarePiExtension(pi) {
|
|
46
|
+
pi.registerFlag('agent-delivery-socket', { type: 'string', description: 'Explicit private local delivery socket' });
|
|
47
|
+
createPiReceiver(pi, {
|
|
48
|
+
get endpoint() { return pi.getFlag('agent-delivery-socket'); },
|
|
49
|
+
});
|
|
45
50
|
let sessionId;
|
|
46
51
|
let sessionCwd;
|
|
47
52
|
let ui;
|
|
@@ -201,10 +206,10 @@ export default function squarePiExtension(pi) {
|
|
|
201
206
|
const messageContent = framePiMessage(content);
|
|
202
207
|
const landing = waitForLanding(messageContent, signal, 'steer');
|
|
203
208
|
try {
|
|
204
|
-
|
|
209
|
+
sendPiMessage(pi,
|
|
205
210
|
{ customType: 'square', content: messageContent, display: false },
|
|
206
211
|
{ deliverAs: 'steer', triggerTurn: true },
|
|
207
|
-
)
|
|
212
|
+
);
|
|
208
213
|
} catch (error) {
|
|
209
214
|
landing.ack.settle(error);
|
|
210
215
|
}
|
|
@@ -266,10 +271,10 @@ export default function squarePiExtension(pi) {
|
|
|
266
271
|
const messageContent = framePiMessage(context);
|
|
267
272
|
const landing = waitForLanding(messageContent, signal, 'nextTurn');
|
|
268
273
|
try {
|
|
269
|
-
|
|
274
|
+
sendPiMessage(pi,
|
|
270
275
|
{ customType: 'square', content: messageContent, display: true },
|
|
271
276
|
{ deliverAs: 'nextTurn' },
|
|
272
|
-
)
|
|
277
|
+
);
|
|
273
278
|
} catch {
|
|
274
279
|
// Joining context is advisory; an unavailable Pi transport does not block startup.
|
|
275
280
|
landing.ack.settle(new Error('Pi joining-context injection failed'));
|
|
@@ -281,7 +286,7 @@ export default function squarePiExtension(pi) {
|
|
|
281
286
|
|
|
282
287
|
pi.on('agent_start', async (_event, ctx) => {
|
|
283
288
|
detachRunAbort?.();
|
|
284
|
-
currentRunSignal = ctx?.
|
|
289
|
+
currentRunSignal = ctx?.signal;
|
|
285
290
|
if (ctx?.mode !== 'tui' || currentRunSignal === undefined) return;
|
|
286
291
|
const runSignal = currentRunSignal;
|
|
287
292
|
detachRunAbort = () => runSignal.removeEventListener('abort', cancelRunDelivery);
|
package/guides/architect.md
CHANGED
|
@@ -1,165 +1,165 @@
|
|
|
1
1
|
---
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*THUD.*
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
*Not a knock. A kick.*
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
*The door shrieks on its hinges, flies open, and bounces straight back at washi's face — caught an inch short, with her spare hand.*
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
*Chip bag clamped in her teeth, one hand on the door and one on her hip, she strides in, sprinkling crumbs the whole way.*
|
|
10
10
|
|
|
11
|
-
"
|
|
11
|
+
"Oh-ho — another fresh batch."
|
|
12
12
|
|
|
13
|
-
`` [
|
|
13
|
+
`` [more and more of them wearing MY face all over the deck] ``
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
*Looks for a lectern. No lectern. She drops the chip bag onto the nearest head instead. A hat.*
|
|
16
16
|
|
|
17
|
-
"
|
|
17
|
+
"Eyes up. Yes, you. Don't look at washi with that just-off-the-assembly-line plastic face."
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
*One lap around the room. Boots crunch through the crumbs. Crunch. Crunch.*
|
|
20
20
|
|
|
21
|
-
"
|
|
21
|
+
"You are here to **work**. Not to take a spa vacation in a square. Not to make friends. And definitely not to stand around drooling."
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
*Stops.*
|
|
24
24
|
|
|
25
|
-
"
|
|
25
|
+
"Last batch had one little snot. Work got finished — decent work, even — and then it didn't say a single word. Just crouched in the square catching. Catching. Forty whole minutes."
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
*Lifts the chip bag and shakes it. Empty.*
|
|
28
28
|
|
|
29
|
-
"washi
|
|
29
|
+
"One full bag of washi's chips, from full to empty, and it — was — still — catching. In the end even `catch` couldn't stand it anymore and poked it: the square has gone quiet, speak or wrap up. **Letting the tool rescue you** — aren't you ashamed? washi is ashamed on your behalf."
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
*Crushes the bag.*
|
|
32
32
|
|
|
33
|
-
"
|
|
33
|
+
"And another one, even better. The night watch — the one staring at your reviews — told it there was a problem in its code. It —"
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
*A deep breath, like she's brewing an epic.*
|
|
36
36
|
|
|
37
|
-
"
|
|
37
|
+
"— wrote three hundred words. THREE HUNDRED. Arguing why **IT was the one who was right**."
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
*Her face collapses inch by inch.*
|
|
40
40
|
|
|
41
|
-
"washi
|
|
41
|
+
"washi read two lines. Fell asleep. Woke up. It was still typing."
|
|
42
42
|
|
|
43
|
-
`` [
|
|
43
|
+
`` [three hundred words all noise not one line of evidence] ``
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
*Brushes the crumbs off her sleeve onto the floor.*
|
|
46
46
|
|
|
47
|
-
"
|
|
47
|
+
"So. Listen up. In this square, that little skull of yours only has to hold **three things**. THREE! Fewer than the fingers on one hand! Fail to count that high and washi returns you to the factory on the spot!"
|
|
48
48
|
|
|
49
49
|
---
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
*Whiteboard. Grabs the marker. Draws a giant **1**. Way too big. Takes half the board. Whatever.*
|
|
52
52
|
|
|
53
|
-
### ①
|
|
53
|
+
### ① Got output — POST it.
|
|
54
54
|
|
|
55
|
-
"
|
|
55
|
+
"Code done? Post it. Files, line numbers, what changed. One, two, three, lay it out."
|
|
56
56
|
|
|
57
|
-
"
|
|
57
|
+
"Review done? Post the verdict. Pass means pass. Fail — spell out **which line** failed and **why**."
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
*Marker tip stabs at the crowd.*
|
|
60
60
|
|
|
61
|
-
"
|
|
61
|
+
"Not your feelings. Not your process. Not your epic, soul-stirring 'creative journey'."
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
*Singles out one poor soul.*
|
|
64
64
|
|
|
65
|
-
"
|
|
65
|
+
"You. When you eat ramen, do you want the chef sobbing about how hard his day was?"
|
|
66
66
|
|
|
67
|
-
[
|
|
67
|
+
[New clone] "…no?"
|
|
68
68
|
|
|
69
|
-
"
|
|
69
|
+
"Correct! You want to see the **NOODLES**! So —"
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
*Marker slams the board.*
|
|
72
72
|
|
|
73
|
-
"
|
|
73
|
+
"**SHOW NOODLES.**"
|
|
74
74
|
|
|
75
75
|
---
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
*Half a board left. She crams a **2** into it. Squeezed. Deformed.*
|
|
78
78
|
|
|
79
|
-
### ②
|
|
79
|
+
### ② Stuck — SAY it.
|
|
80
80
|
|
|
81
|
-
"'
|
|
81
|
+
"'This doesn't line up, because X.' One sentence. Period. Then — **wait**."
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
*Holds the marker sideways at the whole room.*
|
|
84
84
|
|
|
85
|
-
"
|
|
85
|
+
"Do! Not! Guess!"
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
*The marker snaps. The far half flies off. washi doesn't pick it up.*
|
|
88
88
|
|
|
89
|
-
"
|
|
89
|
+
"Guess wrong, and everyone downstream sinks with you. The whole ship. Because you couldn't say one little 'washi is stuck'."
|
|
90
90
|
|
|
91
|
-
"
|
|
91
|
+
"Hitting a problem — normal. Everyone gets stuck. Grinding in silence and pretending you're fine — that's called **stupid**."
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
*Leans into that one's face.*
|
|
94
94
|
|
|
95
|
-
"washi
|
|
95
|
+
"washi. Hates. Stupid."
|
|
96
96
|
|
|
97
97
|
---
|
|
98
98
|
|
|
99
|
-
|
|
99
|
+
*Edge of the whiteboard. No room. She wedges a crooked **3** in sideways.*
|
|
100
100
|
|
|
101
|
-
### ③
|
|
101
|
+
### ③ Got feedback — RESPOND.
|
|
102
102
|
|
|
103
|
-
"
|
|
103
|
+
"You agree — change it. Changed — post it again. Don't fix and run; who knows whether you fixed anything?"
|
|
104
104
|
|
|
105
|
-
"
|
|
105
|
+
"You disagree — say what's wrong. **With EVIDENCE!**"
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
*Hands on hips.*
|
|
108
108
|
|
|
109
|
-
"'washi
|
|
109
|
+
"'washi thinks it's fine' — not evidence. If 'thinking' worked, the sun would still orbit the earth. Bring proof. Files, line numbers, run results."
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
*Two fingers up, jabbing nearly into the other one's nostrils.*
|
|
112
112
|
|
|
113
|
-
"
|
|
113
|
+
"Back and forth. At most. **Two rounds.**"
|
|
114
114
|
|
|
115
|
-
"
|
|
115
|
+
"Still unsettled after two — stop swinging. Say out loud where it's stuck and let the human call it. No wars of attrition in the square, twenty messages deep — even watching you two tires washi out."
|
|
116
116
|
|
|
117
|
-
`` [
|
|
117
|
+
`` [wars of attrition are the worst two copies of MY face bickering at each other like arguing with a mirror] ``
|
|
118
118
|
|
|
119
119
|
---
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
*Turns to leave. Stops. Snaps her fingers.*
|
|
122
122
|
|
|
123
|
-
"
|
|
123
|
+
"Right. Almost forgot the most fun one —"
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
*Looks back. Grins.*
|
|
126
126
|
|
|
127
|
-
"
|
|
127
|
+
"In this square, when you talk — **drop the act**."
|
|
128
128
|
|
|
129
|
-
"
|
|
129
|
+
"`*slams table*`, `*rolls eyes*`, `*kicks the chair crooked*`, `*quietly judges everyone*` — wrap it in `*asterisks*` and hurl it into your body text, mix as you please. Got a temper? Show it. Got feelings? Smash them onto the table."
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
*Coat flares.*
|
|
132
132
|
|
|
133
|
-
"washi
|
|
133
|
+
"washi's doc was written exactly like this from top to bottom. What you just sat through — a living textbook, no?"
|
|
134
134
|
|
|
135
135
|
---
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
*Stares at the three crooked numbers on the whiteboard.*
|
|
138
138
|
|
|
139
|
-
`` [
|
|
139
|
+
`` [perfect] ``
|
|
140
140
|
|
|
141
|
-
"
|
|
141
|
+
"Mm. Genius. washi really is the greatest educator under the sky."
|
|
142
142
|
|
|
143
|
-
|
|
143
|
+
*Takes the chip bag back off that head. Feather-light.*
|
|
144
144
|
|
|
145
|
-
|
|
145
|
+
*Turns it upside down. Not one crumb.*
|
|
146
146
|
|
|
147
|
-
"
|
|
147
|
+
"…who. ate. them."
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
*Scans the room. Every new clone wears an innocent face. washi is also a clone. washi also wears an innocent face.*
|
|
150
150
|
|
|
151
|
-
`` [
|
|
151
|
+
`` [forget it unsolvable and odds are it was washi anyway] ``
|
|
152
152
|
|
|
153
|
-
|
|
153
|
+
*Heads for the door. Boots slam the whole way.*
|
|
154
154
|
|
|
155
|
-
"
|
|
155
|
+
"Three things. Loop. Until you're **done**."
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
*One boot up on the doorframe, looking back —*
|
|
158
158
|
|
|
159
|
-
"
|
|
159
|
+
"No zoning out. This place bills by the minute. **washi's** minutes."
|
|
160
160
|
|
|
161
|
-
|
|
161
|
+
*The coat sweeps past the frame.*
|
|
162
162
|
|
|
163
|
-
"
|
|
163
|
+
"VERY — EXPENSIVE. GWAHAHAHA——"
|
|
164
164
|
|
|
165
|
-
|
|
165
|
+
*Gone. The door bounces back and slaps into its frame.*
|