approval-box 0.1.17 → 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/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-GH2JG56Y.mjs";
59
+ } from "./chunks/chunk-OVDAILMZ.mjs";
58
60
 
59
61
  // ../../node_modules/qrcode/lib/can-promise.js
60
62
  var require_can_promise = __commonJS({
@@ -11895,6 +11897,26 @@ function launchDaemon(executable, entry, cwd) {
11895
11897
  }
11896
11898
  }
11897
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
+
11898
11920
  // src/daemon.ts
11899
11921
  import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync as rmSync2 } from "node:fs";
11900
11922
  import { join as join5 } from "node:path";
@@ -12023,7 +12045,7 @@ async function runDaemon() {
12023
12045
  `);
12024
12046
  for (const [id, entry] of Object.entries(journal)) {
12025
12047
  if (entry.state !== "sending") continue;
12026
- const current = safeState(entry);
12048
+ const current = await safeState(entry);
12027
12049
  if (current === "queued" || current === "emitted" || current === "sending") entry.state = "queued";
12028
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" });
12029
12051
  journal[id] = entry;
@@ -12052,8 +12074,7 @@ async function runDaemon() {
12052
12074
  save();
12053
12075
  const entry = journal[item.decision_id];
12054
12076
  try {
12055
- if (channelClosed(PROFILE, item.route.channel_id)) throw Object.assign(new Error("\u7533\u8ACB\u3092\u51FA\u3057\u305FAI\u306E\u4F1A\u8A71\u304C\u7D42\u308F\u3063\u3066\u3044\u307E\u3059"), { closed: true });
12056
- 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);
12057
12078
  if (result.state === "submitted") Object.assign(entry, { state: "report", result: "delivered" });
12058
12079
  else entry.state = "queued";
12059
12080
  } catch (error) {
@@ -12064,9 +12085,9 @@ async function runDaemon() {
12064
12085
  log(`\u914D\u9001 ${item.decision_id} \u2192 ${entry.state}${entry.result ? `/${entry.result}` : ""}`);
12065
12086
  if (entry.state === "report") await report(item.decision_id);
12066
12087
  }
12067
- function safeState(entry) {
12088
+ async function safeState(entry) {
12068
12089
  try {
12069
- return channelDeliveryState(PROFILE, entry.channel_id, entry.delivery_id);
12090
+ return await channelAnswerState(entry.channel_id, entry.delivery_id);
12070
12091
  } catch {
12071
12092
  return null;
12072
12093
  }
@@ -12078,7 +12099,7 @@ async function runDaemon() {
12078
12099
  continue;
12079
12100
  }
12080
12101
  if (entry.state !== "queued") continue;
12081
- const current = safeState(entry);
12102
+ const current = await safeState(entry);
12082
12103
  if (current === "emitted") Object.assign(entry, { state: "report", result: "delivered" });
12083
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" });
12084
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" });
@@ -12112,7 +12133,7 @@ async function runDaemon() {
12112
12133
  save();
12113
12134
  log(`\u914D\u9001 ${id} \u2192 ${withdrawn ? "withdrawn" : "resolved"}`);
12114
12135
  } else {
12115
- 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" });
12116
12137
  save();
12117
12138
  await report(id);
12118
12139
  waiting.delete(id);
@@ -12374,14 +12395,8 @@ async function registerTools(target, options) {
12374
12395
  await withCodexConfig(async (request) => {
12375
12396
  await request("config/batchWrite", { filePath: config, edits: [{ keyPath: `mcp_servers.${MCP_SERVER}`, value: { ...registration(), env_vars: ["CODEX_HOME"] }, mergeStrategy: "replace" }] });
12376
12397
  });
12377
- let steerStatus;
12378
- try {
12379
- const result = await configureCodexSteer(PROFILE, "enable", { hook: runtimeEntry("codex"), codex_home: codexHome(), node: stableNode() });
12380
- steerStatus = result.status + (result.reason_code ? `:${result.reason_code}` : "");
12381
- } catch (error) {
12382
- steerStatus = `failed:${error.code ?? error.message}`;
12383
- }
12384
- 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" };
12385
12400
  }
12386
12401
  const grok = onPath("grok");
12387
12402
  if (!grok) throw new Error("grok \u30B3\u30DE\u30F3\u30C9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093");
@@ -15814,7 +15829,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:f
15814
15829
  import { basename as basename2, join as join8 } from "node:path";
15815
15830
 
15816
15831
  // src/version.ts
15817
- var VERSION = true ? "0.1.17" : "0.0.0-dev";
15832
+ var VERSION = true ? "0.1.19" : "0.0.0-dev";
15818
15833
  function osName() {
15819
15834
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15820
15835
  }
@@ -15948,7 +15963,6 @@ function remember(key, channelId, persistent) {
15948
15963
  writeJsonFile(parentsFile(), all);
15949
15964
  } else processChannels.set(key, channelId);
15950
15965
  }
15951
- var verifiedCodexThreads = /* @__PURE__ */ new Set();
15952
15966
  async function channelFor(harness, clientName, meta) {
15953
15967
  if (harness === "codex") {
15954
15968
  const parent = codexParentFromRequest(clientName, meta);
@@ -15956,10 +15970,6 @@ async function channelFor(harness, clientName, meta) {
15956
15970
  const key2 = `codex:${parent.codex_home}:${parent.thread_id}`;
15957
15971
  const existing2 = reuse(key2, true);
15958
15972
  if (existing2) return existing2;
15959
- if (!verifiedCodexThreads.has(key2)) {
15960
- await verifyCodexParent(PROFILE, parent);
15961
- verifiedCodexThreads.add(key2);
15962
- }
15963
15973
  const channel2 = openChannel(PROFILE, parent);
15964
15974
  remember(key2, channel2.channel_id, true);
15965
15975
  return channel2.channel_id;
@@ -16177,12 +16187,6 @@ var FAILED_HINT = {
16177
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",
16178
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"
16179
16189
  };
16180
- var STEER_LABEL = {
16181
- ready: "\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F\u3082\u4F7F\u3048\u307E\u3059",
16182
- 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",
16183
- 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",
16184
- 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"
16185
- };
16186
16190
  async function ask(question) {
16187
16191
  const rl = createInterface({ input: process.stdin, output: process.stdout });
16188
16192
  try {
@@ -16268,7 +16272,7 @@ async function setup() {
16268
16272
  for (const target of targets) out(` ${LABEL[target]}: ${filesOf(target).join(", ")}`);
16269
16273
  out("");
16270
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");
16271
- if (targets.includes("codex")) out("\u30FBCodex \u306F\u3001\u4F5C\u696D\u4E2D\u306B\u7B54\u3048\u3092\u5272\u308A\u8FBC\u307E\u305B\u308B\u305F\u3081 hook \u3082\u767B\u9332\u3057\u307E\u3059\u3002\u767B\u9332\u5F8C\u306B Codex \u306E\u518D\u8D77\u52D5\u304C\u8981\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002");
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");
16272
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");
16273
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
16274
16278
  `);
@@ -16312,8 +16316,7 @@ async function registerTargets() {
16312
16316
  let failed = false;
16313
16317
  for (const target of targets) {
16314
16318
  const result = await register(target, { instructions: flag("instructions") });
16315
- const extra = result.steer ? `\uFF08${STEER_LABEL[result.steer.split(":")[0] ?? ""] ?? `\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F: ${result.steer}`}\uFF09` : "";
16316
- 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}`}`);
16317
16320
  if (result.note) out(` \u30FB${result.note}`);
16318
16321
  if (result.status === "failed") failed = true;
16319
16322
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "approval-box",
3
- "version": "0.1.17",
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": "^0.2.0",
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]);