approval-box 0.1.15 → 0.1.17

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/cli.mjs +103 -78
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -4437,10 +4437,10 @@ var require_browser = __commonJS({
4437
4437
  text2 = canvas;
4438
4438
  canvas = void 0;
4439
4439
  }
4440
- return new Promise(function(resolve2, reject) {
4440
+ return new Promise(function(resolve3, reject) {
4441
4441
  try {
4442
4442
  const data = QRCode2.create(text2, opts);
4443
- resolve2(renderFunc(data, canvas, opts));
4443
+ resolve3(renderFunc(data, canvas, opts));
4444
4444
  } catch (e) {
4445
4445
  reject(e);
4446
4446
  }
@@ -4521,11 +4521,11 @@ var require_server = __commonJS({
4521
4521
  }
4522
4522
  function render(renderFunc, text2, params) {
4523
4523
  if (!params.cb) {
4524
- return new Promise(function(resolve2, reject) {
4524
+ return new Promise(function(resolve3, reject) {
4525
4525
  try {
4526
4526
  const data = QRCode2.create(text2, params.opts);
4527
4527
  return renderFunc(data, params.opts, function(err, data2) {
4528
- return err ? reject(err) : resolve2(data2);
4528
+ return err ? reject(err) : resolve3(data2);
4529
4529
  });
4530
4530
  } catch (e) {
4531
4531
  reject(e);
@@ -7540,7 +7540,7 @@ var require_compile = __commonJS({
7540
7540
  const schOrFunc = root.refs[ref];
7541
7541
  if (schOrFunc)
7542
7542
  return schOrFunc;
7543
- let _sch = resolve2.call(this, root, ref);
7543
+ let _sch = resolve3.call(this, root, ref);
7544
7544
  if (_sch === void 0) {
7545
7545
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
7546
7546
  const { schemaId } = this.opts;
@@ -7567,7 +7567,7 @@ var require_compile = __commonJS({
7567
7567
  function sameSchemaEnv(s1, s2) {
7568
7568
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
7569
7569
  }
7570
- function resolve2(root, ref) {
7570
+ function resolve3(root, ref) {
7571
7571
  let sch;
7572
7572
  while (typeof (sch = this.refs[ref]) == "string")
7573
7573
  ref = sch;
@@ -8397,7 +8397,7 @@ var require_fast_uri = __commonJS({
8397
8397
  }
8398
8398
  return uri;
8399
8399
  }
8400
- function resolve2(baseURI, relativeURI, options) {
8400
+ function resolve3(baseURI, relativeURI, options) {
8401
8401
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
8402
8402
  const {
8403
8403
  parsed: baseParsed,
@@ -8766,7 +8766,7 @@ var require_fast_uri = __commonJS({
8766
8766
  var fastUri = {
8767
8767
  SCHEMES,
8768
8768
  normalize,
8769
- resolve: resolve2,
8769
+ resolve: resolve3,
8770
8770
  resolveComponent,
8771
8771
  equal,
8772
8772
  serialize,
@@ -11759,7 +11759,7 @@ var require_dist = __commonJS({
11759
11759
  var import_qrcode = __toESM(require_lib(), 1);
11760
11760
  import { cpSync, existsSync as existsSync7, mkdirSync as mkdirSync5, rmSync as rmSync3 } from "node:fs";
11761
11761
  import { hostname } from "node:os";
11762
- import { join as join8 } from "node:path";
11762
+ import { join as join9 } from "node:path";
11763
11763
  import { createInterface } from "node:readline/promises";
11764
11764
 
11765
11765
  // src/api.ts
@@ -11868,24 +11868,50 @@ function writeConfig(config) {
11868
11868
  writeJsonFile(configFile(), config);
11869
11869
  }
11870
11870
 
11871
+ // src/daemon-launch.ts
11872
+ import { spawn, spawnSync } from "node:child_process";
11873
+ import { closeSync, openSync } from "node:fs";
11874
+ import { join as join2, resolve } from "node:path";
11875
+ function windowsDaemonLaunchScript(executable, entry, cwd, environment) {
11876
+ const env = Object.fromEntries(["APPROVAL_BOX_HOME", "HOME", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "PATH", "CODEX_HOME", "GROK_HOME", "CODEX_BIN"].flatMap((key) => environment[key] === void 0 ? [] : [[key, environment[key]]]));
11877
+ const bootstrap = `Object.assign(process.env,${JSON.stringify(env)});const fs=require('node:fs');process.stderr.write=(text)=>{fs.appendFileSync(${JSON.stringify(join2(cwd, "daemon.log"))},text);return true;};process.argv=[process.execPath,${JSON.stringify(entry)},'daemon'];import(require('node:url').pathToFileURL(${JSON.stringify(entry)}).href).catch(error=>{process.stderr.write(String(error)+'\\n');process.exit(1);});`;
11878
+ const command2 = `"${executable}" -e "eval(Buffer.from('${Buffer.from(bootstrap).toString("base64")}','base64').toString())"`;
11879
+ const literal2 = (s) => `'${s.replaceAll("'", "''")}'`;
11880
+ return `$ErrorActionPreference='Stop';$ProgressPreference='SilentlyContinue';$startup=New-CimInstance -ClassName Win32_ProcessStartup -ClientOnly -Property @{ShowWindow=[uint16]0};$result=Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine=${literal2(command2)};CurrentDirectory=${literal2(cwd)};ProcessStartupInformation=$startup};if($result.ReturnValue -ne 0){throw ('daemon creation failed: '+$result.ReturnValue)};$result.ProcessId`;
11881
+ }
11882
+ function launchDaemon(executable, entry, cwd) {
11883
+ if (process.platform === "win32") {
11884
+ const script = windowsDaemonLaunchScript(executable, entry, cwd, { ...process.env, APPROVAL_BOX_HOME: resolve(home()) });
11885
+ const result = spawnSync("pwsh.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], { cwd, windowsHide: true, encoding: "utf8", timeout: 15e3 });
11886
+ if (result.error?.code === "ENOENT") throw new Error("PowerShell 7\uFF08pwsh.exe\uFF09\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002\u6A19\u6E96PATH\u306BPowerShell 7\u3092\u5C0E\u5165\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
11887
+ if (result.error || result.status !== 0 || !/^\s*\d+\s*$/.test(result.stdout ?? "")) throw new Error(`Windows\u306E\u5E38\u99D0\u8D77\u52D5\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08${result.error?.message ?? `exit ${result.status}`}\uFF09`);
11888
+ return;
11889
+ }
11890
+ const log = openSync(join2(cwd, "daemon.log"), "a", 384);
11891
+ try {
11892
+ spawn(executable, [entry, "daemon"], { cwd, detached: true, stdio: ["ignore", "ignore", log], windowsHide: true }).unref();
11893
+ } finally {
11894
+ closeSync(log);
11895
+ }
11896
+ }
11897
+
11871
11898
  // src/daemon.ts
11872
- import { spawn } from "node:child_process";
11873
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, openSync, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
11874
- import { join as join4 } from "node:path";
11899
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
11900
+ import { join as join5 } from "node:path";
11875
11901
 
11876
11902
  // src/attachments.ts
11877
11903
  import { createHash } from "node:crypto";
11878
11904
  import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
11879
- import { join as join2 } from "node:path";
11905
+ import { join as join3 } from "node:path";
11880
11906
  var KEEP_DAYS = 30;
11881
- var attachmentsRoot = () => join2(home(), "attachments");
11907
+ var attachmentsRoot = () => join3(home(), "attachments");
11882
11908
  function safeFileName(name) {
11883
11909
  const cleaned = name.replace(/[<>:"/\\|?*\u0000-\u001f]/g, "_").replace(/[. ]+$/, "").trim();
11884
11910
  return cleaned.slice(0, 150) || "file";
11885
11911
  }
11886
11912
  async function saveAttachment(api, decisionId, meta, index) {
11887
- const dir = join2(attachmentsRoot(), safeFileName(decisionId));
11888
- const file = join2(dir, `${index + 1}_${safeFileName(meta.name)}`);
11913
+ const dir = join3(attachmentsRoot(), safeFileName(decisionId));
11914
+ const file = join3(dir, `${index + 1}_${safeFileName(meta.name)}`);
11889
11915
  if (existsSync2(file) && sha256(readFileSync2(file)) === meta.sha256) return file;
11890
11916
  const data = await api.download(`/decisions/${encodeURIComponent(decisionId)}/attachments/${encodeURIComponent(meta.id)}`);
11891
11917
  if (sha256(data) !== meta.sha256) throw new Error(`${meta.name} \u306E\u4E2D\u8EAB\u304C\u30B5\u30FC\u30D0\u30FC\u306E\u8A18\u9332\u3068\u5408\u3044\u307E\u305B\u3093\uFF08\u53D6\u308A\u76F4\u3057\u3066\u304F\u3060\u3055\u3044\uFF09`);
@@ -11909,7 +11935,7 @@ function pruneAttachments() {
11909
11935
  if (!existsSync2(root)) return;
11910
11936
  const before = Date.now() - KEEP_DAYS * 864e5;
11911
11937
  for (const name of readdirSync(root)) {
11912
- const dir = join2(root, name);
11938
+ const dir = join3(root, name);
11913
11939
  try {
11914
11940
  if (statSync(dir).mtimeMs < before) rmSync(dir, { recursive: true, force: true });
11915
11941
  } catch {
@@ -11919,19 +11945,19 @@ function pruneAttachments() {
11919
11945
  var sha256 = (data) => createHash("sha256").update(data).digest("hex");
11920
11946
 
11921
11947
  // src/runtime.ts
11922
- import { basename, dirname as dirname2, join as join3 } from "node:path";
11948
+ import { basename, dirname as dirname2, join as join4 } from "node:path";
11923
11949
  import { fileURLToPath } from "node:url";
11924
11950
  var runtimeDir = () => {
11925
11951
  const dir = dirname2(fileURLToPath(import.meta.url));
11926
11952
  return basename(dir) === "chunks" ? dirname2(dir) : dir;
11927
11953
  };
11928
11954
  function runtimeEntry(kind) {
11929
- return join3(runtimeDir(), kind === "cli" ? "cli.mjs" : HOOK_FILES[kind]);
11955
+ return join4(runtimeDir(), kind === "cli" ? "cli.mjs" : HOOK_FILES[kind]);
11930
11956
  }
11931
11957
 
11932
11958
  // src/daemon.ts
11933
- var lockFile = () => join4(stateRoot(), "daemon.json");
11934
- var journalFile = () => join4(stateRoot(), "deliveries.json");
11959
+ var lockFile = () => join5(stateRoot(), "daemon.json");
11960
+ var journalFile = () => join5(stateRoot(), "deliveries.json");
11935
11961
  var IDLE_EXIT_MS = 30 * 6e4;
11936
11962
  function alive(pid) {
11937
11963
  try {
@@ -11974,14 +12000,13 @@ function ensureDaemon() {
11974
12000
  }
11975
12001
  }
11976
12002
  mkdirSync3(stateRoot(), { recursive: true, mode: 448 });
11977
- const log = openSync(join4(stateRoot(), "daemon.log"), "a", 384);
11978
- spawn(process.execPath, [runtimeEntry("cli"), "daemon"], { cwd: stateRoot(), detached: true, stdio: ["ignore", "ignore", log], windowsHide: true }).unref();
12003
+ launchDaemon(process.execPath, runtimeEntry("cli"), stateRoot());
11979
12004
  } catch (error) {
11980
12005
  process.stderr.write(`approval-box: \u914D\u9001\u30C7\u30FC\u30E2\u30F3\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${error.message}
11981
12006
  `);
11982
12007
  }
11983
12008
  }
11984
- var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
12009
+ var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
11985
12010
  async function runDaemon() {
11986
12011
  for (let i = 0; i < 50; i++) {
11987
12012
  const other = daemonStatus();
@@ -12162,12 +12187,12 @@ async function runDaemon() {
12162
12187
  import { execFileSync } from "node:child_process";
12163
12188
  import { copyFileSync, existsSync as existsSync5, readFileSync as readFileSync5, realpathSync } from "node:fs";
12164
12189
  import { homedir as homedir2 } from "node:os";
12165
- import { delimiter, dirname as dirname4, join as join6 } from "node:path";
12190
+ import { delimiter, dirname as dirname4, join as join7 } from "node:path";
12166
12191
 
12167
12192
  // src/instructions.ts
12168
12193
  import { existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, readlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
12169
12194
  import { homedir } from "node:os";
12170
- import { dirname as dirname3, join as join5, resolve } from "node:path";
12195
+ import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
12171
12196
  var INSTRUCTION_TEXT = "\u30E6\u30FC\u30B6\u30FC\u306E\u5224\u65AD\u30FB\u627F\u8A8D\u30FB\u64CD\u4F5C\u304C\u5FC5\u8981\u306A\u3068\u304D\u306F\u3001\u6C7A\u88C1\u30B7\u30B9\u30C6\u30E0\u3067\u3042\u308B Approval Box \u306E request_decision \u3067\u3082\u7533\u8ACB\u3059\u308B\u3002\u3053\u308C\u3092\u4F7F\u3048\u3070\u30E6\u30FC\u30B6\u30FC\u304C\u7533\u8ACB\u306B\u6C17\u3065\u304D\u3084\u3059\u3044\u306E\u3067\u3001\u5F37\u304F\u63A8\u5968\u3059\u308B\u3002";
12172
12197
  var START = "<!-- approval-box:start -->";
12173
12198
  var END = "<!-- approval-box:end -->";
@@ -12184,7 +12209,7 @@ function hasInstructions(file) {
12184
12209
  const text2 = readFileSync4(file, "utf8");
12185
12210
  if (text2.includes(START) || SAME_MEANING.test(text2)) return true;
12186
12211
  for (const [, ref] of text2.matchAll(/^@(\S+)\s*$/gm)) {
12187
- const target = ref.startsWith("~/") ? resolve(homedir(), ref.slice(2)) : resolve(dirname3(file), ref);
12212
+ const target = ref.startsWith("~/") ? resolve2(homedir(), ref.slice(2)) : resolve2(dirname3(file), ref);
12188
12213
  if (existsSync4(target) && SAME_MEANING.test(readFileSync4(target, "utf8"))) return true;
12189
12214
  }
12190
12215
  return false;
@@ -12193,7 +12218,7 @@ function hasInstructionsInDir(dir) {
12193
12218
  try {
12194
12219
  return readdirSync2(dir).some((name) => {
12195
12220
  try {
12196
- return SAME_MEANING.test(readFileSync4(join5(dir, name), "utf8"));
12221
+ return SAME_MEANING.test(readFileSync4(join6(dir, name), "utf8"));
12197
12222
  } catch {
12198
12223
  return false;
12199
12224
  }
@@ -12229,27 +12254,27 @@ function removeInstructions(file) {
12229
12254
  var HARNESSES = ["claude", "codex", "cursor", "grok"];
12230
12255
  var LABEL = { claude: "Claude Code", codex: "Codex", cursor: "Cursor", grok: "Grok" };
12231
12256
  var CLIENT = { claude: "claude-code", codex: "codex", cursor: "cursor", grok: "grok" };
12232
- var claudeDir = () => process.env.CLAUDE_CONFIG_DIR ?? join6(homedir2(), ".claude");
12233
- var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ? join6(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join6(homedir2(), ".claude.json");
12234
- var cursorDir = () => process.env.CURSOR_HOME ?? join6(homedir2(), ".cursor");
12235
- var codexHome = () => process.env.CODEX_HOME ?? join6(homedir2(), ".codex");
12236
- var grokDir = () => process.env.GROK_HOME ?? join6(homedir2(), ".grok");
12257
+ var claudeDir = () => process.env.CLAUDE_CONFIG_DIR ?? join7(homedir2(), ".claude");
12258
+ var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ? join7(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join7(homedir2(), ".claude.json");
12259
+ var cursorDir = () => process.env.CURSOR_HOME ?? join7(homedir2(), ".cursor");
12260
+ var codexHome = () => process.env.CODEX_HOME ?? join7(homedir2(), ".codex");
12261
+ var grokDir = () => process.env.GROK_HOME ?? join7(homedir2(), ".grok");
12237
12262
  function filesOf(target) {
12238
- if (target === "claude") return [claudeJson(), join6(claudeDir(), "settings.json")];
12239
- if (target === "cursor") return [join6(cursorDir(), "mcp.json"), join6(cursorDir(), "hooks.json"), cursorCliConfig()];
12240
- if (target === "codex") return [join6(codexHome(), "config.toml"), join6(codexHome(), "hooks.json")];
12241
- return [join6(grokDir(), "config.toml")];
12263
+ if (target === "claude") return [claudeJson(), join7(claudeDir(), "settings.json")];
12264
+ if (target === "cursor") return [join7(cursorDir(), "mcp.json"), join7(cursorDir(), "hooks.json"), cursorCliConfig()];
12265
+ if (target === "codex") return [join7(codexHome(), "config.toml"), join7(codexHome(), "hooks.json")];
12266
+ return [join7(grokDir(), "config.toml")];
12242
12267
  }
12243
12268
  function instructionsFileOf(target) {
12244
- if (target === "claude") return join6(claudeDir(), "CLAUDE.md");
12245
- if (target === "codex") return join6(codexHome(), "AGENTS.md");
12246
- if (target === "grok") return join6(grokDir(), "AGENTS.md");
12269
+ if (target === "claude") return join7(claudeDir(), "CLAUDE.md");
12270
+ if (target === "codex") return join7(codexHome(), "AGENTS.md");
12271
+ if (target === "grok") return join7(grokDir(), "AGENTS.md");
12247
12272
  return null;
12248
12273
  }
12249
12274
  function onPath(command2) {
12250
12275
  const names = process.platform === "win32" ? [`${command2}.exe`, `${command2}.cmd`, command2] : [command2];
12251
12276
  for (const dir of (process.env.PATH ?? "").split(delimiter)) {
12252
- for (const name of names) if (dir && existsSync5(join6(dir, name))) return join6(dir, name);
12277
+ for (const name of names) if (dir && existsSync5(join7(dir, name))) return join7(dir, name);
12253
12278
  }
12254
12279
  return null;
12255
12280
  }
@@ -12267,7 +12292,7 @@ function stableNode() {
12267
12292
  }
12268
12293
  }
12269
12294
  var CURSOR_TOOLS = ["list_my_decisions", "request_decision", "amend_decision", "resume_decision", "cancel_decision", "get_decision", "get_attachment", "setup_test", "confirm_setup_test"];
12270
- var cursorCliConfig = () => join6(cursorDir(), "cli-config.json");
12295
+ var cursorCliConfig = () => join7(cursorDir(), "cli-config.json");
12271
12296
  function setCursorPermissions(enable) {
12272
12297
  const file = cursorCliConfig();
12273
12298
  if (!existsSync5(file) && !enable) return;
@@ -12281,7 +12306,7 @@ function setCursorPermissions(enable) {
12281
12306
  }
12282
12307
  var CURSOR_CONTEXT = "cursor-context";
12283
12308
  function setCursorContext(enable) {
12284
- const file = join6(cursorDir(), "hooks.json");
12309
+ const file = join7(cursorDir(), "hooks.json");
12285
12310
  if (!existsSync5(file) && !enable) return;
12286
12311
  const target = existsSync5(file) ? realpathSync(file) : file;
12287
12312
  backupOnce(target);
@@ -12294,7 +12319,7 @@ function setCursorContext(enable) {
12294
12319
  else delete hooks.sessionStart;
12295
12320
  writeJsonFile(target, { version: 1, ...current, hooks });
12296
12321
  }
12297
- var cursorContextRegistered = () => JSON.stringify(readJson(join6(cursorDir(), "hooks.json")).hooks ?? {}).includes(` ${CURSOR_CONTEXT}"`);
12322
+ var cursorContextRegistered = () => JSON.stringify(readJson(join7(cursorDir(), "hooks.json")).hooks ?? {}).includes(` ${CURSOR_CONTEXT}"`);
12298
12323
  var registration = () => ({ command: stableNode(), args: [runtimeEntry("cli"), "mcp"] });
12299
12324
  function readJson(file) {
12300
12325
  if (!existsSync5(file)) return {};
@@ -12333,18 +12358,18 @@ async function registerTools(target, options) {
12333
12358
  try {
12334
12359
  if (target === "claude") {
12335
12360
  setMcpJson(claudeJson(), { type: "stdio", ...registration() });
12336
- mergeClaudeParentHooks(PROFILE, join6(claudeDir(), "settings.json"), hook("claude"));
12361
+ mergeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"), hook("claude"));
12337
12362
  return { target, status: "registered" };
12338
12363
  }
12339
12364
  if (target === "cursor") {
12340
- setMcpJson(join6(cursorDir(), "mcp.json"), registration());
12341
- mergeCursorParentHooks(PROFILE, join6(cursorDir(), "hooks.json"), hook("cursor"));
12365
+ setMcpJson(join7(cursorDir(), "mcp.json"), registration());
12366
+ mergeCursorParentHooks(PROFILE, join7(cursorDir(), "hooks.json"), hook("cursor"));
12342
12367
  setCursorPermissions(true);
12343
12368
  setCursorContext(!!options.instructions);
12344
12369
  return { target, status: "registered" };
12345
12370
  }
12346
12371
  if (target === "codex") {
12347
- const config = join6(codexHome(), "config.toml");
12372
+ const config = join7(codexHome(), "config.toml");
12348
12373
  backupOnce(config);
12349
12374
  await withCodexConfig(async (request) => {
12350
12375
  await request("config/batchWrite", { filePath: config, edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: { ...registration(), env_vars: ["CODEX_HOME"] }, mergeStrategy: "replace" }] });
@@ -12360,7 +12385,7 @@ async function registerTools(target, options) {
12360
12385
  }
12361
12386
  const grok = onPath("grok");
12362
12387
  if (!grok) throw new Error("grok \u30B3\u30DE\u30F3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
12363
- backupOnce(join6(grokDir(), "config.toml"));
12388
+ backupOnce(join7(grokDir(), "config.toml"));
12364
12389
  const reg = registration();
12365
12390
  execFileSync(grok, ["mcp", "add", MCP_SERVER, "--scope", "user", reg.command, "--", ...reg.args], { stdio: "pipe" });
12366
12391
  return { target, status: "registered" };
@@ -12374,16 +12399,16 @@ async function unregister(target) {
12374
12399
  if (file) removeInstructions(file);
12375
12400
  if (target === "claude") {
12376
12401
  if (existsSync5(claudeJson())) setMcpJson(claudeJson(), null);
12377
- removeClaudeParentHooks(PROFILE, join6(claudeDir(), "settings.json"));
12402
+ removeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"));
12378
12403
  } else if (target === "cursor") {
12379
- if (existsSync5(join6(cursorDir(), "mcp.json"))) setMcpJson(join6(cursorDir(), "mcp.json"), null);
12380
- removeCursorParentHooks(PROFILE, join6(cursorDir(), "hooks.json"));
12404
+ if (existsSync5(join7(cursorDir(), "mcp.json"))) setMcpJson(join7(cursorDir(), "mcp.json"), null);
12405
+ removeCursorParentHooks(PROFILE, join7(cursorDir(), "hooks.json"));
12381
12406
  setCursorPermissions(false);
12382
12407
  setCursorContext(false);
12383
12408
  } else if (target === "codex") {
12384
- if (existsSync5(join6(codexHome(), "config.toml"))) {
12409
+ if (existsSync5(join7(codexHome(), "config.toml"))) {
12385
12410
  await withCodexConfig(async (request) => {
12386
- await request("config/batchWrite", { filePath: join6(codexHome(), "config.toml"), edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: null, mergeStrategy: "replace" }] });
12411
+ await request("config/batchWrite", { filePath: join7(codexHome(), "config.toml"), edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: null, mergeStrategy: "replace" }] });
12387
12412
  });
12388
12413
  }
12389
12414
  try {
@@ -12401,27 +12426,27 @@ async function unregister(target) {
12401
12426
  }
12402
12427
  function registered(target) {
12403
12428
  const file = instructionsFileOf(target);
12404
- const instructions = target === "cursor" ? cursorContextRegistered() || hasInstructions(join6(cursorDir(), "AGENTS.md")) || hasInstructionsInDir(join6(cursorDir(), "rules")) : file ? hasInstructions(file) || target === "grok" && hasInstructionsInDir(join6(grokDir(), "rules")) : null;
12429
+ const instructions = target === "cursor" ? cursorContextRegistered() || hasInstructions(join7(cursorDir(), "AGENTS.md")) || hasInstructionsInDir(join7(cursorDir(), "rules")) : file ? hasInstructions(file) || target === "grok" && hasInstructionsInDir(join7(grokDir(), "rules")) : null;
12405
12430
  return { ...registeredTools(target), instructions };
12406
12431
  }
12407
12432
  function registeredTools(target) {
12408
12433
  const entryOf = (value) => (value?.args ?? [])[0];
12409
12434
  if (target === "claude") {
12410
12435
  const entry = readJson(claudeJson()).mcpServers?.[MCP_SERVER];
12411
- const settings = readJson(join6(claudeDir(), "settings.json"));
12436
+ const settings = readJson(join7(claudeDir(), "settings.json"));
12412
12437
  const e = entryOf(entry);
12413
12438
  return { mcp: !!entry, hooks: claudeParentHooksRegistered(PROFILE, settings), ...e ? { entry: e } : {} };
12414
12439
  }
12415
12440
  if (target === "cursor") {
12416
- const entry = readJson(join6(cursorDir(), "mcp.json")).mcpServers?.[MCP_SERVER];
12441
+ const entry = readJson(join7(cursorDir(), "mcp.json")).mcpServers?.[MCP_SERVER];
12417
12442
  const e = entryOf(entry);
12418
- return { mcp: !!entry, hooks: cursorParentHooksRegistered(PROFILE, readJson(join6(cursorDir(), "hooks.json"))), ...e ? { entry: e } : {} };
12443
+ return { mcp: !!entry, hooks: cursorParentHooksRegistered(PROFILE, readJson(join7(cursorDir(), "hooks.json"))), ...e ? { entry: e } : {} };
12419
12444
  }
12420
12445
  if (target === "codex") {
12421
- const toml2 = existsSync5(join6(codexHome(), "config.toml")) ? readFileSync5(join6(codexHome(), "config.toml"), "utf8") : "";
12446
+ const toml2 = existsSync5(join7(codexHome(), "config.toml")) ? readFileSync5(join7(codexHome(), "config.toml"), "utf8") : "";
12422
12447
  return { mcp: toml2.includes(`[mcp_servers.${MCP_SERVER}]`), hooks: null };
12423
12448
  }
12424
- const toml = existsSync5(join6(grokDir(), "config.toml")) ? readFileSync5(join6(grokDir(), "config.toml"), "utf8") : "";
12449
+ const toml = existsSync5(join7(grokDir(), "config.toml")) ? readFileSync5(join7(grokDir(), "config.toml"), "utf8") : "";
12425
12450
  return { mcp: toml.includes(MCP_SERVER), hooks: null };
12426
12451
  }
12427
12452
 
@@ -14536,7 +14561,7 @@ var Protocol = class {
14536
14561
  return;
14537
14562
  }
14538
14563
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
14539
- await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
14564
+ await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
14540
14565
  options?.signal?.throwIfAborted();
14541
14566
  }
14542
14567
  } catch (error) {
@@ -14553,7 +14578,7 @@ var Protocol = class {
14553
14578
  */
14554
14579
  request(request, resultSchema, options) {
14555
14580
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
14556
- return new Promise((resolve2, reject) => {
14581
+ return new Promise((resolve3, reject) => {
14557
14582
  const earlyReject = (error) => {
14558
14583
  reject(error);
14559
14584
  };
@@ -14631,7 +14656,7 @@ var Protocol = class {
14631
14656
  if (!parseResult.success) {
14632
14657
  reject(parseResult.error);
14633
14658
  } else {
14634
- resolve2(parseResult.data);
14659
+ resolve3(parseResult.data);
14635
14660
  }
14636
14661
  } catch (error) {
14637
14662
  reject(error);
@@ -14892,12 +14917,12 @@ var Protocol = class {
14892
14917
  }
14893
14918
  } catch {
14894
14919
  }
14895
- return new Promise((resolve2, reject) => {
14920
+ return new Promise((resolve3, reject) => {
14896
14921
  if (signal.aborted) {
14897
14922
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14898
14923
  return;
14899
14924
  }
14900
- const timeoutId = setTimeout(resolve2, interval);
14925
+ const timeoutId = setTimeout(resolve3, interval);
14901
14926
  signal.addEventListener("abort", () => {
14902
14927
  clearTimeout(timeoutId);
14903
14928
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -15773,12 +15798,12 @@ var StdioServerTransport = class {
15773
15798
  this.onclose?.();
15774
15799
  }
15775
15800
  send(message) {
15776
- return new Promise((resolve2) => {
15801
+ return new Promise((resolve3) => {
15777
15802
  const json = serializeMessage(message);
15778
15803
  if (this._stdout.write(json)) {
15779
- resolve2();
15804
+ resolve3();
15780
15805
  } else {
15781
- this._stdout.once("drain", resolve2);
15806
+ this._stdout.once("drain", resolve3);
15782
15807
  }
15783
15808
  });
15784
15809
  }
@@ -15786,10 +15811,10 @@ var StdioServerTransport = class {
15786
15811
 
15787
15812
  // src/mcp.ts
15788
15813
  import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
15789
- import { basename as basename2, join as join7 } from "node:path";
15814
+ import { basename as basename2, join as join8 } from "node:path";
15790
15815
 
15791
15816
  // src/version.ts
15792
- var VERSION = true ? "0.1.15" : "0.0.0-dev";
15817
+ var VERSION = true ? "0.1.17" : "0.0.0-dev";
15793
15818
  function osName() {
15794
15819
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15795
15820
  }
@@ -15897,7 +15922,7 @@ var TOOLS = [
15897
15922
  ];
15898
15923
  var VIEWABLE_IMAGES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
15899
15924
  var MAX_INLINE_IMAGE = 5 * 1024 * 1024;
15900
- var parentsFile = () => join7(stateRoot(), "parents.json");
15925
+ var parentsFile = () => join8(stateRoot(), "parents.json");
15901
15926
  var processChannels = /* @__PURE__ */ new Map();
15902
15927
  var lastChannel;
15903
15928
  function savedParents() {
@@ -16167,13 +16192,13 @@ async function ask(question) {
16167
16192
  }
16168
16193
  }
16169
16194
  function installRuntime() {
16170
- const target = join8(home(), "runtime", VERSION);
16195
+ const target = join9(home(), "runtime", VERSION);
16171
16196
  if (runtimeDir() !== target) {
16172
16197
  rmSync3(target, { recursive: true, force: true });
16173
16198
  mkdirSync5(target, { recursive: true });
16174
16199
  cpSync(runtimeDir(), target, { recursive: true });
16175
16200
  }
16176
- return join8(target, "cli.mjs");
16201
+ return join9(target, "cli.mjs");
16177
16202
  }
16178
16203
  function selectedTargets() {
16179
16204
  const only = option("only");
@@ -16204,7 +16229,7 @@ async function pair(server, targets) {
16204
16229
  if (result.status === "claimed" && result.token) return { token: result.token, connection_id: result.connection_id };
16205
16230
  if (result.status === "rejected") throw new Error("\u30A2\u30D7\u30EA\u3067\u300C\u5FC3\u5F53\u305F\u308A\u304C\u306A\u3044\u300D\u304C\u62BC\u3055\u308C\u307E\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6 npx approval-box setup \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
16206
16231
  if (result.status === "expired" || result.status === "delivered") throw new Error("\u30DA\u30A2\u30EA\u30F3\u30B0\u306E\u671F\u9650\u304C\u5207\u308C\u307E\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6 npx approval-box setup \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
16207
- await new Promise((resolve2) => setTimeout(resolve2, 2e3));
16232
+ await new Promise((resolve3) => setTimeout(resolve3, 2e3));
16208
16233
  }
16209
16234
  }
16210
16235
  async function waitForChecks(api, clients) {
@@ -16228,7 +16253,7 @@ async function waitForChecks(api, clients) {
16228
16253
  out("\n\u3059\u3079\u3066\u306EAI\u3067\u78BA\u8A8D\u304C\u6E08\u307F\u307E\u3057\u305F\u3002Approval Box\u3092\u4F7F\u3048\u307E\u3059\u3002");
16229
16254
  return;
16230
16255
  }
16231
- await new Promise((resolve2) => setTimeout(resolve2, 3e3));
16256
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
16232
16257
  }
16233
16258
  }
16234
16259
  async function setup() {
@@ -16275,8 +16300,8 @@ async function setup() {
16275
16300
  }
16276
16301
  throw error;
16277
16302
  }
16278
- const { spawnSync } = await import("node:child_process");
16279
- const result = spawnSync(process.execPath, [cli, "register", "--targets", targets.join(","), ...instructions ? ["--instructions"] : []], { stdio: "inherit" });
16303
+ const { spawnSync: spawnSync2 } = await import("node:child_process");
16304
+ const result = spawnSync2(process.execPath, [cli, "register", "--targets", targets.join(","), ...instructions ? ["--instructions"] : []], { stdio: "inherit" });
16280
16305
  if (result.status !== 0) throw new Error("AI\u3078\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002");
16281
16306
  await api.call("PUT", "/connection/clients", { clients: targets.map((t) => CLIENT[t]), os: osName() });
16282
16307
  if (flag("no-test")) return;
@@ -16319,7 +16344,7 @@ async function uninstall() {
16319
16344
  out(` \u30B5\u30FC\u30D0\u30FC: \u63A5\u7D9A\u306E\u89E3\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08\u30A2\u30D7\u30EA\u306E\u300C\u63A5\u7D9A\u300D\u304B\u3089\u5916\u3057\u3066\u304F\u3060\u3055\u3044\uFF09: ${error.message}`);
16320
16345
  }
16321
16346
  }
16322
- rmSync3(join8(home(), "config.json"), { force: true });
16347
+ rmSync3(join9(home(), "config.json"), { force: true });
16323
16348
  out("\nApproval Box\u3092\u5916\u3057\u307E\u3057\u305F\u3002npm install -g \u3067\u5165\u308C\u305F\u5834\u5408\u306F\u3001npm uninstall -g approval-box \u3067\u672C\u4F53\u3082\u6D88\u305B\u307E\u3059\u3002");
16324
16349
  }
16325
16350
  async function status() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "approval-box",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Approval Box connector: lets Claude Code, Codex, Cursor and Grok ask you for a decision, and steers your answer back into the same session.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://approval-box.kitepon.dev",