approval-box 0.1.25 → 0.1.27

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
@@ -51,6 +51,20 @@ Requires Node.js 20 or later. License: MIT.
51
51
  この機能はコネクタ0.1.13以降と対応サーバーを使います。会話を開き直しても、
52
52
  再開を指定するまでは元の会話が配送先です。答えは `get_decision` でも取得できます。
53
53
 
54
+ ### 誰から・何の仕事の申請か
55
+
56
+ `request_decision` は `requester_name`(申請するAI自身の名前)と `session_label`(何の仕事の申請か)を必須で受けます。アプリの一覧と通知には「申請者 / 作業名」の一行が出ます。名前を持たないAIは `requester_name` を空文字にします。その申請は、AIの種類と作業名で出ます。
57
+
58
+ AIには、利用者へ申請の話をする時は件名で伝えるよう返します。アプリは申請のID(`K-…`)を出しません。
59
+
54
60
  ### 申請に画像を添える
55
61
 
56
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) {
@@ -14154,6 +14210,9 @@ var Protocol = class {
14154
14210
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
14155
14211
  const handleTaskResult = async () => {
14156
14212
  const taskId = request.params.taskId;
14213
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
14214
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14215
+ }
14157
14216
  if (this._taskMessageQueue) {
14158
14217
  let queuedMessage;
14159
14218
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -14184,12 +14243,12 @@ var Protocol = class {
14184
14243
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
14185
14244
  }
14186
14245
  if (!isTerminal(task.status)) {
14187
- await this._waitForTaskUpdate(taskId, extra.signal);
14246
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
14188
14247
  return await handleTaskResult();
14189
14248
  }
14190
14249
  if (isTerminal(task.status)) {
14191
14250
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
14192
- this._clearTaskQueue(taskId);
14251
+ this._clearTaskQueue(taskId, extra.sessionId);
14193
14252
  return {
14194
14253
  ...result,
14195
14254
  _meta: {
@@ -14226,7 +14285,7 @@ var Protocol = class {
14226
14285
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
14227
14286
  }
14228
14287
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
14229
- this._clearTaskQueue(request.params.taskId);
14288
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
14230
14289
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
14231
14290
  if (!cancelledTask) {
14232
14291
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -14354,6 +14413,19 @@ var Protocol = class {
14354
14413
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
14355
14414
  const capturedTransport = this._transport;
14356
14415
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
14416
+ const sessionId = capturedTransport?.sessionId;
14417
+ const store = this._taskStore;
14418
+ let relatedTaskFound = true;
14419
+ let relatedTaskLookup;
14420
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== void 0) {
14421
+ relatedTaskFound = false;
14422
+ relatedTaskLookup = (async () => {
14423
+ if (!await store.getTask(relatedTaskId, sessionId)) {
14424
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
14425
+ }
14426
+ relatedTaskFound = true;
14427
+ })();
14428
+ }
14357
14429
  if (handler === void 0) {
14358
14430
  const errorResponse = {
14359
14431
  jsonrpc: "2.0",
@@ -14363,7 +14435,10 @@ var Protocol = class {
14363
14435
  message: "Method not found"
14364
14436
  }
14365
14437
  };
14366
- if (relatedTaskId && this._taskMessageQueue) {
14438
+ if (relatedTaskId && relatedTaskLookup) {
14439
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
14440
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error) => this._onerror(new Error(`Failed to send an error response: ${error}`)));
14441
+ } else if (relatedTaskId && this._taskMessageQueue) {
14367
14442
  this._enqueueTaskMessage(relatedTaskId, {
14368
14443
  type: "error",
14369
14444
  message: errorResponse,
@@ -14414,7 +14489,10 @@ var Protocol = class {
14414
14489
  closeSSEStream: extra?.closeSSEStream,
14415
14490
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
14416
14491
  };
14417
- Promise.resolve().then(() => {
14492
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
14493
+ if (relatedTaskLookup && abortController.signal.aborted) {
14494
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
14495
+ }
14418
14496
  if (taskCreationParams) {
14419
14497
  this.assertTaskHandlerCapability(request.method);
14420
14498
  }
@@ -14449,7 +14527,7 @@ var Protocol = class {
14449
14527
  ...error["data"] !== void 0 && { data: error["data"] }
14450
14528
  }
14451
14529
  };
14452
- if (relatedTaskId && this._taskMessageQueue) {
14530
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
14453
14531
  await this._enqueueTaskMessage(relatedTaskId, {
14454
14532
  type: "error",
14455
14533
  message: errorResponse,
@@ -14929,7 +15007,7 @@ var Protocol = class {
14929
15007
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
14930
15008
  }
14931
15009
  const maxQueueSize = this._options?.maxTaskQueueSize;
14932
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
15010
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
14933
15011
  }
14934
15012
  /**
14935
15013
  * Clears the message queue for a task and rejects any pending request resolvers.
@@ -14958,12 +15036,13 @@ var Protocol = class {
14958
15036
  * Uses polling to check for updates at the task's configured poll interval.
14959
15037
  * @param taskId The task ID to wait for
14960
15038
  * @param signal Abort signal to cancel the wait
15039
+ * @param sessionId Session of the request that waits, passed to the task store
14961
15040
  * @returns Promise that resolves when an update occurs or rejects if aborted
14962
15041
  */
14963
- async _waitForTaskUpdate(taskId, signal) {
15042
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
14964
15043
  let interval = this._options?.defaultTaskPollInterval ?? 1e3;
14965
15044
  try {
14966
- const task = await this._taskStore?.getTask(taskId);
15045
+ const task = await this._taskStore?.getTask(taskId, sessionId);
14967
15046
  if (task?.pollInterval) {
14968
15047
  interval = task.pollInterval;
14969
15048
  }
@@ -15922,7 +16001,7 @@ function claudeChannelIsCurrent(profile, channelId, parent) {
15922
16001
  }
15923
16002
 
15924
16003
  // src/version.ts
15925
- var VERSION = true ? "0.1.25" : "0.0.0-dev";
16004
+ var VERSION = true ? "0.1.27" : "0.0.0-dev";
15926
16005
  function osName() {
15927
16006
  return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
15928
16007
  }
@@ -15937,11 +16016,14 @@ function harnessOf(clientName) {
15937
16016
  if (name.startsWith("grok")) return "grok";
15938
16017
  return "other";
15939
16018
  }
16019
+ 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
16020
  var INSTRUCTIONS = [
16021
+ QUESTION_STYLE,
15941
16022
  "\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
16023
  "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
16024
  "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",
15944
16025
  "\u7533\u8ACB\u3057\u305F\u3089\u7B54\u3048\u3092\u5F85\u3063\u3066\u4F55\u5EA6\u3082\u547C\u3070\u306A\u3044\u3002\u7B54\u3048\u306F\u5C4A\u304F\u306E\u3067\u3001\u4ED6\u306E\u4F5C\u696D\u3092\u7D9A\u3051\u308B\u304B\u30BF\u30FC\u30F3\u3092\u7D42\u3048\u3066\u3088\u3044\u3002",
16026
+ "\u5229\u7528\u8005\u3078\u7533\u8ACB\u306E\u8A71\u3092\u3059\u308B\u6642\u306F\u3001\u4EF6\u540D\u3067\u4F1D\u3048\u308B\u3002\u30A2\u30D7\u30EA\u306B\u306F\u4EF6\u540D\u30FB\u7533\u8ACB\u8005\u30FB\u4F5C\u696D\u540D\u304C\u51FA\u3066\u3001\u7533\u8ACB\u306EID\uFF08K-\u2026\uFF09\u306F\u51FA\u306A\u3044\u3002ID\u306F\u9053\u5177\u3092\u547C\u3076\u6642\u306B\u4F7F\u3046\u3002",
15945
16027
  "\u5229\u7528\u8005\u306B\u300CApproval Box\u306Esetup_test\u3092\u5B9F\u884C\u3057\u3066\u300D\u3068\u8A00\u308F\u308C\u305F\u3089 setup_test \u3092\u547C\u3076\u3002\u5C4A\u3044\u305F\u7B54\u3048\u306B\u66F8\u304B\u308C\u305F\u78BA\u8A8D\u30B3\u30FC\u30C9\u3067 confirm_setup_test \u3092\u547C\u3076\u3002"
15946
16028
  ].join("\n");
15947
16029
  var optionSchema = { type: "object", properties: { id: { type: "string" }, label: { type: "string" } }, required: ["id", "label"], additionalProperties: false };
@@ -15953,23 +16035,24 @@ var TOOLS = [
15953
16035
  },
15954
16036
  {
15955
16037
  name: "request_decision",
15956
- 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",
16038
+ 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",
15957
16039
  inputSchema: {
15958
16040
  type: "object",
15959
16041
  properties: {
15960
16042
  title: { type: "string", description: "\u4EF6\u540D\uFF08120\u5B57\u307E\u3067\uFF09\u3002\u4F55\u3092\u6C7A\u3081\u3066\u307B\u3057\u3044\u304B\u4E00\u884C\u3067" },
15961
- context: { type: "string", description: "\u5224\u65AD\u306B\u8981\u308B\u80CC\u666F\u3002\u30D7\u30EC\u30FC\u30F3\u30C6\u30AD\u30B9\u30C8" },
16043
+ 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" },
15962
16044
  options: { type: "array", items: optionSchema, minItems: 2, maxItems: 6, description: "\u9078\u629E\u80A2\uFF082\u301C6\uFF09" },
15963
16045
  recommendation: { type: "string", description: "AI\u306E\u63A8\u5968\u3059\u308B\u9078\u629E\u80A2\u306Eid" },
15964
16046
  urgency: { type: "string", enum: ["low", "normal", "high"] },
15965
16047
  deadline: { type: "string", description: "\u671F\u9650\uFF08ISO 8601\uFF09" },
15966
- session_label: { type: "string", description: "\u3069\u306E\u4F5C\u696D\u306E\u8A71\u304B\uFF08\u4F8B: \u30EA\u30DD\u30B8\u30C8\u30EA\u540D / \u4F5C\u696D\u540D\uFF09\u3002\u7701\u7565\u3059\u308B\u3068\u4F5C\u696D\u30D5\u30A9\u30EB\u30C0\u540D" },
16048
+ requester_name: { type: "string", description: "\u7533\u8ACB\u3059\u308B\u3042\u306A\u305F\u81EA\u8EAB\u306E\u540D\u524D\uFF0860\u5B57\u307E\u3067\uFF09\u3002Bot\u3084\u62C5\u5F53\u3068\u3057\u3066\u306E\u540D\u524D\u3092\u6301\u3064\u306A\u3089\u3001\u305D\u306E\u540D\u524D\u3092\u66F8\u304F\u3002\u5229\u7528\u8005\u306F\u3053\u308C\u3067\u3001\u8AB0\u304B\u3089\u306E\u7533\u8ACB\u304B\u3092\u898B\u5206\u3051\u308B\u3002\u540D\u524D\u3092\u6301\u305F\u306A\u3044AI\u306F\u7A7A\u6587\u5B57\u306B\u3059\u308B\uFF08\u4ECA\u307E\u3067\u3069\u304A\u308A\u3001AI\u306E\u7A2E\u985E\u3068\u4F5C\u696D\u540D\u3067\u51FA\u308B\uFF09" },
16049
+ session_label: { type: "string", description: "\u4F55\u306E\u4ED5\u4E8B\u306E\u7533\u8ACB\u304B\uFF08\u4F8B: \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u540D / \u4F5C\u696D\u540D\uFF09\u3002\u5229\u7528\u8005\u306F\u3053\u308C\u3067\u3001\u3069\u306E\u4ED5\u4E8B\u306E\u7533\u8ACB\u304B\u3092\u898B\u5206\u3051\u308B" },
15967
16050
  distinct_reason: { type: "string", description: "\u540C\u3058\u4EF6\u540D\u306E\u672A\u6C7A\u304C\u3042\u308B\u306E\u306B\u5225\u4EF6\u3068\u3057\u3066\u51FA\u3059\u6642\u3060\u3051\u3001\u305D\u306E\u7406\u7531" },
15968
16051
  image_paths: { type: "array", items: { type: "string" }, maxItems: 10, description: "\u7533\u8ACB\u306B\u6DFB\u3048\u308B\u30ED\u30FC\u30AB\u30EB\u753B\u50CF\u30D1\u30B9\u300210\u4EF6/\u5358\u4F5320MiB/\u5408\u8A0850MiB\u307E\u3067\u3002\u30D1\u30B9\u81EA\u4F53\u306F\u4EBA\u3078\u9001\u3089\u306A\u3044" },
15969
16052
  request_attachment_ids: { type: "array", items: { type: "string" }, maxItems: 10 },
15970
16053
  check_token: { type: "string", description: "1\u56DE\u76EE\u306E request_decision \u3067\u8FD4\u3063\u305F\u78BA\u8A8D\u306E\u672D\u3002\u4E00\u89A7\u3092\u78BA\u304B\u3081\u3001\u76F4\u3059\u30FB\u53D6\u308A\u4E0B\u3052\u308B\u7533\u8ACB\u304C\u7121\u3044\u3068\u5224\u65AD\u3057\u305F\u6642\u306B\u4ED8\u3051\u308B" }
15971
16054
  },
15972
- required: ["title", "options"],
16055
+ required: ["title", "options", "requester_name", "session_label"],
15973
16056
  additionalProperties: false
15974
16057
  }
15975
16058
  },
@@ -16097,6 +16180,10 @@ async function channelFor(harness, clientName, meta) {
16097
16180
  remember(key, channel.channel_id, false);
16098
16181
  return channel.channel_id;
16099
16182
  }
16183
+ var SPEAK_BY_TITLE = "\u5229\u7528\u8005\u3078\u3053\u306E\u7533\u8ACB\u306E\u8A71\u3092\u3059\u308B\u6642\u306F\u3001\u4EF6\u540D\u3067\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002\u30A2\u30D7\u30EA\u306B\u306F\u4EF6\u540D\u30FB\u7533\u8ACB\u8005\u30FB\u4F5C\u696D\u540D\u304C\u51FA\u3066\u3001\u7533\u8ACB\u306EID\u306F\u51FA\u307E\u305B\u3093\u3002ID\u306F\u9053\u5177\u3092\u547C\u3076\u6642\u306B\u4F7F\u3044\u307E\u3059\u3002";
16184
+ function named(decision) {
16185
+ return decision.title ? `\u300C${decision.title}\u300D\uFF08\u7533\u8ACB\u306EID: ${decision.decision_id}\uFF09` : String(decision.decision_id);
16186
+ }
16100
16187
  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";
16101
16188
  function receiveGuide(harness, channelId) {
16102
16189
  if (harness === "codex" || harness === "claude") return "";
@@ -16121,7 +16208,7 @@ function text(value, structured, isError = false) {
16121
16208
  function describe(items) {
16122
16209
  if (!items.length) return "\u3053\u306E\u7AEF\u672B\u304B\u3089\u51FA\u3057\u305F\u7533\u8ACB\u306F\u3042\u308A\u307E\u305B\u3093\u3002";
16123
16210
  return items.map((d) => {
16124
- const parts = [`- ${d.decision_id}\u300C${d.title}\u300D status=${d.status} version=${d.version} \u4F5C\u696D=${d.session_label}${d.this_session ? " (\u3053\u306E\u4F1A\u8A71)" : ""}`];
16211
+ const parts = [`- ${d.decision_id}\u300C${d.title}\u300D status=${d.status} version=${d.version}${d.requester ? ` \u7533\u8ACB\u8005=${d.requester}` : ""} \u4F5C\u696D=${d.session_label}${d.this_session ? " (\u3053\u306E\u4F1A\u8A71)" : ""}`];
16125
16212
  if (d.answer_text) parts.push(` \u7B54\u3048: ${String(d.answer_text).split("\n").slice(1, 3).join(" / ")}`);
16126
16213
  if (d.cancel_reason) parts.push(` \u53D6\u308A\u4E0B\u3052\u7406\u7531: ${d.cancel_reason}`);
16127
16214
  return parts.join("\n");
@@ -16149,19 +16236,22 @@ ${JSON.stringify({ items })}`, { items });
16149
16236
  if (name === "request_decision") {
16150
16237
  const channelId = await channelFor(harness, clientName, request.params._meta);
16151
16238
  lastChannel = channelId;
16152
- const { image_paths, ...rest } = args;
16239
+ const { image_paths, requester_name, ...rest } = args;
16153
16240
  if (image_paths !== void 0 && rest.request_attachment_ids !== void 0) throw new Error("image_paths\u3068request_attachment_ids\u306F\u7247\u65B9\u3060\u3051\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
16154
16241
  const request_attachment_ids = image_paths !== void 0 ? await uploadImagePaths(api, image_paths) : rest.request_attachment_ids;
16155
16242
  const body = {
16156
16243
  ...rest,
16157
16244
  ...request_attachment_ids !== void 0 ? { request_attachment_ids } : {},
16158
16245
  client: CLIENT_OF[harness],
16246
+ // 道具の一覧では両方とも必須。名前を持たないAI(一般の利用者の Claude Code など)は空文字で出すので、その時は送らない。
16247
+ // 一覧を古いまま持つ client の申請も受け付けるため、無い時も断らない。
16248
+ ...typeof requester_name === "string" && requester_name.trim() ? { requester: requester_name.trim() } : {},
16159
16249
  session_label: args.session_label || `${basename3(process.cwd())} (${CLIENT_OF[harness]})`,
16160
16250
  route: { channel_id: channelId, harness }
16161
16251
  };
16162
16252
  try {
16163
16253
  const decision = await api.call("POST", "/decisions", body);
16164
- 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`;
16254
+ const message = `\u7533\u8ACB\u3057\u307E\u3057\u305F: ${named(decision)}\u3002${SPEAK_BY_TITLE}${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`;
16165
16255
  return announced(`${message}${receiveGuide(harness, channelId)}`, decision, channelId);
16166
16256
  } catch (error) {
16167
16257
  if (error instanceof ServerError && error.code === "confirm_required") {
@@ -16200,18 +16290,18 @@ ${JSON.stringify({ error: "duplicate_suspected", existing })}`, { error: "duplic
16200
16290
  const channelId = await channelFor(harness, clientName, request.params._meta);
16201
16291
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(decision_id))}/amend`, { ...rest, route: { channel_id: channelId, harness } });
16202
16292
  lastChannel = channelId;
16203
- return announced(`\u76F4\u3057\u307E\u3057\u305F: ${decision.decision_id} version=${decision.version}${receiveGuide(harness, channelId)}`, decision, channelId);
16293
+ return announced(`\u76F4\u3057\u307E\u3057\u305F: ${named(decision)} version=${decision.version}${receiveGuide(harness, channelId)}`, decision, channelId);
16204
16294
  }
16205
16295
  if (name === "resume_decision") {
16206
16296
  const channelId = await channelFor(harness, clientName, request.params._meta);
16207
16297
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/resume`, { channel_id: channelId, harness });
16208
16298
  lastChannel = channelId;
16209
- const head = decision.answer_text ? String(decision.answer_text) : `\u518D\u958B\u3057\u307E\u3057\u305F: ${decision.decision_id}\u3002${ARRIVAL}`;
16299
+ const head = decision.answer_text ? String(decision.answer_text) : `\u518D\u958B\u3057\u307E\u3057\u305F: ${named(decision)}\u3002${ARRIVAL}`;
16210
16300
  return announced(`${head}${decision.answer_text ? "" : receiveGuide(harness, channelId)}`, decision, channelId);
16211
16301
  }
16212
16302
  if (name === "cancel_decision") {
16213
16303
  const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/cancel`, { reason: args.reason });
16214
- return text(`\u53D6\u308A\u4E0B\u3052\u307E\u3057\u305F: ${decision.decision_id}
16304
+ return text(`\u53D6\u308A\u4E0B\u3052\u307E\u3057\u305F: ${named(decision)}
16215
16305
 
16216
16306
  ${JSON.stringify(decision)}`, decision);
16217
16307
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "approval-box",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
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",