ccsniff 1.1.3 → 1.1.4

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +7 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccsniff",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "Watch Claude Code JSONL output files and emit structured events as a Node.js EventEmitter",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
package/src/cli.js CHANGED
@@ -248,6 +248,11 @@ if (opts['bash-discipline']) {
248
248
  const BAD_LEADING = /^\s*(cat|head|tail|ls|grep|find|sed|awk)\b/;
249
249
  const SLEEP_POLL = /\bsleep\s+\d+\s*;.*(cat|ls|grep|find|head|tail)/;
250
250
  const SPOOL_WRITE = /\.gm\/exec-spool\/in\//;
251
+ // The host harness explicitly endorses `until <check>; do sleep N; done` as
252
+ // the canonical pattern for polling external state (see Bash tool description
253
+ // and Monitor docs). Same for `while !curl ...; do sleep N; done`. These are
254
+ // NOT sleep-poll violations even though they contain `sleep N`.
255
+ const ENDORSED_POLL = /^\s*(until|while)\s+/;
251
256
  const violations = [];
252
257
  for (const ev of all) {
253
258
  if (!filter(ev)) continue;
@@ -256,6 +261,8 @@ if (opts['bash-discipline']) {
256
261
  const cmd = ev.block?.input?.command || '';
257
262
  // `echo > .gm/exec-spool/in/<verb>/N.txt` is the canonical spool-write pattern, not a deviation.
258
263
  if (SPOOL_WRITE.test(cmd) && /^\s*echo\b/.test(cmd)) continue;
264
+ // `until ...; do sleep N; done` is the harness-endorsed poll pattern.
265
+ if (ENDORSED_POLL.test(cmd)) continue;
259
266
  const kind = SLEEP_POLL.test(cmd) ? 'sleep-poll' : (BAD_LEADING.test(cmd) ? 'bad-leading-cmd' : null);
260
267
  if (!kind) continue;
261
268
  violations.push({ ts: ev.timestamp, sid: ev.conversation.id, project: path.basename(ev.conversation.cwd || ''), kind, cmd: cmd.slice(0, 200) });