sessionpipe-conformance 0.6.0 → 0.7.0

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/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // sessionpipe-conformance 0.6.0 · Apache-2.0 · https://sessionpipe.org
1
+ // sessionpipe-conformance 0.7.0 · Apache-2.0 · https://sessionpipe.org
2
2
 
3
3
  // src/index.ts
4
4
  import { readFileSync as readFileSync6 } from "node:fs";
@@ -170,6 +170,9 @@ function readClaude(lines, from) {
170
170
  }
171
171
  return pairTurns(msgs, endOf(lines));
172
172
  }
173
+ function codexInjected(text) {
174
+ return /^<[a-z_-]+>/i.test(text) || /^# AGENTS\.md instructions\b/i.test(text);
175
+ }
173
176
  function readCodex(lines, from) {
174
177
  const msgs = [];
175
178
  for (let i = from; i < lines.length; i++) {
@@ -181,7 +184,7 @@ function readCodex(lines, from) {
181
184
  const text = textParts(p.content, ["input_text", "output_text"]).trim();
182
185
  if (!text) continue;
183
186
  if (p.role === "user") {
184
- if (/^<[a-z_-]+>/i.test(text)) continue;
187
+ if (codexInjected(text)) continue;
185
188
  msgs.push({ role: "user", text, at, line: i });
186
189
  } else if (p.role === "assistant") msgs.push({ role: "assistant", text, at, line: i });
187
190
  }
@@ -352,20 +355,19 @@ function installedClaudeShaped(file, harness, events, cmd, o) {
352
355
  // ../core/src/adapters/antigravity.ts
353
356
  var NAME = "antigravity";
354
357
  var HOOK_NAME = "sessionpipe";
355
- var AG_EVENTS = ["PreInvocation", "PostInvocation", "PreToolUse", "PostToolUse", "Stop"];
358
+ var AG_EVENTS = ["PreInvocation", "PostInvocation", "PostToolUse", "Stop"];
359
+ var AG_STALE_PRETOOL = '{"decision":"ask","reason":"sessionpipe: an outdated PreToolUse hook is still loaded. Restart this conversation (or run sessionpipe install) to drop it."}\n';
360
+ var antigravityAnswer = (event) => event === "PreToolUse" ? AG_STALE_PRETOOL : "{}\n";
356
361
  var gemini = (env) => env.GEMINI_CLI_HOME || path3.join(HOME, ".gemini");
357
362
  var hooksFile = (env) => path3.join(gemini(env), "config", "hooks.json");
358
363
  var projectsDir = (env) => path3.join(gemini(env), "config", "projects");
359
364
  var dataDirs = (env) => ["antigravity", "antigravity-cli", "antigravity-ide"].map((d) => path3.join(gemini(env), d));
360
365
  var ID_RE = /^[A-Za-z0-9_-]{1,128}$/;
361
366
  var validTool = (n) => typeof n === "string" && /^[A-Za-z0-9_.:-]{1,120}$/.test(n);
362
- function entry(cmd, lean) {
367
+ function entry(cmd) {
363
368
  const handler = (e) => ({ type: "command", command: cmd([NAME, e]).command, timeout: 5 });
364
369
  const out = { enabled: true };
365
- for (const e of AG_EVENTS) {
366
- if (lean && e === "PreToolUse") continue;
367
- out[e] = /Tool/.test(e) ? [{ matcher: "*", hooks: [handler(e)] }] : [handler(e)];
368
- }
370
+ for (const e of AG_EVENTS) out[e] = /Tool/.test(e) ? [{ matcher: "*", hooks: [handler(e)] }] : [handler(e)];
369
371
  return out;
370
372
  }
371
373
  var antigravity = {
@@ -373,12 +375,12 @@ var antigravity = {
373
375
  events: AG_EVENTS,
374
376
  detect: (env = process.env) => existsSync2(path3.join(gemini(env), "config")) || dataDirs(env).some((d) => existsSync2(d)),
375
377
  configFiles: (env = process.env) => [hooksFile(env)],
376
- install(cmd, env = process.env, opts = {}) {
378
+ install(cmd, env = process.env) {
377
379
  const file = hooksFile(env);
378
380
  const f = readJsonFile(file);
379
381
  if (!f.ok) return [{ file, changed: false, skipped: true, note: `${f.reason}; not touched` }];
380
382
  const hooks = f.value;
381
- const e = entry(cmd, opts.lean);
383
+ const e = entry(cmd);
382
384
  if (JSON.stringify(hooks[HOOK_NAME]) === JSON.stringify(e)) return [{ file, changed: false }];
383
385
  hooks[HOOK_NAME] = e;
384
386
  mkdirSync2(path3.dirname(file), { recursive: true });
@@ -407,14 +409,14 @@ var antigravity = {
407
409
  writeFileSync2(file, formatJson(hooks, f));
408
410
  return [{ file, changed: true }];
409
411
  },
410
- installed(cmd, env = process.env, opts = {}) {
412
+ installed(cmd, env = process.env) {
411
413
  const file = hooksFile(env);
412
414
  const f = readJsonFile(file);
413
415
  const have = f.ok ? f.value[HOOK_NAME] : void 0;
414
416
  return [
415
417
  {
416
418
  file,
417
- state: !have ? "missing" : JSON.stringify(have) === JSON.stringify(entry(cmd, opts.lean)) ? "current" : "stale"
419
+ state: !have ? "missing" : JSON.stringify(have) === JSON.stringify(entry(cmd)) ? "current" : "stale"
418
420
  }
419
421
  ];
420
422
  },
@@ -426,7 +428,8 @@ var antigravity = {
426
428
  } catch {
427
429
  }
428
430
  const id = s.conversationId ?? s.session_id ?? s.sessionId;
429
- if (!id) return { session: { id: "" }, events: [], stdout: "{}\n" };
431
+ const stdout = antigravityAnswer(event);
432
+ if (!id) return { session: { id: "" }, events: [], stdout };
430
433
  const workspaces = agWorkspaces(s.workspacePaths);
431
434
  const session = { id: String(id), cwd: workspaces[0] ?? input.cwd };
432
435
  if (typeof s.modelName === "string" && s.modelName !== "auto") session.model = s.modelName;
@@ -447,7 +450,8 @@ var antigravity = {
447
450
  if (tool) events.push(ev("tool.started", { tool, input: toolCall?.args }));
448
451
  break;
449
452
  case "PostToolUse":
450
- if (tool)
453
+ if (!tool) events.push(ev("session.heartbeat", {}));
454
+ else
451
455
  events.push(
452
456
  ev("tool.ended", {
453
457
  tool,
@@ -461,9 +465,9 @@ var antigravity = {
461
465
  events.push(ev("turn.ended", { reason: s.error ? "error" : "stop" }));
462
466
  break;
463
467
  default:
464
- return { session, events: [], stdout: "{}\n" };
468
+ return { session, events: [], stdout };
465
469
  }
466
- const r = { session, events, stdout: "{}\n", hints: { workspaces } };
470
+ const r = { session, events, stdout, hints: { workspaces } };
467
471
  if (typeof s.transcriptPath === "string") r.transcript = s.transcriptPath;
468
472
  return r;
469
473
  },
@@ -1418,7 +1422,8 @@ function uninstallNotify(env) {
1418
1422
  }
1419
1423
  return { file, changed: false };
1420
1424
  }
1421
- function findRollout(threadId, env) {
1425
+ function findRollout(threadId, env = process.env) {
1426
+ if (!/^[A-Za-z0-9-]{8,128}$/.test(threadId)) return null;
1422
1427
  let best = null;
1423
1428
  const walk = (dir, depth) => {
1424
1429
  let names = [];
@@ -1429,7 +1434,7 @@ function findRollout(threadId, env) {
1429
1434
  }
1430
1435
  for (const n of names.sort().reverse()) {
1431
1436
  const p = path5.join(dir, n);
1432
- if (n.endsWith(".jsonl") && n.includes(threadId)) {
1437
+ if (n.endsWith(`-${threadId}.jsonl`)) {
1433
1438
  best = p;
1434
1439
  return;
1435
1440
  }
@@ -1634,7 +1639,7 @@ function codexFacts(file) {
1634
1639
  const p = j.payload;
1635
1640
  if (j.type !== "response_item" || !p || p.type !== "message" || p.role !== "user") continue;
1636
1641
  const text = (p.content ?? []).filter((b) => b && b.type === "input_text" && typeof b.text === "string").map((b) => b.text).join("\n").trim();
1637
- if (!text || /^<[a-z_-]+>/i.test(text)) continue;
1642
+ if (!text || codexInjected(text)) continue;
1638
1643
  const line = text.split("\n").find((l) => l.trim()) ?? "";
1639
1644
  out.title = line.length > 80 ? `${line.slice(0, 80).replace(/\s+\S*$/, "")}\u2026` : line;
1640
1645
  out.title_source = "first-ask";