@bububuger/spanory 0.1.22 → 0.1.26

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/dist/index.js +14 -143
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // dist/index.js
4
4
  import { existsSync, readFileSync, realpathSync } from "node:fs";
5
- import { chmod, copyFile, mkdir as mkdir4, readdir as readdir5, readFile as readFile8, rm, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
5
+ import { copyFile, mkdir as mkdir4, readdir as readdir5, readFile as readFile8, rm, stat as stat4, writeFile as writeFile4 } from "node:fs/promises";
6
6
  import path8 from "node:path";
7
7
  import { createHash as createHash4 } from "node:crypto";
8
8
  import { spawnSync } from "node:child_process";
@@ -4473,6 +4473,14 @@ async function backupIfExists(filePath) {
4473
4473
  await copyFile(filePath, backupPath);
4474
4474
  return backupPath;
4475
4475
  }
4476
+ function isSpanoryCodexNotifyConfigured(configText) {
4477
+ return /notify\s*=\s*\[[^\]]*spanory-codex-notify\.sh[^\]]*\]/m.test(String(configText ?? ""));
4478
+ }
4479
+ function stripSpanoryCodexNotifyConfig(configText) {
4480
+ const next = String(configText ?? "").replace(/^notify\s*=\s*\[[^\]]*spanory-codex-notify\.sh[^\]]*\]\s*$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
4481
+ return next ? `${next}
4482
+ ` : "";
4483
+ }
4476
4484
  function isSpanoryHookCommand(command) {
4477
4485
  const text = String(command ?? "");
4478
4486
  return /\bspanory\b/.test(text) && /\bhook\b/.test(text);
@@ -4525,118 +4533,6 @@ async function applyClaudeSetup({ homeRoot, spanoryBin, dryRun }) {
4525
4533
  backup
4526
4534
  };
4527
4535
  }
4528
- function upsertCodexNotifyConfig(configText, notifyScriptRef) {
4529
- const notifyLine = `notify = ["${escapeTomlBasicString(notifyScriptRef)}"]`;
4530
- if (/^notify\s*=.*$/m.test(configText)) {
4531
- return configText.replace(/^notify\s*=.*$/m, notifyLine);
4532
- }
4533
- const withNewline = configText.trimEnd();
4534
- if (!withNewline)
4535
- return `${notifyLine}
4536
- `;
4537
- return `${withNewline}
4538
-
4539
- ${notifyLine}
4540
- `;
4541
- }
4542
- function escapeTomlBasicString(value) {
4543
- return String(value).replaceAll("\\", "\\\\").replaceAll('"', '\\"');
4544
- }
4545
- function isSpanoryCodexNotifyConfigured(configText) {
4546
- return /notify\s*=\s*\[[^\]]*spanory-codex-notify\.sh[^\]]*\]/m.test(String(configText ?? ""));
4547
- }
4548
- function stripSpanoryCodexNotifyConfig(configText) {
4549
- const next = String(configText ?? "").replace(/^notify\s*=\s*\[[^\]]*spanory-codex-notify\.sh[^\]]*\]\s*$/gm, "").replace(/\n{3,}/g, "\n\n").trim();
4550
- return next ? `${next}
4551
- ` : "";
4552
- }
4553
- function codexNotifyScriptContent({ spanoryBin, codexHome, exportDir, logFile }) {
4554
- return `#!/usr/bin/env bash
4555
- set -euo pipefail
4556
- payload="\${1:-}"
4557
- if [[ -z "$payload" ]] && [[ ! -t 0 ]]; then
4558
- IFS= read -r -t 0 payload || true
4559
- fi
4560
- if [[ -z "\${payload//[$'\\t\\r\\n ']/}" ]]; then
4561
- echo "skip=empty-payload source=codex-notify args=$#" >> "${logFile}"
4562
- exit 0
4563
- fi
4564
- payload_file="$(mktemp "\${TMPDIR:-/tmp}/spanory-codex-notify.XXXXXX")"
4565
- printf '%s' "$payload" > "$payload_file"
4566
- echo "$payload" | "${spanoryBin}" runtime codex hook \\
4567
- --last-turn-only \\
4568
- --runtime-home "${codexHome}" \\
4569
- --export-json-dir "${exportDir}" \\
4570
- >> "${logFile}" 2>&1 || true
4571
- (
4572
- sleep 2
4573
- cat "$payload_file" | "${spanoryBin}" runtime codex hook \\
4574
- --last-turn-only \\
4575
- --force \\
4576
- --runtime-home "${codexHome}" \\
4577
- --export-json-dir "${exportDir}" \\
4578
- >> "${logFile}" 2>&1 || true
4579
- rm -f "$payload_file"
4580
- ) >/dev/null 2>&1 &
4581
- `;
4582
- }
4583
- async function applyCodexSetup({ homeRoot, spanoryBin, dryRun }) {
4584
- const codexHome = path8.join(homeRoot, ".codex");
4585
- const spanoryHome = process.env.SPANORY_HOME ?? path8.join(homeRoot, ".spanory");
4586
- const binDir = path8.join(codexHome, "bin");
4587
- const stateDir = path8.join(codexHome, "state", "spanory");
4588
- const scriptPath = path8.join(binDir, "spanory-codex-notify.sh");
4589
- const logFile = path8.join(spanoryHome, "logs", "codex-notify.log");
4590
- const configPath = path8.join(codexHome, "config.toml");
4591
- const notifyScriptRef = scriptPath;
4592
- const scriptContent = codexNotifyScriptContent({
4593
- spanoryBin,
4594
- codexHome,
4595
- exportDir: stateDir,
4596
- logFile
4597
- });
4598
- let currentConfig = "";
4599
- try {
4600
- currentConfig = await readFile8(configPath, "utf-8");
4601
- } catch (error) {
4602
- if (error?.code !== "ENOENT")
4603
- throw error;
4604
- }
4605
- const nextConfig = upsertCodexNotifyConfig(currentConfig, notifyScriptRef);
4606
- const configChanged = currentConfig !== nextConfig;
4607
- let currentScript = "";
4608
- try {
4609
- currentScript = await readFile8(scriptPath, "utf-8");
4610
- } catch (error) {
4611
- if (error?.code !== "ENOENT")
4612
- throw error;
4613
- }
4614
- const scriptChanged = currentScript !== scriptContent;
4615
- const changed = configChanged || scriptChanged;
4616
- let configBackup = null;
4617
- if (changed && !dryRun) {
4618
- await mkdir4(binDir, { recursive: true });
4619
- await mkdir4(stateDir, { recursive: true });
4620
- await mkdir4(path8.dirname(logFile), { recursive: true });
4621
- if (configChanged) {
4622
- configBackup = await backupIfExists(configPath);
4623
- await writeFile4(configPath, nextConfig, "utf-8");
4624
- }
4625
- if (scriptChanged) {
4626
- await writeFile4(scriptPath, scriptContent, "utf-8");
4627
- await chmod(scriptPath, 493);
4628
- }
4629
- }
4630
- return {
4631
- runtime: "codex",
4632
- ok: true,
4633
- changed,
4634
- dryRun,
4635
- configPath,
4636
- scriptPath,
4637
- configBackup
4638
- };
4639
- }
4640
4536
  async function applyCodexWatchSetup({ homeRoot, dryRun }) {
4641
4537
  const codexHome = path8.join(homeRoot, ".codex");
4642
4538
  const scriptPath = path8.join(codexHome, "bin", "spanory-codex-notify.sh");
@@ -5167,7 +5063,6 @@ async function runSetupApply(options) {
5167
5063
  const selected = parseSetupRuntimes(options.runtimes);
5168
5064
  const spanoryBin = options.spanoryBin ?? "spanory";
5169
5065
  const dryRun = Boolean(options.dryRun);
5170
- const codexMode = options.codexMode ?? process.env.SPANORY_CODEX_MODE ?? "watch";
5171
5066
  const results = [];
5172
5067
  if (selected.includes("claude-code")) {
5173
5068
  try {
@@ -5182,35 +5077,11 @@ async function runSetupApply(options) {
5182
5077
  }
5183
5078
  }
5184
5079
  if (selected.includes("codex")) {
5185
- if (codexMode === "notify") {
5186
- try {
5187
- const result = await applyCodexSetup({ homeRoot, spanoryBin, dryRun });
5188
- results.push(result);
5189
- } catch (error) {
5190
- results.push({
5191
- runtime: "codex",
5192
- ok: false,
5193
- error: String(error?.message ?? error)
5194
- });
5195
- }
5196
- } else if (codexMode === "watch") {
5197
- try {
5198
- const result = await applyCodexWatchSetup({ homeRoot, dryRun });
5199
- results.push(result);
5200
- } catch (error) {
5201
- results.push({
5202
- runtime: "codex",
5203
- ok: false,
5204
- error: String(error?.message ?? error)
5205
- });
5206
- }
5207
- } else {
5208
- results.push({
5209
- runtime: "codex",
5210
- ok: true,
5211
- skipped: true,
5212
- detail: `codex mode "${codexMode}" has no setup action`
5213
- });
5080
+ try {
5081
+ const result = await applyCodexWatchSetup({ homeRoot, dryRun });
5082
+ results.push(result);
5083
+ } catch (error) {
5084
+ results.push({ runtime: "codex", ok: false, error: String(error?.message ?? error) });
5214
5085
  }
5215
5086
  }
5216
5087
  if (selected.includes("openclaw")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bububuger/spanory",
3
- "version": "0.1.22",
3
+ "version": "0.1.26",
4
4
  "description": "Spanory CLI for cross-runtime agent observability",
5
5
  "license": "MIT",
6
6
  "type": "module",