approval-box 0.1.26 → 0.1.28

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 CHANGED
@@ -60,3 +60,11 @@ AIには、利用者へ申請の話をする時は件名で伝えるよう返し
60
60
  ### 申請に画像を添える
61
61
 
62
62
  `request_decision` に `image_paths: ["/absolute/path/screenshot.png"]` を指定すると、AIの画像を本文下に添えて申請します。10件、単体20MiB、合計50MiBまで。全画像を上げてから申請と通知を確定します。最初の確認の札を付けた出し直しでも同じ画像パスを渡してください。`amend_decision.changes.image_paths` は全置換、空配列で削除です。回答添付とは別の欄です。リモートMCPは `upload_request_image` のIDを `request_attachment_ids` に渡します。
63
+
64
+ ### 読みやすい申請文
65
+
66
+ MCPは、[unai](https://github.com/kitepon/unai)の方針に沿って申請文を推敲するようAIへ伝えます。件名で判断してほしいことを示し、背景では判断に必要な理由と影響を先に説明します。各AIの口調や、承認対象・範囲・費用・危険・期限・未確認事項を保ちます。
67
+
68
+ 例:「ランタイム更新の実行可否について」より「Approval Boxの実行環境を更新してよいですか?」、背景には「セキュリティ修正を適用します。更新中は数秒使えなくなります。」のように具体的に書きます。
69
+
70
+ AIへの執筆指示のため、文章の品質を機械的に保証するものではありません。保存済みの申請・回答は書き換えません。ローカル接続ではコネクタ0.1.27へ更新し、MCPを再接続すると新しい指示を取得できます。
@@ -2,7 +2,7 @@
2
2
 
3
3
  approval-box bundles the following packages.
4
4
 
5
- ## @modelcontextprotocol/sdk@1.31.0 (MIT)
5
+ ## @modelcontextprotocol/sdk@1.32.2 (MIT)
6
6
 
7
7
  ```
8
8
  MIT License
@@ -157,7 +157,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
157
157
  SOFTWARE.
158
158
  ```
159
159
 
160
- ## fast-uri@3.1.8 (BSD-3-Clause)
160
+ ## fast-uri@3.1.9 (BSD-3-Clause)
161
161
 
162
162
  ```
163
163
  Copyright (c) 2011-2021, Gary Court until https://github.com/garycourt/uri-js/commit/a1acf730b4bba3f1097c9f52e7d9d3aba8cdcaae
@@ -257,7 +257,7 @@ The above copyright notice and this permission notice shall be included in all c
257
257
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
258
258
  ```
259
259
 
260
- ## zod@4.6.5 (MIT)
260
+ ## zod@4.6.7 (MIT)
261
261
 
262
262
  ```
263
263
  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-XTKJLDHY.mjs";
5
+ } from "./chunks/chunk-GFEMLSCW.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-XTKJLDHY.mjs";
8
+ } from "./chunks/chunk-GFEMLSCW.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-XTKJLDHY.mjs";
5
+ } from "./chunks/chunk-GFEMLSCW.mjs";
6
6
 
7
7
  // src/hooks/receive.ts
8
8
  await runChannelReceiveMain(PROFILE);
@@ -734,6 +734,7 @@ __export(util_exports, {
734
734
  required: () => required,
735
735
  safeExtend: () => safeExtend,
736
736
  shallowClone: () => shallowClone,
737
+ sizeCaps: () => sizeCaps,
737
738
  slugify: () => slugify,
738
739
  stringifyPrimitive: () => stringifyPrimitive,
739
740
  toZod: () => toZod,
@@ -1253,6 +1254,18 @@ function prefixIssues(path12, issues) {
1253
1254
  function unwrapMessage(message) {
1254
1255
  return typeof message === "string" ? message : message?.message;
1255
1256
  }
1257
+ function sizeCaps(defChecks) {
1258
+ const caps = [];
1259
+ for (const ch of defChecks ?? []) {
1260
+ const d = ch._zod.def;
1261
+ if (!/_(length|size)$|_equals$/.test(d.check))
1262
+ break;
1263
+ const max = d.maximum ?? d.length ?? d.size;
1264
+ if (max >= 0)
1265
+ caps.push([max, ch]);
1266
+ }
1267
+ return caps;
1268
+ }
1256
1269
  function attachSchema(issues, start, inst) {
1257
1270
  var _a3;
1258
1271
  for (let i = start; i < issues.length; i++) {
@@ -2673,7 +2686,7 @@ ${content.join("\n")}
2673
2686
  var version = {
2674
2687
  major: 4,
2675
2688
  minor: 6,
2676
- patch: 5
2689
+ patch: 7
2677
2690
  };
2678
2691
 
2679
2692
  // ../../node_modules/zod/v4/core/schemas.js
@@ -3429,6 +3442,31 @@ var $ZodDate = /* @__PURE__ */ $constructor("$ZodDate", (inst, def) => {
3429
3442
  return payload;
3430
3443
  };
3431
3444
  });
3445
+ function capSize(inst, size) {
3446
+ const caps = sizeCaps(inst._zod.def.checks);
3447
+ if (!caps.length)
3448
+ return;
3449
+ const cap = Math.min(...caps.map((c) => c[0]));
3450
+ const parse3 = inst._zod.parse;
3451
+ inst._zod.parse = (payload, ctx) => {
3452
+ const n = size(payload.value);
3453
+ if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
3454
+ for (const [max, ch] of sizeCaps(inst._zod.def.checks)) {
3455
+ if (n > max && ch._zod.def.when(payload)) {
3456
+ const start = payload.issues.length;
3457
+ ch._zod.check(payload);
3458
+ payload.issues[start].continue = false;
3459
+ attachSchema(payload.issues, start, inst);
3460
+ return payload;
3461
+ }
3462
+ }
3463
+ }
3464
+ return parse3(payload, ctx);
3465
+ };
3466
+ }
3467
+ var arraySize = (input2) => Array.isArray(input2) ? input2.length : -1;
3468
+ var mapSize = (input2) => input2 instanceof Map ? input2.size : -1;
3469
+ var setSize = (input2) => input2 instanceof Set ? input2.size : -1;
3432
3470
  function handleArrayResult(result, final, index) {
3433
3471
  if (result.issues.length) {
3434
3472
  final.issues.push(...prefixIssues(index, result.issues));
@@ -3472,6 +3510,7 @@ var $ZodArray = /* @__PURE__ */ $constructor("$ZodArray", (inst, def) => {
3472
3510
  }
3473
3511
  return payload;
3474
3512
  };
3513
+ capSize(inst, arraySize);
3475
3514
  });
3476
3515
  function handlePropertyResult(result, final, key, input2, optin, optout) {
3477
3516
  const isPresent = key in input2;
@@ -4428,6 +4467,7 @@ var $ZodMap = /* @__PURE__ */ $constructor("$ZodMap", (inst, def) => {
4428
4467
  return Promise.all(proms).then(() => payload);
4429
4468
  return payload;
4430
4469
  };
4470
+ capSize(inst, mapSize);
4431
4471
  });
4432
4472
  function handleMapResult(keyResult, valueResult, final, key, input2, inst, ctx) {
4433
4473
  if (keyResult.issues.length) {
@@ -4494,6 +4534,7 @@ var $ZodSet = /* @__PURE__ */ $constructor("$ZodSet", (inst, def) => {
4494
4534
  return Promise.all(proms).then(() => payload);
4495
4535
  return payload;
4496
4536
  };
4537
+ capSize(inst, setSize);
4497
4538
  });
4498
4539
  function handleSetResult(result, final) {
4499
4540
  if (result.issues.length) {
@@ -14024,9 +14065,15 @@ function generateNullableCheck(doc, ctx, schema, accessor, buildsValue = true) {
14024
14065
  doc.write(`}`);
14025
14066
  return outputVar;
14026
14067
  }
14068
+ function generateSizeGate(doc, schema, size) {
14069
+ for (const [max, check2] of sizeCaps(schema._zod.def.checks)) {
14070
+ doc.write(`if (${size} > ${numericOperand(max, check2._zod.def.check)}) return INVALID;`);
14071
+ }
14072
+ }
14027
14073
  function generateArrayCheck(doc, ctx, schema, accessor, buildsValue = true) {
14028
14074
  const def = schema._zod.def;
14029
14075
  doc.write(`if (!Array.isArray(${accessor})) return INVALID;`);
14076
+ generateSizeGate(doc, schema, `${accessor}.length`);
14030
14077
  const outputVar = buildsValue ? newVar(ctx) : null;
14031
14078
  const iVar = newVar(ctx);
14032
14079
  const elemVar = newVar(ctx);
@@ -14426,6 +14473,7 @@ function literalPropertyKey(ctx, key) {
14426
14473
  function generateMapCheck(doc, ctx, schema, accessor) {
14427
14474
  const def = schema._zod.def;
14428
14475
  doc.write(`if (!(${accessor} instanceof Map)) return INVALID;`);
14476
+ generateSizeGate(doc, schema, `${accessor}.size`);
14429
14477
  const outputVar = newVar(ctx);
14430
14478
  const kVar = newVar(ctx);
14431
14479
  const valVar = newVar(ctx);
@@ -14442,6 +14490,7 @@ function generateMapCheck(doc, ctx, schema, accessor) {
14442
14490
  function generateSetCheck(doc, ctx, schema, accessor) {
14443
14491
  const def = schema._zod.def;
14444
14492
  doc.write(`if (!(${accessor} instanceof Set)) return INVALID;`);
14493
+ generateSizeGate(doc, schema, `${accessor}.size`);
14445
14494
  const outputVar = newVar(ctx);
14446
14495
  const valVar = newVar(ctx);
14447
14496
  doc.write(`const ${outputVar} = new Set();`);
package/dist/cli.mjs CHANGED
@@ -57,7 +57,7 @@ import {
57
57
  waitProcessCommandLine,
58
58
  withCodexReceiver,
59
59
  withdrawFromChannel
60
- } from "./chunks/chunk-XTKJLDHY.mjs";
60
+ } from "./chunks/chunk-GFEMLSCW.mjs";
61
61
 
62
62
  // ../../node_modules/qrcode/lib/can-promise.js
63
63
  var require_can_promise = __commonJS({
@@ -7896,6 +7896,37 @@ var require_utils3 = __commonJS({
7896
7896
  }
7897
7897
  return output.join("");
7898
7898
  }
7899
+ function removeDotSegmentsRelative(path) {
7900
+ if (path === "" || path[0] === "/") {
7901
+ return removeDotSegments(path);
7902
+ }
7903
+ const segments = path.split("/");
7904
+ const last = segments.length - 1;
7905
+ const output = [];
7906
+ let trailingDirectory = false;
7907
+ for (let i = 0; i <= last; i++) {
7908
+ const segment = segments[i];
7909
+ if (segment === "." || segment === "..") {
7910
+ if (segment === "..") {
7911
+ if (output.length !== 0 && output[output.length - 1] !== "..") {
7912
+ output.pop();
7913
+ } else {
7914
+ output.push("..");
7915
+ }
7916
+ }
7917
+ trailingDirectory = i === last;
7918
+ } else {
7919
+ output.push(segment);
7920
+ }
7921
+ }
7922
+ if (trailingDirectory && output[output.length - 1] !== "..") {
7923
+ output.push("");
7924
+ }
7925
+ if (output.length === 0 || output[0] === "" || output[0].includes(":")) {
7926
+ output.unshift(".");
7927
+ }
7928
+ return output.join("/");
7929
+ }
7899
7930
  var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
7900
7931
  var HOST_DELIM_RE = /[@/?#:]/g;
7901
7932
  var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
@@ -8156,6 +8187,7 @@ var require_utils3 = __commonJS({
8156
8187
  encodeFragment,
8157
8188
  escapePreservingEscapes,
8158
8189
  removeDotSegments,
8190
+ removeDotSegmentsRelative,
8159
8191
  isIPv4,
8160
8192
  isUUID,
8161
8193
  normalizeIPv6,
@@ -8379,16 +8411,18 @@ var require_schemes = __commonJS({
8379
8411
  var require_fast_uri = __commonJS({
8380
8412
  "../../node_modules/fast-uri/index.js"(exports, module) {
8381
8413
  "use strict";
8382
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils3();
8414
+ var { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils3();
8383
8415
  var { SCHEMES, getSchemeHandler } = require_schemes();
8384
8416
  var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
8385
8417
  var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
8386
- function decodeValidScheme(scheme) {
8387
- const decodedScheme = unescape(String(scheme));
8388
- if (!VALID_SCHEME.test(decodedScheme)) {
8418
+ var MALFORMED_HOST_ERROR = "URI host is malformed.";
8419
+ var FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
8420
+ function validateScheme(scheme) {
8421
+ const stringScheme = String(scheme);
8422
+ if (!VALID_SCHEME.test(stringScheme)) {
8389
8423
  throw new TypeError(MALFORMED_SCHEME_ERROR);
8390
8424
  }
8391
- return decodedScheme;
8425
+ return stringScheme;
8392
8426
  }
8393
8427
  function normalize(uri, options) {
8394
8428
  if (typeof uri === "string") {
@@ -8425,6 +8459,9 @@ var require_fast_uri = __commonJS({
8425
8459
  const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
8426
8460
  const resolvedHost = resolved.host;
8427
8461
  const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
8462
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
8463
+ throw new Error(MALFORMED_HOST_ERROR);
8464
+ }
8428
8465
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
8429
8466
  const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
8430
8467
  if (resolved.error && !encodedASCIIHost) {
@@ -8466,14 +8503,15 @@ var require_fast_uri = __commonJS({
8466
8503
  if (relative.path[0] === "/") {
8467
8504
  target.path = removeDotSegments(relative.path);
8468
8505
  } else {
8469
- if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
8506
+ const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
8507
+ if (baseHasAuthority && !base.path) {
8470
8508
  target.path = "/" + relative.path;
8471
8509
  } else if (!base.path) {
8472
8510
  target.path = relative.path;
8473
8511
  } else {
8474
8512
  target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative.path;
8475
8513
  }
8476
- target.path = removeDotSegments(target.path);
8514
+ target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
8477
8515
  }
8478
8516
  target.query = relative.query;
8479
8517
  }
@@ -8511,12 +8549,13 @@ var require_fast_uri = __commonJS({
8511
8549
  const options = Object.assign({}, opts);
8512
8550
  const uriTokens = [];
8513
8551
  if (component.scheme) {
8514
- component.scheme = decodeValidScheme(component.scheme);
8552
+ component.scheme = validateScheme(component.scheme);
8515
8553
  }
8516
8554
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
8517
8555
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
8518
8556
  const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
8519
- const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
8557
+ const schemelessReference = (component.scheme === void 0 || options.reference === "suffix") && !hasAuthority;
8558
+ const pathNoScheme = !options.skipEscape && schemelessReference;
8520
8559
  if (component.path !== void 0) {
8521
8560
  if (!options.skipEscape) {
8522
8561
  component.path = serializePathEncoding(component.path, pathNoScheme);
@@ -8525,7 +8564,7 @@ var require_fast_uri = __commonJS({
8525
8564
  }
8526
8565
  }
8527
8566
  if (options.reference !== "suffix" && component.scheme) {
8528
- component.scheme = decodeValidScheme(component.scheme);
8567
+ component.scheme = validateScheme(component.scheme);
8529
8568
  uriTokens.push(component.scheme, ":");
8530
8569
  }
8531
8570
  const authority = recomposeAuthority(component);
@@ -8541,9 +8580,9 @@ var require_fast_uri = __commonJS({
8541
8580
  if (component.path !== void 0) {
8542
8581
  let s = component.path;
8543
8582
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
8544
- s = removeDotSegments(s);
8583
+ s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
8545
8584
  }
8546
- if (pathNoScheme) {
8585
+ if (schemelessReference) {
8547
8586
  s = serializePathEncoding(s, true);
8548
8587
  }
8549
8588
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
@@ -8590,16 +8629,34 @@ var require_fast_uri = __commonJS({
8590
8629
  return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
8591
8630
  }
8592
8631
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
8632
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
8633
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
8634
+ return true;
8635
+ }
8593
8636
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
8637
+ let url;
8594
8638
  try {
8595
- parsed.host = new URL("http://" + parsed.host).hostname;
8639
+ url = new URL("http://" + parsed.host);
8596
8640
  } catch (e) {
8597
8641
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
8598
8642
  return true;
8599
8643
  }
8644
+ if (!isHostOnlyURL(url)) {
8645
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
8646
+ return true;
8647
+ }
8648
+ parsed.host = url.hostname;
8600
8649
  }
8601
8650
  return false;
8602
8651
  }
8652
+ function hasForbiddenDomainHost(parsed, options, schemeHandler, isIP) {
8653
+ return Boolean(
8654
+ parsed.host && isIP === false && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host)
8655
+ );
8656
+ }
8657
+ function isHostOnlyURL(url) {
8658
+ return url.username === "" && url.password === "" && url.port === "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.hostname !== "";
8659
+ }
8603
8660
  function parseWithStatus(uri, opts) {
8604
8661
  const options = Object.assign({}, opts);
8605
8662
  const parsed = {
@@ -8654,9 +8711,8 @@ var require_fast_uri = __commonJS({
8654
8711
  parsed.query = matches[7];
8655
8712
  parsed.fragment = matches[8];
8656
8713
  if (parsed.scheme !== void 0) {
8657
- const decodedScheme = unescape(parsed.scheme);
8658
- if (VALID_SCHEME.test(decodedScheme)) {
8659
- parsed.scheme = decodedScheme.toLowerCase();
8714
+ if (VALID_SCHEME.test(parsed.scheme)) {
8715
+ parsed.scheme = parsed.scheme.toLowerCase();
8660
8716
  } else {
8661
8717
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
8662
8718
  malformedScheme = true;
@@ -8684,7 +8740,7 @@ var require_fast_uri = __commonJS({
8684
8740
  malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
8685
8741
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
8686
8742
  if (malformedIPLiteral) {
8687
- parsed.error = parsed.error || "URI host is malformed.";
8743
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
8688
8744
  malformedAuthorityOrPort = true;
8689
8745
  }
8690
8746
  } else {
@@ -8712,7 +8768,7 @@ var require_fast_uri = __commonJS({
8712
8768
  if (!isIP) {
8713
8769
  host = normalizePercentEncoding(host.toLowerCase());
8714
8770
  }
8715
- parsed.host = reescapeHostDelimiters(host, isIP);
8771
+ parsed.host = isIP || options.scheme !== "null" ? reescapeHostDelimiters(host, isIP) : host;
8716
8772
  }
8717
8773
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
8718
8774
  if (parsed.path) {
@@ -11884,11 +11940,32 @@ function writeConfig(config) {
11884
11940
 
11885
11941
  // src/daemon-launch.ts
11886
11942
  import { spawn, spawnSync } from "node:child_process";
11887
- import { appendFileSync, closeSync, openSync } from "node:fs";
11943
+ import { writeFileSync as writeFileSync2 } from "node:fs";
11888
11944
  import { join as join2, resolve } from "node:path";
11945
+ function daemonBootstrap(entry, cwd, environment = {}) {
11946
+ return `Object.assign(process.env,${JSON.stringify(environment)});
11947
+ const fs=require('node:fs'),file=${JSON.stringify(join2(cwd, "daemon.log"))},fallback=process.stderr.write.bind(process.stderr);
11948
+ process.stderr.write=(chunk,encoding,callback)=>{
11949
+ try {
11950
+ const limit=1024*1024,next=Buffer.from(chunk,typeof encoding==='string'?encoding:undefined).subarray(-limit);
11951
+ const fd=fs.openSync(file,fs.constants.O_CREAT|fs.constants.O_RDWR,0o600);
11952
+ try {
11953
+ const size=fs.fstatSync(fd).size,keep=Math.min(size,limit-next.length),data=Buffer.alloc(keep+next.length);
11954
+ const read=keep?fs.readSync(fd,data,0,keep,size-keep):0;
11955
+ next.copy(data,read);
11956
+ fs.writeFileSync(fd,data.subarray(0,read+next.length));
11957
+ fs.ftruncateSync(fd,read+next.length);
11958
+ } finally { fs.closeSync(fd); }
11959
+ } catch { try { fallback('approval-box: daemon log write failed\\n'); } catch {} }
11960
+ if(typeof encoding==='function')encoding();else if(typeof callback==='function')callback();
11961
+ return true;
11962
+ };
11963
+ process.argv=[process.execPath,${JSON.stringify(entry)},'daemon'];
11964
+ import(require('node:url').pathToFileURL(${JSON.stringify(entry)}).href).catch(error=>{process.stderr.write(String(error)+'\\n');process.exit(1);});`;
11965
+ }
11889
11966
  function windowsDaemonLaunchScript(executable, entry, cwd, environment) {
11890
11967
  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]]]));
11891
- 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);});`;
11968
+ const bootstrap = daemonBootstrap(entry, cwd, env);
11892
11969
  const command2 = `"${executable}" -e "eval(Buffer.from('${Buffer.from(bootstrap).toString("base64")}','base64').toString())"`;
11893
11970
  const literal2 = (s) => `'${s.replaceAll("'", "''")}'`;
11894
11971
  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`;
@@ -11902,22 +11979,17 @@ function launchDaemon(executable, entry, cwd) {
11902
11979
  return;
11903
11980
  }
11904
11981
  const file = join2(cwd, "daemon.log");
11905
- const log = openSync(file, "a", 384);
11906
- try {
11907
- const child = spawn(executable, [entry, "daemon"], { cwd, detached: true, stdio: ["ignore", "ignore", log], windowsHide: true });
11908
- child.on("error", (error) => {
11909
- const line = `approval-box: \u914D\u9001\u30C7\u30FC\u30E2\u30F3\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\uFF08DAEMON_LAUNCH_FAILED\uFF09: ${executable}: ${error.message}
11982
+ const child = spawn(executable, ["-e", daemonBootstrap(entry, cwd)], { cwd, detached: true, stdio: "ignore", windowsHide: true });
11983
+ child.on("error", (error) => {
11984
+ const line = `approval-box: \u914D\u9001\u30C7\u30FC\u30E2\u30F3\u3092\u8D77\u52D5\u3067\u304D\u307E\u305B\u3093\uFF08DAEMON_LAUNCH_FAILED\uFF09: ${executable}: ${error.message}
11910
11985
  `;
11911
- try {
11912
- appendFileSync(file, `${(/* @__PURE__ */ new Date()).toISOString()} ${line}`, { mode: 384 });
11913
- } catch {
11914
- }
11915
- process.stderr.write(line);
11916
- });
11917
- child.unref();
11918
- } finally {
11919
- closeSync(log);
11920
- }
11986
+ try {
11987
+ writeFileSync2(file, Buffer.from(`${(/* @__PURE__ */ new Date()).toISOString()} ${line}`).subarray(-1024 * 1024), { mode: 384 });
11988
+ } catch {
11989
+ }
11990
+ process.stderr.write(line);
11991
+ });
11992
+ child.unref();
11921
11993
  }
11922
11994
 
11923
11995
  // src/channel-delivery.ts
@@ -11955,7 +12027,7 @@ import { join as join5 } from "node:path";
11955
12027
 
11956
12028
  // src/attachments.ts
11957
12029
  import { createHash } from "node:crypto";
11958
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, statSync, writeFileSync as writeFileSync2 } from "node:fs";
12030
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readdirSync, readFileSync as readFileSync2, rmSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
11959
12031
  import { join as join3 } from "node:path";
11960
12032
  var KEEP_DAYS = 30;
11961
12033
  var attachmentsRoot = () => join3(home(), "attachments");
@@ -11970,7 +12042,7 @@ async function saveAttachment(api, decisionId, meta, index) {
11970
12042
  const data = await api.download(`/decisions/${encodeURIComponent(decisionId)}/attachments/${encodeURIComponent(meta.id)}`);
11971
12043
  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`);
11972
12044
  mkdirSync2(dir, { recursive: true, mode: 448 });
11973
- writeFileSync2(file, data, { mode: 384 });
12045
+ writeFileSync3(file, data, { mode: 384 });
11974
12046
  return file;
11975
12047
  }
11976
12048
  async function saveAll(api, decisionId, items) {
@@ -12248,7 +12320,7 @@ import { homedir as homedir2 } from "node:os";
12248
12320
  import { delimiter, dirname as dirname4, join as join7 } from "node:path";
12249
12321
 
12250
12322
  // src/instructions.ts
12251
- import { existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, readlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
12323
+ import { existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readdirSync as readdirSync2, readlinkSync, writeFileSync as writeFileSync4 } from "node:fs";
12252
12324
  import { homedir } from "node:os";
12253
12325
  import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
12254
12326
  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";
@@ -12296,7 +12368,7 @@ function writeInstructions(file) {
12296
12368
  if (managedElsewhere(file)) return "managed_elsewhere";
12297
12369
  const current = existsSync4(file) ? readFileSync4(file, "utf8").replace(PATTERN, "\n").trimEnd() : "";
12298
12370
  mkdirSync4(dirname3(file), { recursive: true, mode: 448 });
12299
- writeFileSync3(file, current ? `${current}
12371
+ writeFileSync4(file, current ? `${current}
12300
12372
 
12301
12373
  ${BLOCK}` : BLOCK);
12302
12374
  return "written";
@@ -12304,7 +12376,7 @@ ${BLOCK}` : BLOCK);
12304
12376
  function removeInstructions(file) {
12305
12377
  if (!existsSync4(file) || !readFileSync4(file, "utf8").includes(START)) return;
12306
12378
  const rest = readFileSync4(file, "utf8").replace(PATTERN, "\n").trimEnd();
12307
- writeFileSync3(file, rest ? `${rest}
12379
+ writeFileSync4(file, rest ? `${rest}
12308
12380
  ` : "");
12309
12381
  }
12310
12382
 
@@ -14154,6 +14226,9 @@ var Protocol = class {
14154
14226
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
14155
14227
  const handleTaskResult = async () => {
14156
14228
  const taskId = request.params.taskId;
14229
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
14230
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14231
+ }
14157
14232
  if (this._taskMessageQueue) {
14158
14233
  let queuedMessage;
14159
14234
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -14184,12 +14259,12 @@ var Protocol = class {
14184
14259
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14185
14260
  }
14186
14261
  if (!isTerminal(task.status)) {
14187
- await this._waitForTaskUpdate(taskId, extra.signal);
14262
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
14188
14263
  return await handleTaskResult();
14189
14264
  }
14190
14265
  if (isTerminal(task.status)) {
14191
14266
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
14192
- this._clearTaskQueue(taskId);
14267
+ this._clearTaskQueue(taskId, extra.sessionId);
14193
14268
  return {
14194
14269
  ...result,
14195
14270
  _meta: {
@@ -14226,7 +14301,7 @@ var Protocol = class {
14226
14301
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
14227
14302
  }
14228
14303
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
14229
- this._clearTaskQueue(request.params.taskId);
14304
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
14230
14305
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
14231
14306
  if (!cancelledTask) {
14232
14307
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -14354,6 +14429,19 @@ var Protocol = class {
14354
14429
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
14355
14430
  const capturedTransport = this._transport;
14356
14431
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
14432
+ const sessionId = capturedTransport?.sessionId;
14433
+ const store = this._taskStore;
14434
+ let relatedTaskFound = true;
14435
+ let relatedTaskLookup;
14436
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
14437
+ relatedTaskFound = false;
14438
+ relatedTaskLookup = (async () => {
14439
+ if (!await store.getTask(relatedTaskId, sessionId)) {
14440
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
14441
+ }
14442
+ relatedTaskFound = true;
14443
+ })();
14444
+ }
14357
14445
  if (handler === void 0) {
14358
14446
  const errorResponse = {
14359
14447
  jsonrpc: "2.0",
@@ -14363,7 +14451,10 @@ var Protocol = class {
14363
14451
  message: "Method not found"
14364
14452
  }
14365
14453
  };
14366
- if (relatedTaskId && this._taskMessageQueue) {
14454
+ if (relatedTaskId && relatedTaskLookup) {
14455
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
14456
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error) => this._onerror(new Error(`Failed to send an error response: ${error}`)));
14457
+ } else if (relatedTaskId && this._taskMessageQueue) {
14367
14458
  this._enqueueTaskMessage(relatedTaskId, {
14368
14459
  type: "error",
14369
14460
  message: errorResponse,
@@ -14414,7 +14505,10 @@ var Protocol = class {
14414
14505
  closeSSEStream: extra?.closeSSEStream,
14415
14506
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
14416
14507
  };
14417
- Promise.resolve().then(() => {
14508
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
14509
+ if (relatedTaskLookup && abortController.signal.aborted) {
14510
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
14511
+ }
14418
14512
  if (taskCreationParams) {
14419
14513
  this.assertTaskHandlerCapability(request.method);
14420
14514
  }
@@ -14449,7 +14543,7 @@ var Protocol = class {
14449
14543
  ...error["data"] !== void 0 && { data: error["data"] }
14450
14544
  }
14451
14545
  };
14452
- if (relatedTaskId && this._taskMessageQueue) {
14546
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
14453
14547
  await this._enqueueTaskMessage(relatedTaskId, {
14454
14548
  type: "error",
14455
14549
  message: errorResponse,
@@ -14929,7 +15023,7 @@ var Protocol = class {
14929
15023
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
14930
15024
  }
14931
15025
  const maxQueueSize = this._options?.maxTaskQueueSize;
14932
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
15026
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
14933
15027
  }
14934
15028
  /**
14935
15029
  * Clears the message queue for a task and rejects any pending request resolvers.
@@ -14958,12 +15052,13 @@ var Protocol = class {
14958
15052
  * Uses polling to check for updates at the task's configured poll interval.
14959
15053
  * @param taskId The task ID to wait for
14960
15054
  * @param signal Abort signal to cancel the wait
15055
+ * @param sessionId Session of the request that waits, passed to the task store
14961
15056
  * @returns Promise that resolves when an update occurs or rejects if aborted
14962
15057
  */
14963
- async _waitForTaskUpdate(taskId, signal) {
15058
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
14964
15059
  let interval = this._options?.defaultTaskPollInterval ?? 1e3;
14965
15060
  try {
14966
- const task = await this._taskStore?.getTask(taskId);
15061
+ const task = await this._taskStore?.getTask(taskId, sessionId);
14967
15062
  if (task?.pollInterval) {
14968
15063
  interval = task.pollInterval;
14969
15064
  }
@@ -15922,7 +16017,7 @@ function claudeChannelIsCurrent(profile, channelId, parent) {
15922
16017
  }
15923
16018
 
15924
16019
  // src/version.ts
15925
- var VERSION = true ? "0.1.26" : "0.0.0-dev";
16020
+ var VERSION = true ? "0.1.28" : "0.0.0-dev";
15926
16021
  function osName() {
15927
16022
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15928
16023
  }
@@ -15937,7 +16032,9 @@ function harnessOf(clientName) {
15937
16032
  if (name.startsWith("grok")) return "grok";
15938
16033
  return "other";
15939
16034
  }
16035
+ var QUESTION_STYLE = "\u7533\u8ACB\u6587\u306F unai\uFF08https://github.com/kitepon/unai\uFF09\u306E\u65B9\u91DD\u3067\u63A8\u6572\u3059\u308B\u3002\u5404AI\u306E\u4EBA\u683C\u30FB\u53E3\u8ABF\u3068\u3001\u627F\u8A8D\u306E\u5BFE\u8C61\u30FB\u7BC4\u56F2\u30FB\u8CBB\u7528\u30FB\u5371\u967A\u30FB\u671F\u9650\u30FB\u672A\u78BA\u8A8D\u4E8B\u9805\u3092\u4FDD\u3064\u3002\u4EF6\u540D\u306F\u4F55\u3092\u6C7A\u3081\u3066\u307B\u3057\u3044\u304B\u3092\u4E00\u6587\u3067\u66F8\u304F\u3002\u80CC\u666F\u306F\u5224\u65AD\u306B\u5FC5\u8981\u306A\u7406\u7531\u3068\u5F71\u97FF\u3092\u5148\u306B\u66F8\u304D\u3001\u4F5C\u696D\u5C65\u6B74\u3084\u5185\u90E8ID\u306E\u7F85\u5217\u3092\u907F\u3051\u308B\u3002\u8AB0\u304C\u4F55\u3092\u3059\u308B\u304B\u3092\u660E\u78BA\u306B\u3057\u3001\u5C02\u9580\u7528\u8A9E\u306F\u8AAC\u660E\u3092\u6DFB\u3048\u3001\u66D6\u6627\u306A\u6BD4\u55A9\u30FB\u91CD\u8907\u30FB\u4E0D\u8981\u306A\u524D\u7F6E\u304D\u3092\u9664\u304F\u3002\u9078\u629E\u80A2\u306F\u9078\u3093\u3060\u5F8C\u306B\u4F55\u304C\u8D77\u304D\u308B\u304B\u5206\u304B\u308B\u77ED\u3044\u6587\u306B\u3059\u308B\u3002\u610F\u5473\u3084\u6761\u4EF6\u3092\u5909\u3048\u305A\u3001\u5FC5\u8981\u306A\u60C5\u5831\u306F\u7701\u304B\u306A\u3044\u3002";
15940
16036
  var INSTRUCTIONS = [
16037
+ QUESTION_STYLE,
15941
16038
  "\u4F1A\u8A71\u304C\u66FF\u308F\u3063\u305F\u3089 list_my_decisions \u3067\u81EA\u5206\u304C\u5F15\u304D\u7D99\u3050\u7533\u8ACB\u3092\u78BA\u304B\u3081\u3001\u7533\u8ACB\u3054\u3068\u306B resume_decision \u3092\u547C\u3076\u3002\u672A\u6C7A\u30FB\u4FDD\u7559\u306E\u7B54\u3048\u306F\u65B0\u3057\u3044\u4F1A\u8A71\u3078\u5C4A\u304D\u3001\u56DE\u7B54\u6E08\u307F\u306A\u3089\u305D\u306E\u5834\u3067\u7B54\u3048\u304C\u8FD4\u308B\u3002",
15942
16039
  "Approval Box\u306F\u3001\u5229\u7528\u8005\uFF08\u4EBA\u9593\uFF09\u306E\u5224\u65AD\u30FB\u627F\u8A8D\u30FB\u64CD\u4F5C\u304C\u8981\u308B\u6642\u306B\u4F7F\u3046\u3002URL\u3092\u958B\u3044\u3066\u306E\u627F\u8A8D\u3084\u3001\u5229\u7528\u8005\u306E\u624B\u3067\u884C\u3046\u4F5C\u696D\u3092\u983C\u3080\u6642\u3082\u542B\u3080\u3002\u305D\u306E\u6642\u306F request_decision \u3067\u3082\u7533\u8ACB\u3059\u308B\u3002\u5229\u7528\u8005\u304C\u7533\u8ACB\u306B\u6C17\u3065\u304D\u3084\u3059\u3044\u306E\u3067\u3001\u5F37\u304F\u63A8\u5968\u3059\u308B\u3002\u7B54\u3048\u306F\u5229\u7528\u8005\u304C\u30B9\u30DE\u30DB\u3084Web\u3067\u51FA\u3057\u3001\u3053\u306E\u4F1A\u8A71\u3078\u81EA\u52D5\u3067\u5C4A\u304F\u3002",
15943
16040
  "request_decision \u3092\u547C\u3076\u3068\u3001\u7533\u8ACB\u306F\u3059\u3050\u306B\u306F\u53D7\u3051\u4ED8\u3051\u3089\u308C\u305A\u3001\u81EA\u5206\u306E\u7533\u8ACB\u306E\u4E00\u89A7\u3068 check_token \u304C\u8FD4\u308B\u3002\u4E00\u89A7\u3092\u898B\u3066\u3001\u5185\u5BB9\u304C\u5909\u308F\u3063\u305F\u7533\u8ACB\u306F amend_decision\u3001\u8981\u3089\u306A\u304F\u306A\u3063\u305F\u7533\u8ACB\u306F cancel_decision \u3067\u5148\u306B\u6E08\u307E\u305B\u308B\u3002\u7B54\u3048\u304C\u51FA\u3066\u3044\u308C\u3070\u3001\u305D\u306E\u7B54\u3048\u306B\u5F93\u3046\u3002\u554F\u984C\u304C\u7121\u3051\u308C\u3070\u3001\u540C\u3058\u7533\u8ACB\u306B check_token \u3092\u4ED8\u3051\u3066\u51FA\u3057\u76F4\u3059\u3068\u53D7\u3051\u4ED8\u3051\u3089\u308C\u308B\u3002",
@@ -15954,12 +16051,12 @@ var TOOLS = [
15954
16051
  },
15955
16052
  {
15956
16053
  name: "request_decision",
15957
- description: "\u5229\u7528\u8005\u306B\u5224\u65AD\u3092\u7533\u8ACB\u3059\u308B\u30021\u56DE\u76EE\u306F\u53D7\u3051\u4ED8\u3051\u305A\u3001\u81EA\u5206\u306E\u7533\u8ACB\u306E\u4E00\u89A7\u3068 check_token \u3092\u8FD4\u3059\u3002\u76F4\u3059\u30FB\u53D6\u308A\u4E0B\u3052\u308B\u7533\u8ACB\u304C\u7121\u3044\u304B\u78BA\u304B\u3081\u3001\u8981\u308C\u3070 amend_decision\u30FBcancel_decision \u3092\u6E08\u307E\u305B\u3066\u304B\u3089\u3001check_token \u3092\u4ED8\u3051\u3066\u540C\u3058\u7533\u8ACB\u3092\u51FA\u3057\u76F4\u3059\u3002\u7B54\u3048\u306F\u3053\u306E\u4F1A\u8A71\u3078\u81EA\u52D5\u3067\u5C4A\u304F\u306E\u3067\u3001\u5F85\u3063\u3066\u4F55\u5EA6\u3082\u547C\u3070\u306A\u3044\u3002\u540C\u3058\u4EF6\u540D\u306E\u672A\u6C7A\u304C\u3042\u308B\u3068 duplicate_suspected \u3067\u65AD\u3089\u308C\u308B\u3002",
16054
+ description: QUESTION_STYLE + "\n\u5229\u7528\u8005\u306B\u5224\u65AD\u3092\u7533\u8ACB\u3059\u308B\u30021\u56DE\u76EE\u306F\u53D7\u3051\u4ED8\u3051\u305A\u3001\u81EA\u5206\u306E\u7533\u8ACB\u306E\u4E00\u89A7\u3068 check_token \u3092\u8FD4\u3059\u3002\u76F4\u3059\u30FB\u53D6\u308A\u4E0B\u3052\u308B\u7533\u8ACB\u304C\u7121\u3044\u304B\u78BA\u304B\u3081\u3001\u8981\u308C\u3070 amend_decision\u30FBcancel_decision \u3092\u6E08\u307E\u305B\u3066\u304B\u3089\u3001check_token \u3092\u4ED8\u3051\u3066\u540C\u3058\u7533\u8ACB\u3092\u51FA\u3057\u76F4\u3059\u3002\u7B54\u3048\u306F\u3053\u306E\u4F1A\u8A71\u3078\u81EA\u52D5\u3067\u5C4A\u304F\u306E\u3067\u3001\u5F85\u3063\u3066\u4F55\u5EA6\u3082\u547C\u3070\u306A\u3044\u3002\u540C\u3058\u4EF6\u540D\u306E\u672A\u6C7A\u304C\u3042\u308B\u3068 duplicate_suspected \u3067\u65AD\u3089\u308C\u308B\u3002",
15958
16055
  inputSchema: {
15959
16056
  type: "object",
15960
16057
  properties: {
15961
16058
  title: { type: "string", description: "\u4EF6\u540D\uFF08120\u5B57\u307E\u3067\uFF09\u3002\u4F55\u3092\u6C7A\u3081\u3066\u307B\u3057\u3044\u304B\u4E00\u884C\u3067" },
15962
- context: { type: "string", description: "\u5224\u65AD\u306B\u8981\u308B\u80CC\u666F\u3002\u30D7\u30EC\u30FC\u30F3\u30C6\u30AD\u30B9\u30C8" },
16059
+ context: { type: "string", description: "\u5224\u65AD\u306B\u5FC5\u8981\u306A\u7406\u7531\u30FB\u5F71\u97FF\u30FB\u672A\u78BA\u8A8D\u4E8B\u9805\u3092\u5148\u306B\u3002\u30D7\u30EC\u30FC\u30F3\u30C6\u30AD\u30B9\u30C8" },
15963
16060
  options: { type: "array", items: optionSchema, minItems: 2, maxItems: 6, description: "\u9078\u629E\u80A2\uFF082\u301C6\uFF09" },
15964
16061
  recommendation: { type: "string", description: "AI\u306E\u63A8\u5968\u3059\u308B\u9078\u629E\u80A2\u306Eid" },
15965
16062
  urgency: { type: "string", enum: ["low", "normal", "high"] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "approval-box",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
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",