approval-box 0.1.15 → 0.1.16

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 +102 -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,49 @@ 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("powershell.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], { cwd, windowsHide: true, encoding: "utf8", timeout: 15e3 });
11886
+ 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`);
11887
+ return;
11888
+ }
11889
+ const log = openSync(join2(cwd, "daemon.log"), "a", 384);
11890
+ try {
11891
+ spawn(executable, [entry, "daemon"], { cwd, detached: true, stdio: ["ignore", "ignore", log], windowsHide: true }).unref();
11892
+ } finally {
11893
+ closeSync(log);
11894
+ }
11895
+ }
11896
+
11871
11897
  // 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";
11898
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
11899
+ import { join as join5 } from "node:path";
11875
11900
 
11876
11901
  // src/attachments.ts
11877
11902
  import { createHash } from "node:crypto";
11878
11903
  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";
11904
+ import { join as join3 } from "node:path";
11880
11905
  var KEEP_DAYS = 30;
11881
- var attachmentsRoot = () => join2(home(), "attachments");
11906
+ var attachmentsRoot = () => join3(home(), "attachments");
11882
11907
  function safeFileName(name) {
11883
11908
  const cleaned = name.replace(/[<>:"/\\|?*\u0000-\u001f]/g, "_").replace(/[. ]+$/, "").trim();
11884
11909
  return cleaned.slice(0, 150) || "file";
11885
11910
  }
11886
11911
  async function saveAttachment(api, decisionId, meta, index) {
11887
- const dir = join2(attachmentsRoot(), safeFileName(decisionId));
11888
- const file = join2(dir, `${index + 1}_${safeFileName(meta.name)}`);
11912
+ const dir = join3(attachmentsRoot(), safeFileName(decisionId));
11913
+ const file = join3(dir, `${index + 1}_${safeFileName(meta.name)}`);
11889
11914
  if (existsSync2(file) && sha256(readFileSync2(file)) === meta.sha256) return file;
11890
11915
  const data = await api.download(`/decisions/${encodeURIComponent(decisionId)}/attachments/${encodeURIComponent(meta.id)}`);
11891
11916
  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 +11934,7 @@ function pruneAttachments() {
11909
11934
  if (!existsSync2(root)) return;
11910
11935
  const before = Date.now() - KEEP_DAYS * 864e5;
11911
11936
  for (const name of readdirSync(root)) {
11912
- const dir = join2(root, name);
11937
+ const dir = join3(root, name);
11913
11938
  try {
11914
11939
  if (statSync(dir).mtimeMs < before) rmSync(dir, { recursive: true, force: true });
11915
11940
  } catch {
@@ -11919,19 +11944,19 @@ function pruneAttachments() {
11919
11944
  var sha256 = (data) => createHash("sha256").update(data).digest("hex");
11920
11945
 
11921
11946
  // src/runtime.ts
11922
- import { basename, dirname as dirname2, join as join3 } from "node:path";
11947
+ import { basename, dirname as dirname2, join as join4 } from "node:path";
11923
11948
  import { fileURLToPath } from "node:url";
11924
11949
  var runtimeDir = () => {
11925
11950
  const dir = dirname2(fileURLToPath(import.meta.url));
11926
11951
  return basename(dir) === "chunks" ? dirname2(dir) : dir;
11927
11952
  };
11928
11953
  function runtimeEntry(kind) {
11929
- return join3(runtimeDir(), kind === "cli" ? "cli.mjs" : HOOK_FILES[kind]);
11954
+ return join4(runtimeDir(), kind === "cli" ? "cli.mjs" : HOOK_FILES[kind]);
11930
11955
  }
11931
11956
 
11932
11957
  // src/daemon.ts
11933
- var lockFile = () => join4(stateRoot(), "daemon.json");
11934
- var journalFile = () => join4(stateRoot(), "deliveries.json");
11958
+ var lockFile = () => join5(stateRoot(), "daemon.json");
11959
+ var journalFile = () => join5(stateRoot(), "deliveries.json");
11935
11960
  var IDLE_EXIT_MS = 30 * 6e4;
11936
11961
  function alive(pid) {
11937
11962
  try {
@@ -11974,14 +11999,13 @@ function ensureDaemon() {
11974
11999
  }
11975
12000
  }
11976
12001
  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();
12002
+ launchDaemon(process.execPath, runtimeEntry("cli"), stateRoot());
11979
12003
  } catch (error) {
11980
12004
  process.stderr.write(`approval-box: \u914D\u9001\u30C7\u30FC\u30E2\u30F3\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093: ${error.message}
11981
12005
  `);
11982
12006
  }
11983
12007
  }
11984
- var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
12008
+ var sleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
11985
12009
  async function runDaemon() {
11986
12010
  for (let i = 0; i < 50; i++) {
11987
12011
  const other = daemonStatus();
@@ -12162,12 +12186,12 @@ async function runDaemon() {
12162
12186
  import { execFileSync } from "node:child_process";
12163
12187
  import { copyFileSync, existsSync as existsSync5, readFileSync as readFileSync5, realpathSync } from "node:fs";
12164
12188
  import { homedir as homedir2 } from "node:os";
12165
- import { delimiter, dirname as dirname4, join as join6 } from "node:path";
12189
+ import { delimiter, dirname as dirname4, join as join7 } from "node:path";
12166
12190
 
12167
12191
  // src/instructions.ts
12168
12192
  import { existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, readlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
12169
12193
  import { homedir } from "node:os";
12170
- import { dirname as dirname3, join as join5, resolve } from "node:path";
12194
+ import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
12171
12195
  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
12196
  var START = "<!-- approval-box:start -->";
12173
12197
  var END = "<!-- approval-box:end -->";
@@ -12184,7 +12208,7 @@ function hasInstructions(file) {
12184
12208
  const text2 = readFileSync4(file, "utf8");
12185
12209
  if (text2.includes(START) || SAME_MEANING.test(text2)) return true;
12186
12210
  for (const [, ref] of text2.matchAll(/^@(\S+)\s*$/gm)) {
12187
- const target = ref.startsWith("~/") ? resolve(homedir(), ref.slice(2)) : resolve(dirname3(file), ref);
12211
+ const target = ref.startsWith("~/") ? resolve2(homedir(), ref.slice(2)) : resolve2(dirname3(file), ref);
12188
12212
  if (existsSync4(target) && SAME_MEANING.test(readFileSync4(target, "utf8"))) return true;
12189
12213
  }
12190
12214
  return false;
@@ -12193,7 +12217,7 @@ function hasInstructionsInDir(dir) {
12193
12217
  try {
12194
12218
  return readdirSync2(dir).some((name) => {
12195
12219
  try {
12196
- return SAME_MEANING.test(readFileSync4(join5(dir, name), "utf8"));
12220
+ return SAME_MEANING.test(readFileSync4(join6(dir, name), "utf8"));
12197
12221
  } catch {
12198
12222
  return false;
12199
12223
  }
@@ -12229,27 +12253,27 @@ function removeInstructions(file) {
12229
12253
  var HARNESSES = ["claude", "codex", "cursor", "grok"];
12230
12254
  var LABEL = { claude: "Claude Code", codex: "Codex", cursor: "Cursor", grok: "Grok" };
12231
12255
  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");
12256
+ var claudeDir = () => process.env.CLAUDE_CONFIG_DIR ?? join7(homedir2(), ".claude");
12257
+ var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ? join7(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join7(homedir2(), ".claude.json");
12258
+ var cursorDir = () => process.env.CURSOR_HOME ?? join7(homedir2(), ".cursor");
12259
+ var codexHome = () => process.env.CODEX_HOME ?? join7(homedir2(), ".codex");
12260
+ var grokDir = () => process.env.GROK_HOME ?? join7(homedir2(), ".grok");
12237
12261
  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")];
12262
+ if (target === "claude") return [claudeJson(), join7(claudeDir(), "settings.json")];
12263
+ if (target === "cursor") return [join7(cursorDir(), "mcp.json"), join7(cursorDir(), "hooks.json"), cursorCliConfig()];
12264
+ if (target === "codex") return [join7(codexHome(), "config.toml"), join7(codexHome(), "hooks.json")];
12265
+ return [join7(grokDir(), "config.toml")];
12242
12266
  }
12243
12267
  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");
12268
+ if (target === "claude") return join7(claudeDir(), "CLAUDE.md");
12269
+ if (target === "codex") return join7(codexHome(), "AGENTS.md");
12270
+ if (target === "grok") return join7(grokDir(), "AGENTS.md");
12247
12271
  return null;
12248
12272
  }
12249
12273
  function onPath(command2) {
12250
12274
  const names = process.platform === "win32" ? [`${command2}.exe`, `${command2}.cmd`, command2] : [command2];
12251
12275
  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);
12276
+ for (const name of names) if (dir && existsSync5(join7(dir, name))) return join7(dir, name);
12253
12277
  }
12254
12278
  return null;
12255
12279
  }
@@ -12267,7 +12291,7 @@ function stableNode() {
12267
12291
  }
12268
12292
  }
12269
12293
  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");
12294
+ var cursorCliConfig = () => join7(cursorDir(), "cli-config.json");
12271
12295
  function setCursorPermissions(enable) {
12272
12296
  const file = cursorCliConfig();
12273
12297
  if (!existsSync5(file) && !enable) return;
@@ -12281,7 +12305,7 @@ function setCursorPermissions(enable) {
12281
12305
  }
12282
12306
  var CURSOR_CONTEXT = "cursor-context";
12283
12307
  function setCursorContext(enable) {
12284
- const file = join6(cursorDir(), "hooks.json");
12308
+ const file = join7(cursorDir(), "hooks.json");
12285
12309
  if (!existsSync5(file) && !enable) return;
12286
12310
  const target = existsSync5(file) ? realpathSync(file) : file;
12287
12311
  backupOnce(target);
@@ -12294,7 +12318,7 @@ function setCursorContext(enable) {
12294
12318
  else delete hooks.sessionStart;
12295
12319
  writeJsonFile(target, { version: 1, ...current, hooks });
12296
12320
  }
12297
- var cursorContextRegistered = () => JSON.stringify(readJson(join6(cursorDir(), "hooks.json")).hooks ?? {}).includes(` ${CURSOR_CONTEXT}"`);
12321
+ var cursorContextRegistered = () => JSON.stringify(readJson(join7(cursorDir(), "hooks.json")).hooks ?? {}).includes(` ${CURSOR_CONTEXT}"`);
12298
12322
  var registration = () => ({ command: stableNode(), args: [runtimeEntry("cli"), "mcp"] });
12299
12323
  function readJson(file) {
12300
12324
  if (!existsSync5(file)) return {};
@@ -12333,18 +12357,18 @@ async function registerTools(target, options) {
12333
12357
  try {
12334
12358
  if (target === "claude") {
12335
12359
  setMcpJson(claudeJson(), { type: "stdio", ...registration() });
12336
- mergeClaudeParentHooks(PROFILE, join6(claudeDir(), "settings.json"), hook("claude"));
12360
+ mergeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"), hook("claude"));
12337
12361
  return { target, status: "registered" };
12338
12362
  }
12339
12363
  if (target === "cursor") {
12340
- setMcpJson(join6(cursorDir(), "mcp.json"), registration());
12341
- mergeCursorParentHooks(PROFILE, join6(cursorDir(), "hooks.json"), hook("cursor"));
12364
+ setMcpJson(join7(cursorDir(), "mcp.json"), registration());
12365
+ mergeCursorParentHooks(PROFILE, join7(cursorDir(), "hooks.json"), hook("cursor"));
12342
12366
  setCursorPermissions(true);
12343
12367
  setCursorContext(!!options.instructions);
12344
12368
  return { target, status: "registered" };
12345
12369
  }
12346
12370
  if (target === "codex") {
12347
- const config = join6(codexHome(), "config.toml");
12371
+ const config = join7(codexHome(), "config.toml");
12348
12372
  backupOnce(config);
12349
12373
  await withCodexConfig(async (request) => {
12350
12374
  await request("config/batchWrite", { filePath: config, edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: { ...registration(), env_vars: ["CODEX_HOME"] }, mergeStrategy: "replace" }] });
@@ -12360,7 +12384,7 @@ async function registerTools(target, options) {
12360
12384
  }
12361
12385
  const grok = onPath("grok");
12362
12386
  if (!grok) throw new Error("grok \u30B3\u30DE\u30F3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
12363
- backupOnce(join6(grokDir(), "config.toml"));
12387
+ backupOnce(join7(grokDir(), "config.toml"));
12364
12388
  const reg = registration();
12365
12389
  execFileSync(grok, ["mcp", "add", MCP_SERVER, "--scope", "user", reg.command, "--", ...reg.args], { stdio: "pipe" });
12366
12390
  return { target, status: "registered" };
@@ -12374,16 +12398,16 @@ async function unregister(target) {
12374
12398
  if (file) removeInstructions(file);
12375
12399
  if (target === "claude") {
12376
12400
  if (existsSync5(claudeJson())) setMcpJson(claudeJson(), null);
12377
- removeClaudeParentHooks(PROFILE, join6(claudeDir(), "settings.json"));
12401
+ removeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"));
12378
12402
  } else if (target === "cursor") {
12379
- if (existsSync5(join6(cursorDir(), "mcp.json"))) setMcpJson(join6(cursorDir(), "mcp.json"), null);
12380
- removeCursorParentHooks(PROFILE, join6(cursorDir(), "hooks.json"));
12403
+ if (existsSync5(join7(cursorDir(), "mcp.json"))) setMcpJson(join7(cursorDir(), "mcp.json"), null);
12404
+ removeCursorParentHooks(PROFILE, join7(cursorDir(), "hooks.json"));
12381
12405
  setCursorPermissions(false);
12382
12406
  setCursorContext(false);
12383
12407
  } else if (target === "codex") {
12384
- if (existsSync5(join6(codexHome(), "config.toml"))) {
12408
+ if (existsSync5(join7(codexHome(), "config.toml"))) {
12385
12409
  await withCodexConfig(async (request) => {
12386
- await request("config/batchWrite", { filePath: join6(codexHome(), "config.toml"), edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: null, mergeStrategy: "replace" }] });
12410
+ await request("config/batchWrite", { filePath: join7(codexHome(), "config.toml"), edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: null, mergeStrategy: "replace" }] });
12387
12411
  });
12388
12412
  }
12389
12413
  try {
@@ -12401,27 +12425,27 @@ async function unregister(target) {
12401
12425
  }
12402
12426
  function registered(target) {
12403
12427
  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;
12428
+ 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
12429
  return { ...registeredTools(target), instructions };
12406
12430
  }
12407
12431
  function registeredTools(target) {
12408
12432
  const entryOf = (value) => (value?.args ?? [])[0];
12409
12433
  if (target === "claude") {
12410
12434
  const entry = readJson(claudeJson()).mcpServers?.[MCP_SERVER];
12411
- const settings = readJson(join6(claudeDir(), "settings.json"));
12435
+ const settings = readJson(join7(claudeDir(), "settings.json"));
12412
12436
  const e = entryOf(entry);
12413
12437
  return { mcp: !!entry, hooks: claudeParentHooksRegistered(PROFILE, settings), ...e ? { entry: e } : {} };
12414
12438
  }
12415
12439
  if (target === "cursor") {
12416
- const entry = readJson(join6(cursorDir(), "mcp.json")).mcpServers?.[MCP_SERVER];
12440
+ const entry = readJson(join7(cursorDir(), "mcp.json")).mcpServers?.[MCP_SERVER];
12417
12441
  const e = entryOf(entry);
12418
- return { mcp: !!entry, hooks: cursorParentHooksRegistered(PROFILE, readJson(join6(cursorDir(), "hooks.json"))), ...e ? { entry: e } : {} };
12442
+ return { mcp: !!entry, hooks: cursorParentHooksRegistered(PROFILE, readJson(join7(cursorDir(), "hooks.json"))), ...e ? { entry: e } : {} };
12419
12443
  }
12420
12444
  if (target === "codex") {
12421
- const toml2 = existsSync5(join6(codexHome(), "config.toml")) ? readFileSync5(join6(codexHome(), "config.toml"), "utf8") : "";
12445
+ const toml2 = existsSync5(join7(codexHome(), "config.toml")) ? readFileSync5(join7(codexHome(), "config.toml"), "utf8") : "";
12422
12446
  return { mcp: toml2.includes(`[mcp_servers.${MCP_SERVER}]`), hooks: null };
12423
12447
  }
12424
- const toml = existsSync5(join6(grokDir(), "config.toml")) ? readFileSync5(join6(grokDir(), "config.toml"), "utf8") : "";
12448
+ const toml = existsSync5(join7(grokDir(), "config.toml")) ? readFileSync5(join7(grokDir(), "config.toml"), "utf8") : "";
12425
12449
  return { mcp: toml.includes(MCP_SERVER), hooks: null };
12426
12450
  }
12427
12451
 
@@ -14536,7 +14560,7 @@ var Protocol = class {
14536
14560
  return;
14537
14561
  }
14538
14562
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
14539
- await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
14563
+ await new Promise((resolve3) => setTimeout(resolve3, pollInterval));
14540
14564
  options?.signal?.throwIfAborted();
14541
14565
  }
14542
14566
  } catch (error) {
@@ -14553,7 +14577,7 @@ var Protocol = class {
14553
14577
  */
14554
14578
  request(request, resultSchema, options) {
14555
14579
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
14556
- return new Promise((resolve2, reject) => {
14580
+ return new Promise((resolve3, reject) => {
14557
14581
  const earlyReject = (error) => {
14558
14582
  reject(error);
14559
14583
  };
@@ -14631,7 +14655,7 @@ var Protocol = class {
14631
14655
  if (!parseResult.success) {
14632
14656
  reject(parseResult.error);
14633
14657
  } else {
14634
- resolve2(parseResult.data);
14658
+ resolve3(parseResult.data);
14635
14659
  }
14636
14660
  } catch (error) {
14637
14661
  reject(error);
@@ -14892,12 +14916,12 @@ var Protocol = class {
14892
14916
  }
14893
14917
  } catch {
14894
14918
  }
14895
- return new Promise((resolve2, reject) => {
14919
+ return new Promise((resolve3, reject) => {
14896
14920
  if (signal.aborted) {
14897
14921
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
14898
14922
  return;
14899
14923
  }
14900
- const timeoutId = setTimeout(resolve2, interval);
14924
+ const timeoutId = setTimeout(resolve3, interval);
14901
14925
  signal.addEventListener("abort", () => {
14902
14926
  clearTimeout(timeoutId);
14903
14927
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -15773,12 +15797,12 @@ var StdioServerTransport = class {
15773
15797
  this.onclose?.();
15774
15798
  }
15775
15799
  send(message) {
15776
- return new Promise((resolve2) => {
15800
+ return new Promise((resolve3) => {
15777
15801
  const json = serializeMessage(message);
15778
15802
  if (this._stdout.write(json)) {
15779
- resolve2();
15803
+ resolve3();
15780
15804
  } else {
15781
- this._stdout.once("drain", resolve2);
15805
+ this._stdout.once("drain", resolve3);
15782
15806
  }
15783
15807
  });
15784
15808
  }
@@ -15786,10 +15810,10 @@ var StdioServerTransport = class {
15786
15810
 
15787
15811
  // src/mcp.ts
15788
15812
  import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:fs";
15789
- import { basename as basename2, join as join7 } from "node:path";
15813
+ import { basename as basename2, join as join8 } from "node:path";
15790
15814
 
15791
15815
  // src/version.ts
15792
- var VERSION = true ? "0.1.15" : "0.0.0-dev";
15816
+ var VERSION = true ? "0.1.16" : "0.0.0-dev";
15793
15817
  function osName() {
15794
15818
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15795
15819
  }
@@ -15897,7 +15921,7 @@ var TOOLS = [
15897
15921
  ];
15898
15922
  var VIEWABLE_IMAGES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
15899
15923
  var MAX_INLINE_IMAGE = 5 * 1024 * 1024;
15900
- var parentsFile = () => join7(stateRoot(), "parents.json");
15924
+ var parentsFile = () => join8(stateRoot(), "parents.json");
15901
15925
  var processChannels = /* @__PURE__ */ new Map();
15902
15926
  var lastChannel;
15903
15927
  function savedParents() {
@@ -16167,13 +16191,13 @@ async function ask(question) {
16167
16191
  }
16168
16192
  }
16169
16193
  function installRuntime() {
16170
- const target = join8(home(), "runtime", VERSION);
16194
+ const target = join9(home(), "runtime", VERSION);
16171
16195
  if (runtimeDir() !== target) {
16172
16196
  rmSync3(target, { recursive: true, force: true });
16173
16197
  mkdirSync5(target, { recursive: true });
16174
16198
  cpSync(runtimeDir(), target, { recursive: true });
16175
16199
  }
16176
- return join8(target, "cli.mjs");
16200
+ return join9(target, "cli.mjs");
16177
16201
  }
16178
16202
  function selectedTargets() {
16179
16203
  const only = option("only");
@@ -16204,7 +16228,7 @@ async function pair(server, targets) {
16204
16228
  if (result.status === "claimed" && result.token) return { token: result.token, connection_id: result.connection_id };
16205
16229
  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
16230
  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));
16231
+ await new Promise((resolve3) => setTimeout(resolve3, 2e3));
16208
16232
  }
16209
16233
  }
16210
16234
  async function waitForChecks(api, clients) {
@@ -16228,7 +16252,7 @@ async function waitForChecks(api, clients) {
16228
16252
  out("\n\u3059\u3079\u3066\u306EAI\u3067\u78BA\u8A8D\u304C\u6E08\u307F\u307E\u3057\u305F\u3002Approval Box\u3092\u4F7F\u3048\u307E\u3059\u3002");
16229
16253
  return;
16230
16254
  }
16231
- await new Promise((resolve2) => setTimeout(resolve2, 3e3));
16255
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
16232
16256
  }
16233
16257
  }
16234
16258
  async function setup() {
@@ -16275,8 +16299,8 @@ async function setup() {
16275
16299
  }
16276
16300
  throw error;
16277
16301
  }
16278
- const { spawnSync } = await import("node:child_process");
16279
- const result = spawnSync(process.execPath, [cli, "register", "--targets", targets.join(","), ...instructions ? ["--instructions"] : []], { stdio: "inherit" });
16302
+ const { spawnSync: spawnSync2 } = await import("node:child_process");
16303
+ const result = spawnSync2(process.execPath, [cli, "register", "--targets", targets.join(","), ...instructions ? ["--instructions"] : []], { stdio: "inherit" });
16280
16304
  if (result.status !== 0) throw new Error("AI\u3078\u306E\u767B\u9332\u306B\u5931\u6557\u3057\u307E\u3057\u305F\u3002");
16281
16305
  await api.call("PUT", "/connection/clients", { clients: targets.map((t) => CLIENT[t]), os: osName() });
16282
16306
  if (flag("no-test")) return;
@@ -16319,7 +16343,7 @@ async function uninstall() {
16319
16343
  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
16344
  }
16321
16345
  }
16322
- rmSync3(join8(home(), "config.json"), { force: true });
16346
+ rmSync3(join9(home(), "config.json"), { force: true });
16323
16347
  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
16348
  }
16325
16349
  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.16",
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",