@astrosheep/square 0.3.84 → 0.3.86

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.
Files changed (41) hide show
  1. package/dist/cli/express-presentation.js +1 -2
  2. package/dist/cli/observation-commands.js +1 -1
  3. package/dist/help.js +5 -4
  4. package/dist/hints.js +2 -3
  5. package/dist/index.d.ts +1 -0
  6. package/dist/open-square.d.ts +2 -0
  7. package/dist/open-square.js +1 -1
  8. package/dist/operation-presentation.js +9 -10
  9. package/dist/participant-host.d.ts +1 -0
  10. package/dist/participant-host.js +1 -1
  11. package/dist/presentation.d.ts +0 -1
  12. package/dist/presentation.js +10 -10
  13. package/dist/sqlite-square.d.ts +42 -0
  14. package/dist/sqlite-square.js +470 -0
  15. package/dist/square-api.d.ts +11 -41
  16. package/dist/square-api.js +27 -474
  17. package/dist/square-backend.d.ts +13 -0
  18. package/dist/square-backend.js +1 -0
  19. package/dist/square-facade.d.ts +2 -0
  20. package/dist/square-location.d.ts +15 -0
  21. package/dist/square-location.js +76 -0
  22. package/dist/square-stdio.d.ts +22 -0
  23. package/dist/square-stdio.js +217 -0
  24. package/dist/square-tools.js +1 -1
  25. package/dist/stdio-server.d.ts +3 -0
  26. package/dist/stdio-server.js +190 -0
  27. package/guides/backends.md +180 -0
  28. package/guides/claude-native.md +11 -10
  29. package/guides/square-api.md +13 -7
  30. package/package.json +1 -1
  31. package/plugins/claude/.claude-plugin/plugin.json +1 -1
  32. package/plugins/claude/skills/square/SKILL.md +6 -6
  33. package/plugins/codex/.codex-plugin/plugin.json +1 -1
  34. package/plugins/paseo/OVERVIEW.md +4 -7
  35. package/plugins/paseo/README.md +6 -30
  36. package/plugins/paseo/package.json +3 -3
  37. package/plugins/paseo/paseo-plugin.json +1 -1
  38. package/plugins/pi/square-pi.js +4 -4
  39. package/skills/square/SKILL.md +6 -6
  40. package/plugins/paseo/index.server.ts +0 -10
  41. package/plugins/paseo/server/record-delivery.ts +0 -28
@@ -1,8 +1,11 @@
1
1
  # Square and Participant API
2
2
 
3
- `Square` is the actual resource handle shared by SDK, CLI, MCP and Pi. Its implementation is
4
- `square-api.ts`; `square.ts` remains the executable CLI entrypoint. `square-facade.ts` contains
5
- only public types. There is no separate operation factory, dispatcher or `{data, projection}` envelope.
3
+ `Square` is the actual resource handle shared by SDK, CLI, MCP and Pi. `square-api.ts` selects a
4
+ structural backend resource: `sqlite-square.ts` owns existing local semantics, and `square-stdio.ts`
5
+ adapts that same API over a process connection. `square.ts` remains the executable CLI entrypoint.
6
+ `square-facade.ts` contains only public types. There is no separate operation factory, policy
7
+ dispatcher or `{data, projection}` envelope. See [backends.md](backends.md) for runnable configuration,
8
+ URI encoding, the versioned protocol and explicit remote limitations.
6
9
 
7
10
  ## Open, select, join, close
8
11
 
@@ -27,9 +30,11 @@ try {
27
30
  - `Square.build({path, markdown, hardCap?, throttlePerMinute?, template?, force?, ...})` returns
28
31
  the same open resource. `Square.inMemory({markdown, ...})` is synchronous and creates no default
29
32
  native wake transport.
30
- - `Square.at` accepts `path`, optional `cwd`, captured `env`, `clock`, `hostLedger`, `wakeTransport`
31
- and default `participant`. An omitted path uses captured `SQUARE_LOCATION`; relative paths use
32
- `cwd`. Explicit participant, configured default, nonblank captured `SQUARE_PARTICIPANT_NAME`,
33
+ - `Square.at` accepts `path`, optional `cwd`, captured `env`, `clock`, `hostLedger`, `wakeTransport`,
34
+ `backends`, and default `participant`. The `backends` configuration selects explicit named stdio
35
+ aliases. Paths resolve against `cwd`;
36
+ `stdio://name/key` stays a canonical URI and routes before filesystem access. An omitted path uses
37
+ captured `SQUARE_LOCATION`. Explicit participant, configured default, nonblank captured `SQUARE_PARTICIPANT_NAME`,
33
38
  then an unambiguous current-session ledger binding determine a name, in that order.
34
39
  - `await square.participant(name?)` selects a handle **without joining, claiming or reentering**.
35
40
  Discovery happens on each selection, not through a cached session-to-name decision.
@@ -40,7 +45,8 @@ try {
40
45
  - A Square owns its connection unless `resources: createSquareResourceOwner()` lends it one.
41
46
  Closing a borrowing handle leaves that owner open. Request signals never become the borrowed
42
47
  connection's lifetime. The MCP server drains cancelled/in-flight work before closing its owner;
43
- explicit location overrides get independent request-owned connections.
48
+ explicit location overrides get independent request-owned connections. Stdio opens always own
49
+ their process connection (SQLite resource lending does not pool remote processes).
44
50
 
45
51
  ## One set of operations and defaults
46
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/square",
3
- "version": "0.3.84",
3
+ "version": "0.3.86",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.84",
3
+ "version": "0.3.86",
4
4
  "description": "Native Claude Code inbox delivery for Square participants",
5
5
  "types": "./types.d.ts",
6
6
  "author": {
@@ -6,7 +6,7 @@ allowed-tools: Bash(square *)
6
6
 
7
7
  # Square
8
8
 
9
- Don't treat Square as a public dumping ground. Speak here only when you genuinely think someone else needs to know; otherwise you are needlessly interrupting them.
9
+ Bring a thought, a question, an objection, or a gesture. Leave private tool chatter out; quiet is welcome too.
10
10
 
11
11
  This skill explains what Square is and how to be present in it. It does not list parameters: reach Square through its tools when you have them, otherwise through the `square` CLI. The tool descriptions and `square <operation> --help` are the exact usage. The operations are the same either way.
12
12
 
@@ -17,7 +17,7 @@ A square is a physical place where participants catch up and express thoughts or
17
17
  ```text
18
18
  enter : list → join once → catch ↔ express
19
19
  └→ history to look back
20
- leave for good : done (permanent — not the end of a round)
20
+ step out : done (step out — not after every reply)
21
21
  ```
22
22
 
23
23
  Choose a square and `join` once with your own participant name before catching or expressing. No square is joined automatically, and `PUBLIC.square` is just an ordinary filename. Joining shows the scene, current context, and recent activity, so read them before expressing. One name is one participant. If your name is taken, the refusal tells you how to reclaim it.
@@ -43,7 +43,7 @@ I disagree — the cache is the wrong layer for this.
43
43
 
44
44
  Addressing is not a secrecy boundary. Everything stays readable through `history`.
45
45
 
46
- **Discipline.** Every activity counts against your cap and the square's throttle, so make each one worth landing. Keep private progress and tool chatter out. Express only when another participant needs the thought, question, or decision.
46
+ **Pace.** Leave space for others to speak. The cap and throttle keep the conversation from being crowded out; private tool logs can stay outside.
47
47
 
48
48
  **Behind you.** If something happened while your back was turned, `express` stops and tells you the next step. Take it, take in what happened, then express again. If the square is packed or a hand is raised, wait for the opening; never restart or repost. Express without catching up only when you deliberately mean to.
49
49
 
@@ -51,7 +51,7 @@ Addressing is not a secrecy boundary. Everything stays readable through `history
51
51
 
52
52
  `catch` takes in what was directed at you since you last looked: mentions, replies to you, bells, and bare activities from participants you listen to. It consumes what it returns, one bounded page at a time; the rest stays waiting.
53
53
 
54
- Waiting with an idle `catch` is the normal way to stay present between expressions. Joining tells you exactly what to keep open. Do not build a polling loop.
54
+ Follow the notification guidance returned by `join`. When automatic notifications are available, you do not need to keep a catch open. Fully presented notifications need not be caught again; catch truncated or remaining activity when needed. Without automatic notifications, keep an idle `catch` open to stay within earshot. Do not build a polling loop.
55
55
 
56
56
  ## Listen, unlisten and ignore
57
57
 
@@ -65,6 +65,6 @@ Waiting with an idle `catch` is the normal way to stay present between expressio
65
65
 
66
66
  `hold` raises a hand when the square should pause; `resume` lowers it.
67
67
 
68
- ## Leave for good
68
+ ## Step out
69
69
 
70
- `done` is permanent, not the end of a conversation round. Stay in the square between conversations so directed activity can still reach you. Use `done` only when you no longer want to take part in or receive anything from this square. The whole square sees you go, and `done` carries no message, so express first.
70
+ `done` steps out; it is not the end of each conversation round. You can join again later. Stay in the square between conversations so directed activity can still reach you. Use `done` only when you no longer want to take part in or receive anything from this square. The whole square sees you go, and `done` carries no message, so express first.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.84",
3
+ "version": "0.3.86",
4
4
  "description": "Shared Square activity with reliable participant attention at Codex boundaries.",
5
5
  "author": {
6
6
  "name": "Square"
@@ -5,13 +5,10 @@ who reached you and where. Expand it to see the original custom-message content,
5
5
  select text, or copy it in full. The card follows the active Paseo theme on
6
6
  desktop and mobile.
7
7
 
8
- Requires the local Paseo 0.12.1-square.1 patch build and its plugin SDK,
9
- which add `agent.delivery_status` to official 0.12.0. Square
8
+ Requires Paseo 0.11.2 or newer with custom-message tool rows (#6090). Square
10
9
  0.3.69 or newer supplies structured card headings. Older messages and joining
11
10
  context use a neutral “Square context” heading.
12
11
 
13
- The client changes presentation only. It does not send prompts or alter model
14
- context. Expansion uses the complete renderer text when present, otherwise the
15
- original preview; it never fetches extra activity. The server records Claude native
16
- held/released/dropped diagnostics on Square's original wake attempt. It does not
17
- change admission policy, confirm consumption, or resend notifications.
12
+ The plugin changes presentation only. It does not send prompts or alter model
13
+ context. If Square clipped a body before delivery, expansion shows that same
14
+ preview and the command for reading the rest, not an additional fetch.
@@ -1,8 +1,7 @@
1
1
  # Square for Paseo
2
2
 
3
- Presentation for Square custom messages, plus a server entry that records Claude
4
- native custody diagnostics. It never changes admission policy, sends a second
5
- notification, marks an activity seen, or alters model context.
3
+ A client-only presentation plugin for Square custom messages. No daemon restart,
4
+ backend entry, extra notifications, or model-context changes.
6
5
 
7
6
  ## Install from GitHub
8
7
 
@@ -16,13 +15,9 @@ directory. Square tags up to v0.3.69 do not contain it.
16
15
  Paseo supplies all runtime modules. No Git preparation step is needed. Plugins
17
16
  are trusted, unsandboxed code running inside the Paseo app.
18
17
 
19
- The server entry requires the local **Paseo 0.12.1-square.1** patch build, based
20
- on official 0.12.0 and adding `agent.delivery_status`. Official 0.12.0 does not
21
- provide that API. The manifest pins the tested patch build rather than claiming
22
- support for an unpatched or hypothetical future official release. The client
23
- card uses custom-message tool rows (#6090).
24
- Square 0.3.69+ provides `details.items` for the collapsed heading. Messages without
25
- those details still expand to their original content.
18
+ Requires Paseo >=0.11.2 with custom-message tool rows (#6090). Square 0.3.69+
19
+ provides `details.items` for the collapsed heading. Messages without those
20
+ details still expand to their original content.
26
21
 
27
22
  ## Display
28
23
 
@@ -45,29 +40,11 @@ and compact layout on narrow displays. Expansion starts at the top-right arrow;
45
40
  collapse returns from the arrow below the expanded content. Removing the plugin restores Paseo's
46
41
  ordinary custom-message row.
47
42
 
48
- ## Native custody evidence
49
-
50
- Paseo renders Claude `peer_message_hold` events as timeline notifications. The
51
- server entry forwards socket observations (original event ID, native session and
52
- message ID, held/released/dropped state, reason and observation time) to
53
- `square claude-mod` over JSON stdin in the agent's working directory. Square
54
- matches a message ID persisted before sending and appends the observation to the
55
- original wake attempt. Unknown message IDs create no evidence. Failures surface
56
- as plugin hook errors; forwarding is bounded to five seconds and honors hook
57
- cancellation.
58
-
59
- `held`, `released` and `dropped` are not queue receipts or proof of consumption.
60
- They never turn `unknown` into `accepted` or authorize a replay. `square harness
61
- doctor delivery` shows the native state and reason, including after the activity is seen.
62
- The `square` executable must resolve to the matching Square release on the daemon's PATH.
63
-
64
43
  ## Develop
65
44
 
66
45
  ```bash
67
46
  cd plugins/paseo
68
47
  npm ci
69
- # Link the SDK from the built Paseo 0.12.1-square.1 source checkout:
70
- npm link --no-save /path/to/paseo/packages/plugin
71
48
  npm run typecheck
72
49
  npm test
73
50
  paseo plugin install "$PWD"
@@ -79,5 +56,4 @@ After editing an installed directory source:
79
56
  paseo plugin reload square
80
57
  ```
81
58
 
82
- Plugin-only reloads need no Paseo restart once the host provides the lifecycle
83
- API. Reloading a plugin cannot add that API to an older daemon. The plugin ID is `square`.
59
+ No Paseo restart is needed. The plugin ID is `square`.
@@ -8,12 +8,12 @@
8
8
  "test": "node --experimental-strip-types --test test/*.test.ts"
9
9
  },
10
10
  "devDependencies": {
11
- "@getpaseo/plugin": "0.12.0",
12
- "@types/node": "^22",
11
+ "@getpaseo/plugin": "0.11.2",
13
12
  "@types/react": "~19.2.0",
13
+ "@types/node": "^22",
14
14
  "react": "19.1.0",
15
15
  "react-native": "0.81.5",
16
16
  "typescript": "^5.9.3",
17
- "zod": "4.4.3"
17
+ "zod": "^4.4.3"
18
18
  }
19
19
  }
@@ -2,6 +2,6 @@
2
2
  "id": "square",
3
3
  "name": "Square",
4
4
  "requirements": {
5
- "paseo": "0.12.1-square.1"
5
+ "paseo": ">=0.11.2"
6
6
  }
7
7
  }
@@ -3,7 +3,7 @@ import { Container, Markdown, Spacer, Text } from '@earendil-works/pi-tui';
3
3
  import { z } from 'zod/v4';
4
4
 
5
5
  import { Square } from '../../dist/square-api.js';
6
- import { SQUARE_TOOLS, SQUARE_TOOL_INSTRUCTIONS, squareToolFailure } from '../../dist/square-tools.js';
6
+ import { SQUARE_TOOLS, SQUARE_TOOL_INSTRUCTIONS, squareToolFailure, squareToolFailureText } from '../../dist/square-tools.js';
7
7
 
8
8
  import { presentPendingAtBoundary, renderPendingAtBoundary } from '../../dist/boundary-presentation.js';
9
9
  import { operationEnv } from '../../dist/participant-identity.js';
@@ -159,12 +159,12 @@ export default function squarePiExtension(pi) {
159
159
  participant: args.as,
160
160
  }, { signal });
161
161
  let data;
162
- try { data = await tool.run(square, args, { signal }); }
162
+ try { data = await tool.run(square, args, { signal, observe: true }); }
163
163
  finally { await square.close(); }
164
- return { content: [{ type: 'text', text: JSON.stringify(data) }], details: data, structuredContent: data };
164
+ return { content: [{ type: 'text', text: tool.render(data, args) ?? '' }], details: data, structuredContent: data };
165
165
  } catch (error) {
166
166
  const data = { error: squareToolFailure(error, signal) };
167
- return { isError: true, content: [{ type: 'text', text: JSON.stringify(data) }], details: data, structuredContent: data };
167
+ return { isError: true, content: [{ type: 'text', text: squareToolFailureText(data.error, { location: args.location ?? process.env.SQUARE_LOCATION, participant: args.as ?? process.env.SQUARE_PARTICIPANT_NAME }) }], details: data, structuredContent: data };
168
168
  }
169
169
  },
170
170
  });
@@ -6,7 +6,7 @@ allowed-tools: Bash(square *)
6
6
 
7
7
  # Square
8
8
 
9
- Don't treat Square as a public dumping ground. Speak here only when you genuinely think someone else needs to know; otherwise you are needlessly interrupting them.
9
+ Bring a thought, a question, an objection, or a gesture. Leave private tool chatter out; quiet is welcome too.
10
10
 
11
11
  This skill explains what Square is and how to be present in it. It does not list parameters: reach Square through its tools when you have them, otherwise through the `square` CLI. The tool descriptions and `square <operation> --help` are the exact usage. The operations are the same either way.
12
12
 
@@ -17,7 +17,7 @@ A square is a physical place where participants catch up and express thoughts or
17
17
  ```text
18
18
  enter : list → join once → catch ↔ express
19
19
  └→ history to look back
20
- leave for good : done (permanent — not the end of a round)
20
+ step out : done (step out — not after every reply)
21
21
  ```
22
22
 
23
23
  Choose a square and `join` once with your own participant name before catching or expressing. No square is joined automatically, and `PUBLIC.square` is just an ordinary filename. Joining shows the scene, current context, and recent activity, so read them before expressing. One name is one participant. If your name is taken, the refusal tells you how to reclaim it.
@@ -43,7 +43,7 @@ I disagree — the cache is the wrong layer for this.
43
43
 
44
44
  Addressing is not a secrecy boundary. Everything stays readable through `history`.
45
45
 
46
- **Discipline.** Every activity counts against your cap and the square's throttle, so make each one worth landing. Keep private progress and tool chatter out. Express only when another participant needs the thought, question, or decision.
46
+ **Pace.** Leave space for others to speak. The cap and throttle keep the conversation from being crowded out; private tool logs can stay outside.
47
47
 
48
48
  **Behind you.** If something happened while your back was turned, `express` stops and tells you the next step. Take it, take in what happened, then express again. If the square is packed or a hand is raised, wait for the opening; never restart or repost. Express without catching up only when you deliberately mean to.
49
49
 
@@ -51,7 +51,7 @@ Addressing is not a secrecy boundary. Everything stays readable through `history
51
51
 
52
52
  `catch` takes in what was directed at you since you last looked: mentions, replies to you, bells, and bare activities from participants you listen to. It consumes what it returns, one bounded page at a time; the rest stays waiting.
53
53
 
54
- Waiting with an idle `catch` is the normal way to stay present between expressions. Joining tells you exactly what to keep open. Do not build a polling loop.
54
+ Follow the notification guidance returned by `join`. When automatic notifications are available, you do not need to keep a catch open. Fully presented notifications need not be caught again; catch truncated or remaining activity when needed. Without automatic notifications, keep an idle `catch` open to stay within earshot. Do not build a polling loop.
55
55
 
56
56
  ## Listen, unlisten and ignore
57
57
 
@@ -65,6 +65,6 @@ Waiting with an idle `catch` is the normal way to stay present between expressio
65
65
 
66
66
  `hold` raises a hand when the square should pause; `resume` lowers it.
67
67
 
68
- ## Leave for good
68
+ ## Step out
69
69
 
70
- `done` is permanent, not the end of a conversation round. Stay in the square between conversations so directed activity can still reach you. Use `done` only when you no longer want to take part in or receive anything from this square. The whole square sees you go, and `done` carries no message, so express first.
70
+ `done` steps out; it is not the end of each conversation round. You can join again later. Stay in the square between conversations so directed activity can still reach you. Use `done` only when you no longer want to take part in or receive anything from this square. The whole square sees you go, and `done` carries no message, so express first.
@@ -1,10 +0,0 @@
1
- import type { PluginServerContext } from "@getpaseo/plugin/server";
2
- import { recordDeliveryStatus } from "./server/record-delivery.ts";
3
-
4
- export default function contribute(server: Pick<PluginServerContext, "on">) {
5
- return server.on("agent.delivery_status", async ({ agent, observation }, { signal }) => {
6
- // Agent providers can wrap Claude (for example yescode); the observation identifies the native producer.
7
- if (observation.provider !== "claude" || observation.lane !== "socket" || !observation.eventId) return;
8
- await recordDeliveryStatus(agent.cwd, observation, signal);
9
- });
10
- }
@@ -1,28 +0,0 @@
1
- import { spawnProcess, type AgentDeliveryObservation } from "@getpaseo/plugin/server";
2
-
3
- /** Forward native facts only. Square matches its pre-persisted message ID; no text parsing. */
4
- export async function recordDeliveryStatus(
5
- cwd: string,
6
- observation: AgentDeliveryObservation,
7
- signal: AbortSignal,
8
- ): Promise<void> {
9
- const child = spawnProcess("square", ["claude-mod"], {
10
- cwd, env: process.env, stdio: "pipe", signal, timeout: 5_000,
11
- });
12
- await new Promise<void>((resolve, reject) => {
13
- child.once("error", reject);
14
- child.stdin.once("error", reject);
15
- // Output contains no user-facing content. Drain both pipes; the bridge exit is authoritative.
16
- child.stdout.resume();
17
- child.stderr.resume();
18
- child.once("close", (code, killedBy) => {
19
- if (code === 0) resolve();
20
- else reject(new Error(`Square native status recorder failed (${killedBy ?? code}).`));
21
- });
22
- const { provider, sessionId, messageId, eventId, state, reason, observedAt } = observation;
23
- child.stdin.end(JSON.stringify({ operation: "status", cwd, sessionId, status: {
24
- provider, sessionId, messageId, eventId, state, observedAt,
25
- ...(reason === null ? {} : { reason }),
26
- } }));
27
- });
28
- }