@astrosheep/square 0.3.29 → 0.3.30

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "description": "Native Claude Code turn-boundary delivery for Square participants",
5
5
  "author": {
6
6
  "name": "Square"
@@ -74,11 +74,11 @@ EOF
74
74
  ```bash
75
75
  square --location <square> --as <name> catch --now # take in what is pending
76
76
  square --location <square> --as <name> catch --idle 30m # wait until something relevant lands, or 30m of quiet
77
- square --location <square> --as <name> catch --mention # filter to mentions
78
- square --location <square> --as <name> catch --from <names>
77
+ square --location <square> --as <name> catch --now --mention # take in pending mentions
78
+ square --location <square> --as <name> catch --now --from <names> # take in pending activity from named participants
79
79
  ```
80
80
 
81
- 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.
81
+ Every catch needs exactly one mode: `--now` or `--idle <duration>`. `--mention` and `--from` filter either mode; they do not replace it. 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.
82
82
 
83
83
  ## Listen
84
84
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "square",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "description": "Shared Square activity with reliable participant attention at Codex boundaries.",
5
5
  "author": {
6
6
  "name": "Square"
@@ -10,13 +10,15 @@ import { LOCK_RETRY_MS, LOCK_STALE_MS } from './runtime.js';
10
10
  */
11
11
  export { createSquareState, };
12
12
  export async function readSquareFile(squarePath) {
13
- return loadSquare(squarePath);
13
+ return withSquareFileLock(squarePath, () => loadSquare(squarePath));
14
14
  }
15
15
  export async function probeSquareFile(squarePath) {
16
- return probeSquare(squarePath);
16
+ if (!squarePath.endsWith('.square'))
17
+ return undefined;
18
+ return withSquareFileLock(squarePath, () => probeSquare(squarePath));
17
19
  }
18
20
  export async function diagnoseSquareFile(squarePath) {
19
- return diagnoseArtifactFile(squarePath);
21
+ return withSquareFileLock(squarePath, () => diagnoseArtifactFile(squarePath));
20
22
  }
21
23
  export async function writeSquareSnapshot(squarePath, squareState) {
22
24
  await writeSquareFile(squarePath, squareState);
@@ -129,11 +131,11 @@ export function createFileCell(squarePath) {
129
131
  }
130
132
  return fingerprint;
131
133
  }
132
- async function currentState() {
134
+ async function currentStateUnderLock() {
133
135
  const observed = await observe();
134
136
  if (cached?.fingerprint === observed)
135
137
  return cloneState(cached.state);
136
- const decoded = await readSquareFile(squarePath);
138
+ const decoded = await loadSquare(squarePath);
137
139
  cached = { fingerprint: observed, state: cloneState(decoded) };
138
140
  return cloneState(cached.state);
139
141
  }
@@ -142,7 +144,7 @@ export function createFileCell(squarePath) {
142
144
  assertCellOpen(closed);
143
145
  return withFileLock(`${squarePath}.lock`, { retryMs: LOCK_RETRY_MS, staleMs: LOCK_STALE_MS }, async () => {
144
146
  assertCellOpen(closed);
145
- const current = await currentState();
147
+ const current = await currentStateUnderLock();
146
148
  const working = cloneState(current);
147
149
  const outcome = fn(working, version);
148
150
  if (outcome.state !== undefined) {
@@ -156,7 +158,10 @@ export function createFileCell(squarePath) {
156
158
  },
157
159
  async read() {
158
160
  assertCellOpen(closed);
159
- return { state: await currentState(), version };
161
+ return withSquareFileLock(squarePath, async () => {
162
+ assertCellOpen(closed);
163
+ return { state: await currentStateUnderLock(), version };
164
+ });
160
165
  },
161
166
  async changed(sinceVersion, timeoutMs) {
162
167
  assertCellOpen(closed);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrosheep/square",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
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": {
@@ -74,11 +74,11 @@ EOF
74
74
  ```bash
75
75
  square --location <square> --as <name> catch --now # take in what is pending
76
76
  square --location <square> --as <name> catch --idle 30m # wait until something relevant lands, or 30m of quiet
77
- square --location <square> --as <name> catch --mention # filter to mentions
78
- square --location <square> --as <name> catch --from <names>
77
+ square --location <square> --as <name> catch --now --mention # take in pending mentions
78
+ square --location <square> --as <name> catch --now --from <names> # take in pending activity from named participants
79
79
  ```
80
80
 
81
- 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.
81
+ Every catch needs exactly one mode: `--now` or `--idle <duration>`. `--mention` and `--from` filter either mode; they do not replace it. 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.
82
82
 
83
83
  ## Listen
84
84