approval-box 0.1.22 → 0.1.24

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.
@@ -28,7 +28,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
28
  SOFTWARE.
29
29
  ```
30
30
 
31
- ## aiterm-steer-delivery@0.4.4 (MIT)
31
+ ## aiterm-steer-delivery@0.4.5 (MIT)
32
32
 
33
33
  ```
34
34
  MIT License
@@ -2,7 +2,7 @@ import { createRequire as __kbCreateRequire } from 'node:module'; const require
2
2
  import {
3
3
  PROFILE,
4
4
  runClaudeHookMain
5
- } from "./chunks/chunk-SN7I52NL.mjs";
5
+ } from "./chunks/chunk-HBSDWG62.mjs";
6
6
 
7
7
  // src/hooks/claude.ts
8
8
  await runClaudeHookMain(PROFILE);
@@ -5,7 +5,7 @@ import {
5
5
  handleCursorChannelHook,
6
6
  handleCursorHook,
7
7
  withoutBom
8
- } from "./chunks/chunk-SN7I52NL.mjs";
8
+ } from "./chunks/chunk-HBSDWG62.mjs";
9
9
 
10
10
  // src/cursor-binding.ts
11
11
  async function bindCursorResult(profile, raw) {
@@ -2,7 +2,7 @@ import { createRequire as __kbCreateRequire } from 'node:module'; const require
2
2
  import {
3
3
  PROFILE,
4
4
  runChannelReceiveMain
5
- } from "./chunks/chunk-SN7I52NL.mjs";
5
+ } from "./chunks/chunk-HBSDWG62.mjs";
6
6
 
7
7
  // src/hooks/receive.ts
8
8
  await runChannelReceiveMain(PROFILE);
@@ -20200,6 +20200,136 @@ function hookOwnerProcess(rows, pid) {
20200
20200
  current = byPid.get(current.parent_pid);
20201
20201
  return current;
20202
20202
  }
20203
+ function processExists(pid) {
20204
+ if (!Number.isSafeInteger(pid) || pid <= 0)
20205
+ return false;
20206
+ try {
20207
+ process.kill(pid, 0);
20208
+ return true;
20209
+ } catch (error62) {
20210
+ return error62.code === "EPERM";
20211
+ }
20212
+ }
20213
+ function windowsJson(script, failure2) {
20214
+ const source = ["$ErrorActionPreference='Stop'", "[Console]::OutputEncoding=[Text.UTF8Encoding]::new($false)", script].join("\n");
20215
+ const result = spawnSync3(resolveWindowsPowerShell7(), ["-NoLogo", "-NoProfile", "-NonInteractive", "-EncodedCommand", Buffer.from(source, "utf16le").toString("base64")], {
20216
+ encoding: "utf8",
20217
+ timeout: 15e3,
20218
+ maxBuffer: 16 * 1024 * 1024,
20219
+ windowsHide: true
20220
+ });
20221
+ if (result.error || result.status !== 0)
20222
+ throw new ProcessTableError(failure2);
20223
+ try {
20224
+ return JSON.parse(result.stdout);
20225
+ } catch {
20226
+ throw new ProcessTableError(failure2);
20227
+ }
20228
+ }
20229
+ function assertPids(pids) {
20230
+ const wanted = [...new Set(pids)];
20231
+ if (wanted.some((pid) => !Number.isSafeInteger(pid) || pid < 0))
20232
+ throw new ProcessTableError("process\u7167\u4F1A\u306Epid\u304C\u4E0D\u6B63\u3067\u3059");
20233
+ return wanted;
20234
+ }
20235
+ var WINDOWS_STARTED = [
20236
+ "function Started($p) {",
20237
+ " try { return $p.StartTime.ToUniversalTime().ToString('o') }",
20238
+ " catch [InvalidOperationException] { return '' }",
20239
+ ` catch { $w = Get-CimInstance Win32_Process -Filter "ProcessId=$($p.Id)" -Property CreationDate; if ($null -eq $w) { return '' }`,
20240
+ " if ($null -eq $w.CreationDate) { return $null }; return $w.CreationDate.ToUniversalTime().ToString('o') }",
20241
+ "}"
20242
+ ].join("\n");
20243
+ function readProcessIdentities(pids) {
20244
+ const wanted = assertPids(pids).filter(processExists);
20245
+ if (wanted.length === 0)
20246
+ return [];
20247
+ if (!isWin2) {
20248
+ const result = spawnSync3("/bin/ps", ["-o", "pid=,lstart=", "-p", wanted.join(",")], {
20249
+ encoding: "utf8",
20250
+ env: { ...process.env, LC_ALL: "C" },
20251
+ timeout: 1e4
20252
+ });
20253
+ if (result.error || result.status !== 0 && !(result.status === 1 && !result.stdout.trim())) {
20254
+ throw new ProcessTableError("OS\u306Eprocess\u4E00\u89A7\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093");
20255
+ }
20256
+ return result.stdout.split("\n").filter((line) => line.trim()).map((line) => {
20257
+ const match = /^\s*(\d+)\s+(\S+\s+\S+\s+\d+\s+\S+\s+\d+)\s*$/.exec(line);
20258
+ if (!match)
20259
+ throw new ProcessTableError("process\u4E00\u89A7\u306E\u5F62\u5F0F\u3092\u8A8D\u8B58\u3067\u304D\u307E\u305B\u3093");
20260
+ return { pid: Number(match[1]), started_identity: match[2].trim() };
20261
+ });
20262
+ }
20263
+ const rows = windowsJson([
20264
+ WINDOWS_STARTED,
20265
+ "$rows=@()",
20266
+ `foreach ($id in @(${wanted.join(",")})) {`,
20267
+ " try { $p=[Diagnostics.Process]::GetProcessById($id) } catch [ArgumentException] { continue }",
20268
+ " $started=Started $p",
20269
+ " if ($started -eq '') { continue }",
20270
+ " $rows += [ordered]@{ pid=[int]$id; started_identity=$started }",
20271
+ "}",
20272
+ "ConvertTo-Json -Compress -InputObject $rows"
20273
+ ].join("\n"), "Windows\u306Eprocess\u306E\u958B\u59CB\u6642\u523B\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093");
20274
+ if (!Array.isArray(rows))
20275
+ throw new ProcessTableError("Windows process\u306E\u8AAD\u307F\u304C\u914D\u5217\u3067\u306F\u3042\u308A\u307E\u305B\u3093");
20276
+ return rows.map((row) => {
20277
+ if (!row || !Number.isSafeInteger(row.pid))
20278
+ throw new ProcessTableError("Windows process\u306E\u8AAD\u307F\u306Efield\u304C\u4E0D\u6B63\u3067\u3059");
20279
+ if (row.started_identity === null)
20280
+ return { pid: row.pid, started_identity: null };
20281
+ if (typeof row.started_identity !== "string" || !Number.isFinite(Date.parse(row.started_identity)))
20282
+ throw new ProcessTableError("Windows process\u306E\u8AAD\u307F\u306Efield\u304C\u4E0D\u6B63\u3067\u3059");
20283
+ return { pid: row.pid, started_identity: new Date(row.started_identity).toISOString() };
20284
+ });
20285
+ }
20286
+ function processIsRunning(pid, startedIdentity) {
20287
+ return processExists(pid) && readProcessIdentities([pid])[0]?.started_identity === startedIdentity;
20288
+ }
20289
+ function readProcessLineage(pid, depth = 8) {
20290
+ if (!isWin2)
20291
+ return readRuntimeProcesses();
20292
+ if (!Number.isSafeInteger(pid) || pid <= 0 || !Number.isSafeInteger(depth) || depth <= 0)
20293
+ throw new ProcessTableError("process\u7167\u4F1A\u306Epid\u304C\u4E0D\u6B63\u3067\u3059");
20294
+ let rows;
20295
+ try {
20296
+ rows = windowsJson([
20297
+ "$rows=@(); $child=$null",
20298
+ `$id=${pid}`,
20299
+ `for ($i=0; $i -lt ${depth} -and $id -gt 0; $i++) {`,
20300
+ " try { $p=Get-Process -Id $id; $started=$p.StartTime.ToUniversalTime() } catch { break }",
20301
+ // Windowsの親PIDは親の終了後も残り、別のprocessへ使い回される。子より後に始まったprocessは親でない。
20302
+ " if ($null -ne $child -and $started -gt $child) { break }",
20303
+ " $parent=0; try { if ($null -ne $p.Parent) { $parent=[int]$p.Parent.Id } } catch { }",
20304
+ " $exe=''; try { $exe=[string]$p.Path } catch { }",
20305
+ " if (-not $exe) { $exe=[string]$p.ProcessName }",
20306
+ " $cpu=0.0; try { $cpu=[double]$p.TotalProcessorTime.TotalSeconds } catch { }",
20307
+ " $rows += [ordered]@{ pid=[int]$p.Id; parent_pid=$parent; executable=$exe; started_identity=$started.ToString('o'); cpu_seconds=$cpu }",
20308
+ " $child=$started; $id=$parent",
20309
+ "}",
20310
+ "ConvertTo-Json -Compress -InputObject $rows"
20311
+ ].join("\n"), "Windows\u306Eprocess\u306E\u5148\u7956\u3092\u53D6\u5F97\u3067\u304D\u307E\u305B\u3093");
20312
+ } catch {
20313
+ return readRuntimeProcesses();
20314
+ }
20315
+ if (!Array.isArray(rows) || rows[0]?.pid !== pid)
20316
+ return readRuntimeProcesses();
20317
+ return rows.map((row) => {
20318
+ if (!row || !Number.isSafeInteger(row.pid) || !Number.isSafeInteger(row.parent_pid) || typeof row.executable !== "string" || !Number.isFinite(row.cpu_seconds) || typeof row.started_identity !== "string" || !Number.isFinite(Date.parse(row.started_identity)))
20319
+ throw new ProcessTableError("Windows process\u306E\u8AAD\u307F\u306Efield\u304C\u4E0D\u6B63\u3067\u3059");
20320
+ return {
20321
+ pid: row.pid,
20322
+ parent_pid: row.parent_pid,
20323
+ process_group_id: null,
20324
+ stopped: null,
20325
+ executable: row.executable,
20326
+ started_identity: new Date(row.started_identity).toISOString(),
20327
+ command: row.executable,
20328
+ cpu_seconds: row.cpu_seconds,
20329
+ argv_digest: createHash2("sha256").update(row.executable).digest("hex")
20330
+ };
20331
+ });
20332
+ }
20203
20333
  function readRuntimeProcesses() {
20204
20334
  if (!isWin2) {
20205
20335
  const result2 = spawnSync3("/bin/ps", ["-axww", "-o", "pid=,ppid=,pgid=,stat=,lstart=,time=,command="], {
@@ -20506,7 +20636,7 @@ var claudeParentSchema = external_exports.object({
20506
20636
  hook_root: external_exports.string()
20507
20637
  }).strict();
20508
20638
  function processIdentity(pid) {
20509
- return readRuntimeProcesses().find((entry) => entry.pid === pid)?.started_identity;
20639
+ return readProcessIdentities([pid])[0]?.started_identity ?? void 0;
20510
20640
  }
20511
20641
  function directory(parent) {
20512
20642
  return path7.join(parent.hook_root, parent.request_id);
@@ -20530,8 +20660,7 @@ function assertOpen(parent) {
20530
20660
  }
20531
20661
  function prepareClaudeHookRequest(input2, root) {
20532
20662
  const event = external_exports.object({ session_id: external_exports.uuid(), tool_use_id: requestId, agent_id: external_exports.string().optional() }).parse(input2);
20533
- const rows = readRuntimeProcesses();
20534
- const owner = hookOwnerProcess(rows, process.ppid);
20663
+ const owner = hookOwnerProcess(readProcessLineage(process.ppid), process.ppid);
20535
20664
  if (!owner)
20536
20665
  throw new ClaudeDeliveryError("CLAUDE_PARENT_PROCESS_UNAVAILABLE", "hook\u3092\u8D77\u52D5\u3057\u305F\u89AAprocess\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093");
20537
20666
  const dir = path7.join(root, event.tool_use_id);
@@ -20544,13 +20673,14 @@ function prepareClaudeHookRequest(input2, root) {
20544
20673
  parent_started_identity: owner.started_identity
20545
20674
  });
20546
20675
  try {
20547
- sweepClaudeHookRequests(root, rows);
20676
+ sweepClaudeHookRequests(root, processIsRunning);
20548
20677
  } catch {
20549
20678
  }
20550
20679
  }
20551
20680
  var STALE_REQUEST_MS = 24 * 60 * 60 * 1e3;
20552
20681
  var REQUEST_FILES = /* @__PURE__ */ new Set(["request.json", "delivery.json", "answer.json", "hook.json", "sending.json", "emitted.json", "failed.json", "closed.json"]);
20553
20682
  function sweepClaudeHookRequests(root, rows, now = Date.now()) {
20683
+ const running = typeof rows === "function" ? rows : (pid, startedIdentity) => rows.find((row) => row.pid === pid)?.started_identity === startedIdentity;
20554
20684
  let entries;
20555
20685
  try {
20556
20686
  entries = fs5.readdirSync(root, { withFileTypes: true });
@@ -20576,7 +20706,7 @@ function sweepClaudeHookRequests(root, rows, now = Date.now()) {
20576
20706
  invocation = invocationSchema.parse(JSON.parse(fs5.readFileSync(path7.join(dir, "request.json"), "utf8")));
20577
20707
  } catch {
20578
20708
  }
20579
- if (invocation && rows.find((row) => row.pid === invocation.parent_pid)?.started_identity === invocation.parent_started_identity)
20709
+ if (invocation && running(invocation.parent_pid, invocation.parent_started_identity))
20580
20710
  continue;
20581
20711
  }
20582
20712
  fs5.rmSync(dir, { recursive: true, force: true });
@@ -20635,7 +20765,7 @@ function closeClaudeParentSession(input2, root) {
20635
20765
  throw failure2;
20636
20766
  }
20637
20767
  function assertParentAlive(invocation) {
20638
- if (processIdentity(invocation.parent_pid) !== invocation.parent_started_identity) {
20768
+ if (!processIsRunning(invocation.parent_pid, invocation.parent_started_identity)) {
20639
20769
  throw new ClaudeDeliveryError("CLAUDE_PARENT_PROCESS_CLOSED", "\u4F9D\u983C\u5143\u306EClaude process\u306F\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002\u56DE\u7B54\u306F\u4FDD\u5B58\u3057\u305F\u307E\u307E\u3067\u3059");
20640
20770
  }
20641
20771
  }
@@ -21146,7 +21276,7 @@ function channelDir(profile, channelId) {
21146
21276
  return path9.join(channelRoot(profile), uuid3.parse(channelId));
21147
21277
  }
21148
21278
  function processIdentity2(pid) {
21149
- return readRuntimeProcesses().find((entry) => entry.pid === pid)?.started_identity;
21279
+ return readProcessIdentities([pid])[0]?.started_identity ?? void 0;
21150
21280
  }
21151
21281
  function mkdirs(...dirs) {
21152
21282
  for (const dir of dirs)
@@ -21255,7 +21385,7 @@ function channelDeliveryState(profile, channelId, deliveryId) {
21255
21385
  return "unknown";
21256
21386
  if (value.state === "withdrawn")
21257
21387
  return "withdrawn";
21258
- if (typeof value.pid === "number" && typeof value.started_identity === "string" && processIdentity2(value.pid) !== value.started_identity)
21388
+ if (typeof value.pid === "number" && typeof value.started_identity === "string" && !processIsRunning(value.pid, value.started_identity))
21259
21389
  return "unknown";
21260
21390
  return "sending";
21261
21391
  }
@@ -21380,7 +21510,7 @@ function acquireWaiter(index) {
21380
21510
  owner = JSON.parse(fs7.readFileSync(file2, "utf8"));
21381
21511
  } catch {
21382
21512
  }
21383
- if (typeof owner.pid === "number" && typeof owner.started_identity === "string" && processIdentity2(owner.pid) === owner.started_identity)
21513
+ if (typeof owner.pid === "number" && typeof owner.started_identity === "string" && processIsRunning(owner.pid, owner.started_identity))
21384
21514
  return null;
21385
21515
  try {
21386
21516
  fs7.renameSync(file2, path9.join(index, `waiter.${randomUUID3()}.stale`));
@@ -21401,9 +21531,10 @@ function releaseWaiter(index, identity) {
21401
21531
  }
21402
21532
  }
21403
21533
  function currentHookOwner() {
21404
- const owner = hookOwnerProcess(readRuntimeProcesses(), process.ppid);
21534
+ const owner = hookOwnerProcess(readProcessLineage(process.ppid), process.ppid);
21405
21535
  return owner ? { pid: owner.pid, started_identity: owner.started_identity } : null;
21406
21536
  }
21537
+ var WAITER_OWNER_IDENTITY_RECHECK_MS = 6e4;
21407
21538
  async function runClaudeChannelWaiter(profile, input2, emit, options = {}) {
21408
21539
  const event = external_exports.object({ session_id: external_exports.uuid() }).loose().parse(input2);
21409
21540
  if (!openClaudeChannels(profile, event.session_id).length)
@@ -21414,15 +21545,22 @@ async function runClaudeChannelWaiter(profile, input2, emit, options = {}) {
21414
21545
  if (!identity)
21415
21546
  return 0;
21416
21547
  const deadline = Date.now() + (options.wait_ms ?? 8634e4);
21548
+ const runtime = options.runtime ?? { exists: processExists, identity: processIdentity2 };
21549
+ const recheckMs = options.identity_recheck_ms ?? WAITER_OWNER_IDENTITY_RECHECK_MS;
21417
21550
  let lastParentCheck = 0;
21551
+ let lastIdentityCheck = null;
21418
21552
  try {
21419
21553
  for (; ; ) {
21420
21554
  const channels = openClaudeChannels(profile, event.session_id);
21421
21555
  if (!channels.length)
21422
21556
  return 0;
21423
- if (Date.now() - lastParentCheck >= 5e3) {
21557
+ if (Date.now() - lastParentCheck >= (options.owner_check_ms ?? 5e3)) {
21424
21558
  lastParentCheck = Date.now();
21425
- const alive = owner ? processIdentity2(owner.pid) === owner.started_identity : channels.some((channel) => processIdentity2(channel.claude.parent_pid) === channel.claude.parent_started_identity);
21559
+ const verify = lastIdentityCheck === null || lastParentCheck - lastIdentityCheck >= recheckMs;
21560
+ if (verify)
21561
+ lastIdentityCheck = lastParentCheck;
21562
+ const running = (pid, identity2) => runtime.exists(pid) && (!verify || runtime.identity(pid) === identity2);
21563
+ const alive = owner ? running(owner.pid, owner.started_identity) : channels.some((channel) => running(channel.claude.parent_pid, channel.claude.parent_started_identity));
21426
21564
  if (!alive)
21427
21565
  return 0;
21428
21566
  }
package/dist/cli.mjs CHANGED
@@ -56,7 +56,7 @@ import {
56
56
  waitProcessCommandLine,
57
57
  withCodexReceiver,
58
58
  withdrawFromChannel
59
- } from "./chunks/chunk-SN7I52NL.mjs";
59
+ } from "./chunks/chunk-HBSDWG62.mjs";
60
60
 
61
61
  // ../../node_modules/qrcode/lib/can-promise.js
62
62
  var require_can_promise = __commonJS({
@@ -12089,7 +12089,9 @@ async function runDaemon() {
12089
12089
  async function deliver(item) {
12090
12090
  const existing = journal[item.decision_id];
12091
12091
  if (existing) return;
12092
- const text2 = item.attachments?.length ? item.text + await saveAll(api, item.decision_id, item.attachments) : item.text;
12092
+ const verify = `
12093
+ \u78BA\u304B\u3081\u308B\u6642\u306F\u3001Approval Box\u306E get_decision \u3092 decision_id="${item.decision_id}" \u3067\u547C\u3076\u3068\u3001\u540C\u3058\u7B54\u3048\u304C\u8FD4\u308A\u307E\u3059\u3002`;
12094
+ const text2 = (item.attachments?.length ? item.text + await saveAll(api, item.decision_id, item.attachments) : item.text) + verify;
12093
12095
  journal[item.decision_id] = { delivery_id: item.delivery_id, channel_id: item.route.channel_id, harness: item.route.harness, state: "sending", at: (/* @__PURE__ */ new Date()).toISOString() };
12094
12096
  save();
12095
12097
  const entry = journal[item.decision_id];
@@ -15905,7 +15907,7 @@ function claudeChannelIsCurrent(profile, channelId, parent) {
15905
15907
  }
15906
15908
 
15907
15909
  // src/version.ts
15908
- var VERSION = true ? "0.1.22" : "0.0.0-dev";
15910
+ var VERSION = true ? "0.1.24" : "0.0.0-dev";
15909
15911
  function osName() {
15910
15912
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15911
15913
  }
@@ -16080,6 +16082,7 @@ async function channelFor(harness, clientName, meta) {
16080
16082
  remember(key, channel.channel_id, false);
16081
16083
  return channel.channel_id;
16082
16084
  }
16085
+ var ARRIVAL = "\u7B54\u3048\u306F\u3001\u3042\u3068\u3067\u3053\u306E\u4F1A\u8A71\u3078\u300C[Approval Box]\u300D\u3067\u59CB\u307E\u308B\u6587\u3068\u3057\u3066\u81EA\u52D5\u3067\u5C4A\u304D\u307E\u3059\u3002\u4F5C\u696D\u306E\u9014\u4E2D\u306A\u3089\u3001\u307B\u304B\u306E\u9053\u5177\u306E\u7D50\u679C\u3084 hook \u306E\u901A\u77E5\u3068\u4E00\u7DD2\u306B\u5C4A\u304F\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002\u5C4A\u3044\u305F\u7B54\u3048\u306F get_decision \u3067\u78BA\u304B\u3081\u3089\u308C\u307E\u3059\u3002";
16083
16086
  function receiveGuide(harness, channelId) {
16084
16087
  if (harness === "codex" || harness === "claude") return "";
16085
16088
  const line = waitProcessCommandLine(channelReceiveProcess(runtimeEntry("receive"), channelId));
@@ -16092,6 +16095,11 @@ function receiveGuide(harness, channelId) {
16092
16095
  );
16093
16096
  return lines.join("\n");
16094
16097
  }
16098
+ function announced(message, decision, channelId) {
16099
+ return text(`${message}
16100
+
16101
+ ${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId }, guide: message });
16102
+ }
16095
16103
  function text(value, structured, isError = false) {
16096
16104
  return { content: [{ type: "text", text: value }], ...structured ? { structuredContent: structured } : {}, ...isError ? { isError: true } : {} };
16097
16105
  }
@@ -16138,10 +16146,8 @@ ${JSON.stringify({ items })}`, { items });
16138
16146
  };
16139
16147
  try {
16140
16148
  const decision = await api.call("POST", "/decisions", body);
16141
- const message = `\u7533\u8ACB\u3057\u307E\u3057\u305F: ${decision.decision_id}\u300C${decision.title}\u300D\u3002\u7B54\u3048\u306F\u3053\u306E\u4F1A\u8A71\u3078\u81EA\u52D5\u3067\u5C4A\u304D\u307E\u3059\u3002\u5F85\u3063\u3066\u547C\u3073\u76F4\u3055\u305A\u3001\u4ED6\u306E\u4F5C\u696D\u3092\u7D9A\u3051\u308B\u304B\u30BF\u30FC\u30F3\u3092\u7D42\u3048\u3066\u304F\u3060\u3055\u3044\u3002`;
16142
- return text(`${message}${receiveGuide(harness, channelId)}
16143
-
16144
- ${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
16149
+ const message = `\u7533\u8ACB\u3057\u307E\u3057\u305F: ${decision.decision_id}\u300C${decision.title}\u300D\u3002${ARRIVAL}\u5F85\u3063\u3066\u547C\u3073\u76F4\u3055\u305A\u3001\u4ED6\u306E\u4F5C\u696D\u3092\u7D9A\u3051\u308B\u304B\u30BF\u30FC\u30F3\u3092\u7D42\u3048\u3066\u304F\u3060\u3055\u3044\u3002`;
16150
+ return announced(`${message}${receiveGuide(harness, channelId)}`, decision, channelId);
16145
16151
  } catch (error) {
16146
16152
  if (error instanceof ServerError && error.code === "confirm_required") {
16147
16153
  const decisions = error.body.decisions ?? [];
@@ -16179,18 +16185,14 @@ ${JSON.stringify({ error: "duplicate_suspected", existing })}`, { error: "duplic
16179
16185
  const channelId = await channelFor(harness, clientName, request.params._meta);
16180
16186
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(decision_id))}/amend`, { ...rest, route: { channel_id: channelId, harness } });
16181
16187
  lastChannel = channelId;
16182
- return text(`\u76F4\u3057\u307E\u3057\u305F: ${decision.decision_id} version=${decision.version}${receiveGuide(harness, channelId)}
16183
-
16184
- ${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
16188
+ return announced(`\u76F4\u3057\u307E\u3057\u305F: ${decision.decision_id} version=${decision.version}${receiveGuide(harness, channelId)}`, decision, channelId);
16185
16189
  }
16186
16190
  if (name === "resume_decision") {
16187
16191
  const channelId = await channelFor(harness, clientName, request.params._meta);
16188
16192
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/resume`, { channel_id: channelId, harness });
16189
16193
  lastChannel = channelId;
16190
- const head = decision.answer_text ? String(decision.answer_text) : `\u518D\u958B\u3057\u307E\u3057\u305F: ${decision.decision_id}\u3002\u7B54\u3048\u306F\u3053\u306E\u4F1A\u8A71\u3078\u5C4A\u304D\u307E\u3059\u3002`;
16191
- return text(`${head}${decision.answer_text ? "" : receiveGuide(harness, channelId)}
16192
-
16193
- ${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
16194
+ const head = decision.answer_text ? String(decision.answer_text) : `\u518D\u958B\u3057\u307E\u3057\u305F: ${decision.decision_id}\u3002${ARRIVAL}`;
16195
+ return announced(`${head}${decision.answer_text ? "" : receiveGuide(harness, channelId)}`, decision, channelId);
16194
16196
  }
16195
16197
  if (name === "cancel_decision") {
16196
16198
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/cancel`, { reason: args.reason });
@@ -16232,9 +16234,7 @@ ${JSON.stringify(decision)}`, decision);
16232
16234
  route: { channel_id: channelId, harness }
16233
16235
  });
16234
16236
  const message = `\u63A5\u7D9A\u30C6\u30B9\u30C8\u306E\u7533\u8ACB\u3092\u9001\u308A\u307E\u3057\u305F\uFF08${decision.decision_id}\uFF09\u3002\u5229\u7528\u8005\u306B\u30A2\u30D7\u30EA\u304BWeb\u7248\u3067\u7B54\u3048\u308B\u3088\u3046\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002\u7B54\u3048\u304C\u3053\u306E\u4F1A\u8A71\u3078\u5C4A\u3044\u305F\u3089\u3001\u305D\u3053\u306B\u66F8\u304B\u308C\u305F\u78BA\u8A8D\u30B3\u30FC\u30C9\u3067 confirm_setup_test \u3092\u547C\u3093\u3067\u304F\u3060\u3055\u3044\u3002`;
16235
- return text(`${message}${receiveGuide(harness, channelId)}
16236
-
16237
- ${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
16237
+ return announced(`${message}${receiveGuide(harness, channelId)}`, decision, channelId);
16238
16238
  }
16239
16239
  if (name === "confirm_setup_test") {
16240
16240
  const result = await api.call("POST", "/setup-test/confirm", { decision_id: args.decision_id, code: String(args.code) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "approval-box",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
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.4.4",
35
+ "aiterm-steer-delivery": "0.4.5",
36
36
  "esbuild": "^0.28.2",
37
37
  "qrcode": "^1.5.4",
38
38
  "typescript": "^6.0.3",