approval-box 0.1.14 → 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.
- package/dist/cli.mjs +102 -78
- 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(
|
|
4440
|
+
return new Promise(function(resolve3, reject) {
|
|
4441
4441
|
try {
|
|
4442
4442
|
const data = QRCode2.create(text2, opts);
|
|
4443
|
-
|
|
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(
|
|
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) :
|
|
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 =
|
|
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
|
|
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
|
|
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:
|
|
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
|
|
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 {
|
|
11873
|
-
import {
|
|
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
|
|
11904
|
+
import { join as join3 } from "node:path";
|
|
11880
11905
|
var KEEP_DAYS = 30;
|
|
11881
|
-
var attachmentsRoot = () =>
|
|
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 =
|
|
11888
|
-
const file =
|
|
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 =
|
|
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
|
|
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
|
|
11954
|
+
return join4(runtimeDir(), kind === "cli" ? "cli.mjs" : HOOK_FILES[kind]);
|
|
11930
11955
|
}
|
|
11931
11956
|
|
|
11932
11957
|
// src/daemon.ts
|
|
11933
|
-
var lockFile = () =>
|
|
11934
|
-
var journalFile = () =>
|
|
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
|
-
|
|
11978
|
-
spawn(process.execPath, [runtimeEntry("cli"), "daemon"], { 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((
|
|
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
|
|
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
|
|
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("~/") ?
|
|
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(
|
|
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 ??
|
|
12233
|
-
var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ?
|
|
12234
|
-
var cursorDir = () => process.env.CURSOR_HOME ??
|
|
12235
|
-
var codexHome = () => process.env.CODEX_HOME ??
|
|
12236
|
-
var grokDir = () => process.env.GROK_HOME ??
|
|
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(),
|
|
12239
|
-
if (target === "cursor") return [
|
|
12240
|
-
if (target === "codex") return [
|
|
12241
|
-
return [
|
|
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
|
|
12245
|
-
if (target === "codex") return
|
|
12246
|
-
if (target === "grok") return
|
|
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(
|
|
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 = () =>
|
|
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 =
|
|
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(
|
|
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,
|
|
12360
|
+
mergeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"), hook("claude"));
|
|
12337
12361
|
return { target, status: "registered" };
|
|
12338
12362
|
}
|
|
12339
12363
|
if (target === "cursor") {
|
|
12340
|
-
setMcpJson(
|
|
12341
|
-
mergeCursorParentHooks(PROFILE,
|
|
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 =
|
|
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(
|
|
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,
|
|
12401
|
+
removeClaudeParentHooks(PROFILE, join7(claudeDir(), "settings.json"));
|
|
12378
12402
|
} else if (target === "cursor") {
|
|
12379
|
-
if (existsSync5(
|
|
12380
|
-
removeCursorParentHooks(PROFILE,
|
|
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(
|
|
12408
|
+
if (existsSync5(join7(codexHome(), "config.toml"))) {
|
|
12385
12409
|
await withCodexConfig(async (request) => {
|
|
12386
|
-
await request("config/batchWrite", { filePath:
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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(
|
|
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((
|
|
15800
|
+
return new Promise((resolve3) => {
|
|
15777
15801
|
const json = serializeMessage(message);
|
|
15778
15802
|
if (this._stdout.write(json)) {
|
|
15779
|
-
|
|
15803
|
+
resolve3();
|
|
15780
15804
|
} else {
|
|
15781
|
-
this._stdout.once("drain",
|
|
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
|
|
15813
|
+
import { basename as basename2, join as join8 } from "node:path";
|
|
15790
15814
|
|
|
15791
15815
|
// src/version.ts
|
|
15792
|
-
var VERSION = true ? "0.1.
|
|
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 = () =>
|
|
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 =
|
|
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
|
|
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((
|
|
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((
|
|
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 =
|
|
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(
|
|
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.
|
|
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",
|