approval-box 0.1.16 → 0.1.19
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/README.md +4 -0
- package/dist/THIRD_PARTY_NOTICES.md +1 -1
- package/dist/approval-box-claude-hook.mjs +1 -1
- package/dist/approval-box-cursor-hook.mjs +1 -1
- package/dist/approval-box-receive.mjs +1 -1
- package/dist/chunks/{chunk-GH2JG56Y.mjs → chunk-OVDAILMZ.mjs} +408 -388
- package/dist/cli.mjs +37 -33
- package/package.json +2 -2
- package/dist/approval-box-codex-hook.mjs +0 -8
package/dist/cli.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire as __kbCreateRequire } from 'node:module'; const require = __kbCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
|
+
CodexDeliveryError,
|
|
4
5
|
HOOK_FILES,
|
|
5
6
|
MCP_SERVER,
|
|
6
7
|
PROFILE,
|
|
@@ -18,6 +19,7 @@ import {
|
|
|
18
19
|
claudeHookRoot,
|
|
19
20
|
claudeParentFromRequest,
|
|
20
21
|
claudeParentHooksRegistered,
|
|
22
|
+
codexDeliveryStateViaAiterm,
|
|
21
23
|
codexParentFromRequest,
|
|
22
24
|
configureCodexSteer,
|
|
23
25
|
cursorHookRoot,
|
|
@@ -47,14 +49,14 @@ import {
|
|
|
47
49
|
setupNodeExecutable,
|
|
48
50
|
stateRoot,
|
|
49
51
|
string,
|
|
52
|
+
submitCodexParentAnswerViaAiterm,
|
|
50
53
|
union,
|
|
51
54
|
unknown,
|
|
52
|
-
verifyCodexParent,
|
|
53
55
|
verifyCursorParent,
|
|
54
56
|
waitProcessCommandLine,
|
|
55
57
|
withCodexReceiver,
|
|
56
58
|
withdrawFromChannel
|
|
57
|
-
} from "./chunks/chunk-
|
|
59
|
+
} from "./chunks/chunk-OVDAILMZ.mjs";
|
|
58
60
|
|
|
59
61
|
// ../../node_modules/qrcode/lib/can-promise.js
|
|
60
62
|
var require_can_promise = __commonJS({
|
|
@@ -11882,7 +11884,8 @@ function windowsDaemonLaunchScript(executable, entry, cwd, environment) {
|
|
|
11882
11884
|
function launchDaemon(executable, entry, cwd) {
|
|
11883
11885
|
if (process.platform === "win32") {
|
|
11884
11886
|
const script = windowsDaemonLaunchScript(executable, entry, cwd, { ...process.env, APPROVAL_BOX_HOME: resolve(home()) });
|
|
11885
|
-
const result = spawnSync("
|
|
11887
|
+
const result = spawnSync("pwsh.exe", ["-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(script, "utf16le").toString("base64")], { cwd, windowsHide: true, encoding: "utf8", timeout: 15e3 });
|
|
11888
|
+
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");
|
|
11886
11889
|
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
11890
|
return;
|
|
11888
11891
|
}
|
|
@@ -11894,6 +11897,26 @@ function launchDaemon(executable, entry, cwd) {
|
|
|
11894
11897
|
}
|
|
11895
11898
|
}
|
|
11896
11899
|
|
|
11900
|
+
// src/channel-delivery.ts
|
|
11901
|
+
var provider = {
|
|
11902
|
+
submit: (parent, id, text2) => submitCodexParentAnswerViaAiterm(parent, id, text2),
|
|
11903
|
+
state: (parent, id) => codexDeliveryStateViaAiterm(parent, id)
|
|
11904
|
+
};
|
|
11905
|
+
async function sendChannelAnswer(channelId, deliveryId, text2, codex = provider) {
|
|
11906
|
+
if (channelClosed(PROFILE, channelId)) throw Object.assign(new Error("\u7533\u8ACB\u3092\u51FA\u3057\u305FAI\u306E\u4F1A\u8A71\u304C\u7D42\u308F\u3063\u3066\u3044\u307E\u3059"), { closed: true });
|
|
11907
|
+
const channel = readChannel(PROFILE, channelId);
|
|
11908
|
+
if (channel.kind !== "codex") return sendToChannel(PROFILE, channelId, deliveryId, text2);
|
|
11909
|
+
if (!channel.codex) throw new CodexDeliveryError("CODEX_PARENT_ID_UNAVAILABLE", "channel\u306B\u5143\u306ECodex\u4F1A\u8A71\u304C\u3042\u308A\u307E\u305B\u3093");
|
|
11910
|
+
const result = await codex.submit(channel.codex, deliveryId, text2);
|
|
11911
|
+
return { state: "submitted", queued_submission_id: result.queued_submission_id };
|
|
11912
|
+
}
|
|
11913
|
+
async function channelAnswerState(channelId, deliveryId, codex = provider) {
|
|
11914
|
+
const channel = readChannel(PROFILE, channelId);
|
|
11915
|
+
if (channel.kind !== "codex") return channelDeliveryState(PROFILE, channelId, deliveryId);
|
|
11916
|
+
if (!channel.codex) throw new CodexDeliveryError("CODEX_PARENT_ID_UNAVAILABLE", "channel\u306B\u5143\u306ECodex\u4F1A\u8A71\u304C\u3042\u308A\u307E\u305B\u3093");
|
|
11917
|
+
return codex.state(channel.codex, deliveryId);
|
|
11918
|
+
}
|
|
11919
|
+
|
|
11897
11920
|
// src/daemon.ts
|
|
11898
11921
|
import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
|
|
11899
11922
|
import { join as join5 } from "node:path";
|
|
@@ -12022,7 +12045,7 @@ async function runDaemon() {
|
|
|
12022
12045
|
`);
|
|
12023
12046
|
for (const [id, entry] of Object.entries(journal)) {
|
|
12024
12047
|
if (entry.state !== "sending") continue;
|
|
12025
|
-
const current = safeState(entry);
|
|
12048
|
+
const current = await safeState(entry);
|
|
12026
12049
|
if (current === "queued" || current === "emitted" || current === "sending") entry.state = "queued";
|
|
12027
12050
|
else Object.assign(entry, { state: "report", result: "unknown", detail: "\u9001\u4FE1\u306E\u9014\u4E2D\u3067\u914D\u9001\u30C7\u30FC\u30E2\u30F3\u304C\u6B62\u307E\u308A\u307E\u3057\u305F" });
|
|
12028
12051
|
journal[id] = entry;
|
|
@@ -12051,8 +12074,7 @@ async function runDaemon() {
|
|
|
12051
12074
|
save();
|
|
12052
12075
|
const entry = journal[item.decision_id];
|
|
12053
12076
|
try {
|
|
12054
|
-
|
|
12055
|
-
const result = await sendToChannel(PROFILE, item.route.channel_id, item.delivery_id, text2);
|
|
12077
|
+
const result = await sendChannelAnswer(item.route.channel_id, item.delivery_id, text2);
|
|
12056
12078
|
if (result.state === "submitted") Object.assign(entry, { state: "report", result: "delivered" });
|
|
12057
12079
|
else entry.state = "queued";
|
|
12058
12080
|
} catch (error) {
|
|
@@ -12063,9 +12085,9 @@ async function runDaemon() {
|
|
|
12063
12085
|
log(`\u914D\u9001 ${item.decision_id} \u2192 ${entry.state}${entry.result ? `/${entry.result}` : ""}`);
|
|
12064
12086
|
if (entry.state === "report") await report(item.decision_id);
|
|
12065
12087
|
}
|
|
12066
|
-
function safeState(entry) {
|
|
12088
|
+
async function safeState(entry) {
|
|
12067
12089
|
try {
|
|
12068
|
-
return
|
|
12090
|
+
return await channelAnswerState(entry.channel_id, entry.delivery_id);
|
|
12069
12091
|
} catch {
|
|
12070
12092
|
return null;
|
|
12071
12093
|
}
|
|
@@ -12077,7 +12099,7 @@ async function runDaemon() {
|
|
|
12077
12099
|
continue;
|
|
12078
12100
|
}
|
|
12079
12101
|
if (entry.state !== "queued") continue;
|
|
12080
|
-
const current = safeState(entry);
|
|
12102
|
+
const current = await safeState(entry);
|
|
12081
12103
|
if (current === "emitted") Object.assign(entry, { state: "report", result: "delivered" });
|
|
12082
12104
|
else if (current === "unknown") Object.assign(entry, { state: "report", result: "unknown", detail: "\u53D7\u3051\u53E3\u306E\u51FA\u529B\u3092\u78BA\u304B\u3081\u3089\u308C\u307E\u305B\u3093\u3067\u3057\u305F" });
|
|
12083
12105
|
else if (current === null || current === "withdrawn") Object.assign(entry, { state: "report", result: "failed", detail: "\u914D\u9001\u306E\u8A18\u9332\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093" });
|
|
@@ -12111,7 +12133,7 @@ async function runDaemon() {
|
|
|
12111
12133
|
save();
|
|
12112
12134
|
log(`\u914D\u9001 ${id} \u2192 ${withdrawn ? "withdrawn" : "resolved"}`);
|
|
12113
12135
|
} else {
|
|
12114
|
-
Object.assign(entry, safeState(entry) === "emitted" ? { state: "report", result: "delivered" } : { state: "report", result: "unknown", detail: "\u914D\u9001\u5148\u306E\u5909\u66F4\u524D\u306B\u53D7\u3051\u53E3\u304C\u672C\u6587\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F\u3002\u518D\u9001\u3057\u307E\u305B\u3093" });
|
|
12136
|
+
Object.assign(entry, await safeState(entry) === "emitted" ? { state: "report", result: "delivered" } : { state: "report", result: "unknown", detail: "\u914D\u9001\u5148\u306E\u5909\u66F4\u524D\u306B\u53D7\u3051\u53E3\u304C\u672C\u6587\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F\u3002\u518D\u9001\u3057\u307E\u305B\u3093" });
|
|
12115
12137
|
save();
|
|
12116
12138
|
await report(id);
|
|
12117
12139
|
waiting.delete(id);
|
|
@@ -12373,14 +12395,8 @@ async function registerTools(target, options) {
|
|
|
12373
12395
|
await withCodexConfig(async (request) => {
|
|
12374
12396
|
await request("config/batchWrite", { filePath: config, edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: { ...registration(), env_vars: ["CODEX_HOME"] }, mergeStrategy: "replace" }] });
|
|
12375
12397
|
});
|
|
12376
|
-
|
|
12377
|
-
|
|
12378
|
-
const result = await configureCodexSteer(PROFILE, "enable", { hook: runtimeEntry("codex"), codex_home: codexHome(), node: stableNode() });
|
|
12379
|
-
steerStatus = result.status + (result.reason_code ? `:${result.reason_code}` : "");
|
|
12380
|
-
} catch (error) {
|
|
12381
|
-
steerStatus = `failed:${error.code ?? error.message}`;
|
|
12382
|
-
}
|
|
12383
|
-
return { target, status: "registered", steer: steerStatus };
|
|
12398
|
+
await configureCodexSteer(PROFILE, "disable", { hook: runtimeEntry("codex"), codex_home: codexHome() });
|
|
12399
|
+
return { target, status: "registered", note: "Codex\u306E\u56DE\u7B54\u914D\u9001\u306FAiterm\u306E\u5171\u901ASteer\u3092\u4F7F\u3044\u307E\u3059\u3002\u65E7\u7248\u306E\u5C02\u7528\u914D\u9001hook\u306F\u767B\u9332\u3057\u307E\u305B\u3093\u3002" };
|
|
12384
12400
|
}
|
|
12385
12401
|
const grok = onPath("grok");
|
|
12386
12402
|
if (!grok) throw new Error("grok \u30B3\u30DE\u30F3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
|
|
@@ -15813,7 +15829,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:f
|
|
|
15813
15829
|
import { basename as basename2, join as join8 } from "node:path";
|
|
15814
15830
|
|
|
15815
15831
|
// src/version.ts
|
|
15816
|
-
var VERSION = true ? "0.1.
|
|
15832
|
+
var VERSION = true ? "0.1.19" : "0.0.0-dev";
|
|
15817
15833
|
function osName() {
|
|
15818
15834
|
return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
|
|
15819
15835
|
}
|
|
@@ -15947,7 +15963,6 @@ function remember(key, channelId, persistent) {
|
|
|
15947
15963
|
writeJsonFile(parentsFile(), all);
|
|
15948
15964
|
} else processChannels.set(key, channelId);
|
|
15949
15965
|
}
|
|
15950
|
-
var verifiedCodexThreads = /* @__PURE__ */ new Set();
|
|
15951
15966
|
async function channelFor(harness, clientName, meta) {
|
|
15952
15967
|
if (harness === "codex") {
|
|
15953
15968
|
const parent = codexParentFromRequest(clientName, meta);
|
|
@@ -15955,10 +15970,6 @@ async function channelFor(harness, clientName, meta) {
|
|
|
15955
15970
|
const key2 = `codex:${parent.codex_home}:${parent.thread_id}`;
|
|
15956
15971
|
const existing2 = reuse(key2, true);
|
|
15957
15972
|
if (existing2) return existing2;
|
|
15958
|
-
if (!verifiedCodexThreads.has(key2)) {
|
|
15959
|
-
await verifyCodexParent(PROFILE, parent);
|
|
15960
|
-
verifiedCodexThreads.add(key2);
|
|
15961
|
-
}
|
|
15962
15973
|
const channel2 = openChannel(PROFILE, parent);
|
|
15963
15974
|
remember(key2, channel2.channel_id, true);
|
|
15964
15975
|
return channel2.channel_id;
|
|
@@ -16176,12 +16187,6 @@ var FAILED_HINT = {
|
|
|
16176
16187
|
notify: "\u30A2\u30D7\u30EA\u306E\u901A\u77E5\u304C\u5C4A\u3044\u3066\u3044\u307E\u305B\u3093\u3002\u30A2\u30D7\u30EA\u306E\u901A\u77E5\u306E\u8A31\u53EF\u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
16177
16188
|
delivery: "\u7B54\u3048\u304CAI\u3078\u5C4A\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002npx approval-box doctor \u3067\u539F\u56E0\u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002"
|
|
16178
16189
|
};
|
|
16179
|
-
var STEER_LABEL = {
|
|
16180
|
-
ready: "\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F\u3082\u4F7F\u3048\u307E\u3059",
|
|
16181
|
-
restart_required: "\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F\u306F\u3001\u958B\u3044\u3066\u3044\u308BCodex\u3092\u3059\u3079\u3066\u9589\u3058\u3066\u958B\u304D\u76F4\u3059\u3068\u4F7F\u3048\u307E\u3059\u3002\u305D\u308C\u307E\u3067\u306F\u4F5C\u696D\u306E\u533A\u5207\u308A\u3067\u5C4A\u304D\u307E\u3059",
|
|
16182
|
-
disabled: "\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F\u306F\u4F7F\u3044\u307E\u305B\u3093\u3002\u7B54\u3048\u306F\u4F5C\u696D\u306E\u533A\u5207\u308A\u3067\u5C4A\u304D\u307E\u3059",
|
|
16183
|
-
failed: "\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F\u3092\u6709\u52B9\u306B\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7B54\u3048\u306F\u4F5C\u696D\u306E\u533A\u5207\u308A\u3067\u5C4A\u304D\u307E\u3059\uFF08npx approval-box doctor \u3067\u539F\u56E0\u3092\u78BA\u304B\u3081\u3089\u308C\u307E\u3059\uFF09"
|
|
16184
|
-
};
|
|
16185
16190
|
async function ask(question) {
|
|
16186
16191
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
16187
16192
|
try {
|
|
@@ -16267,7 +16272,7 @@ async function setup() {
|
|
|
16267
16272
|
for (const target of targets) out(` ${LABEL[target]}: ${filesOf(target).join(", ")}`);
|
|
16268
16273
|
out("");
|
|
16269
16274
|
if (targets.includes("claude")) out("\u30FBClaude Code \u306E Stop hook \u306F\u3001\u3059\u3079\u3066\u306E\u4F1A\u8A71\u3067\u30BF\u30FC\u30F3\u304C\u7D42\u308F\u308B\u305F\u3073\u306B node \u30921\u56DE\u8D77\u52D5\u3057\u307E\u3059\uFF08Approval Box\u306E\u7533\u8ACB\u304C\u7121\u3051\u308C\u3070\u3059\u3050\u7D42\u308F\u308A\u307E\u3059\uFF09\u3002");
|
|
16270
|
-
if (targets.includes("codex")) out("\u30FBCodex \
|
|
16275
|
+
if (targets.includes("codex")) out("\u30FBCodex \u306E\u7B54\u3048\u306F Aiterm \u306E Steer \u3067\u5143\u306E\u4F1A\u8A71\u3078\u8FD4\u3057\u307E\u3059\u3002\u65E7\u7248\u306EApproval Box\u5C02\u7528\u914D\u9001hook\u306F\u64A4\u53BB\u3057\u307E\u3059\u3002");
|
|
16271
16276
|
if (targets.includes("cursor") || targets.includes("grok")) out("\u30FBCursor\uFF08\u6B62\u307E\u3063\u3066\u3044\u308B\u6642\uFF09\u3068 Grok \u306F\u3001\u7533\u8ACB\u306E\u6642\u306BAI\u304C\u80CC\u666F\u3067\u53D7\u4FE1\u3092\u8D77\u52D5\u3057\u307E\u3059\u3002");
|
|
16272
16277
|
out(`\u30FB\u66F8\u304D\u63DB\u3048\u308B\u524D\u306E\u30D5\u30A1\u30A4\u30EB\u306F\u300C${".approval-box-backup"}\u300D\u3092\u4ED8\u3051\u3066\u63A7\u3048\u307E\u3059\u3002\u5143\u306B\u623B\u3059\u306B\u306F npx approval-box uninstall\u3002
|
|
16273
16278
|
`);
|
|
@@ -16311,8 +16316,7 @@ async function registerTargets() {
|
|
|
16311
16316
|
let failed = false;
|
|
16312
16317
|
for (const target of targets) {
|
|
16313
16318
|
const result = await register(target, { instructions: flag("instructions") });
|
|
16314
|
-
|
|
16315
|
-
out(` ${LABEL[target]}: ${result.status === "registered" ? "\u767B\u9332\u3057\u307E\u3057\u305F" : `\u5931\u6557 \u2014 ${result.detail}`}${extra}`);
|
|
16319
|
+
out(` ${LABEL[target]}: ${result.status === "registered" ? "\u767B\u9332\u3057\u307E\u3057\u305F" : `\u5931\u6557 \u2014 ${result.detail}`}`);
|
|
16316
16320
|
if (result.note) out(` \u30FB${result.note}`);
|
|
16317
16321
|
if (result.status === "failed") failed = true;
|
|
16318
16322
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "approval-box",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.19",
|
|
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",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"@modelcontextprotocol/sdk": "^1.31.0",
|
|
33
33
|
"@types/node": "^25.9.1",
|
|
34
34
|
"@types/qrcode": "^1.5.5",
|
|
35
|
-
"aiterm-steer-delivery": "
|
|
35
|
+
"aiterm-steer-delivery": "0.3.0",
|
|
36
36
|
"esbuild": "^0.28.2",
|
|
37
37
|
"qrcode": "^1.5.4",
|
|
38
38
|
"typescript": "^6.0.3",
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { createRequire as __kbCreateRequire } from 'node:module'; const require = __kbCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
PROFILE,
|
|
4
|
-
runCodexHookMain
|
|
5
|
-
} from "./chunks/chunk-GH2JG56Y.mjs";
|
|
6
|
-
|
|
7
|
-
// src/hooks/codex.ts
|
|
8
|
-
await runCodexHookMain(PROFILE, process.argv[2]);
|