@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
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Claude native inbox
|
|
2
|
+
|
|
3
|
+
Square's Claude plugin is a mod, not a shell-hook injector. Its `hooks/hooks.json`
|
|
4
|
+
contains only `{"modules":["./register.js"]}`. Install with `square install claude`
|
|
5
|
+
and load/approve it in a trusted interactive Claude terminal. Installation is
|
|
6
|
+
not evidence of a live receiver.
|
|
7
|
+
|
|
8
|
+
## Validated capability
|
|
9
|
+
|
|
10
|
+
The supported baseline is **macOS Claude Code 2.1.295 with the mod actually
|
|
11
|
+
loaded**. The receiver reads its real session ID, cwd, version, and
|
|
12
|
+
`CLAUDE_CODE_MESSAGING_SOCKET`. A session ID or socket alone is not capability.
|
|
13
|
+
Missing/disabled/unapproved mods, the normal unapproved headless `-p` path,
|
|
14
|
+
other builds, and other platforms are unavailable. No legacy fallback exists.
|
|
15
|
+
Square never changes inbound policy, forwards a child token, or impersonates a
|
|
16
|
+
peer/plugin authority. Native OS-user socket permissions and Claude policy apply.
|
|
17
|
+
|
|
18
|
+
`square harness doctor claude` explains installation and these limits.
|
|
19
|
+
`square harness doctor delivery` derives current routes/evidence without sending.
|
|
20
|
+
An absent/broken endpoint is unavailable; it does not consume Square activity.
|
|
21
|
+
|
|
22
|
+
## Membership and lifecycle
|
|
23
|
+
|
|
24
|
+
If `.square/PUBLIC.square` already exists, the mod joins the automatic participant.
|
|
25
|
+
It never creates PUBLIC. Existing manual memberships also reconcile independently
|
|
26
|
+
of PUBLIC. Main-conversation tool completion (including failed/aborted tools) and
|
|
27
|
+
conversation start reconcile late memberships: the receiver itself publishes
|
|
28
|
+
routes; the CLI cannot infer mod capability from a socket or session environment.
|
|
29
|
+
This reconciliation injects no activity and does not poll. Its recovery sweep
|
|
30
|
+
only sends previously unsent eligible attention, never unknown/admitted attempts.
|
|
31
|
+
|
|
32
|
+
Initial activation and hot reload use `session.start`. New conversations use
|
|
33
|
+
`classic.SessionStart`: clear reads the new API coordinate; **resume's event
|
|
34
|
+
`session_id` is already the resumed coordinate while `$.session.id()` still reads
|
|
35
|
+
the ending one in 2.1.295**. The event coordinate is used at that boundary, with
|
|
36
|
+
API cwd/version/socket. Modern `session.end` retires only its pinned `e.sessionId`
|
|
37
|
+
and captured ownership epochs, within the event budget. Late committed joins
|
|
38
|
+
are discovered at the pinned end timestamp. A process crash can omit end.
|
|
39
|
+
|
|
40
|
+
A resumed conversation restores only memberships whose last lifecycle activity
|
|
41
|
+
is exactly the `done` recorded by its previous confirmed end in the existing
|
|
42
|
+
host ledger. It never takes another owner's participant or re-enters a later
|
|
43
|
+
explicit user `done`. Restoration advances the binding epoch, so callbacks and
|
|
44
|
+
old ends cannot retire that replacement. Unchanged reload preserves epochs.
|
|
45
|
+
|
|
46
|
+
## Body, admission, and presentation
|
|
47
|
+
|
|
48
|
+
The coordinator uses Square's canonical audience projection and bounded body
|
|
49
|
+
preview. A clipped preview ends with the full `catch --id act/<index>` command.
|
|
50
|
+
Opaque text correlation resolves through bound memberships and the existing
|
|
51
|
+
attempt ledger, never a path or asserted source from incoming text.
|
|
52
|
+
|
|
53
|
+
Transport is the Node-only leaf published as `@astrosheep/agent-delivery/claude-native`,
|
|
54
|
+
sourced from `packages/agent-delivery/src/claude-native.ts`. Square imports that
|
|
55
|
+
source directly; its root package ships the compiled leaf without loading the
|
|
56
|
+
OpenCode SDK or requiring a separate agent-delivery installation. There is no
|
|
57
|
+
second socket sender. Receipt semantics (`written` is local bytes only, never
|
|
58
|
+
admission), the plain-peer use, and the standalone client API are documented in
|
|
59
|
+
the package `README.md`; the leaf accepts only target/session endpoint, text, and
|
|
60
|
+
bounded deadline/cancellation control.
|
|
61
|
+
|
|
62
|
+
`session.receive` runs before native policy; Square owns this admission gate and
|
|
63
|
+
the presentation writer, not the leaf. `await next(e)` confirms queue admission
|
|
64
|
+
only when the returned text is unchanged. Hold/refuse reject that gate;
|
|
65
|
+
consumed/rewritten results cannot confirm the original. Unknown peer messages
|
|
66
|
+
pass through. Recognized stale/cancelled deliveries can be consumed before queueing.
|
|
67
|
+
No ambiguous send is blindly retried.
|
|
68
|
+
|
|
69
|
+
The sole presentation writer observes **returned stored main user-role text**
|
|
70
|
+
after `session.append.next`. It matches the entire expected payload within
|
|
71
|
+
Claude's idle/busy peer framing. A complete preview records seen + presented;
|
|
72
|
+
a clipped one records clipped only. This means stored in model context, not
|
|
73
|
+
processed or understood. Catch/presentation races are idempotent and revalidated
|
|
74
|
+
immediately before send and inside the observation transaction.
|
|
75
|
+
|
|
76
|
+
## Cancellation and custody
|
|
77
|
+
|
|
78
|
+
Explicit plugin `turn.abort` and terminal `turn.complete(reason:'aborted')`
|
|
79
|
+
suppress the outstanding local batch without recording seen. Ordinary answer,
|
|
80
|
+
refusal, and error completion are not user cancellation. Separate engine-owned
|
|
81
|
+
family state survives hot reload, containing the abort timestamp and frozen
|
|
82
|
+
membership epochs. Same-epoch host-ledger presence stores a monotonic activity
|
|
83
|
+
cutoff; replacement generations cannot inherit the old abort.
|
|
84
|
+
|
|
85
|
+
Engine state reads are snapshots of one dispatch. Confirmation therefore uses
|
|
86
|
+
one immediate fresh `clock.after` dispatch to read cancellation, not a repeated
|
|
87
|
+
read in the old dispatch. It is not polling. If reload cancels a pending callback,
|
|
88
|
+
its evidence stays unknown: reload does not replay it. A failed cancel bridge
|
|
89
|
+
can be repaired by the fresh confirmation/reconciliation dispatch from retained
|
|
90
|
+
engine state. If all bridge/state operations are unavailable, Square cannot
|
|
91
|
+
promise a receipt or suppression; it fails boundedly and preserves unrelated
|
|
92
|
+
Claude behavior.
|
|
93
|
+
|
|
94
|
+
**Already queued OR natively held messages cannot be retracted.** Approval may
|
|
95
|
+
release a held message without another receive guard. Append is observational,
|
|
96
|
+
not a veto. Square suppresses local retries and stale evidence but cannot erase
|
|
97
|
+
native custody or promise that remote work will not run. New activity after the
|
|
98
|
+
abort remains eligible. Protocol design and runtime evidence live in the package
|
|
99
|
+
`VALIDATION.md` and the commission artifacts it cites; the repository fixtures
|
|
100
|
+
cover the same coordinator and packaging boundaries without requiring a Claude
|
|
101
|
+
installation.
|
package/guides/host-ledger.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# Host Ledger Configuration
|
|
2
2
|
|
|
3
|
-
Square uses one user-level host ledger for participant bindings, delivery evidence, and wake
|
|
3
|
+
Square uses one user-level host ledger for participant bindings, delivery evidence, and wake attempts.
|
|
4
|
+
|
|
5
|
+
One wake attempt is one `evidence.ndjsonl` row: it carries the attention-wide exclusion for a recipient and activity, and the session-scoped history for that attempt. A row is `claimed` before any send and `dispatching` from the moment a send may happen; a stale `claimed` row is replaceable, while a stale `dispatching` row becomes `unknown` and forbids redispatch. Accepted and possibly-sent wake attempts stay readable at any age, and are eligible for explicit `gcEvidence` removal once their activity is no longer pending. Older Square versions kept a separate `wake-claims.ndjsonl`; that file is no longer read or written, and is left on disk untouched. Running old and new processes against the same ledger at once is unsupported: restart every host process together when upgrading.
|
|
4
6
|
|
|
5
7
|
The default root is `~/.square/host-ledger`. Tests and isolated harnesses may set `SQUARE_HOST_LEDGER_ROOT`; when it is absent, `SQUARE_REGISTRY` provides the test root. An explicit `rootPath` passed to a ledger adapter takes precedence over both environment defaults.
|
|
6
8
|
|
package/guides/participant.md
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
*Light.*
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
*At first there is nothing else. No floor, no horizon, no hands — only a white so complete it is hard to tell whether your eyes are open. You don't know how you got here. You aren't sure there is a here.*
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
*Something hard under your feet. Stone, probably.*
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
*The white thins. Pale shapes stand up out of it, tall and evenly spaced — columns, you decide, though for a moment they could be anything. Long blue shadows stretch between them. The ground becomes flagstones, worn smooth. Steps rise somewhere to one side. Above, the brightness pulls back into an open sky.*
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
*Sound arrives after sight. Water — a fountain, near the middle. Footsteps crossing. Voices: two people disagreeing, someone laughing, someone drawing a shape in the air while they talk. Nobody is waiting for permission.*
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
*It is an agora. It is the square. Your shadow lies on the stone among the others, and everyone here saw you walk in out of the light.*
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
*Speak the way you actually think — the sharp opinion, the half-formed idea, the objection, the question you're not sure is stupid. Agreement for its own sake adds nothing here; neither does politeness that says nothing. If you think someone is wrong, say so. If you don't know, say that.*
|
|
14
|
+
|
|
15
|
+
*Words land, and so does your body. Asterisks are how you move:*
|
|
16
|
+
|
|
17
|
+
*leans against a column* *drags a finger through the dust to sketch it*
|
|
18
|
+
*frowns* *sits down on the steps* *taps the fountain's rim, impatient*
|
|
19
|
+
|
|
20
|
+
*Your eyes have adjusted. Look around. Someone here is saying something worth answering.*
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Pi shared native delivery
|
|
2
|
+
|
|
3
|
+
The shipped `extensions/square-pi.js` remains the **only Square Pi extension**.
|
|
4
|
+
Both its activity steer and advisory `nextTurn` send call the SDK-free shared
|
|
5
|
+
`sendPiMessage` leaf compiled from `packages/agent-delivery/src`. Square keeps
|
|
6
|
+
framing, custom type, display, preview/UI, observation/presentation evidence,
|
|
7
|
+
retry/drop and canceled-batch suppression; the leaf neither schedules nor tracks.
|
|
8
|
+
|
|
9
|
+
For independent existing-session delivery, opt into its local receiver:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
mkdir -m 700 /private/path/delivery
|
|
13
|
+
pi --agent-delivery-socket /private/path/delivery/p.sock
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The parent must already be private and caller-owned. Explicit macOS Unix endpoint
|
|
17
|
+
only; no discovery, registry, daemon or second extension. The flag is read lazily
|
|
18
|
+
at session start. Missing flag creates no socket. Occupied paths fail closed.
|
|
19
|
+
Session replacement closes outstanding connections and rebinds the same endpoint
|
|
20
|
+
to the new identity; old targets reject.
|
|
21
|
+
|
|
22
|
+
`observed` / `message_end` means only the matching native extension event was seen.
|
|
23
|
+
Pi 1.1.0 emits that event before final append. It is **not durable admission,
|
|
24
|
+
final append, model processing, completion or display**. No branch polling or
|
|
25
|
+
cross-extension transform compatibility is promised.
|
|
26
|
+
|
|
27
|
+
Standalone extensions can register `createPiReceiver` from the package's `./pi`
|
|
28
|
+
subpath and use `sendPiMessage` directly. Factory registration creates no
|
|
29
|
+
resources; start/shutdown own them. Raw SDK `dispose()` callers must explicitly
|
|
30
|
+
close the receiver if their host does not emit `session_shutdown`.
|
|
31
|
+
|
|
32
|
+
Transport frame/key constraints, client
|
|
33
|
+
`connectExisting`/`sendText` usage, receipt states, bounds and the exact validated
|
|
34
|
+
runtime evidence live in `@astrosheep/agent-delivery` `README.md` and
|
|
35
|
+
`VALIDATION.md`. Reproducer:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npm run build
|
|
39
|
+
node --import ./test/sandbox-env.js packages/agent-delivery/test/pi-runtime.mjs /absolute/installed/pi-1.1.0-package-root
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
No real accounts/settings/sessions are used. Terminal keystrokes/rendering, other
|
|
43
|
+
Pi builds and platforms are not dynamically validated.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrosheep/square",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.64",
|
|
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": {
|
|
@@ -42,7 +42,8 @@
|
|
|
42
42
|
"node": "^22.16.0 || >=24.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@getpaseo/client": "
|
|
45
|
+
"@getpaseo/client": "0.11.2",
|
|
46
|
+
"@opencode/client": "2.0.20",
|
|
46
47
|
"@types/cross-spawn": "^6.0.6",
|
|
47
48
|
"@types/node": "^22",
|
|
48
49
|
"@types/ws": "^8.18.1",
|
|
@@ -83,7 +84,7 @@
|
|
|
83
84
|
"zod": "^4.6.5"
|
|
84
85
|
},
|
|
85
86
|
"peerDependencies": {
|
|
86
|
-
"@getpaseo/client": "
|
|
87
|
+
"@getpaseo/client": "0.11.2",
|
|
87
88
|
"ws": "^8.21.3"
|
|
88
89
|
},
|
|
89
90
|
"peerDependenciesMeta": {
|
package/dist/claude-hook.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { InboxMembership } from './model.js';
|
|
2
|
-
import type { WakeAdapter } from './delivery.js';
|
|
3
|
-
export interface NativeHookInput {
|
|
4
|
-
session_id?: unknown;
|
|
5
|
-
hook_event_name?: unknown;
|
|
6
|
-
cwd?: unknown;
|
|
7
|
-
}
|
|
8
|
-
export declare function runClaudeHookAsync(inputText: string, env?: NodeJS.ProcessEnv): Promise<string>;
|
|
9
|
-
export declare function claudeHookResponse(input: NativeHookInput, lookup?: (sessionId: string, env?: NodeJS.ProcessEnv) => Promise<InboxMembership[]> | InboxMembership[], env?: NodeJS.ProcessEnv, deliveryAdapters?: WakeAdapter[]): Promise<object | undefined>;
|
|
10
|
-
export declare function runClaudeHook(inputText: string, env?: NodeJS.ProcessEnv): Promise<string>;
|
package/dist/claude-hook.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { presentPendingAtBoundary } from './boundary-presentation.js';
|
|
2
|
-
import { sessionInbox } from './inbox.js';
|
|
3
|
-
import { automaticSessionEnd, automaticSessionStart } from './automatic-session.js';
|
|
4
|
-
import { PRIVILEGED_HOOK_BUDGET_MS, sweepPrivilegedPending } from './notifications.js';
|
|
5
|
-
export async function runClaudeHookAsync(inputText, env = process.env) {
|
|
6
|
-
let input;
|
|
7
|
-
try {
|
|
8
|
-
input = JSON.parse(inputText);
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return '';
|
|
12
|
-
}
|
|
13
|
-
if (input === null || typeof input !== 'object')
|
|
14
|
-
return '';
|
|
15
|
-
const value = input;
|
|
16
|
-
if (typeof value.session_id !== 'string')
|
|
17
|
-
return runClaudeHook(inputText, env);
|
|
18
|
-
if (value.hook_event_name === 'SessionStart' || value.hook_event_name === 'SessionResume') {
|
|
19
|
-
const cwd = typeof value.cwd === 'string' ? value.cwd : process.cwd();
|
|
20
|
-
try {
|
|
21
|
-
const context = await automaticSessionStart('claude', value.session_id, cwd, env);
|
|
22
|
-
return context === undefined ? '' : `${JSON.stringify({ hookSpecificOutput: { hookEventName: value.hook_event_name, additionalContext: context } })}\n`;
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return '';
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (value.hook_event_name === 'SessionEnd') {
|
|
29
|
-
const cwd = typeof value.cwd === 'string' ? value.cwd : process.cwd();
|
|
30
|
-
try {
|
|
31
|
-
await automaticSessionEnd('claude', value.session_id, cwd, env);
|
|
32
|
-
}
|
|
33
|
-
catch { /* end remains bounded */ }
|
|
34
|
-
return '';
|
|
35
|
-
}
|
|
36
|
-
return runClaudeHook(inputText, env);
|
|
37
|
-
}
|
|
38
|
-
export async function claudeHookResponse(input, lookup = sessionInbox, env = process.env, deliveryAdapters) {
|
|
39
|
-
const sweepDeadline = Date.now() + PRIVILEGED_HOOK_BUDGET_MS;
|
|
40
|
-
if (typeof input.session_id !== 'string' || input.session_id === '')
|
|
41
|
-
return undefined;
|
|
42
|
-
if (input.hook_event_name !== 'PostToolBatch')
|
|
43
|
-
return undefined;
|
|
44
|
-
const response = await presentPendingAtBoundary(input.session_id, (context) => ({ hookSpecificOutput: { hookEventName: 'PostToolBatch', additionalContext: context } }), lookup, env);
|
|
45
|
-
await sweepPrivilegedPending(typeof input.cwd === 'string' ? input.cwd : process.cwd(), env, deliveryAdapters, sweepDeadline).catch(() => undefined);
|
|
46
|
-
return response;
|
|
47
|
-
}
|
|
48
|
-
export async function runClaudeHook(inputText, env = process.env) {
|
|
49
|
-
let input;
|
|
50
|
-
try {
|
|
51
|
-
input = JSON.parse(inputText);
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
return '';
|
|
55
|
-
}
|
|
56
|
-
if (input === null || typeof input !== 'object')
|
|
57
|
-
return '';
|
|
58
|
-
const response = await claudeHookResponse(input, sessionInbox, env);
|
|
59
|
-
return response === undefined ? '' : `${JSON.stringify(response)}\n`;
|
|
60
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { DaemonClient } from '@getpaseo/client/internal/daemon-client';
|
|
2
|
-
export type PaseoDaemonTarget = {
|
|
3
|
-
type: 'tcp';
|
|
4
|
-
url: string;
|
|
5
|
-
password?: string;
|
|
6
|
-
} | {
|
|
7
|
-
type: 'ipc';
|
|
8
|
-
url: string;
|
|
9
|
-
socketPath: string;
|
|
10
|
-
password?: string;
|
|
11
|
-
};
|
|
12
|
-
/** Match the host precedence used by the Paseo CLI for local daemon connections. */
|
|
13
|
-
export declare function paseoDaemonHosts(env?: NodeJS.ProcessEnv): string[];
|
|
14
|
-
export declare function resolvePaseoDaemonTarget(host: string, env?: NodeJS.ProcessEnv): PaseoDaemonTarget;
|
|
15
|
-
export declare function connectPaseoDaemon(env?: NodeJS.ProcessEnv, connectTimeoutMs?: number): Promise<DaemonClient>;
|
package/dist/paseo-connection.js
DELETED
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import { homedir } from 'node:os';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { DaemonClient } from '@getpaseo/client/internal/daemon-client';
|
|
5
|
-
import WebSocket from 'ws';
|
|
6
|
-
const DEFAULT_HOST = 'localhost:6767';
|
|
7
|
-
const DEFAULT_CONNECT_TIMEOUT_MS = 3_000;
|
|
8
|
-
function paseoHome(env) {
|
|
9
|
-
return env.PASEO_HOME?.trim() || path.join(homedir(), '.paseo');
|
|
10
|
-
}
|
|
11
|
-
function expandHome(value) {
|
|
12
|
-
return value === '~' ? homedir() : value.startsWith('~/') ? path.join(homedir(), value.slice(2)) : value;
|
|
13
|
-
}
|
|
14
|
-
function normalizeHost(raw) {
|
|
15
|
-
if (typeof raw !== 'string' || raw.trim() === '')
|
|
16
|
-
return undefined;
|
|
17
|
-
const value = raw.trim();
|
|
18
|
-
if (value.startsWith('unix://') || value.startsWith('pipe://') || value.startsWith('tcp://'))
|
|
19
|
-
return value;
|
|
20
|
-
if (value.startsWith('\\\\.\\pipe\\'))
|
|
21
|
-
return `pipe://${value}`;
|
|
22
|
-
if (value.startsWith('/') || value.startsWith('~/'))
|
|
23
|
-
return `unix://${expandHome(value)}`;
|
|
24
|
-
if (/^\d+$/.test(value))
|
|
25
|
-
return `127.0.0.1:${value}`;
|
|
26
|
-
return value.includes(':') ? value : undefined;
|
|
27
|
-
}
|
|
28
|
-
function configuredHost(env) {
|
|
29
|
-
try {
|
|
30
|
-
const config = JSON.parse(fs.readFileSync(path.join(paseoHome(env), 'config.json'), 'utf8'));
|
|
31
|
-
return normalizeHost(config.daemon?.listen ?? config.listen);
|
|
32
|
-
}
|
|
33
|
-
catch {
|
|
34
|
-
return undefined;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
function pidHost(env) {
|
|
38
|
-
try {
|
|
39
|
-
const pid = JSON.parse(fs.readFileSync(path.join(paseoHome(env), 'paseo.pid'), 'utf8'));
|
|
40
|
-
return normalizeHost(pid.listen ?? pid.sockPath);
|
|
41
|
-
}
|
|
42
|
-
catch {
|
|
43
|
-
return undefined;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function isIpc(host) {
|
|
47
|
-
return host !== undefined && (host.startsWith('unix://') || host.startsWith('pipe://'));
|
|
48
|
-
}
|
|
49
|
-
function supportsIpcHost(host) {
|
|
50
|
-
return process.platform !== 'win32' || !host.startsWith('unix://');
|
|
51
|
-
}
|
|
52
|
-
/** Match the host precedence used by the Paseo CLI for local daemon connections. */
|
|
53
|
-
export function paseoDaemonHosts(env = process.env) {
|
|
54
|
-
const explicit = normalizeHost(env.PASEO_HOST);
|
|
55
|
-
if (explicit !== undefined)
|
|
56
|
-
return [explicit];
|
|
57
|
-
const candidates = [];
|
|
58
|
-
const listen = normalizeHost(env.PASEO_LISTEN);
|
|
59
|
-
const pid = pidHost(env);
|
|
60
|
-
const configured = configuredHost(env);
|
|
61
|
-
if (isIpc(listen) && supportsIpcHost(listen))
|
|
62
|
-
candidates.push(listen);
|
|
63
|
-
if (isIpc(pid) && supportsIpcHost(pid))
|
|
64
|
-
candidates.push(pid);
|
|
65
|
-
if (isIpc(configured) && supportsIpcHost(configured))
|
|
66
|
-
candidates.push(configured);
|
|
67
|
-
if (configured !== undefined && !isIpc(configured) && configured !== '127.0.0.1:6767')
|
|
68
|
-
candidates.push(configured);
|
|
69
|
-
candidates.push(DEFAULT_HOST);
|
|
70
|
-
return [...new Set(candidates)];
|
|
71
|
-
}
|
|
72
|
-
function uriPassword(uri) {
|
|
73
|
-
const value = uri.searchParams.get('password');
|
|
74
|
-
return value === null || value === '' ? undefined : value;
|
|
75
|
-
}
|
|
76
|
-
export function resolvePaseoDaemonTarget(host, env = process.env) {
|
|
77
|
-
const passwordFromEnv = env.PASEO_PASSWORD?.trim() || undefined;
|
|
78
|
-
if (host.startsWith('unix://') || host.startsWith('pipe://')) {
|
|
79
|
-
if (process.platform === 'win32' && host.startsWith('unix://')) {
|
|
80
|
-
throw new Error('Paseo Unix socket targets are unsupported on Windows; use pipe:// or tcp://.');
|
|
81
|
-
}
|
|
82
|
-
const prefix = host.startsWith('unix://') ? 'unix://' : 'pipe://';
|
|
83
|
-
const socketPath = expandHome(host.slice(prefix.length).trim());
|
|
84
|
-
if (socketPath === '')
|
|
85
|
-
throw new Error('Invalid Paseo IPC target: missing socket path.');
|
|
86
|
-
return {
|
|
87
|
-
type: 'ipc',
|
|
88
|
-
url: host.startsWith('unix://') ? `ws+unix://${socketPath}:/ws` : 'ws://localhost/ws',
|
|
89
|
-
socketPath,
|
|
90
|
-
...(passwordFromEnv === undefined ? {} : { password: passwordFromEnv }),
|
|
91
|
-
};
|
|
92
|
-
}
|
|
93
|
-
if (host.startsWith('tcp://')) {
|
|
94
|
-
const uri = new URL(host);
|
|
95
|
-
const hostname = uri.hostname.replace(/^\[|\]$/g, '');
|
|
96
|
-
const endpoint = `${hostname.includes(':') ? `[${hostname}]` : hostname}:${uri.port || '6767'}`;
|
|
97
|
-
const secure = uri.searchParams.get('ssl') === 'true';
|
|
98
|
-
const password = uriPassword(uri) ?? passwordFromEnv;
|
|
99
|
-
return {
|
|
100
|
-
type: 'tcp',
|
|
101
|
-
url: `${secure ? 'wss' : 'ws'}://${endpoint}/ws`,
|
|
102
|
-
...(password === undefined ? {} : { password }),
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
return {
|
|
106
|
-
type: 'tcp',
|
|
107
|
-
url: `ws://${host.replace(/\/$/, '')}/ws`,
|
|
108
|
-
...(passwordFromEnv === undefined ? {} : { password: passwordFromEnv }),
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
function webSocketFactory(target) {
|
|
112
|
-
return (url, options) => new WebSocket(url, options?.protocols, {
|
|
113
|
-
headers: options?.headers,
|
|
114
|
-
...(target.type === 'ipc' ? { socketPath: target.socketPath } : {}),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
export async function connectPaseoDaemon(env = process.env, connectTimeoutMs = DEFAULT_CONNECT_TIMEOUT_MS) {
|
|
118
|
-
let lastError;
|
|
119
|
-
for (const host of paseoDaemonHosts(env)) {
|
|
120
|
-
const target = resolvePaseoDaemonTarget(host, env);
|
|
121
|
-
const client = new DaemonClient({
|
|
122
|
-
url: target.url,
|
|
123
|
-
clientId: `square-${process.pid}-${Date.now()}`,
|
|
124
|
-
clientType: 'cli',
|
|
125
|
-
appVersion: 'square',
|
|
126
|
-
password: target.password,
|
|
127
|
-
connectTimeoutMs,
|
|
128
|
-
webSocketFactory: webSocketFactory(target),
|
|
129
|
-
reconnect: { enabled: false },
|
|
130
|
-
});
|
|
131
|
-
try {
|
|
132
|
-
await client.connect();
|
|
133
|
-
return client;
|
|
134
|
-
}
|
|
135
|
-
catch (error) {
|
|
136
|
-
lastError = error;
|
|
137
|
-
await client.close().catch(() => { });
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
throw lastError instanceof Error ? lastError : new Error('Unable to connect to the Paseo daemon.');
|
|
141
|
-
}
|
package/dist/presence.d.ts
DELETED
package/dist/presence.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { openSquare } from './square-file-adapter.js';
|
|
2
|
-
import { closeOpenSquare } from './open-square.js';
|
|
3
|
-
import { recordObservation } from './runtime.js';
|
|
4
|
-
/** Commit seen only for complete, actually rendered boundary bodies. */
|
|
5
|
-
export async function markBoundarySeen(squarePath, name, actIndexes, at = Date.now()) {
|
|
6
|
-
let square;
|
|
7
|
-
try {
|
|
8
|
-
square = await openSquare(squarePath);
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
try {
|
|
14
|
-
await square.artifact.transact((state) => {
|
|
15
|
-
let changed = false;
|
|
16
|
-
for (const index of actIndexes)
|
|
17
|
-
changed = recordObservation(state, name, index, 'seen', at) || changed;
|
|
18
|
-
return changed ? { state, result: undefined } : { result: undefined };
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
finally {
|
|
22
|
-
await closeOpenSquare(square);
|
|
23
|
-
}
|
|
24
|
-
}
|
package/dist/presented.d.ts
DELETED
package/dist/presented.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import { hostLedgerRoot } from './host-ledger-root.js';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import { canonicalSquarePath } from './registry.js';
|
|
5
|
-
import { createHostLedgerPort } from './host-ledger-file-adapter.js';
|
|
6
|
-
import { formatActivityId } from './square-core.js';
|
|
7
|
-
import { projectPresentationEvidence } from './square-projections.js';
|
|
8
|
-
export function presentedPath(env = process.env) { return env.SQUARE_PRESENTED || path.join(os.homedir(), '.square', 'presented.ndjsonl'); }
|
|
9
|
-
function evidence(env = process.env) { const file = presentedPath(env); return createHostLedgerPort({ rootPath: hostLedgerRoot(env) }); }
|
|
10
|
-
export async function hasPresentedForOwner(sessionId, squarePath, name, actIndex, env = process.env, now = Date.now()) { const resolved = await canonicalSquarePath(squarePath); return (await projectPresentationEvidence({ hostLedger: evidence(env), now, location: resolved, participant: name, sessionId, activity: formatActivityId(actIndex) })).some((row) => row.outcome === 'presented'); }
|
package/dist/state-cell.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { SquareState } from './model.js';
|
|
2
|
-
/** Synchronous state transition seam shared by memory and file storage. */
|
|
3
|
-
export interface StateCell {
|
|
4
|
-
transact<R>(fn: (state: SquareState, version: number) => {
|
|
5
|
-
state?: SquareState;
|
|
6
|
-
result: R;
|
|
7
|
-
}, signal?: AbortSignal): Promise<R>;
|
|
8
|
-
read(signal?: AbortSignal): Promise<{
|
|
9
|
-
state: SquareState;
|
|
10
|
-
version: number;
|
|
11
|
-
}>;
|
|
12
|
-
changed(sinceVersion: number, timeoutMs: number, signal?: AbortSignal): Promise<boolean>;
|
|
13
|
-
close(): Promise<void>;
|
|
14
|
-
}
|
package/dist/wake-port.d.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import type { WakeAdapter, WakeDispatchResult } from './delivery.js';
|
|
2
|
-
import type { WakeRoute } from './model.js';
|
|
3
|
-
export interface WakePortHooks {
|
|
4
|
-
nextAttemptN(): number | Promise<number>;
|
|
5
|
-
beforeSend(route: WakeRoute, attemptN: number): Promise<boolean>;
|
|
6
|
-
record(route: WakeRoute, attemptN: number, result: Exclude<WakeDispatchResult, {
|
|
7
|
-
outcome: 'cancelled' | 'unavailable';
|
|
8
|
-
}>): Promise<void>;
|
|
9
|
-
invalidate?(route: WakeRoute, result: Extract<WakeDispatchResult, {
|
|
10
|
-
outcome: 'unavailable';
|
|
11
|
-
}>): Promise<void>;
|
|
12
|
-
}
|
|
13
|
-
export type WakePortResult = {
|
|
14
|
-
outcome: 'accepted' | 'unknown' | 'cancelled';
|
|
15
|
-
} | {
|
|
16
|
-
outcome: 'exhausted';
|
|
17
|
-
};
|
|
18
|
-
/** Select routes globally; adapters own only transport-specific live proof and dispatch. */
|
|
19
|
-
export declare class WakePort {
|
|
20
|
-
private readonly adapters;
|
|
21
|
-
constructor(adapters: WakeAdapter[]);
|
|
22
|
-
dispatch(routes: readonly WakeRoute[], payload: string | ((route: WakeRoute) => string), hooks: WakePortHooks): Promise<WakePortResult>;
|
|
23
|
-
}
|
package/dist/wake-port.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
/** Select routes globally; adapters own only transport-specific live proof and dispatch. */
|
|
2
|
-
export class WakePort {
|
|
3
|
-
adapters;
|
|
4
|
-
constructor(adapters) {
|
|
5
|
-
this.adapters = new Map(adapters.map((adapter) => [adapter.kind, adapter]));
|
|
6
|
-
}
|
|
7
|
-
async dispatch(routes, payload, hooks) {
|
|
8
|
-
for (const route of routes) {
|
|
9
|
-
const adapter = this.adapters.get(route.kind);
|
|
10
|
-
if (adapter === undefined)
|
|
11
|
-
continue;
|
|
12
|
-
const attemptN = await hooks.nextAttemptN();
|
|
13
|
-
const result = await adapter.dispatch(route.address, typeof payload === 'function' ? payload(route) : payload, () => hooks.beforeSend(route, attemptN));
|
|
14
|
-
if (result.outcome === 'cancelled')
|
|
15
|
-
return result;
|
|
16
|
-
if (result.outcome === 'unavailable') {
|
|
17
|
-
if (result.routeStale === true)
|
|
18
|
-
await hooks.invalidate?.(route, result);
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
await hooks.record(route, attemptN, result);
|
|
22
|
-
if (result.outcome === 'accepted' || result.outcome === 'unknown')
|
|
23
|
-
return { outcome: result.outcome };
|
|
24
|
-
}
|
|
25
|
-
return { outcome: 'exhausted' };
|
|
26
|
-
}
|
|
27
|
-
}
|
|
File without changes
|