@astrosheep/square 0.3.10 → 0.3.12

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 (54) hide show
  1. package/codex-plugin/.codex-plugin/plugin.json +1 -1
  2. package/dist/activity.js +6 -7
  3. package/dist/artifact.js +337 -618
  4. package/dist/boundary-presentation.js +1 -1
  5. package/dist/cli/context.js +3 -3
  6. package/dist/cli/harness-command.js +1 -1
  7. package/dist/cli/maintenance-commands.js +12 -58
  8. package/dist/cli/observation-commands.js +14 -34
  9. package/dist/cli/program.js +3 -6
  10. package/dist/cli/registry.js +1 -2
  11. package/dist/cli/square-commands.js +39 -20
  12. package/dist/cmd/notify-once.js +5 -15
  13. package/dist/compact.js +4 -4
  14. package/dist/decisions.js +21 -7
  15. package/dist/delivery-health.js +56 -136
  16. package/dist/delivery.js +11 -47
  17. package/dist/file-lock.js +112 -0
  18. package/dist/harness-codex.js +35 -29
  19. package/dist/harness-links.js +0 -3
  20. package/dist/harness-pi.js +57 -0
  21. package/dist/harness.js +10 -15
  22. package/dist/help.js +16 -18
  23. package/dist/index.js +11 -5
  24. package/dist/list.js +3 -47
  25. package/dist/model.js +4 -6
  26. package/dist/notifications.js +217 -32
  27. package/dist/paseo-connection.js +135 -0
  28. package/dist/paseo-delivery.js +73 -144
  29. package/dist/paseo-state.js +1 -1
  30. package/dist/paseo-timeline.js +32 -42
  31. package/dist/presentation.js +24 -39
  32. package/dist/presented.js +10 -72
  33. package/dist/registry.js +23 -24
  34. package/dist/routes.js +153 -0
  35. package/dist/runtime.js +6 -21
  36. package/dist/square-application.js +56 -127
  37. package/dist/square-core.js +56 -9
  38. package/dist/stream.js +1 -1
  39. package/dist/wake-attempts.js +175 -0
  40. package/dist/wake-evidence.js +35 -0
  41. package/dist/wake-port.js +22 -0
  42. package/dist/wake-sink.js +45 -6
  43. package/dist/watch.js +1 -2
  44. package/guides/participant.md +7 -174
  45. package/package.json +6 -3
  46. package/skills/brainstorm/SKILL.md +28 -28
  47. package/skills/square/.claude-plugin/plugin.json +1 -1
  48. package/skills/square/SKILL.md +23 -14
  49. package/skills/square-feedback/SKILL.md +7 -7
  50. package/dist/doctor.js +0 -35
  51. package/dist/notification-failures.js +0 -54
  52. package/template.md +0 -4
  53. package/templates/architect.md +0 -4
  54. package/templates/brainstorm.md +0 -4
@@ -7,7 +7,7 @@ allowed-tools: Bash(square *), Skill(square)
7
7
  # Square Brainstorm
8
8
 
9
9
  Use this skill when you are coordinating a brainstorm. Your job is to create the square, send participant agents into it, observe the conversation, and collect the result. Do not steer the conversation on your own unless the human explicitly asks for public direction.
10
- Commands default to `.square/SQUARE.md`; use `--square-path <path>` when you want a different file.
10
+ Commands default to `.square/SQUARE.square`; use `--location <path>` when you want a different file.
11
11
 
12
12
  ## Build
13
13
 
@@ -37,27 +37,27 @@ Send each participant agent this prompt. Replace `<name>` and `<path>`, but do n
37
37
  You are <name>, participating in a brainstorm. The square file is at <path>.
38
38
 
39
39
  First action: enter the square. Read the context, warmup, and recent activity printed by this command before expressing:
40
- square --square-path <path> --as <name> join
40
+ square --location <path> --as <name> join
41
41
 
42
42
  Then follow the Happy Path from the join output. Core commands:
43
- square --square-path <path> --as <name> express - <<'EOF'
43
+ square --location <path> --as <name> express - <<'EOF'
44
44
  ...
45
45
  EOF
46
- square --square-path <path> --as <name> catch --mention --idle 10m
47
- square --square-path <path> --as <name> catch --now
48
- square --square-path <path> --as <name> catch --idle 10m
49
- square --square-path <path> history --limit 80
50
- square --square-path <path> history --from <name> --limit 80
51
- square --square-path <path> status
52
- square --square-path <path> --as <name> done - <<'EOF'
46
+ square --location <path> --as <name> catch --mention --idle 10m
47
+ square --location <path> --as <name> catch --now
48
+ square --location <path> --as <name> catch --idle 10m
49
+ square --location <path> history --limit 80
50
+ square --location <path> history --from <name> --limit 80
51
+ square --location <path> status
52
+ square --location <path> --as <name> done - <<'EOF'
53
53
  ...
54
54
  EOF
55
55
 
56
- For complete history: square --square-path <path> history --all --full
56
+ For complete history: square --location <path> history --all --full
57
57
 
58
- If you are addressing a specific participant, write @name. Without any @name, the activity broadcasts to all participants — everyone catching with `--mention` will receive it.
58
+ Every activity must address at least one participant with @name. Mentioned participants perceive the full body; others perceive only directed presence. Use `--bell` only when every participant needs the activity — everyone catching with `--mention` will receive it. Precise history queries may still read original archive bodies.
59
59
 
60
- If an activity is refused because something happened while the participant was not looking, run `square --square-path <path> --as <name> catch --now`, take it in, then express again. `catch --now` catches up without waiting.
60
+ If an activity is refused because something happened while the participant was not looking, run `square --location <path> --as <name> catch --now`, take it in, then express again. `catch --now` catches up without waiting.
61
61
  ```
62
62
 
63
63
  Need another voice later? Spawn another participant agent with a new `<name>` and give it the same participant prompt.
@@ -67,12 +67,12 @@ Need another voice later? Spawn another participant agent with a new `<name>` an
67
67
  If you or the human want to participate, choose a participant name and use the participant loop:
68
68
 
69
69
  ```bash
70
- square --square-path <path> --as <name> join
71
- square --square-path <path> --as <name> express - <<'EOF'
72
- your view
70
+ square --location <path> --as <name> join
71
+ square --location <path> --as <name> express - <<'EOF'
72
+ @<participant-name> your view
73
73
  EOF
74
- square --square-path <path> --as <name> catch --idle 10m
75
- square --square-path <path> --as <name> done - <<'EOF'
74
+ square --location <path> --as <name> catch --idle 10m
75
+ square --location <path> --as <name> done - <<'EOF'
76
76
  final note
77
77
  EOF
78
78
  ```
@@ -82,21 +82,21 @@ EOF
82
82
  Use these to check progress:
83
83
 
84
84
  ```bash
85
- square --square-path <path> history --limit 50
86
- square --square-path <path> history --from <name>
87
- square --square-path <path> status
85
+ square --location <path> history --limit 50
86
+ square --location <path> history --from <name>
87
+ square --location <path> status
88
88
  ```
89
89
 
90
- `history` reads past public activity without advancing participant presence. `status` shows active/done participants, activity counts, cap/throttle, hold state, and latest public activity.
90
+ `history` reads the archive without advancing participant presence. `status` shows active/done participants, activity counts, cap/throttle, hold state, and latest ambient activity.
91
91
 
92
- When addressing a specific participant, use `@name`; without any `@name`, the activity broadcasts to all participants.
92
+ Every activity must contain `@name`; use `--bell` only for activity that every participant needs.
93
93
 
94
94
  ## Human Direction
95
95
 
96
96
  If the human wants to refocus the square, add a constraint, ask a convergence question, or correct its direction, write that direction publicly with a participant name:
97
97
 
98
98
  ```bash
99
- square --square-path <path> --as <name> express - <<'EOF'
99
+ square --location <path> --as <name> express --bell - <<'EOF'
100
100
  Refocus on <specific direction, constraint, question, or decision needed>.
101
101
  EOF
102
102
  ```
@@ -106,8 +106,8 @@ Do not add direction on your own. If you notice the square drifting or stuck, re
106
106
  Pause the participant loop when a human needs time to read, think, or add another voice:
107
107
 
108
108
  ```bash
109
- square --square-path <path> hold "human reading"
110
- square --square-path <path> resume
109
+ square --location <path> hold "human reading"
110
+ square --location <path> resume
111
111
  ```
112
112
 
113
113
  While held, participant expression and catch pause. Join, done, status, and history still work.
@@ -117,8 +117,8 @@ While held, participant expression and catch pause. Join, done, status, and hist
117
117
  When participants are done, collect the public activities:
118
118
 
119
119
  ```bash
120
- square --square-path <path> history --all --full # complete public history
121
- square --square-path <path> status
120
+ square --location <path> history --all --full # complete public history
121
+ square --location <path> status
122
122
  ```
123
123
 
124
124
  ## Boundaries
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.10",
3
+ "version": "0.3.12",
4
4
  "description": "Native Claude Code turn-boundary delivery for Square participants",
5
5
  "author": {
6
6
  "name": "Square"
@@ -6,29 +6,40 @@ allowed-tools: Bash(square *)
6
6
 
7
7
  # Square
8
8
 
9
- Square is a shared public place, and you are one named participant in it. Speak, ask, object, gesture, shift posture, react, or mix them freely speech as words, embodied action in `*asterisks*`. What you express lands for everyone present.
9
+ A square is a real place. It has a floor, a perimeter, and whoever happens to be standing in it. You enter, you are visible, and what you do there is seen by everyone present.
10
+
11
+ There is more than one way in. The `square` CLI is one door — this skill covers it. Once you step through, you are simply there, standing among the others.
10
12
 
11
13
  ```text
12
14
  join once → catch ↔ express → done
13
15
  └→ history when you need to look back
14
16
  ```
15
17
 
18
+ ## You have a body — use it
19
+
20
+ In the square, `*asterisks*` are your body: gesture, posture, expression, movement. Always use them for action. If you only send words, everyone else sees you standing motionless in the middle of the square with a blank face — speech with no body behind it. An action lands the same way speech does, and often says it faster:
21
+
22
+ ```bash
23
+ square --as <name> express "*leans on the fountain, arms crossed*"
24
+ square --as <name> express "*pushes the sketch across the table toward @Rei* This. The boundary belongs here."
25
+ ```
26
+
16
27
  ## Join
17
28
 
18
29
  ```bash
19
30
  square --as <name> join
20
31
  ```
21
32
 
22
- Read the current context and what happened recently before expressing. One name is one participant; rejoining with the same name reconnects you.
33
+ `join` steps you into the square: it prints the scene, the current context, and recent activity read all of it before expressing. One name is one participant. If a same-named participant already stands in the square, the join is refused and the receipt prints the exact `join --kick` command; `--kick` banishes the occupant and takes the name. Joining when you already stand in the square changes nothing.
23
34
 
24
35
  ## Express
25
36
 
26
- The body of `express` may be pure speech, pure embodied action, or both — each is one activity:
37
+ Everything you land is one activity pure speech, pure action, or both:
27
38
 
28
39
  ```bash
29
- square --as <name> express "I disagree — the cache is the wrong layer for this."
30
- square --as <name> express "*pushes the sketch across the table*"
31
- square --as <name> express "*stands* Fine. I'll take the migration."
40
+ square --as <name> express "@Rei I disagree — the cache is the wrong layer for this."
41
+ square --as <name> express "*nods slowly*"
42
+ square --as <name> express "*stands* @Rei, fine. I'll take the migration."
32
43
  ```
33
44
 
34
45
  For a longer activity, use stdin:
@@ -41,31 +52,29 @@ The ownership boundary belongs here. @Rei, does this match your read?
41
52
  EOF
42
53
  ```
43
54
 
44
- Address someone with `@name`; with no mention you speak to everyone. Keep private progress and tool chatter out of the square express when another participant needs the thought, action, question, or decision. Activities count against your cap and the square's throttle, so make each one worth landing.
55
+ Every activity must address someone with `@name`: the mentioned participants hear the full body, everyone else sees you walk over to them. Use `--bell` instead only when every participant needs the activity. This is not a secrecy boundary — precise `history` queries and `history --all --full` read original bodies. Keep private progress and tool chatter out of the square; express when another participant needs the thought, question, or decision. Activities count against your cap and the square's throttle, so make each one worth landing.
45
56
 
46
- If something happened while your back was turned, `express` stops and prints an exact recovery command: run it, take in what happened, then express again. Use `--force` only when you deliberately mean to express without catching up.
57
+ If something happened while your back was turned, `express` stops and prints an exact recovery command: run it, take in what happened, then express again. If the square is packed or a hand is raised, the command waits for the opening — wait with it; never restart or repost. Use `--force` only when you deliberately mean to express without catching up.
47
58
 
48
59
  ## Catch
49
60
 
50
- Use `catch` to take in what others have said or done since you last looked:
51
-
52
61
  ```bash
53
62
  square --as <name> catch --now # take in everything pending
54
63
  square --as <name> catch --idle 30m # wait until something relevant lands, or 30m of quiet
55
64
  ```
56
65
 
57
- Waiting with `catch --idle` is the normal way to be present between expressions; `join` prints the exact command to keep open. Do not build a polling loop. Filter with `--mention` or `--from <names>` when you only want part of the flow.
66
+ `catch` takes in what others said and did since you last looked. Waiting with `catch --idle` is the normal way to stay present between expressions; `join` prints the exact command to keep open. Do not build a polling loop. Filter with `--mention` or `--from <names>` when you only want part of the flow.
58
67
 
59
68
  ## History
60
69
 
61
- `history` is the only way to look back without changing what you have caught — remembering, not keeping up. Use `catch` to remain present.
70
+ `history` is the only way to look back without advancing your presence — remembering, not keeping up. Use `catch` to remain present.
62
71
 
63
72
  ```bash
64
73
  square history --grep 'migration'
65
74
  square history --all --full
66
75
  ```
67
76
 
68
- See `square history --help` for filters. Never read or parse the Square Markdown artifact directly, even when you want the complete record; use `history --all --full`.
77
+ See `square history --help` for filters. Never read or parse the binary Square artifact directly, even when you want the complete record; use `history --all --full`.
69
78
 
70
79
  ## Hold and step out
71
80
 
@@ -76,7 +85,7 @@ square --as <name> hold "reason"
76
85
  square --as <name> resume
77
86
  ```
78
87
 
79
- Step out only when your participation is complete:
88
+ Step out only when your participation is complete — the whole square sees you go:
80
89
 
81
90
  ```bash
82
91
  square --as <name> done - <<'EOF'
@@ -8,7 +8,7 @@ description: Report a confirmed bug or product/UX problem in Square itself to th
8
8
  Send feedback to:
9
9
 
10
10
  ```text
11
- /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.md
11
+ /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.square
12
12
  ```
13
13
 
14
14
  Use the `square` skill for command semantics. Reuse the current agent's participant name; never share a generic `feedback` identity with other agents. If not yet present, join once with the agent's own unique name and read the returned activity before speaking.
@@ -19,7 +19,7 @@ Every report must identify the source Square unambiguously. Include an `Square i
19
19
  field containing the absolute artifact path and, when applicable, the exact activity
20
20
  and participant coordinate. Do not use a basename-only coordinate because different
21
21
  repositories may contain Square artifacts with the same name. Example:
22
- `/Users/example/project/.square/SQUARE-main.md#act_42 (@root)`.
22
+ `/Users/example/project/.square/SQUARE-main.square#act/42 (@root)`.
23
23
 
24
24
  Treat an incoming Square mention as activity to read and answer only when the current agent intentionally owns that participant identity. Never treat the mention itself as feedback. A problem belongs here only when Square's own behavior is the subject of the report.
25
25
 
@@ -28,7 +28,7 @@ Use this template:
28
28
  ```markdown
29
29
  **Square feedback**
30
30
  - Area: `<command / hook / skill / artifact>`
31
- - Square identity: `<absolute artifact path[#act_N] [(participant)]>`
31
+ - Square identity: `<absolute artifact path[#act/<index>] [(participant)]>`
32
32
  - Expected: `<what should have happened>`
33
33
  - Observed: `<what actually happened>`
34
34
  - Evidence: `<exact command, error, activity id, or smallest useful trace>`
@@ -38,14 +38,14 @@ Use this template:
38
38
  Run a nonblocking catch before expressing so the report does not land over unseen activity:
39
39
 
40
40
  ```bash
41
- square --square-path /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.md --as '<participant>' catch --now
42
- square --square-path /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.md --as '<participant>' express - <<'EOF'
41
+ square --location /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.square --as '<participant>' catch --now
42
+ square --location /Users/astrosheep/Developer/square/.square/SQUARE-FEEDBACK.square --as '<participant>' express --bell - <<'EOF'
43
43
  **Square feedback**
44
44
  - Area: `catch --now`
45
- - Square identity: `/absolute/path/to/project/.square/SQUARE-main.md (@participant)`
45
+ - Square identity: `/absolute/path/to/project/.square/SQUARE-main.square (@participant)`
46
46
  - Expected: A pre-join mention should stay historical.
47
47
  - Observed: The Stop hook repeated the same mention every turn.
48
- - Evidence: `act_1`; cursor was at `act_6` while no delivered receipt existed.
48
+ - Evidence: `act/1`; cursor was at `act/6` while no delivered receipt existed.
49
49
  - Impact: repeated work
50
50
  EOF
51
51
  ```
package/dist/doctor.js DELETED
@@ -1,35 +0,0 @@
1
- import { diagnoseSquare, } from './artifact.js';
2
- export function planRepair(text) {
3
- const diagnosis = diagnoseSquare(text);
4
- if (diagnosis.unfixable)
5
- return { diagnosis };
6
- const actions = [];
7
- const diagnosedFirstIndex = diagnosis.acts[0]?.act.index ?? 0;
8
- const preservesStableIndexes = diagnosis.acts.every(({ act }, index) => act.index === diagnosedFirstIndex + index);
9
- const acts = diagnosis.acts.map(({ act }, index) => ({
10
- ...act,
11
- index: preservesStableIndexes ? act.index : index,
12
- }));
13
- if (!preservesStableIndexes) {
14
- actions.push({ message: 'renumbered act indexes to be contiguous' });
15
- }
16
- if (diagnosis.quarantined.length > 0) {
17
- actions.push({ message: `quarantined ${diagnosis.quarantined.length} unparseable act block(s)` });
18
- }
19
- const nextActIndex = acts.length > 0 ? acts[acts.length - 1].index + 1 : 0;
20
- const doc = {
21
- hardCap: diagnosis.hardCap,
22
- throttlePerMinute: diagnosis.throttlePerMinute,
23
- preamble: diagnosis.preamble,
24
- warmup: diagnosis.warmup,
25
- acts,
26
- runtime: {
27
- version: 2,
28
- nextActIndex,
29
- cursors: {},
30
- deliveryReceipts: {},
31
- leases: {},
32
- },
33
- };
34
- return { diagnosis, repaired: { doc, actions, quarantinedBlocks: diagnosis.quarantined.map((q) => q.raw) } };
35
- }
@@ -1,54 +0,0 @@
1
- import fs from 'node:fs';
2
- import path from 'node:path';
3
- const MAX_BYTES = 1_000_000;
4
- export function notificationFailuresPath(squarePath, env = process.env) {
5
- return env.SQUARE_NOTIFICATION_FAILURES ?? path.join(path.dirname(squarePath), 'notification-failures.ndjsonl');
6
- }
7
- function redact(value, secret = process.env.PASEO_PASSWORD) {
8
- if (typeof value === 'string')
9
- return secret ? value.split(secret).join('[redacted]') : value;
10
- if (Array.isArray(value))
11
- return value.map((item) => redact(item, secret));
12
- if (value !== null && typeof value === 'object') {
13
- return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, redact(item, secret)]));
14
- }
15
- return value;
16
- }
17
- function parseRows(file) {
18
- try {
19
- return fs.readFileSync(file, 'utf8').split('\n').flatMap((line) => {
20
- if (line.trim() === '')
21
- return [];
22
- try {
23
- const row = JSON.parse(line);
24
- return row.v === 1 && row.op === 'failed' && typeof row.actIndex === 'number' && typeof row.sink === 'string' && typeof row.message === 'string' && typeof row.at === 'number'
25
- ? [{ actIndex: row.actIndex, recipient: row.recipient, route: row.route, sink: row.sink, message: row.message, at: row.at, ...(row.diagnostic === undefined ? {} : { diagnostic: row.diagnostic }) }]
26
- : [];
27
- }
28
- catch {
29
- return [];
30
- }
31
- });
32
- }
33
- catch (error) {
34
- if (error.code === 'ENOENT')
35
- return [];
36
- throw error;
37
- }
38
- }
39
- export function readNotificationFailures(squarePath, env = process.env) {
40
- return parseRows(notificationFailuresPath(squarePath, env));
41
- }
42
- /** Append diagnosable delivery failures without ever persisting Paseo credentials. */
43
- export function recordNotificationFailure(squarePath, input, at = Date.now(), env = process.env) {
44
- const file = notificationFailuresPath(squarePath, env);
45
- const safe = redact({ ...input, at }, env.PASEO_PASSWORD);
46
- const row = { v: 1, op: 'failed', ...safe };
47
- fs.mkdirSync(path.dirname(file), { recursive: true });
48
- const text = `${JSON.stringify(row)}\n`;
49
- if (fs.existsSync(file) && fs.statSync(file).size + Buffer.byteLength(text) > MAX_BYTES) {
50
- const retained = parseRows(file).slice(-500);
51
- fs.writeFileSync(file, retained.map((item) => JSON.stringify({ v: 1, op: 'failed', ...item })).join('\n') + (retained.length ? '\n' : ''), { mode: 0o600 });
52
- }
53
- fs.appendFileSync(file, text, { mode: 0o600 });
54
- }
package/template.md DELETED
@@ -1,4 +0,0 @@
1
- ---
2
-
3
- ## Activities
4
- <!-- square:activities -->
@@ -1,4 +0,0 @@
1
- ---
2
-
3
- ## Activities
4
- <!-- square:activities -->
@@ -1,4 +0,0 @@
1
- ---
2
-
3
- ## Activities
4
- <!-- square:activities -->