approval-box 0.1.19 → 0.1.21
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 +4 -0
- package/dist/cli.mjs +101 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,3 +50,7 @@ Requires Node.js 20 or later. License: MIT.
|
|
|
50
50
|
|
|
51
51
|
この機能はコネクタ0.1.13以降と対応サーバーを使います。会話を開き直しても、
|
|
52
52
|
再開を指定するまでは元の会話が配送先です。答えは `get_decision` でも取得できます。
|
|
53
|
+
|
|
54
|
+
### 申請に画像を添える
|
|
55
|
+
|
|
56
|
+
`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` に渡します。
|
package/dist/cli.mjs
CHANGED
|
@@ -1336,11 +1336,11 @@ var require_dijkstra = __commonJS({
|
|
|
1336
1336
|
var predecessors = {};
|
|
1337
1337
|
var costs = {};
|
|
1338
1338
|
costs[s] = 0;
|
|
1339
|
-
var
|
|
1340
|
-
|
|
1339
|
+
var open2 = dijkstra.PriorityQueue.make();
|
|
1340
|
+
open2.push(s, 0);
|
|
1341
1341
|
var closest, u, v, cost_of_s_to_u, adjacent_nodes, cost_of_e, cost_of_s_to_u_plus_cost_of_e, cost_of_s_to_v, first_visit;
|
|
1342
|
-
while (!
|
|
1343
|
-
closest =
|
|
1342
|
+
while (!open2.empty()) {
|
|
1343
|
+
closest = open2.pop();
|
|
1344
1344
|
u = closest.value;
|
|
1345
1345
|
cost_of_s_to_u = closest.cost;
|
|
1346
1346
|
adjacent_nodes = graph[u] || {};
|
|
@@ -1352,7 +1352,7 @@ var require_dijkstra = __commonJS({
|
|
|
1352
1352
|
first_visit = typeof costs[v] === "undefined";
|
|
1353
1353
|
if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
|
|
1354
1354
|
costs[v] = cost_of_s_to_u_plus_cost_of_e;
|
|
1355
|
-
|
|
1355
|
+
open2.push(v, cost_of_s_to_u_plus_cost_of_e);
|
|
1356
1356
|
predecessors[v] = u;
|
|
1357
1357
|
}
|
|
1358
1358
|
}
|
|
@@ -11761,7 +11761,7 @@ var require_dist = __commonJS({
|
|
|
11761
11761
|
var import_qrcode = __toESM(require_lib(), 1);
|
|
11762
11762
|
import { cpSync, existsSync as existsSync7, mkdirSync as mkdirSync5, rmSync as rmSync3 } from "node:fs";
|
|
11763
11763
|
import { hostname } from "node:os";
|
|
11764
|
-
import { join as
|
|
11764
|
+
import { join as join10 } from "node:path";
|
|
11765
11765
|
import { createInterface } from "node:readline/promises";
|
|
11766
11766
|
|
|
11767
11767
|
// src/api.ts
|
|
@@ -11814,6 +11814,17 @@ var Api = class {
|
|
|
11814
11814
|
}
|
|
11815
11815
|
return json;
|
|
11816
11816
|
}
|
|
11817
|
+
/** 申請前画像をバイナリで上げる。 */
|
|
11818
|
+
async uploadRequestImage(data, name, contentType) {
|
|
11819
|
+
const response = await fetch(this.url(`/request-images?name=${encodeURIComponent(name)}`), {
|
|
11820
|
+
method: "POST",
|
|
11821
|
+
headers: { authorization: `Bearer ${this.token}`, "content-type": contentType },
|
|
11822
|
+
body: new Uint8Array(data)
|
|
11823
|
+
});
|
|
11824
|
+
const json = await response.json();
|
|
11825
|
+
if (!response.ok) throw new ServerError(response.status, json.error?.code ?? "internal", json.error?.message ?? `HTTP ${response.status}`, json);
|
|
11826
|
+
return json;
|
|
11827
|
+
}
|
|
11817
11828
|
/** ファイルを取る(添付)。誤りはJSONの本文から読む。 */
|
|
11818
11829
|
async download(path) {
|
|
11819
11830
|
let response;
|
|
@@ -12192,8 +12203,8 @@ async function runDaemon() {
|
|
|
12192
12203
|
await sync();
|
|
12193
12204
|
try {
|
|
12194
12205
|
const { items } = await api.call("GET", "/decisions");
|
|
12195
|
-
const
|
|
12196
|
-
if (
|
|
12206
|
+
const open2 = items.some((d) => d.status === "pending" || d.status === "held");
|
|
12207
|
+
if (open2 || Object.keys(journal).length) idleSince = Date.now();
|
|
12197
12208
|
else if (Date.now() - idleSince > IDLE_EXIT_MS) stop();
|
|
12198
12209
|
} catch {
|
|
12199
12210
|
idleSince = Date.now();
|
|
@@ -15825,11 +15836,67 @@ var StdioServerTransport = class {
|
|
|
15825
15836
|
};
|
|
15826
15837
|
|
|
15827
15838
|
// src/mcp.ts
|
|
15828
|
-
import { existsSync as existsSync6, readFileSync as
|
|
15829
|
-
import { basename as
|
|
15839
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "node:fs";
|
|
15840
|
+
import { basename as basename3, join as join9 } from "node:path";
|
|
15841
|
+
|
|
15842
|
+
// src/request-images.ts
|
|
15843
|
+
import { open } from "node:fs/promises";
|
|
15844
|
+
import { basename as basename2 } from "node:path";
|
|
15845
|
+
var MAX_FILE = 20 * 1024 * 1024;
|
|
15846
|
+
var MAX_TOTAL = 50 * 1024 * 1024;
|
|
15847
|
+
function imageType(b) {
|
|
15848
|
+
if (b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) return "image/png";
|
|
15849
|
+
if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return "image/jpeg";
|
|
15850
|
+
if (b.subarray(0, 4).toString() === "GIF8") return "image/gif";
|
|
15851
|
+
if (b.subarray(0, 4).toString() === "RIFF" && b.subarray(8, 12).toString() === "WEBP") return "image/webp";
|
|
15852
|
+
if (b.subarray(4, 8).toString() === "ftyp" && ["heic", "heix", "hevc", "hevx", "heim", "heis", "mif1", "msf1", "heif"].includes(b.subarray(8, 12).toString())) return "image/heic";
|
|
15853
|
+
throw new Error("\u7533\u8ACB\u306B\u4ED8\u3051\u3089\u308C\u308B\u306E\u306FJPEG\u30FBPNG\u30FBGIF\u30FBWebP\u30FBHEIC\u753B\u50CF\u3067\u3059\u3002");
|
|
15854
|
+
}
|
|
15855
|
+
async function uploadImagePaths(api, paths) {
|
|
15856
|
+
if (!Array.isArray(paths) || paths.length > 10 || paths.some((p) => typeof p !== "string" || !p.trim())) throw new Error("image_paths\u306F10\u4EF6\u307E\u3067\u306E\u753B\u50CF\u30D5\u30A1\u30A4\u30EB\u30D1\u30B9\u914D\u5217\u3067\u3059\u3002");
|
|
15857
|
+
const images = [];
|
|
15858
|
+
let total = 0;
|
|
15859
|
+
for (const path of paths) {
|
|
15860
|
+
const file = await open(path, "r");
|
|
15861
|
+
try {
|
|
15862
|
+
const stat = await file.stat();
|
|
15863
|
+
if (!stat.isFile() || !stat.size || stat.size > MAX_FILE) throw new Error(`${basename2(path)}: \u7A7A\u3067\u306A\u3044\u901A\u5E38\u30D5\u30A1\u30A4\u30EB\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\uFF0820MiB\u307E\u3067\uFF09\u3002`);
|
|
15864
|
+
total += stat.size;
|
|
15865
|
+
if (total > MAX_TOTAL) throw new Error("\u7533\u8ACB\u753B\u50CF\u306F\u5408\u8A0850MiB\u307E\u3067\u3067\u3059\u3002");
|
|
15866
|
+
const data = Buffer.alloc(stat.size + 1);
|
|
15867
|
+
let n = 0;
|
|
15868
|
+
while (n < data.length) {
|
|
15869
|
+
const r = await file.read(data, n, data.length - n, n);
|
|
15870
|
+
if (!r.bytesRead) break;
|
|
15871
|
+
n += r.bytesRead;
|
|
15872
|
+
}
|
|
15873
|
+
if (n !== stat.size) throw new Error(`${basename2(path)}: \u8AAD\u307F\u53D6\u308A\u4E2D\u306B\u753B\u50CF\u304C\u5909\u308F\u308A\u307E\u3057\u305F\u3002`);
|
|
15874
|
+
const bytes = data.subarray(0, n);
|
|
15875
|
+
images.push({ name: basename2(path), data: bytes, type: imageType(bytes) });
|
|
15876
|
+
} finally {
|
|
15877
|
+
await file.close();
|
|
15878
|
+
}
|
|
15879
|
+
}
|
|
15880
|
+
const ids = [];
|
|
15881
|
+
for (const image of images) ids.push((await api.uploadRequestImage(image.data, image.name, image.type)).id);
|
|
15882
|
+
return ids;
|
|
15883
|
+
}
|
|
15884
|
+
|
|
15885
|
+
// src/claude-channel.ts
|
|
15886
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
15887
|
+
import { join as join8 } from "node:path";
|
|
15888
|
+
function claudeChannelIsCurrent(profile, channelId, parent) {
|
|
15889
|
+
try {
|
|
15890
|
+
const bound = readChannel(profile, channelId).claude;
|
|
15891
|
+
const now = JSON.parse(readFileSync6(join8(parent.hook_root, parent.request_id, "request.json"), "utf8"));
|
|
15892
|
+
return !!bound && bound.session_id === parent.session_id && bound.parent_pid === now.parent_pid && bound.parent_started_identity === now.parent_started_identity;
|
|
15893
|
+
} catch {
|
|
15894
|
+
return false;
|
|
15895
|
+
}
|
|
15896
|
+
}
|
|
15830
15897
|
|
|
15831
15898
|
// src/version.ts
|
|
15832
|
-
var VERSION = true ? "0.1.
|
|
15899
|
+
var VERSION = true ? "0.1.21" : "0.0.0-dev";
|
|
15833
15900
|
function osName() {
|
|
15834
15901
|
return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
|
|
15835
15902
|
}
|
|
@@ -15872,6 +15939,8 @@ var TOOLS = [
|
|
|
15872
15939
|
deadline: { type: "string", description: "\u671F\u9650\uFF08ISO 8601\uFF09" },
|
|
15873
15940
|
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" },
|
|
15874
15941
|
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" },
|
|
15942
|
+
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" },
|
|
15943
|
+
request_attachment_ids: { type: "array", items: { type: "string" }, maxItems: 10 },
|
|
15875
15944
|
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" }
|
|
15876
15945
|
},
|
|
15877
15946
|
required: ["title", "options"],
|
|
@@ -15890,6 +15959,8 @@ var TOOLS = [
|
|
|
15890
15959
|
changes: {
|
|
15891
15960
|
type: "object",
|
|
15892
15961
|
properties: {
|
|
15962
|
+
image_paths: { type: "array", items: { type: "string" }, maxItems: 10 },
|
|
15963
|
+
request_attachment_ids: { type: "array", items: { type: "string" }, maxItems: 10 },
|
|
15893
15964
|
title: { type: "string" },
|
|
15894
15965
|
context: { type: "string" },
|
|
15895
15966
|
options: { type: "array", items: optionSchema, minItems: 2, maxItems: 6 },
|
|
@@ -15937,12 +16008,12 @@ var TOOLS = [
|
|
|
15937
16008
|
];
|
|
15938
16009
|
var VIEWABLE_IMAGES = ["image/jpeg", "image/png", "image/gif", "image/webp"];
|
|
15939
16010
|
var MAX_INLINE_IMAGE = 5 * 1024 * 1024;
|
|
15940
|
-
var parentsFile = () =>
|
|
16011
|
+
var parentsFile = () => join9(stateRoot(), "parents.json");
|
|
15941
16012
|
var processChannels = /* @__PURE__ */ new Map();
|
|
15942
16013
|
var lastChannel;
|
|
15943
16014
|
function savedParents() {
|
|
15944
16015
|
try {
|
|
15945
|
-
return existsSync6(parentsFile()) ? JSON.parse(
|
|
16016
|
+
return existsSync6(parentsFile()) ? JSON.parse(readFileSync7(parentsFile(), "utf8")) : {};
|
|
15946
16017
|
} catch {
|
|
15947
16018
|
return {};
|
|
15948
16019
|
}
|
|
@@ -15979,7 +16050,7 @@ async function channelFor(harness, clientName, meta) {
|
|
|
15979
16050
|
if (!parent) throw new Error("Claude Code\u306Ehook\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3002npx approval-box setup \u3092\u3084\u308A\u76F4\u3057\u3001Claude Code\u3092\u518D\u8D77\u52D5\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
15980
16051
|
const key2 = `claude:${parent.session_id}`;
|
|
15981
16052
|
const existing2 = reuse(key2, true);
|
|
15982
|
-
if (existing2) return existing2;
|
|
16053
|
+
if (existing2 && claudeChannelIsCurrent(PROFILE, existing2, parent)) return existing2;
|
|
15983
16054
|
const channel2 = openChannel(PROFILE, parent);
|
|
15984
16055
|
remember(key2, channel2.channel_id, true);
|
|
15985
16056
|
return channel2.channel_id;
|
|
@@ -16046,10 +16117,14 @@ ${JSON.stringify({ items })}`, { items });
|
|
|
16046
16117
|
if (name === "request_decision") {
|
|
16047
16118
|
const channelId = await channelFor(harness, clientName, request.params._meta);
|
|
16048
16119
|
lastChannel = channelId;
|
|
16120
|
+
const { image_paths, ...rest } = args;
|
|
16121
|
+
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");
|
|
16122
|
+
const request_attachment_ids = image_paths !== void 0 ? await uploadImagePaths(api, image_paths) : rest.request_attachment_ids;
|
|
16049
16123
|
const body = {
|
|
16050
|
-
...
|
|
16124
|
+
...rest,
|
|
16125
|
+
...request_attachment_ids !== void 0 ? { request_attachment_ids } : {},
|
|
16051
16126
|
client: CLIENT_OF[harness],
|
|
16052
|
-
session_label: args.session_label || `${
|
|
16127
|
+
session_label: args.session_label || `${basename3(process.cwd())} (${CLIENT_OF[harness]})`,
|
|
16053
16128
|
route: { channel_id: channelId, harness }
|
|
16054
16129
|
};
|
|
16055
16130
|
try {
|
|
@@ -16088,6 +16163,10 @@ ${JSON.stringify({ error: "duplicate_suspected", existing })}`, { error: "duplic
|
|
|
16088
16163
|
}
|
|
16089
16164
|
if (name === "amend_decision") {
|
|
16090
16165
|
const { decision_id, ...rest } = args;
|
|
16166
|
+
const { image_paths, ...changes } = rest.changes ?? {};
|
|
16167
|
+
if (image_paths !== void 0 && changes.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");
|
|
16168
|
+
if (image_paths !== void 0) changes.request_attachment_ids = await uploadImagePaths(api, image_paths);
|
|
16169
|
+
rest.changes = changes;
|
|
16091
16170
|
const channelId = await channelFor(harness, clientName, request.params._meta);
|
|
16092
16171
|
const decision = await api.call("POST", `/decisions/${encodeURIComponent(String(decision_id))}/amend`, { ...rest, route: { channel_id: channelId, harness } });
|
|
16093
16172
|
lastChannel = channelId;
|
|
@@ -16122,7 +16201,7 @@ ${JSON.stringify(decision)}`, decision);
|
|
|
16122
16201
|
if (name === "get_attachment") {
|
|
16123
16202
|
const decisionId = String(args.decision_id);
|
|
16124
16203
|
const decision = await api.call("GET", `/decisions/${encodeURIComponent(decisionId)}`);
|
|
16125
|
-
const list = decision.answer?.attachments ?? [];
|
|
16204
|
+
const list = [...decision.request_attachments ?? [], ...decision.answer?.attachments ?? []];
|
|
16126
16205
|
const index = list.findIndex((a) => a.id === args.attachment_id);
|
|
16127
16206
|
if (index < 0) return text(`Approval Box: ${decisionId} \u306E\u7B54\u3048\u306B\u3001\u305D\u306E\u6DFB\u4ED8\u306F\u3042\u308A\u307E\u305B\u3093\u3002get_decision \u306E answer.attachments \u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002`, { error: "not_found" }, true);
|
|
16128
16207
|
const meta = list[index];
|
|
@@ -16130,7 +16209,7 @@ ${JSON.stringify(decision)}`, decision);
|
|
|
16130
16209
|
const head = `${decisionId} \u306E\u6DFB\u4ED8 ${index + 1}: ${meta.name}\uFF08${meta.content_type}\u3001${meta.size}\u30D0\u30A4\u30C8\uFF09\u3092\u4FDD\u5B58\u3057\u307E\u3057\u305F: ${path}`;
|
|
16131
16210
|
const structured = { decision_id: decisionId, attachment: meta, path };
|
|
16132
16211
|
if (VIEWABLE_IMAGES.includes(meta.content_type) && meta.size <= MAX_INLINE_IMAGE) {
|
|
16133
|
-
return { content: [{ type: "text", text: head }, { type: "image", data:
|
|
16212
|
+
return { content: [{ type: "text", text: head }, { type: "image", data: readFileSync7(path).toString("base64"), mimeType: meta.content_type }], structuredContent: structured };
|
|
16134
16213
|
}
|
|
16135
16214
|
return text(head, structured);
|
|
16136
16215
|
}
|
|
@@ -16140,7 +16219,7 @@ ${JSON.stringify(decision)}`, decision);
|
|
|
16140
16219
|
const decision = await api.call("POST", "/setup-test", {
|
|
16141
16220
|
client: CLIENT_OF[harness],
|
|
16142
16221
|
os: osName(),
|
|
16143
|
-
session_label: `\u63A5\u7D9A\u30C6\u30B9\u30C8 ${
|
|
16222
|
+
session_label: `\u63A5\u7D9A\u30C6\u30B9\u30C8 ${basename3(process.cwd())} (${CLIENT_OF[harness]})`,
|
|
16144
16223
|
route: { channel_id: channelId, harness }
|
|
16145
16224
|
});
|
|
16146
16225
|
const message = `\u63A5\u7D9A\u30C6\u30B9\u30C8\u306E\u7533\u8ACB\u3092\u9001\u308A\u307E\u3057\u305F\uFF08${decision.decision_id}\uFF09\u3002\u5229\u7528\u8005\u306B\u30A2\u30D7\u30EA\u304BWeb\u7248\u3067\u7B54\u3048\u308B\u3088\u3046\u4F1D\u3048\u3066\u304F\u3060\u3055\u3044\u3002\u7B54\u3048\u304C\u3053\u306E\u4F1A\u8A71\u3078\u5C4A\u3044\u305F\u3089\u3001\u305D\u3053\u306B\u66F8\u304B\u308C\u305F\u78BA\u8A8D\u30B3\u30FC\u30C9\u3067 confirm_setup_test \u3092\u547C\u3093\u3067\u304F\u3060\u3055\u3044\u3002`;
|
|
@@ -16196,13 +16275,13 @@ async function ask(question) {
|
|
|
16196
16275
|
}
|
|
16197
16276
|
}
|
|
16198
16277
|
function installRuntime() {
|
|
16199
|
-
const target =
|
|
16278
|
+
const target = join10(home(), "runtime", VERSION);
|
|
16200
16279
|
if (runtimeDir() !== target) {
|
|
16201
16280
|
rmSync3(target, { recursive: true, force: true });
|
|
16202
16281
|
mkdirSync5(target, { recursive: true });
|
|
16203
16282
|
cpSync(runtimeDir(), target, { recursive: true });
|
|
16204
16283
|
}
|
|
16205
|
-
return
|
|
16284
|
+
return join10(target, "cli.mjs");
|
|
16206
16285
|
}
|
|
16207
16286
|
function selectedTargets() {
|
|
16208
16287
|
const only = option("only");
|
|
@@ -16347,7 +16426,7 @@ async function uninstall() {
|
|
|
16347
16426
|
out(` \u30B5\u30FC\u30D0\u30FC: \u63A5\u7D9A\u306E\u89E3\u9664\u306B\u5931\u6557\u3057\u307E\u3057\u305F\uFF08\u30A2\u30D7\u30EA\u306E\u300C\u63A5\u7D9A\u300D\u304B\u3089\u5916\u3057\u3066\u304F\u3060\u3055\u3044\uFF09: ${error.message}`);
|
|
16348
16427
|
}
|
|
16349
16428
|
}
|
|
16350
|
-
rmSync3(
|
|
16429
|
+
rmSync3(join10(home(), "config.json"), { force: true });
|
|
16351
16430
|
out("\nApproval Box\u3092\u5916\u3057\u307E\u3057\u305F\u3002npm install -g \u3067\u5165\u308C\u305F\u5834\u5408\u306F\u3001npm uninstall -g approval-box \u3067\u672C\u4F53\u3082\u6D88\u305B\u307E\u3059\u3002");
|
|
16352
16431
|
}
|
|
16353
16432
|
async function status() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "approval-box",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
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",
|