approval-box 0.1.11 → 0.1.13
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 +13 -0
- package/dist/approval-box-claude-hook.mjs +1 -1
- package/dist/approval-box-codex-hook.mjs +1 -1
- package/dist/approval-box-cursor-hook.mjs +39 -3
- package/dist/approval-box-receive.mjs +1 -1
- package/dist/chunks/{chunk-LEWADASG.mjs → chunk-YBOJCW6Y.mjs} +24 -36
- package/dist/cli.mjs +43 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@ Approval Box connector. When an AI coding agent needs a human decision, approval
|
|
|
4
4
|
|
|
5
5
|
Supported agents: Claude Code, Codex, Cursor, Grok — on macOS, Windows and Linux.
|
|
6
6
|
|
|
7
|
+
Cursor and Grok receive answers through the background receiver command returned by the request tool. Cursor hooks bind that receiver to the conversation; they do not consume answers. Keep the receiver running until it returns the answer. Its output includes a command to wait for the next answer.
|
|
8
|
+
|
|
7
9
|
AIが人間の判断・承認・操作を求める時に、Approval Boxへも申請します。アプリかWeb版で答えると、その答えが申請したAIの会話へそのまま届きます。
|
|
8
10
|
|
|
9
11
|
## Setup / 使い方
|
|
@@ -33,3 +35,14 @@ npx approval-box uninstall # remove everything and unlink this device / 全部
|
|
|
33
35
|
Self-hosted server: `npx -y approval-box@latest setup --server https://your-server`.
|
|
34
36
|
|
|
35
37
|
Requires Node.js 20 or later. License: MIT.
|
|
38
|
+
|
|
39
|
+
### 会話を開き直した時
|
|
40
|
+
|
|
41
|
+
`list_my_decisions` で、自分が引き継ぐ申請を確かめ、対象ごとに
|
|
42
|
+
`resume_decision({decision_id: "K-…"})` を呼びます。未決・保留なら今の会話へ
|
|
43
|
+
配送先を移し、回答済みなら答えを直接返します。同じ端末にある他の作業の申請は、
|
|
44
|
+
引き継ぐ対象に含めないでください。`amend_decision` も、修正が成功した時に配送先を
|
|
45
|
+
呼び出した会話へ更新します。Cursor・Grokでは、返る案内に従って背景の受信を起動します。
|
|
46
|
+
|
|
47
|
+
この機能はコネクタ0.1.13以降と対応サーバーを使います。会話を開き直しても、
|
|
48
|
+
再開を指定するまでは元の会話が配送先です。答えは `get_decision` でも取得できます。
|
|
@@ -2,7 +2,7 @@ import { createRequire as __kbCreateRequire } from 'node:module'; const require
|
|
|
2
2
|
import {
|
|
3
3
|
PROFILE,
|
|
4
4
|
runCodexHookMain
|
|
5
|
-
} from "./chunks/chunk-
|
|
5
|
+
} from "./chunks/chunk-YBOJCW6Y.mjs";
|
|
6
6
|
|
|
7
7
|
// src/hooks/codex.ts
|
|
8
8
|
await runCodexHookMain(PROFILE, process.argv[2]);
|
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
import { createRequire as __kbCreateRequire } from 'node:module'; const require = __kbCreateRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
PROFILE,
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
cursorHookRoot,
|
|
5
|
+
handleCursorChannelHook,
|
|
6
|
+
handleCursorHook,
|
|
7
|
+
withoutBom
|
|
8
|
+
} from "./chunks/chunk-YBOJCW6Y.mjs";
|
|
9
|
+
|
|
10
|
+
// src/cursor-binding.ts
|
|
11
|
+
async function bindCursorResult(profile, raw) {
|
|
12
|
+
let parsed;
|
|
13
|
+
try {
|
|
14
|
+
parsed = JSON.parse(withoutBom(raw));
|
|
15
|
+
} catch {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return;
|
|
19
|
+
const event = parsed;
|
|
20
|
+
const name = event.hook_event_name;
|
|
21
|
+
if (name !== "afterMCPExecution" && name !== "postToolUse" && name !== "postToolUseFailure") return;
|
|
22
|
+
const binding = {
|
|
23
|
+
...event,
|
|
24
|
+
hook_event_name: "afterMCPExecution",
|
|
25
|
+
result_json: name === "afterMCPExecution" ? event.result_json : event.tool_output
|
|
26
|
+
};
|
|
27
|
+
await handleCursorHook(profile, JSON.stringify(binding), cursorHookRoot(profile));
|
|
28
|
+
if (profile.channels) await handleCursorChannelHook(profile, binding, () => {
|
|
29
|
+
throw new Error("CURSOR_BIND_HOOK_MUST_NOT_CONSUME_ANSWERS");
|
|
30
|
+
});
|
|
31
|
+
}
|
|
6
32
|
|
|
7
33
|
// src/hooks/cursor.ts
|
|
8
|
-
|
|
34
|
+
try {
|
|
35
|
+
let raw = "";
|
|
36
|
+
process.stdin.setEncoding("utf8");
|
|
37
|
+
for await (const chunk of process.stdin) raw += chunk;
|
|
38
|
+
await bindCursorResult(PROFILE, raw);
|
|
39
|
+
process.stdout.write("{}\n");
|
|
40
|
+
} catch (error) {
|
|
41
|
+
process.stderr.write(`${error instanceof Error ? error.message : "CURSOR_PARENT_HOOK_FAILED"}
|
|
42
|
+
`);
|
|
43
|
+
process.exitCode = 2;
|
|
44
|
+
}
|
|
@@ -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-
|
|
5
|
+
} from "./chunks/chunk-YBOJCW6Y.mjs";
|
|
6
6
|
|
|
7
7
|
// src/hooks/receive.ts
|
|
8
8
|
await runChannelReceiveMain(PROFILE);
|
|
@@ -43,7 +43,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
43
43
|
import { homedir } from "node:os";
|
|
44
44
|
import { join } from "node:path";
|
|
45
45
|
var MCP_SERVER = "approval-box";
|
|
46
|
-
var DISPATCH_TOOLS = ["request_decision", "setup_test"];
|
|
46
|
+
var DISPATCH_TOOLS = ["request_decision", "setup_test", "amend_decision", "resume_decision"];
|
|
47
47
|
var home = () => process.env.APPROVAL_BOX_HOME ?? join(homedir(), ".approval-box");
|
|
48
48
|
var stateRoot = () => join(home(), "state");
|
|
49
49
|
var HOOK_FILES = {
|
|
@@ -21019,6 +21019,25 @@ function channelDeliveryState(profile, channelId, deliveryId) {
|
|
|
21019
21019
|
}
|
|
21020
21020
|
return fs7.readdirSync(path10.join(dir, "inbox")).some((name) => name.endsWith(`-${deliveryId}.json`)) ? "queued" : null;
|
|
21021
21021
|
}
|
|
21022
|
+
function withdrawFromChannel(profile, channelId, deliveryId) {
|
|
21023
|
+
uuid3.parse(deliveryId);
|
|
21024
|
+
const dir = channelDir(profile, channelId);
|
|
21025
|
+
const inbox = path10.join(dir, "inbox");
|
|
21026
|
+
const name = fs7.existsSync(inbox) ? fs7.readdirSync(inbox).find((entry) => entry.endsWith(`-${deliveryId}.json`)) : void 0;
|
|
21027
|
+
if (!name)
|
|
21028
|
+
return false;
|
|
21029
|
+
const claim3 = path10.join(dir, "claims", `${deliveryId}.json`);
|
|
21030
|
+
try {
|
|
21031
|
+
fs7.linkSync(path10.join(inbox, name), claim3);
|
|
21032
|
+
fs7.unlinkSync(path10.join(inbox, name));
|
|
21033
|
+
} catch (error62) {
|
|
21034
|
+
if (["ENOENT", "EEXIST"].includes(error62.code ?? ""))
|
|
21035
|
+
return false;
|
|
21036
|
+
throw error62;
|
|
21037
|
+
}
|
|
21038
|
+
writeJson0600(claim3, { delivery_id: deliveryId, state: "withdrawn", at: (/* @__PURE__ */ new Date()).toISOString() });
|
|
21039
|
+
return true;
|
|
21040
|
+
}
|
|
21022
21041
|
function claimPending(profile, channelId, by, limit = Infinity) {
|
|
21023
21042
|
const dir = channelDir(profile, channelId);
|
|
21024
21043
|
const inbox = path10.join(dir, "inbox");
|
|
@@ -21344,40 +21363,6 @@ async function runClaudeHookMain(profile, root = claudeHookRoot(profile)) {
|
|
|
21344
21363
|
process.exitCode = 2;
|
|
21345
21364
|
}
|
|
21346
21365
|
}
|
|
21347
|
-
async function runCursorHookMain(profile, root = cursorHookRoot(profile)) {
|
|
21348
|
-
try {
|
|
21349
|
-
const input2 = await readStdin();
|
|
21350
|
-
const result = {};
|
|
21351
|
-
for (const each of typeof root === "string" ? [root] : [...new Set(root)]) {
|
|
21352
|
-
const found = await handleCursorHook(profile, input2.length > 0 ? input2 : "{}", each);
|
|
21353
|
-
if (typeof found.additional_context === "string") {
|
|
21354
|
-
result.additional_context = typeof result.additional_context === "string" ? `${result.additional_context}
|
|
21355
|
-
|
|
21356
|
-
${found.additional_context}` : found.additional_context;
|
|
21357
|
-
}
|
|
21358
|
-
}
|
|
21359
|
-
if (profile.channels) {
|
|
21360
|
-
let event = null;
|
|
21361
|
-
try {
|
|
21362
|
-
event = JSON.parse(input2);
|
|
21363
|
-
} catch {
|
|
21364
|
-
}
|
|
21365
|
-
if (event !== null && typeof event === "object") {
|
|
21366
|
-
await handleCursorChannelHook(profile, event, (text) => {
|
|
21367
|
-
result.additional_context = typeof result.additional_context === "string" ? `${result.additional_context}
|
|
21368
|
-
|
|
21369
|
-
${text}` : text;
|
|
21370
|
-
});
|
|
21371
|
-
}
|
|
21372
|
-
}
|
|
21373
|
-
process.stdout.write(`${JSON.stringify(result)}
|
|
21374
|
-
`);
|
|
21375
|
-
} catch (error62) {
|
|
21376
|
-
process.stderr.write(`${error62 instanceof Error ? error62.message : "CURSOR_PARENT_HOOK_FAILED"}
|
|
21377
|
-
`);
|
|
21378
|
-
process.exitCode = 2;
|
|
21379
|
-
}
|
|
21380
|
-
}
|
|
21381
21366
|
async function runChannelReceiveMain(profile, argv = process.argv.slice(2), script = process.argv[1]) {
|
|
21382
21367
|
const emit = (value) => new Promise((resolve2, reject) => {
|
|
21383
21368
|
process.stdout.write(JSON.stringify(value) + "\n", (error62) => error62 ? reject(error62) : resolve2());
|
|
@@ -21918,6 +21903,7 @@ export {
|
|
|
21918
21903
|
PROFILE,
|
|
21919
21904
|
claudeHookRoot,
|
|
21920
21905
|
cursorHookRoot,
|
|
21906
|
+
withoutBom,
|
|
21921
21907
|
setupNodeExecutable,
|
|
21922
21908
|
safeParse,
|
|
21923
21909
|
string2 as string,
|
|
@@ -21946,6 +21932,7 @@ export {
|
|
|
21946
21932
|
isCursorMcpClient,
|
|
21947
21933
|
cursorParentHooksRegistered,
|
|
21948
21934
|
verifyCursorParent,
|
|
21935
|
+
handleCursorHook,
|
|
21949
21936
|
waitProcessCommandLine,
|
|
21950
21937
|
mergeClaudeParentHooks,
|
|
21951
21938
|
removeClaudeParentHooks,
|
|
@@ -21957,10 +21944,11 @@ export {
|
|
|
21957
21944
|
channelClosed,
|
|
21958
21945
|
sendToChannel,
|
|
21959
21946
|
channelDeliveryState,
|
|
21947
|
+
withdrawFromChannel,
|
|
21960
21948
|
channelMarker,
|
|
21949
|
+
handleCursorChannelHook,
|
|
21961
21950
|
channelReceiveProcess,
|
|
21962
21951
|
runCodexHookMain,
|
|
21963
21952
|
runClaudeHookMain,
|
|
21964
|
-
runCursorHookMain,
|
|
21965
21953
|
runChannelReceiveMain
|
|
21966
21954
|
};
|
package/dist/cli.mjs
CHANGED
|
@@ -51,8 +51,9 @@ import {
|
|
|
51
51
|
verifyCodexParent,
|
|
52
52
|
verifyCursorParent,
|
|
53
53
|
waitProcessCommandLine,
|
|
54
|
-
withCodexReceiver
|
|
55
|
-
|
|
54
|
+
withCodexReceiver,
|
|
55
|
+
withdrawFromChannel
|
|
56
|
+
} from "./chunks/chunk-YBOJCW6Y.mjs";
|
|
56
57
|
|
|
57
58
|
// ../../node_modules/qrcode/lib/can-promise.js
|
|
58
59
|
var require_can_promise = __commonJS({
|
|
@@ -12074,7 +12075,24 @@ async function runDaemon() {
|
|
|
12074
12075
|
again = false;
|
|
12075
12076
|
try {
|
|
12076
12077
|
const { items } = await api.call("GET", "/deliveries");
|
|
12077
|
-
|
|
12078
|
+
const waiting = new Map(items.map((item) => [item.decision_id, item]));
|
|
12079
|
+
for (const [id, entry] of Object.entries(journal)) {
|
|
12080
|
+
if (entry.state !== "queued") continue;
|
|
12081
|
+
const item = waiting.get(id);
|
|
12082
|
+
if (item && item.delivery_id === entry.delivery_id && item.route.channel_id === entry.channel_id) continue;
|
|
12083
|
+
const withdrawn = withdrawFromChannel(PROFILE, entry.channel_id, entry.delivery_id);
|
|
12084
|
+
if (withdrawn || !item) {
|
|
12085
|
+
delete journal[id];
|
|
12086
|
+
save();
|
|
12087
|
+
log(`\u914D\u9001 ${id} \u2192 ${withdrawn ? "withdrawn" : "resolved"}`);
|
|
12088
|
+
} else {
|
|
12089
|
+
Object.assign(entry, safeState(entry) === "emitted" ? { state: "report", result: "delivered" } : { state: "report", result: "unknown", detail: "\u914D\u9001\u5148\u306E\u5909\u66F4\u524D\u306B\u53D7\u3051\u53E3\u304C\u672C\u6587\u3092\u53D6\u5F97\u3057\u307E\u3057\u305F\u3002\u518D\u9001\u3057\u307E\u305B\u3093" });
|
|
12090
|
+
save();
|
|
12091
|
+
await report(id);
|
|
12092
|
+
waiting.delete(id);
|
|
12093
|
+
}
|
|
12094
|
+
}
|
|
12095
|
+
for (const item of waiting.values()) await deliver(item);
|
|
12078
12096
|
} catch (error) {
|
|
12079
12097
|
log(`\u914D\u9001\u5F85\u3061\u306E\u53D6\u5F97\u306B\u5931\u6557: ${error.message}`);
|
|
12080
12098
|
}
|
|
@@ -12247,7 +12265,7 @@ function stableNode() {
|
|
|
12247
12265
|
return process.execPath;
|
|
12248
12266
|
}
|
|
12249
12267
|
}
|
|
12250
|
-
var CURSOR_TOOLS = ["list_my_decisions", "request_decision", "amend_decision", "cancel_decision", "get_decision", "get_attachment", "setup_test", "confirm_setup_test"];
|
|
12268
|
+
var CURSOR_TOOLS = ["list_my_decisions", "request_decision", "amend_decision", "resume_decision", "cancel_decision", "get_decision", "get_attachment", "setup_test", "confirm_setup_test"];
|
|
12251
12269
|
var cursorCliConfig = () => join6(cursorDir(), "cli-config.json");
|
|
12252
12270
|
function setCursorPermissions(enable) {
|
|
12253
12271
|
const file = cursorCliConfig();
|
|
@@ -15770,7 +15788,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:f
|
|
|
15770
15788
|
import { basename as basename2, join as join7 } from "node:path";
|
|
15771
15789
|
|
|
15772
15790
|
// src/version.ts
|
|
15773
|
-
var VERSION = true ? "0.1.
|
|
15791
|
+
var VERSION = true ? "0.1.13" : "0.0.0-dev";
|
|
15774
15792
|
function osName() {
|
|
15775
15793
|
return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
|
|
15776
15794
|
}
|
|
@@ -15786,6 +15804,7 @@ function harnessOf(clientName) {
|
|
|
15786
15804
|
return "other";
|
|
15787
15805
|
}
|
|
15788
15806
|
var INSTRUCTIONS = [
|
|
15807
|
+
"\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",
|
|
15789
15808
|
"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",
|
|
15790
15809
|
"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",
|
|
15791
15810
|
"\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",
|
|
@@ -15844,6 +15863,11 @@ var TOOLS = [
|
|
|
15844
15863
|
additionalProperties: false
|
|
15845
15864
|
}
|
|
15846
15865
|
},
|
|
15866
|
+
{
|
|
15867
|
+
name: "resume_decision",
|
|
15868
|
+
description: "\u524D\u306E\u4F1A\u8A71\u304B\u3089\u5F15\u304D\u7D99\u3044\u3060\u81EA\u5206\u306E\u7533\u8ACB\u3092\u3001\u3053\u306E\u4F1A\u8A71\u3067\u518D\u958B\u3059\u308B\u3002\u672A\u6C7A\u30FB\u4FDD\u7559\u306A\u3089\u7B54\u3048\u306E\u914D\u9001\u5148\u3092\u3053\u306E\u4F1A\u8A71\u3078\u5909\u66F4\u3057\u3001\u56DE\u7B54\u6E08\u307F\u306A\u3089\u7B54\u3048\u3092\u76F4\u63A5\u8FD4\u3059\u3002list_my_decisions\u3067\u5BFE\u8C61\u3092\u78BA\u304B\u3081\u3001\u5F15\u304D\u7D99\u3050\u7533\u8ACB\u3054\u3068\u306B\u547C\u3076\u3002",
|
|
15869
|
+
inputSchema: { type: "object", properties: { decision_id: { type: "string" } }, required: ["decision_id"], additionalProperties: false }
|
|
15870
|
+
},
|
|
15847
15871
|
{
|
|
15848
15872
|
name: "cancel_decision",
|
|
15849
15873
|
description: "\u672A\u6C7A\u30FB\u4FDD\u7559\u306E\u81EA\u5206\u306E\u7533\u8ACB\u3092\u53D6\u308A\u4E0B\u3052\u308B\u3002reason \u306B\u7406\u7531\u3092\u66F8\u304F\u3002",
|
|
@@ -16028,10 +16052,21 @@ ${JSON.stringify({ error: "duplicate_suspected", existing })}`, { error: "duplic
|
|
|
16028
16052
|
}
|
|
16029
16053
|
if (name === "amend_decision") {
|
|
16030
16054
|
const { decision_id, ...rest } = args;
|
|
16031
|
-
const
|
|
16032
|
-
|
|
16055
|
+
const channelId = await channelFor(harness, clientName, request.params._meta);
|
|
16056
|
+
const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(decision_id))}/amend`, { ...rest, route: { channel_id: channelId, harness } });
|
|
16057
|
+
lastChannel = channelId;
|
|
16058
|
+
return text(`\u76F4\u3057\u307E\u3057\u305F: ${decision.decision_id} version=${decision.version}${receiveGuide(harness, channelId)}
|
|
16033
16059
|
|
|
16034
|
-
${JSON.stringify(decision)}`, decision);
|
|
16060
|
+
${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
|
|
16061
|
+
}
|
|
16062
|
+
if (name === "resume_decision") {
|
|
16063
|
+
const channelId = await channelFor(harness, clientName, request.params._meta);
|
|
16064
|
+
const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/resume`, { channel_id: channelId, harness });
|
|
16065
|
+
lastChannel = channelId;
|
|
16066
|
+
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`;
|
|
16067
|
+
return text(`${head}${decision.answer_text ? "" : receiveGuide(harness, channelId)}
|
|
16068
|
+
|
|
16069
|
+
${JSON.stringify(decision)}`, { ...decision, steer_channel: { channel_id: channelId } });
|
|
16035
16070
|
}
|
|
16036
16071
|
if (name === "cancel_decision") {
|
|
16037
16072
|
const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(args.decision_id))}/cancel`, { reason: args.reason });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "approval-box",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
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",
|