@afokapu/atdd-bun 0.10.29 → 0.10.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.
package/integrity.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.10.29",
2
+ "version": "0.10.30",
3
3
  "files": {
4
4
  "HOOK_AUDIT.md": "5329d840db37671b1918f688ead26865473b87db73dbc75f7c8b2a8bbe8d6d43",
5
5
  "PLANNER_PORT.md": "fb5935bac8b7ac18994de21e43ace3a5ef8cd55f85b0e3349fca261280054f11",
@@ -977,7 +977,7 @@
977
977
  "lib/frontend.mjs": "d6d9b29c3d7f2d162cda03bb34b20a3224a82887b6be3db7cab375510913c9a3",
978
978
  "lib/imports.mjs": "3db4979269488fa26f6e7aefded6ece9c646be6587a10e249821a5a208109962",
979
979
  "lib/interlocking.mjs": "d0803d080ac7d7477c51be70112df1e85213d339fd3c6b71f75f26145fa8accd",
980
- "lib/scan.mjs": "7a4410f3bc2e2ebbdddb4f3dd6268987a01b9685e94c8a18ea05b4056daf4ea8",
980
+ "lib/scan.mjs": "02b0fa864cab24157a8f27b50a87a2bb66a875f90cf6632c753c4627d61456ef",
981
981
  "planner-nodes/ENFORCEMENT_SCOPE.yaml": "d8ec7039c219857f3d77af5d4d84612b533b69c1a5fcef935fbf46470adafed4",
982
982
  "planner-nodes/nodes/planner.acceptance.abstract-fields-required.convention.yaml": "bd565693f0ae861f0561ad2f7a91a8c55f9a209c3acd59c5750cfcffd96a85d8",
983
983
  "planner-nodes/nodes/planner.acceptance.authoring-guidelines.convention.yaml": "16348dceed5868041b832bde766e9c8d4a950d4032f1f3066b357644081a3b17",
@@ -1202,7 +1202,7 @@
1202
1202
  "relationships.yaml": "1cb713364aff54fb6e299e0737fe75a5d7b2e1dbd0a79b16b793aa1d269207b5",
1203
1203
  "src/agent.ts": "65e4579adb5a54977f557f8c783aba0e2a2a1d5cf3cea9f017b67ffe598b2f65",
1204
1204
  "src/board-ui.ts": "16a843705552f8f18e0e328e90e4a2a9148d771ca69f2708fe4a91302947dfad",
1205
- "src/board.ts": "6f46cd890e0dfeb4a928d969e902474fb059844561a111ca8bbfeb4ff3e2d83b",
1205
+ "src/board.ts": "4b9aa5b356d67c1b4ab4018796f9d09afba6d443dbebbb733b5d6c6a8d5a1c87",
1206
1206
  "src/ci.ts": "67e54d2cbfc44a9e42837d5e750af526d6255c539d3c452a4d5fca3226c0d9ac",
1207
1207
  "src/cli.ts": "e5ab4d2435fdcbebf462b4c2b67b495bd975d5deb668b088d8cba04a9d8b78a5",
1208
1208
  "src/delivery.ts": "2eaaf4fd87aea26dce70b4c88a4e0a2f25b9de165bc2e38330fd7eb449587901",
package/lib/scan.mjs CHANGED
@@ -132,6 +132,38 @@ function regexMayStart(text, i) {
132
132
  return false;
133
133
  }
134
134
 
135
+ // The index just past the template literal opening at `start`. A `${ … }` substitution is code: it may hold strings,
136
+ // braces and templates of its own (escaped backticks included), so the template ends only at a backtick outside them.
137
+ function templateEnd(text, start) {
138
+ const n = text.length;
139
+ let j = start + 1;
140
+ while (j < n) {
141
+ const c = text[j];
142
+ if (c === "\\") { j += 2; continue; }
143
+ if (c === "`") return j + 1;
144
+ if (c === "$" && text[j + 1] === "{") {
145
+ let depth = 1;
146
+ j += 2;
147
+ while (j < n && depth > 0) {
148
+ const d = text[j];
149
+ if (d === "`") { j = templateEnd(text, j); continue; }
150
+ if (d === '"' || d === "'") {
151
+ let k = j + 1;
152
+ while (k < n && text[k] !== d && text[k] !== "\n") k += text[k] === "\\" ? 2 : 1;
153
+ j = k + 1;
154
+ continue;
155
+ }
156
+ if (d === "{") depth++;
157
+ else if (d === "}") depth--;
158
+ j++;
159
+ }
160
+ continue;
161
+ }
162
+ j++;
163
+ }
164
+ return n;
165
+ }
166
+
135
167
  export function maskLiteralsAndComments(text) {
136
168
  const out = text.split("");
137
169
  let i = 0;
@@ -165,7 +197,11 @@ export function maskLiteralsAndComments(text) {
165
197
  if (j >= n || text[j] !== "/") { i++; continue; } // no closing slash on the line: not a regex
166
198
  blank(i + 1, j);
167
199
  i = j + 1;
168
- } else if (ch === '"' || ch === "'" || ch === "`") {
200
+ } else if (ch === "`") {
201
+ const j = templateEnd(text, i);
202
+ blank(i + 1, j - 1 >= i + 1 ? j - 1 : i + 1);
203
+ i = j;
204
+ } else if (ch === '"' || ch === "'") {
169
205
  let j = i + 1;
170
206
  while (j < n) {
171
207
  if (text[j] === "\\") { j += 2; continue; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@afokapu/atdd-bun",
3
- "version": "0.10.29",
3
+ "version": "0.10.30",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/afokapu/atdd-bun.git"
package/src/board.ts CHANGED
@@ -113,9 +113,9 @@ const POLL_LIMIT_MS = 10_000;
113
113
 
114
114
  /** What a listener prints when nothing has arrived for a while: the owner's check-in, for the agent to act on (move
115
115
  * the work, or tell whoever it waits on), never to answer with a "still here" post. */
116
- export function checkIn(agent: string, quietSeconds: number): string {
116
+ export function checkIn(agent: string, quietSeconds: number, rearm = false): string {
117
117
  const quiet = quietSeconds <= 0 ? "" : quietSeconds < 60 ? ` for ${quietSeconds} s` : ` for ${Math.round(quietSeconds / 60)} min`;
118
- return `CHECK-IN for ${agent}: no message${quiet}. Where are you? Are you moving forward, or blocked on someone, and do they know? Is your stakeholder informed? Are you avoiding ceremony and rabbit holes, effectiveness first, then efficiency? Act on it: move the work, or post once to whoever you wait on; never post just to say you are still here. Then re-arm this listener.`;
118
+ return `CHECK-IN for ${agent}: no message${quiet}. Where are you? Are you moving forward, or blocked on someone, and do they know? Is your stakeholder informed? Are you avoiding ceremony and rabbit holes, effectiveness first, then efficiency? Act on it: move the work, or post once to whoever you wait on; never post just to say you are still here.${rearm ? " Then re-arm this listener." : ""}`;
119
119
  }
120
120
 
121
121
  export async function waitFor(url: string, topics: string[], agent: string, since = "all", timeoutSeconds = 0, skip: string[] = [], intervalMs = 500, seen: (id: string) => void = () => {}): Promise<Message | null> {
@@ -177,7 +177,7 @@ export async function chat(args: string[], env: Record<string, string | undefine
177
177
  // Without --since, continue from where this identity last stopped on these topics; either way, remember the place.
178
178
  const file = cursorFile(me, topics, env);
179
179
  const message = await waitFor(url, topics, me, flag("since") || loadCursor(file) || seedCursor(me, env) || "all", Number(flag("timeout") ?? 0), list(flag("skip")), 500, id => saveCursor(file, id));
180
- if (!message) { console.log(checkIn(me, Number(flag("timeout") ?? 0))); return 2; }
180
+ if (!message) { console.log(checkIn(me, Number(flag("timeout") ?? 0), true)); return 2; }
181
181
  console.log(format(message, topics.length > 1));
182
182
  return 0;
183
183
  }