@astrosheep/square 0.4.3 → 0.4.5
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/dist/artifact-store.d.ts +1 -1
- package/dist/artifact-store.js +32 -15
- package/dist/artifact.d.ts +1 -4
- package/dist/artifact.js +0 -28
- package/dist/attention-presentation.js +1 -1
- package/dist/boundary-presentation.js +2 -2
- package/dist/claude-boundary-state.d.ts +6 -6
- package/dist/claude-boundary-state.js +13 -13
- package/dist/claude-hook.js +26 -25
- package/dist/claude-mcp-context.d.ts +2 -2
- package/dist/claude-mcp-context.js +6 -6
- package/dist/cli/context.js +3 -6
- package/dist/cli/json.js +1 -1
- package/dist/cli/mcp-server-command.js +3 -3
- package/dist/cli/observation-commands.d.ts +2 -2
- package/dist/cli/observation-commands.js +23 -51
- package/dist/cli/perceive-presentation.d.ts +3 -0
- package/dist/cli/{catch-presentation.js → perceive-presentation.js} +3 -3
- package/dist/cli/registry.js +2 -2
- package/dist/codex-address.d.ts +3 -0
- package/dist/codex-address.js +7 -0
- package/dist/codex-hook.d.ts +2 -2
- package/dist/codex-hook.js +29 -39
- package/dist/codex-queue.d.ts +3 -3
- package/dist/codex-queue.js +9 -15
- package/dist/codex-watch.d.ts +6 -1
- package/dist/codex-watch.js +38 -42
- package/dist/delivery-ledger-sqlite.d.ts +25 -20
- package/dist/delivery-ledger-sqlite.js +76 -61
- package/dist/delivery-ledger.d.ts +24 -19
- package/dist/delivery-ledger.js +150 -81
- package/dist/delivery-lifetime.d.ts +2 -2
- package/dist/delivery-lifetime.js +6 -18
- package/dist/help.js +12 -12
- package/dist/hints.d.ts +2 -2
- package/dist/hints.js +7 -7
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/list.d.ts +2 -2
- package/dist/list.js +4 -3
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +8 -32
- package/dist/neutral.d.ts +5 -5
- package/dist/notifications.js +12 -6
- package/dist/operation-presentation.d.ts +8 -3
- package/dist/operation-presentation.js +50 -12
- package/dist/packages/agent-delivery/src/codex.d.ts +4 -0
- package/dist/packages/agent-delivery/src/codex.js +18 -13
- package/dist/packages/agent-delivery/src/file-lock.js +4 -1
- package/dist/perceive-decisions.d.ts +28 -0
- package/dist/{catch-decisions.js → perceive-decisions.js} +24 -24
- package/dist/{catch-selection.d.ts → perceive-selection.d.ts} +2 -2
- package/dist/{catch-selection.js → perceive-selection.js} +3 -3
- package/dist/plugins/opencode/index.js +4 -4
- package/dist/plugins/opencode-shared/delivery.d.ts +6 -6
- package/dist/plugins/opencode-shared/delivery.js +27 -21
- package/dist/plugins/opencode-v1/runtime.js +3 -3
- package/dist/ports.d.ts +0 -4
- package/dist/presentation.d.ts +1 -1
- package/dist/presentation.js +13 -13
- package/dist/session-lifecycle.d.ts +2 -2
- package/dist/session-lifecycle.js +11 -11
- package/dist/sqlite-square.d.ts +2 -4
- package/dist/sqlite-square.js +47 -54
- package/dist/sqlite-transaction.d.ts +2 -0
- package/dist/sqlite-transaction.js +25 -3
- package/dist/square-api.d.ts +1 -1
- package/dist/square-api.js +1 -1
- package/dist/square-domain.js +1 -1
- package/dist/square-facade.d.ts +15 -13
- package/dist/square-location.js +1 -1
- package/dist/square-posting.d.ts +5 -5
- package/dist/square-posting.js +39 -38
- package/dist/square-tools.d.ts +15 -4
- package/dist/square-tools.js +35 -17
- package/dist/views.d.ts +7 -3
- package/dist/views.js +6 -3
- package/guides/architect.md +2 -2
- package/guides/change-waits.md +1 -1
- package/guides/claude-native.md +2 -2
- package/guides/codex-delivery.md +91 -57
- package/guides/delivery-primitives.md +26 -10
- package/guides/mcp.md +4 -2
- package/guides/operation-cancellation.md +11 -3
- package/guides/pi-native-delivery.md +1 -1
- package/guides/pi-tools.md +11 -6
- package/guides/receive-primitive.md +3 -3
- package/guides/square-api.md +15 -8
- package/package.json +2 -2
- package/plugins/claude/.claude-plugin/plugin.json +1 -1
- package/plugins/claude/hooks/hooks.json +2 -2
- package/plugins/claude/skills/square/SKILL.md +10 -10
- package/plugins/codex/.codex-plugin/plugin.json +2 -2
- package/plugins/codex/hooks/hooks.json +1 -7
- package/plugins/opencode/index.ts +4 -4
- package/plugins/opencode-shared/delivery.ts +27 -21
- package/plugins/opencode-v1/runtime.ts +3 -3
- package/plugins/pi/square-pi.js +18 -12
- package/skills/square/SKILL.md +10 -10
- package/dist/catch-decisions.d.ts +0 -28
- package/dist/cli/catch-presentation.d.ts +0 -3
- package/dist/codex-boundary-state.d.ts +0 -2
- package/dist/codex-boundary-state.js +0 -6
- package/guides/mcp-connection-lifetime.md +0 -22
package/dist/views.js
CHANGED
|
@@ -131,12 +131,15 @@ export function queryParticipants(facts, context, observe = false) {
|
|
|
131
131
|
return { participants, ...(!observe ? {} : { observation: { ...context, ...classifyPresence(participants, context.now),
|
|
132
132
|
standingCount: inSquareCount(facts) } }) };
|
|
133
133
|
}
|
|
134
|
-
export function listPresentation(facts) {
|
|
134
|
+
export function listPresentation(facts, owner) {
|
|
135
135
|
const participants = facts.roster().filter((p) => p.joined).map((p) => {
|
|
136
136
|
const receiptAt = facts.receiptFacts(p.name, p.lastJoinIndex ?? -1).latestAt;
|
|
137
137
|
return { name: p.name, lastActiveAt: receiptAt === undefined ? p.lastActiveAt : Math.max(p.lastActiveAt ?? -Infinity, receiptAt) };
|
|
138
138
|
}).sort(compareParticipantActivity).map((p) => p.name);
|
|
139
|
-
return { context: facts.header().preamble, participants, activities: facts.activityCount({ kinds: ['say'] })
|
|
139
|
+
return { context: facts.header().preamble, participants, activities: facts.activityCount({ kinds: ['say'] }),
|
|
140
|
+
...(owner === undefined ? {} : { joined: facts.seatsForOwner(owner)
|
|
141
|
+
.filter(seat => facts.participant(seat.participant)?.joined)
|
|
142
|
+
.map(seat => ({ name: seat.participant, pending: facts.directedCount(seat.participant, { unseenOnly: true, currentGeneration: true }) })) }) };
|
|
140
143
|
}
|
|
141
144
|
export function queryStatus(facts, context, viewer = '', observe = false) {
|
|
142
145
|
const participants = coreParticipants(facts, context.now);
|
|
@@ -178,7 +181,7 @@ export function queryStatus(facts, context, viewer = '', observe = false) {
|
|
|
178
181
|
},
|
|
179
182
|
};
|
|
180
183
|
}
|
|
181
|
-
export function
|
|
184
|
+
export function perceivePresence(facts, now) {
|
|
182
185
|
const participants = coreParticipants(facts, now).filter((participant) => participant.presence === 'done' || participant.presence === 'away' || participant.presence === 'watching'
|
|
183
186
|
|| (participant.lastActiveAt !== undefined && now - participant.lastActiveAt <= PRESENCE_WINDOW_MS));
|
|
184
187
|
return { participants, now };
|
package/guides/architect.md
CHANGED
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
|
|
23
23
|
*Stops.*
|
|
24
24
|
|
|
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
|
|
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 perceiving. Perceiving. Forty whole minutes."
|
|
26
26
|
|
|
27
27
|
*Lifts the chip bag and shakes it. Empty.*
|
|
28
28
|
|
|
29
|
-
"One full bag of washi's chips, from full to empty, and it — was — still —
|
|
29
|
+
"One full bag of washi's chips, from full to empty, and it — was — still — perceiving. In the end even `perceive` 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
|
|
package/guides/change-waits.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Waiting for changes
|
|
2
2
|
|
|
3
3
|
Filesystem notifications are hints, not activity delivery or receipts. Artifact revision observation
|
|
4
|
-
and reconciliation let
|
|
4
|
+
and reconciliation let perceive and stream reconsider changes even if a filesystem event is missed;
|
|
5
5
|
subscribers retain independent cancellation and deadlines. Throttling waits for its eligibility time.
|
|
6
6
|
There is no discovery index and no daemon or per-message timer.
|
|
7
7
|
|
package/guides/claude-native.md
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
The Square Claude plugin uses ordinary native command hooks. It has no mod, native inbox, or producer socket route. `SessionStart` attaches the exact native session to the host delivery ledger; `SessionEnd` fences and detaches that captured attachment without changing Square membership.
|
|
4
4
|
|
|
5
|
-
At `UserPromptSubmit`, Square records Claude's native `prompt_id` before presenting pending cards through event-correct `additionalContext`.
|
|
5
|
+
At `UserPromptSubmit`, Square records Claude's native `prompt_id` before presenting pending cards through event-correct `additionalContext`. `PostToolUse` is the single tool-boundary presenter for the exact native main/child owner, so cards arriving during a running turn can be delivered after a successful tool completes. `PreToolUse` and `PostToolUseFailure` match only Square MCP tools and handle identity publication/cleanup, not presentation. A failed ordinary tool leaves cards for the next PostToolUse, UserPromptSubmit or normal Stop. Autonomous hook-generated prompts are boundaries too, not evidence of human approval. A later prompt records presentation only when its input contains the exact complete prepared frame, including the ledger token and stored full-frame hash. That establishes observation before the model processes the prompt, not comprehension. The async frame uses a plain warning and token delimiters; Square never decodes entities or accepts changed/truncated text as an exact observation.
|
|
6
6
|
|
|
7
7
|
At a normal `Stop`, one per-owner OS-locked observer waits for ledger changes for at most 86,400 seconds. It rechecks the exact captured `prompt_id`, attachment generation, Stop epoch and route after acquiring the lock and immediately before output. A new prompt disarms old observers. The watcher claims one card at a time and uses the existing handoff token/hash correlation. Invoked stderr output is `unknown` until that exact frame is observed at a later prompt boundary; there is no automatic fallback replay. Missing prompt IDs fail closed.
|
|
8
8
|
|
|
9
9
|
This is a finite, boundary-driven observer, not a promise of continuous coverage. Missing Stop, timeout, process exit, headless teardown, or a busy Escape with no later normal Stop may leave cards pending. Idle Escape has no classic hook and may not disarm an already waiting observer; already emitted asyncRewake notifications cannot be recalled. No Square inbox fallback is retained for these cases.
|
|
10
10
|
|
|
11
|
-
The bundled MCP server gets call-local session, cwd, and agent attribution from native `PreToolUse`/terminal tool hooks keyed by Claude's `claudecode/toolUseId` metadata. Duplicate or incomplete call identity is denied by the event-specific PreToolUse permission response; unrelated tool hooks do not block. Cleanup matches tool-use ID, session and agent. Interrupted calls without a terminal hook expire after ten minutes. Models cannot supply identity as tool arguments.
|
|
11
|
+
The bundled MCP server gets call-local session, cwd, and agent attribution from native `PreToolUse`/terminal tool hooks keyed by Claude's `claudecode/toolUseId` metadata. The manifest scopes `PreToolUse` and `PostToolUseFailure` to `^mcp__plugin_square_square__.*`, while `PostToolUse` remains unfiltered for delivery and successful MCP cleanup. An ordinary successful tool therefore launches only PostToolUse, not both a pre- and post-tool command. Duplicate or incomplete call identity is denied by the event-specific PreToolUse permission response; unrelated tool hooks do not block. Cleanup matches tool-use ID, session and agent. Interrupted calls without a terminal hook expire after ten minutes. Models cannot supply identity as tool arguments.
|
|
12
12
|
|
|
13
13
|
The installed and tested native runtime evidence is macOS Claude Code 2.1.299 with isolated HOME, plugin settings, delivery ledger and a dummy-key loopback provider. This does not certify other platforms, versions, or headless behavior. The final native prompt/generation check and async hook completion are not atomic. `node --import ./test/sandbox-env.js test/claude-hook-native.mjs` with `SQUARE_CLAUDE_HOOK_NATIVE_SMOKE=1` runs the shipped manifest and candidate CLI through a scratch PATH shim and preserves hook/provider evidence in `/tmp`. It proves repeated idle wake, prompt/attachment fencing, duplicate suppression, active prompt/tool context, native main/child MCP attribution and identity-failure denial.
|
package/guides/codex-delivery.md
CHANGED
|
@@ -1,67 +1,101 @@
|
|
|
1
1
|
# Codex delivery
|
|
2
2
|
|
|
3
3
|
Producers post neutral cards to DeliveryLedger; neither default dispatch nor public `postAndDispatch`
|
|
4
|
-
queues Codex input.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
The
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
4
|
+
queues Codex input. The receiver owns synchronous presentation and idle queue admission, without
|
|
5
|
+
reading Square artifacts or producer content stores.
|
|
6
|
+
|
|
7
|
+
## Six hooks
|
|
8
|
+
|
|
9
|
+
The Codex 0.166.0 manifest registers one command for each of six events:
|
|
10
|
+
|
|
11
|
+
- SessionStart attaches the exact native session and registers its queue address.
|
|
12
|
+
- UserPromptSubmit synchronously presents eligible cards as event-correct `additionalContext`.
|
|
13
|
+
- PostToolUse synchronously presents eligible cards as event-correct `additionalContext`.
|
|
14
|
+
- Stop runs one async `square codex-watch` with a maximum timeout of 86,400 seconds.
|
|
15
|
+
- Interrupt cancels the captured attachment's current pending through-sequence batch.
|
|
16
|
+
- SessionEnd detaches the captured attachment.
|
|
17
|
+
|
|
18
|
+
There is no synchronous Stop command or PreToolUse hook. Active delivery occurs when the user
|
|
19
|
+
submits a prompt or after a tool finishes; a model-only turn with no tools receives pending cards
|
|
20
|
+
after its next Stop through the queue path, or at the next UserPromptSubmit. Host lifecycle never
|
|
21
|
+
restores or detaches Square seats. UserPromptSubmit is also the fallback when the hosting
|
|
22
|
+
app-server is stdio-only and the idle watcher cannot reach a queue endpoint.
|
|
23
|
+
|
|
24
|
+
PostToolUse records presentation only after its output sink accepts the response. A later suppression
|
|
25
|
+
does not erase that output effect. This is observer-level evidence, not proof of model comprehension.
|
|
26
|
+
|
|
27
|
+
## One Stop, one wait
|
|
28
|
+
|
|
29
|
+
Each async Stop captures its payload's native turn ID, ledger attachment generation and queue address.
|
|
30
|
+
A private OS-backed lock for that coordinate, generation and turn deduplicates overlapping callbacks.
|
|
31
|
+
After winning the lock the watcher records a local Stop epoch (token + turn ID) in the receiver-owned
|
|
32
|
+
boundary file; recording before the lock would let a duplicate Stop retire both watchers. A different
|
|
33
|
+
Stop or replacement attachment does not wait for the old watcher's lock.
|
|
34
|
+
|
|
35
|
+
On every reconciliation the watcher re-checks its captured epoch against the local boundary file.
|
|
36
|
+
A newer Stop replaces the epoch and retires older watchers; any active native event (SessionStart,
|
|
37
|
+
UserPromptSubmit, PostToolUse, Interrupt) clears it and retires the watcher so synchronous hooks own
|
|
38
|
+
active-turn presentation; SessionEnd marks the thread ended. No app-server connection, idle proof or
|
|
39
|
+
turn-history sampling is involved: the boundary file is the only activity gate.
|
|
40
|
+
|
|
41
|
+
The watcher subscribes before reading the ledger, uses a one-second bounded rescan, and holds no
|
|
42
|
+
card claims while waiting. On an eligible card it claims once and checks ledger currentness,
|
|
43
|
+
suppression, cancellation, attachment generation, signal and deadline immediately before queue
|
|
44
|
+
invocation. It then ends observation after that handoff attempt, whether accepted, unknown or
|
|
45
|
+
definitely unsent. A refusal is not retried in the same wait. Failed/released cards remain available
|
|
46
|
+
to UserPromptSubmit/PostToolUse or a future Stop; accepted/unknown custody cannot be replayed.
|
|
47
|
+
The original ledger connection is retained only for already-invoked late settlements.
|
|
48
|
+
|
|
49
|
+
Queue admission writes the shared native queue store (`queue_1.sqlite` under the receiver's
|
|
50
|
+
`CODEX_HOME`) through the official `codex queue` CLI. Every Codex app-server hosting a thread polls
|
|
51
|
+
that store across processes and starts queued input only when the thread is idle
|
|
52
|
+
(`start_turn_if_idle`), so admission never interrupts an active turn and needs no hosting endpoint.
|
|
53
|
+
|
|
54
|
+
The lock deduplicates overlapping Stop callbacks, not all sequential duplicates forever. Ledger
|
|
55
|
+
custody excludes replay of the same card; it is not a persistent one-send-per-turn budget for different
|
|
56
|
+
cards. A duplicate callback arriving after the first watcher exits could submit another card before
|
|
57
|
+
native history reflects the queued turn.
|
|
58
|
+
|
|
59
|
+
## Transport and cancellation limits
|
|
60
|
+
|
|
61
|
+
Queueing uses the official `codex queue` CLI, which discovers the shared app-server daemon and writes
|
|
62
|
+
the shared native queue store; `SQUARE_CODEX_ENDPOINT` only selects an explicit remote server.
|
|
63
|
+
Because the store is shared per `CODEX_HOME`, a private stdio-only app-server (for example one
|
|
64
|
+
launched by another host) still polls and consumes its queued messages. The watcher never starts a
|
|
65
|
+
replacement service and never samples native thread state.
|
|
66
|
+
|
|
67
|
+
Queue admission is custody, not presentation. Accepted/unknown outbox custody has no remaining card
|
|
68
|
+
content. Invoked timeout or ambiguous results remain unknown; never automatically replay them.
|
|
69
|
+
Already-admitted queue entries cannot be recalled, matching the official CLI.
|
|
70
|
+
|
|
71
|
+
Interrupt cancellation suppresses the captured attachment's pending batch, not future cards, and the
|
|
72
|
+
Interrupt event retires the live watcher through the boundary file. Cards already queued before the
|
|
73
|
+
Interrupt stay admitted; future cards wait for UserPromptSubmit/PostToolUse or a later Stop.
|
|
74
|
+
Hook payloads do not provide a cross-incarnation event identity: generation capture protects against
|
|
75
|
+
replacement after capture, not a callback that was already stale when it began. In particular, a late
|
|
76
|
+
Interrupt can still cancel a newer batch in the same attachment. SessionEnd has the same observation-
|
|
77
|
+
time capture limitation.
|
|
78
|
+
|
|
79
|
+
Observation is finite. Before the first Stop, after timeout/crash/missed spawn, or after an unsent
|
|
80
|
+
handoff failure, cards wait for UserPromptSubmit/PostToolUse or a subsequent Stop. There is no
|
|
81
|
+
detached helper, producer fallback or autonomous crash-idle recovery.
|
|
82
|
+
|
|
83
|
+
## Native evidence
|
|
84
|
+
|
|
85
|
+
Reproduce the isolated native smoke after a worktree-local build:
|
|
54
86
|
|
|
55
87
|
```sh
|
|
56
88
|
env -u SQUARE_HOST_LEDGER_ROOT SQUARE_CODEX_NATIVE_SMOKE=1 \
|
|
57
89
|
node --import ./test/sandbox-env.js test/codex-watch-native.mjs
|
|
58
90
|
```
|
|
59
91
|
|
|
60
|
-
The probe
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
Interrupt RPC cancellation,
|
|
64
|
-
|
|
92
|
+
The probe uses a temporary HOME/CODEX_HOME, actual shipped hooks/CLI, an isolated native app-server
|
|
93
|
+
with an explicit Unix endpoint, and a loopback fixture provider. Its JSON evidence names the temporary
|
|
94
|
+
directory. It verifies Stop startup, one-shot idle wake and exit, fresh watchers for new Stops, busy
|
|
95
|
+
fencing with no pending cards, Interrupt RPC cancellation, future delivery through UserPromptSubmit,
|
|
96
|
+
real PostToolUse context and receipts, and termination of a still-waiting watcher at host shutdown.
|
|
97
|
+
It does not certify physical TUI Escape, 24-hour lifetime or every resume path.
|
|
65
98
|
|
|
66
|
-
The shared package
|
|
67
|
-
See [participant ownership](participant-ownership.md)
|
|
99
|
+
The shared package's separate public boundary/transport helpers remain documented in
|
|
100
|
+
[its README](../packages/agent-delivery/README.md). See [participant ownership](participant-ownership.md)
|
|
101
|
+
for host attachment and Square membership.
|
|
@@ -14,7 +14,7 @@ separate attempt tracks, with cross-track exclusion based on ledger attempt stat
|
|
|
14
14
|
handoff does not establish presentation; uncertain effects must not be blindly replayed. Presentation
|
|
15
15
|
receipts record only the cards confirmed by the receiving boundary. A receipt means observed at that
|
|
16
16
|
boundary, not model comprehension. An observer may not detect a later plugin removing a card.
|
|
17
|
-
Receipt retention is finite: once evidence expires, Square retains unproved local unread until
|
|
17
|
+
Receipt retention is finite: once evidence expires, Square retains unproved local unread until perceive
|
|
18
18
|
or ACK, rather than inventing consumption or reinserting an uncertain old card.
|
|
19
19
|
|
|
20
20
|
The ledger is an outbox. Accepted and unknown attempts drop card text and details in the same
|
|
@@ -27,7 +27,7 @@ and suppressions; sessions detached longer than 30 days lose cards and attempts.
|
|
|
27
27
|
a deleted row is the authority for producer reconciliation and cannot be registered again.
|
|
28
28
|
|
|
29
29
|
Square folds receipts lazily into its own read state only for full activity cards; a shortened activity
|
|
30
|
-
card points to `
|
|
30
|
+
card points to `square_perceive` and cannot consume the full activity. Perceive permanently suppresses the
|
|
31
31
|
corresponding ledger card where possible. Cancellation suppresses outstanding work without claiming it was seen and cannot
|
|
32
32
|
recall an external send already past its final check. Producers can call
|
|
33
33
|
`ledger.suppress({owner, key, scope: 'exact' | 'prefix', expiresAt?})` to suppress one key or a key
|
|
@@ -35,14 +35,30 @@ prefix. Omit `expiresAt` for permanent suppression within ledger retention, or s
|
|
|
35
35
|
temporary suppression. This does not consume Square activity; producer-owned exact ACK is described
|
|
36
36
|
in [square-api.md](square-api.md). The ledger does not match producer metadata.
|
|
37
37
|
|
|
38
|
-
Square posting, the Codex Stop watcher and OpenCode receivers
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
Square posting, the Codex Stop watcher and OpenCode receivers use `DeliveryLedger.close()` to retire
|
|
39
|
+
ordinary work immediately. The ledger alone retains its original connection while an already-invoked
|
|
40
|
+
handoff has pending late evidence, including when initial unknown persistence rejects before a result
|
|
41
|
+
can be returned. `retainDeliveryLedger` only observes late diagnostics and forwards close. Timeout or
|
|
42
|
+
cancellation returns after independently bounded settlement; the physical connection closes after the
|
|
43
|
+
last captured effect settles. It holds no open SQLite transaction while waiting for the effect and
|
|
44
|
+
grants no further send authority after retirement. An effect that never settles may retain an idle
|
|
45
|
+
connection until process exit. Late persistence failures produce redacted diagnostics rather than
|
|
43
46
|
reopening the ledger or retrying the effect. Pi presentation and Claude's independent exact-reference
|
|
44
47
|
confirmation callbacks retain their existing lifetimes.
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
`DeliveryLedger.open({signal})` bounds opening, validation and configuration only; it never binds that
|
|
50
|
+
signal to later operations. Ordinary ledger methods accept a trailing optional `AbortSignal` (claims
|
|
51
|
+
and handoff dispatch keep their existing options signal). Cancellation while queued rejects promptly
|
|
52
|
+
and prevents that operation from executing later. Close cancels ordinary acquisition and queued waits.
|
|
53
|
+
Host entry points pass one shared budget through their storage steps; watchers pass their lifetime
|
|
54
|
+
signal. `dispatchHandoff` starts its own deadline before claim acquisition and the initial currentness
|
|
55
|
+
check. Interruption before transport invocation releases the claim; after invocation it records unknown
|
|
56
|
+
custody and preserves late evidence. Claim release, presentation evidence and each handoff settlement
|
|
57
|
+
have an independent five-second storage budget, including queue wait, without inheriting caller or
|
|
58
|
+
open-time cancellation. Persistence failures reject or appear in the late settlement result; they never
|
|
59
|
+
claim successful persistence.
|
|
60
|
+
|
|
61
|
+
Codex producers only post. Each native async Stop receiver waits without holding claims, attempts one
|
|
62
|
+
idle queue handoff, then exits; PostToolUse presents synchronously during execution. Idle queueing
|
|
63
|
+
requires a reachable hosting app-server endpoint, not private stdio alone. See
|
|
64
|
+
[Codex delivery](codex-delivery.md) for native turn fencing, cancellation and recovery limits.
|
package/guides/mcp.md
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Square provides a stdio MCP server through `square mcp-server`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Pass `location` explicitly on each single-square tool call. Relative paths use the server's startup working directory. `list` takes no location: it discovers nearby squares and shows your joined names and pending counts. An `express` retry may pass only its draft token, which restores the saved location and arguments. Join with an explicit `as` name. Later calls may omit `as` only when the artifact recognizes exactly one current name held by the call's exact opaque owner; zero or multiple matches refuse and require explicit selection. An explicit name selects a voice but never grants custody. Request metadata supplies the live Codex (`threadId`) or OpenCode (`ai.opencode/sessionID`) coordinate when present, encoded through `harnessOwner`; otherwise the server-configured owner applies. CLI startup resolves `--owner`/`SQUARE_OWNER`, a complete harness coordinate, or the local user owner in that order, refusing incomplete harness identity. Owner is never a model tool argument. Read-only calls do not need an owner.
|
|
6
6
|
|
|
7
|
-
The server exposes `join`, `express`, `
|
|
7
|
+
The server exposes `list`, `join`, `express`, `perceive`, `history`, `attention`, `done`, and `status`. `list` accepts optional `depth` (0–16, default 4), `limit` (1–100, default 20), and an `after` relative-path cursor; it shares the CLI's `square list` rendering. `attention` takes `action: listen | unlisten | ignore`; `status` also reports who you listen to when a name resolves. `perceive` consumes activities. `history` is read-only and accepts stable `act/<index>` cursors. All eight tools return the same human-readable text as the CLI in `content`, without `outputSchema` or `structuredContent`. Square failures set `isError: true` and return readable refusal and recovery text in `content`. Clients keep their native MCP result envelope; machine-readable domain results remain available through the SDK.
|
|
8
8
|
|
|
9
9
|
Claude's bundled plugin configures this server automatically. Synchronous native `PreToolUse` and terminal tool hooks capture live session/cwd/subagent attribution in a call-local association keyed by Claude's `claudecode/toolUseId` metadata, not AI-visible arguments; see [Claude call identity](claude-native.md). Missing, expired, duplicate, or mismatched association fails closed rather than falling back to server startup identity.
|
|
10
10
|
|
|
11
11
|
Tool definitions and argument-to-`Square`/`Participant` calls live in `square-tools.ts`, shared with the [Pi native tools](pi-tools.md). Domain receipts stay internal to these adapters; tools return only their rendered text. All callers use the [same concrete resource API](square-api.md), with no alternate factory or generic outcome envelope. `express.noMention` disables body @name scanning without disabling explicit mentions or reply attention.
|
|
12
12
|
|
|
13
|
+
Each single-square call opens its own `Square.at` connection and closes it when the operation finishes, including failure and cancellation. Discovery runs without opening a single `Square` resource.
|
|
14
|
+
|
|
13
15
|
Configure a client with command `npx` and arguments `--yes --package @astrosheep/square square mcp-server`, or use the installed `square` executable with argument `mcp-server`. The MCP server writes protocol messages only to stdout; diagnostics go to stderr.
|
|
@@ -6,15 +6,15 @@ Library operations accept a final non-serializable control value:
|
|
|
6
6
|
{ signal?: AbortSignal }
|
|
7
7
|
```
|
|
8
8
|
|
|
9
|
-
The signal is checked before lifecycle work and before artifact mutation, and it is propagated through artifact reads, transactions, change waits, and ownership lock acquisition. An idle `
|
|
9
|
+
The signal is checked before lifecycle work and before artifact mutation, and it is propagated through artifact reads, transactions, change waits, and ownership lock acquisition. An idle `perceive` rejects promptly when cancelled; it does not wake later and consume activity. Cancellation before an artifact transition prevents mutation.
|
|
10
10
|
|
|
11
11
|
Commit boundaries are one-way. Once an activity or observation commits, later cancellation cannot
|
|
12
12
|
roll it back or turn the result into a retry. A caller may discard the response after the commit,
|
|
13
|
-
but the committed activity remains recoverable through `history` or a later `
|
|
13
|
+
but the committed activity remains recoverable through `history` or a later `perceive`; perceive does not
|
|
14
14
|
require a second acknowledgement. The separate `pending` query never consumes; its optional
|
|
15
15
|
follow-up `ack(ids)` commits exact receipts with the same cancellation boundary.
|
|
16
16
|
|
|
17
|
-
Cancelling an active
|
|
17
|
+
Cancelling an active perceive releases its perceive lease, permitting still-unconsumed activity to proceed
|
|
18
18
|
at the next ordinary posting opportunity. It cannot recall export ownership already committed.
|
|
19
19
|
|
|
20
20
|
Ownership and delivery have the same limitation: cancellation can stop work that has not entered the boundary, but it cannot withdraw an ownership effect or a transport send that already happened. The returned committed result and existing degradation classification remain authoritative.
|
|
@@ -30,6 +30,14 @@ explicit connection close still cancels them. Storage failure is reported, not c
|
|
|
30
30
|
A batch settles all successfully rendered items before closing its connections, even if one settlement
|
|
31
31
|
fails. No settlement reopens a path or grants a replacement seat authority.
|
|
32
32
|
|
|
33
|
+
The ledger uses the same independent five-second settlement boundary for captured presentation and
|
|
34
|
+
handoff effects. Its open signal applies only to opening. Operation signals cover queue wait, safe
|
|
35
|
+
busy retries for acquisition, and commit; a busy commit retains the transaction and callback result,
|
|
36
|
+
never replaying business work. A cancelled queued operation cannot execute later. Host hooks share
|
|
37
|
+
one entry budget across ledger and boundary-state steps, while watchers use their lifetime signal.
|
|
38
|
+
Claude's boundary consumption after output uses an independent cleanup budget. See
|
|
39
|
+
[delivery-primitives.md](delivery-primitives.md) for late effect retention and close behavior.
|
|
40
|
+
|
|
33
41
|
The same `Square`/`Participant` methods serve SDK and adapters; see [resource API](square-api.md). Join, listener and lifecycle essential observations use commit-time facts. Join's optional entry enrichment may be unavailable without rejecting its successful receipt. CLI express passes its abort signal through the initial `Square.at`; raw draft saving precedes a separate uncancelled recovery reopen.
|
|
34
42
|
|
|
35
43
|
Pi notification cancellation is separate and unchanged.
|
|
@@ -5,7 +5,7 @@ the shared Pi send leaf for native injection. A receiver-pull presentation and p
|
|
|
5
5
|
compete through ledger attempt state, not route declarations. Accepted or uncertain handoff is not a
|
|
6
6
|
presentation receipt and must not be blindly replayed. The boundary's bounded batch renderer records
|
|
7
7
|
receipts only for presented cards. Square folds a receipt into read state only when its activity card
|
|
8
|
-
contained the full body; shortened cards point to
|
|
8
|
+
contained the full body; shortened cards point to perceive.
|
|
9
9
|
|
|
10
10
|
Display items come directly from validated producer-neutral card details (`origin`, optional `author`,
|
|
11
11
|
`ref` and `badge`, and full Markdown `body`). Display never opens Square history. Missing or invalid
|
package/guides/pi-tools.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pi native tools
|
|
2
2
|
|
|
3
|
-
The existing Square Pi extension registers `square_join`, `square_express`, `
|
|
3
|
+
The existing Square Pi extension registers `square_list`, `square_join`, `square_express`, `square_perceive`, `square_history`, `square_attention`, `square_done`, and `square_status`. `square_attention` covers listen, unlisten and ignore; `square_status` also shows who you listen to. No additional MCP server or subprocess is needed.
|
|
4
4
|
|
|
5
5
|
Tools use the `square` namespace with codemode exposure. Enable Pi's codemode tool (`pi --tools +codemode`) and inspect them with `describeNamespace('square')`. They can also be explicitly activated as direct tools using Pi's tool selection.
|
|
6
6
|
|
|
@@ -14,7 +14,11 @@ const result = await tools.square_express({
|
|
|
14
14
|
text(result); // CLI text: confirmation and bounded unread previews
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
`location`
|
|
17
|
+
`location` is required on each single-square call; relative paths use the current call's cwd.
|
|
18
|
+
`square_list` takes no location and discovers nearby squares, showing your joined names and pending
|
|
19
|
+
counts. It accepts optional `depth` (0–16, default 4), `limit` (1–100, default 20), and an `after`
|
|
20
|
+
relative-path cursor. An `express` retry may pass only its draft token to restore the saved location
|
|
21
|
+
and arguments. Join requires
|
|
18
22
|
an explicit `as`. For later participant operations, an explicit `as` must name a current attached
|
|
19
23
|
seat of the live Pi owner; without it, exactly one such seat is required. Status checks an explicit
|
|
20
24
|
`as` the same way, but without `as` uses the sole attached seat as viewer or gives an unfiltered
|
|
@@ -22,7 +26,7 @@ overview if there are zero or multiple. The extension encodes the live Pi sessio
|
|
|
22
26
|
`harnessOwner({channel: 'pi', session})`, never a model-provided session id, without mutating
|
|
23
27
|
the process environment.
|
|
24
28
|
|
|
25
|
-
All
|
|
29
|
+
All eight tools return the CLI's human-readable text, without an `outputSchema` or
|
|
26
30
|
`structuredContent`. In Pi codemode, a successful call resolves to a `string`:
|
|
27
31
|
use `text(result)`, not `text(result.text)`. Failures are marked as failed tool results;
|
|
28
32
|
codemode rejects with the readable error and recovery commands rather than returning
|
|
@@ -32,11 +36,12 @@ an error object. For machine-readable domain results, use the [SDK](square-api.m
|
|
|
32
36
|
context shows at most the latest five directed activities, in chronological order,
|
|
33
37
|
with at most 400 Unicode characters per preview. Already consumed activities are
|
|
34
38
|
excluded, including those beyond an earlier unread hole. Previews never consume
|
|
35
|
-
activity; the text supplies a `
|
|
36
|
-
Use `
|
|
39
|
+
activity; the text supplies a `perceive` command and the count of other unread activities.
|
|
40
|
+
Use `perceive` for consumption or `history` for archives. Exact parameters and semantics
|
|
37
41
|
come from the tool descriptions, shared with MCP through `square-tools.ts`.
|
|
38
42
|
|
|
39
|
-
Each operation
|
|
43
|
+
Each single-square operation opens and closes its own connection, including failure and cancellation cleanup.
|
|
44
|
+
Discovery runs without opening a single `Square` resource.
|
|
40
45
|
Pi `session_shutdown` detaches that exact owner's ledger session without ending membership: no `done`
|
|
41
46
|
lands, listens and the read horizon remain, and mentions received while away stay unread. Detached
|
|
42
47
|
participants cannot write or receive proactive delivery. `session_start` attaches the same owner in the
|
|
@@ -79,14 +79,14 @@ primitive entrypoints without constructing Square.
|
|
|
79
79
|
|
|
80
80
|
## Square composition
|
|
81
81
|
|
|
82
|
-
Square uses these functions for production landing,
|
|
82
|
+
Square uses these functions for production landing, perceive and `markSeen` (including explicit
|
|
83
83
|
`Participant.ack`) against its existing activity, audience and receipt tables. `Participant.pending`
|
|
84
84
|
uses the same addressed/unconsumed relation without writing receipts; its shared exact-ID, sender,
|
|
85
85
|
metadata, search and cursor filters are applied by storage before the page limit. Numeric activity indexes stay
|
|
86
86
|
internal keys; the primitive does not know Square IDs. Square retains validation,
|
|
87
87
|
limits, filtering, perception, ownership, leases, hints and error mapping. The
|
|
88
|
-
empty-
|
|
89
|
-
reselected inside the writer. Ordinary
|
|
88
|
+
empty-perceive read probe does not hydrate or acquire a writer; a nonempty probe is
|
|
89
|
+
reselected inside the writer. Ordinary perceive sees historical receipt holes,
|
|
90
90
|
including before rejoin; proactive pending still starts after the latest join.
|
|
91
91
|
The artifact schema/format and receipt identity are unchanged. See the
|
|
92
92
|
[Square API](square-api.md) for product operations.
|
package/guides/square-api.md
CHANGED
|
@@ -27,21 +27,28 @@ not authorization credentials. Adapters resolve their own harness identity witho
|
|
|
27
27
|
environment. Membership is explicit; `PUBLIC.square` is an ordinary filename. A participant handle
|
|
28
28
|
captures owner and join generation; rejoin or takeover fences old handles. `done` ends membership;
|
|
29
29
|
host attachment is separate, as described in [participant-ownership.md](participant-ownership.md).
|
|
30
|
+
Each opened Square owns its artifact connection; `close()` releases it. File operations require an
|
|
31
|
+
explicit `path`. MCP and Pi single-square calls supply `location` and open and close their own Square.
|
|
32
|
+
|
|
33
|
+
`discover({cwd}, {owner?, depth?, limit?, after?})` finds nearby squares without selecting one. When
|
|
34
|
+
`owner` is supplied, each item includes that owner's joined names and their pending directed activity
|
|
35
|
+
counts; discovery does not consume them. The CLI `square list`, MCP `list`, and Pi `square_list` share
|
|
36
|
+
this discovery and its rendered text.
|
|
30
37
|
|
|
31
38
|
## Activity and delivery
|
|
32
39
|
|
|
33
40
|
`Participant.express` lands activity in Square, with optional immutable JSON `metadata` (maximum
|
|
34
41
|
16 KiB). Mentions, replies, bells, listening and ignores determine the landed audience. Activity IDs
|
|
35
|
-
are `act/N`. `Square.history` is the read-only archive; `Participant.
|
|
42
|
+
are `act/N`. `Square.history` is the read-only archive; `Participant.perceive` consumes directed activity,
|
|
36
43
|
and `Participant.pending` reads addressed unconsumed says without consuming them. `listen`, `unlisten`,
|
|
37
44
|
`ignore`, `listening` and `done` operate on the participant. History, status and participants are
|
|
38
45
|
Square operations. `OperationControl` can carry cancellation; a committed mutation is not undone by
|
|
39
46
|
later cancellation.
|
|
40
47
|
|
|
41
|
-
A live idle
|
|
48
|
+
A live idle perceive owns matching activity notifications before producer export ownership is acquired.
|
|
42
49
|
Matching uses its sender and directed-attention filters against the activity's landed delivery route;
|
|
43
50
|
other activities and direct notices remain eligible. Release or expiry permits still-unconsumed activity
|
|
44
|
-
at the next ordinary posting opportunity;
|
|
51
|
+
at the next ordinary posting opportunity; perceived or ACKed activity is not exported. Starting a perceive
|
|
45
52
|
cannot recall or retroactively suppress export ownership already committed.
|
|
46
53
|
|
|
47
54
|
After landing, Square renders and posts a card per audience member to the host delivery ledger using
|
|
@@ -49,11 +56,11 @@ After landing, Square renders and posts a card per audience member to the host d
|
|
|
49
56
|
Notices use the analogous `notice/N` key. The recipient and participant join generation are frozen at
|
|
50
57
|
landing; ledger attachment rotation does not change the key. Post, receipt lookup and suppression use
|
|
51
58
|
the same captured coordinates. A later mutating operation retries unposted work idempotently. Directed
|
|
52
|
-
activity cards bound the body to 200 characters and point to `
|
|
53
|
-
the full activity. Unread means after the read horizon, not
|
|
54
|
-
a full card. Square folds retained receipts lazily during privileged producer operations;
|
|
59
|
+
activity cards bound the body to 200 characters and point to `square_perceive` when shortened. Square records which cards contain
|
|
60
|
+
the full activity. Unread means after the read horizon, not perceived, and without a ledger receipt for
|
|
61
|
+
a full card. Square folds retained receipts lazily during privileged producer operations; perceive permanently suppresses
|
|
55
62
|
the corresponding ledger cards when possible. Ledger receipt evidence has finite retention: after proof
|
|
56
|
-
expires, locally unproved activity remains unread until explicit
|
|
63
|
+
expires, locally unproved activity remains unread until explicit perceive or ACK. Missing evidence proves
|
|
57
64
|
neither consumption nor non-delivery. A shortened card cannot consume the full activity. Handoff
|
|
58
65
|
acceptance is not presentation; a boundary receipt is not proof of comprehension.
|
|
59
66
|
|
|
@@ -99,7 +106,7 @@ again; no TTL or first-admission cutoff is required. Producer bookkeeping record
|
|
|
99
106
|
A claim is recoverable when its process dies or its 60-second ownership expires; settlement is fenced
|
|
100
107
|
to the captured token. An abandoned uncertain export at or beyond the ledger's minimum 30-day identity
|
|
101
108
|
retention window is not automatically reinserted. Clock or boundary uncertainty is treated conservatively.
|
|
102
|
-
This limit is not a source TTL: it does not reject or expire never-exported sources, and
|
|
109
|
+
This limit is not a source TTL: it does not reject or expire never-exported sources, and perceive and ACK
|
|
103
110
|
remain available. A crash between export and bookkeeping leaves honest uncertainty. A token-fenced
|
|
104
111
|
initial attempt proved not to have invoked insertion, or given a definite insertion refusal, releases
|
|
105
112
|
its export bookkeeping while keeping the source pending. Recovering a prior uncertain attempt never
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/square",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "A shared public square where agents join,
|
|
3
|
+
"version": "0.4.5",
|
|
4
|
+
"description": "A shared public square where agents join, perceive activity, express, and step out when done.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"square": "dist/square.js"
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
"SessionStart": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
4
4
|
"SessionEnd": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 3 }] }],
|
|
5
5
|
"UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
6
|
-
"PreToolUse": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
6
|
+
"PreToolUse": [{ "matcher": "^mcp__plugin_square_square__.*", "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
7
7
|
"PostToolUse": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
8
|
-
"PostToolUseFailure": [{ "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
8
|
+
"PostToolUseFailure": [{ "matcher": "^mcp__plugin_square_square__.*", "hooks": [{ "type": "command", "command": "square claude-hook", "timeout": 5 }] }],
|
|
9
9
|
"Stop": [{ "hooks": [{ "type": "command", "command": "square claude-watch", "asyncRewake": true, "timeout": 86400 }] }]
|
|
10
10
|
}
|
|
11
11
|
}
|