approval-box 0.1.9 → 0.1.10
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 +2 -2
- package/dist/cli.mjs +62 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,8 +14,8 @@ npx -y approval-box@latest setup
|
|
|
14
14
|
|
|
15
15
|
1. `setup` finds the agents on this machine and registers Approval Box (MCP server and hooks). It shows the files it will change and keeps a backup (`*.approval-box-backup`) before writing.
|
|
16
16
|
PCにあるAIを見つけて登録します。書き換えるファイルを先に見せ、控えを残してから書き換えます。
|
|
17
|
-
It also offers to add one short paragraph to each agent's global instructions (`~/.claude/CLAUDE.md`, `$CODEX_HOME/AGENTS.md`, `~/.grok/AGENTS.md`) so the agent also files decisions, approvals and actions with `request_decision`. Cursor does not read a global file, so setup passes the same text through a `sessionStart` hook in `~/.cursor/hooks.json`. Skip with `--no-instructions`.
|
|
18
|
-
AIが毎回読む全体の指示に「判断・承認・操作が要る時は request_decision でも申請する」という一節を足すかを聞きます。Cursor はファイルから読まないので、会話の始まりのhook(`~/.cursor/hooks.json` の sessionStart
|
|
17
|
+
It also offers to add one short paragraph to each agent's global instructions (`~/.claude/CLAUDE.md`, `$CODEX_HOME/AGENTS.md`, `~/.grok/AGENTS.md`) so the agent also files decisions, approvals and actions with `request_decision`. Cursor does not read a global file, so setup passes the same text through a `sessionStart` hook in `~/.cursor/hooks.json`. If an instructions file is a symlink (for example, generated by a dotfiles repo), setup leaves it alone and asks you to add the paragraph to the source instead. Skip with `--no-instructions`.
|
|
18
|
+
AIが毎回読む全体の指示に「判断・承認・操作が要る時は request_decision でも申請する」という一節を足すかを聞きます。Cursor はファイルから読まないので、会話の始まりのhook(`~/.cursor/hooks.json` の sessionStart)で渡します。指示ファイルが別の所への参照(symlink、dotfilesの生成物など)の時は書かず、管理元の規範に足すよう案内します。足さない時は `--no-instructions`。
|
|
19
19
|
2. Scan the QR code or enter the code in “Add device” in the app or web.
|
|
20
20
|
画面のQRコードかコードを、アプリかWeb版の「端末を追加」で読み取ります。
|
|
21
21
|
3. Tell your agent: `Approval Boxのsetup_testを実行して` (or “run Approval Box setup_test”). Answer the test request; when the answer reaches the agent, you are ready.
|
package/dist/cli.mjs
CHANGED
|
@@ -4435,10 +4435,10 @@ var require_browser = __commonJS({
|
|
|
4435
4435
|
text2 = canvas;
|
|
4436
4436
|
canvas = void 0;
|
|
4437
4437
|
}
|
|
4438
|
-
return new Promise(function(
|
|
4438
|
+
return new Promise(function(resolve2, reject) {
|
|
4439
4439
|
try {
|
|
4440
4440
|
const data = QRCode2.create(text2, opts);
|
|
4441
|
-
|
|
4441
|
+
resolve2(renderFunc(data, canvas, opts));
|
|
4442
4442
|
} catch (e) {
|
|
4443
4443
|
reject(e);
|
|
4444
4444
|
}
|
|
@@ -4519,11 +4519,11 @@ var require_server = __commonJS({
|
|
|
4519
4519
|
}
|
|
4520
4520
|
function render(renderFunc, text2, params) {
|
|
4521
4521
|
if (!params.cb) {
|
|
4522
|
-
return new Promise(function(
|
|
4522
|
+
return new Promise(function(resolve2, reject) {
|
|
4523
4523
|
try {
|
|
4524
4524
|
const data = QRCode2.create(text2, params.opts);
|
|
4525
4525
|
return renderFunc(data, params.opts, function(err, data2) {
|
|
4526
|
-
return err ? reject(err) :
|
|
4526
|
+
return err ? reject(err) : resolve2(data2);
|
|
4527
4527
|
});
|
|
4528
4528
|
} catch (e) {
|
|
4529
4529
|
reject(e);
|
|
@@ -7538,7 +7538,7 @@ var require_compile = __commonJS({
|
|
|
7538
7538
|
const schOrFunc = root.refs[ref];
|
|
7539
7539
|
if (schOrFunc)
|
|
7540
7540
|
return schOrFunc;
|
|
7541
|
-
let _sch =
|
|
7541
|
+
let _sch = resolve2.call(this, root, ref);
|
|
7542
7542
|
if (_sch === void 0) {
|
|
7543
7543
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
7544
7544
|
const { schemaId } = this.opts;
|
|
@@ -7565,7 +7565,7 @@ var require_compile = __commonJS({
|
|
|
7565
7565
|
function sameSchemaEnv(s1, s2) {
|
|
7566
7566
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
7567
7567
|
}
|
|
7568
|
-
function
|
|
7568
|
+
function resolve2(root, ref) {
|
|
7569
7569
|
let sch;
|
|
7570
7570
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
7571
7571
|
ref = sch;
|
|
@@ -8395,7 +8395,7 @@ var require_fast_uri = __commonJS({
|
|
|
8395
8395
|
}
|
|
8396
8396
|
return uri;
|
|
8397
8397
|
}
|
|
8398
|
-
function
|
|
8398
|
+
function resolve2(baseURI, relativeURI, options) {
|
|
8399
8399
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
8400
8400
|
const {
|
|
8401
8401
|
parsed: baseParsed,
|
|
@@ -8764,7 +8764,7 @@ var require_fast_uri = __commonJS({
|
|
|
8764
8764
|
var fastUri = {
|
|
8765
8765
|
SCHEMES,
|
|
8766
8766
|
normalize,
|
|
8767
|
-
resolve,
|
|
8767
|
+
resolve: resolve2,
|
|
8768
8768
|
resolveComponent,
|
|
8769
8769
|
equal,
|
|
8770
8770
|
serialize,
|
|
@@ -11967,7 +11967,7 @@ function ensureDaemon() {
|
|
|
11967
11967
|
`);
|
|
11968
11968
|
}
|
|
11969
11969
|
}
|
|
11970
|
-
var sleep = (ms) => new Promise((
|
|
11970
|
+
var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
11971
11971
|
async function runDaemon() {
|
|
11972
11972
|
const status2 = daemonStatus();
|
|
11973
11973
|
if (status2.running && status2.pid !== process.pid) return;
|
|
@@ -12121,12 +12121,13 @@ async function runDaemon() {
|
|
|
12121
12121
|
// src/harness.ts
|
|
12122
12122
|
import { execFileSync } from "node:child_process";
|
|
12123
12123
|
import { copyFileSync, existsSync as existsSync5, readFileSync as readFileSync5, realpathSync } from "node:fs";
|
|
12124
|
-
import { homedir } from "node:os";
|
|
12124
|
+
import { homedir as homedir2 } from "node:os";
|
|
12125
12125
|
import { delimiter, dirname as dirname4, join as join5 } from "node:path";
|
|
12126
12126
|
|
|
12127
12127
|
// src/instructions.ts
|
|
12128
|
-
import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
12129
|
-
import {
|
|
12128
|
+
import { existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, readFileSync as readFileSync4, readlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
|
|
12129
|
+
import { homedir } from "node:os";
|
|
12130
|
+
import { dirname as dirname3, resolve } from "node:path";
|
|
12130
12131
|
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";
|
|
12131
12132
|
var START = "<!-- approval-box:start -->";
|
|
12132
12133
|
var END = "<!-- approval-box:end -->";
|
|
@@ -12137,18 +12138,35 @@ ${INSTRUCTION_TEXT}
|
|
|
12137
12138
|
${END}
|
|
12138
12139
|
`;
|
|
12139
12140
|
var PATTERN = new RegExp(`\\n*${START}[\\s\\S]*?${END}\\n?`, "g");
|
|
12141
|
+
var SAME_MEANING = /Approval Box\s*の\s*`?request_decision`?\s*でも申請/;
|
|
12140
12142
|
function hasInstructions(file) {
|
|
12141
|
-
|
|
12143
|
+
if (!existsSync4(file)) return false;
|
|
12144
|
+
const text2 = readFileSync4(file, "utf8");
|
|
12145
|
+
if (text2.includes(START) || SAME_MEANING.test(text2)) return true;
|
|
12146
|
+
for (const [, ref] of text2.matchAll(/^@(\S+)\s*$/gm)) {
|
|
12147
|
+
const target = ref.startsWith("~/") ? resolve(homedir(), ref.slice(2)) : resolve(dirname3(file), ref);
|
|
12148
|
+
if (existsSync4(target) && SAME_MEANING.test(readFileSync4(target, "utf8"))) return true;
|
|
12149
|
+
}
|
|
12150
|
+
return false;
|
|
12151
|
+
}
|
|
12152
|
+
function managedElsewhere(file) {
|
|
12153
|
+
try {
|
|
12154
|
+
return lstatSync(file).isSymbolicLink() ? readlinkSync(file) : null;
|
|
12155
|
+
} catch {
|
|
12156
|
+
return null;
|
|
12157
|
+
}
|
|
12142
12158
|
}
|
|
12143
12159
|
function writeInstructions(file) {
|
|
12160
|
+
if (managedElsewhere(file)) return "managed_elsewhere";
|
|
12144
12161
|
const current = existsSync4(file) ? readFileSync4(file, "utf8").replace(PATTERN, "\n").trimEnd() : "";
|
|
12145
12162
|
mkdirSync4(dirname3(file), { recursive: true, mode: 448 });
|
|
12146
12163
|
writeFileSync3(file, current ? `${current}
|
|
12147
12164
|
|
|
12148
12165
|
${BLOCK}` : BLOCK);
|
|
12166
|
+
return "written";
|
|
12149
12167
|
}
|
|
12150
12168
|
function removeInstructions(file) {
|
|
12151
|
-
if (!
|
|
12169
|
+
if (!existsSync4(file) || !readFileSync4(file, "utf8").includes(START)) return;
|
|
12152
12170
|
const rest = readFileSync4(file, "utf8").replace(PATTERN, "\n").trimEnd();
|
|
12153
12171
|
writeFileSync3(file, rest ? `${rest}
|
|
12154
12172
|
` : "");
|
|
@@ -12158,11 +12176,11 @@ function removeInstructions(file) {
|
|
|
12158
12176
|
var HARNESSES = ["claude", "codex", "cursor", "grok"];
|
|
12159
12177
|
var LABEL = { claude: "Claude Code", codex: "Codex", cursor: "Cursor", grok: "Grok" };
|
|
12160
12178
|
var CLIENT = { claude: "claude-code", codex: "codex", cursor: "cursor", grok: "grok" };
|
|
12161
|
-
var claudeDir = () => process.env.CLAUDE_CONFIG_DIR ?? join5(
|
|
12162
|
-
var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ? join5(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join5(
|
|
12163
|
-
var cursorDir = () => process.env.CURSOR_HOME ?? join5(
|
|
12164
|
-
var codexHome = () => process.env.CODEX_HOME ?? join5(
|
|
12165
|
-
var grokDir = () => process.env.GROK_HOME ?? join5(
|
|
12179
|
+
var claudeDir = () => process.env.CLAUDE_CONFIG_DIR ?? join5(homedir2(), ".claude");
|
|
12180
|
+
var claudeJson = () => process.env.CLAUDE_CONFIG_DIR ? join5(process.env.CLAUDE_CONFIG_DIR, ".claude.json") : join5(homedir2(), ".claude.json");
|
|
12181
|
+
var cursorDir = () => process.env.CURSOR_HOME ?? join5(homedir2(), ".cursor");
|
|
12182
|
+
var codexHome = () => process.env.CODEX_HOME ?? join5(homedir2(), ".codex");
|
|
12183
|
+
var grokDir = () => process.env.GROK_HOME ?? join5(homedir2(), ".grok");
|
|
12166
12184
|
function filesOf(target) {
|
|
12167
12185
|
if (target === "claude") return [claudeJson(), join5(claudeDir(), "settings.json")];
|
|
12168
12186
|
if (target === "cursor") return [join5(cursorDir(), "mcp.json"), join5(cursorDir(), "hooks.json"), cursorCliConfig()];
|
|
@@ -12246,13 +12264,18 @@ async function withCodexConfig(fn) {
|
|
|
12246
12264
|
}
|
|
12247
12265
|
async function register(target, options = {}) {
|
|
12248
12266
|
const file = instructionsFileOf(target);
|
|
12267
|
+
let note;
|
|
12249
12268
|
if (options.instructions && file) {
|
|
12250
12269
|
try {
|
|
12251
|
-
writeInstructions(file)
|
|
12270
|
+
if (writeInstructions(file) === "managed_elsewhere") note = `\u5168\u4F53\u306E\u6307\u793A\uFF08${file} \u2192 ${managedElsewhere(file)}\uFF09\u306F\u5225\u306E\u6240\u3067\u7BA1\u7406\u3055\u308C\u3066\u3044\u308B\u306E\u3067\u66F8\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u7BA1\u7406\u5143\u306E\u898F\u7BC4\u306B\u4E00\u7BC0\u3092\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044`;
|
|
12252
12271
|
} catch (error) {
|
|
12253
12272
|
return { target, status: "failed", detail: `${file}: ${error.message}` };
|
|
12254
12273
|
}
|
|
12255
12274
|
}
|
|
12275
|
+
const result = await registerTools(target, options);
|
|
12276
|
+
return note && result.status === "registered" ? { ...result, note } : result;
|
|
12277
|
+
}
|
|
12278
|
+
async function registerTools(target, options) {
|
|
12256
12279
|
const hook = (kind) => ({ command: stableNode(), script: runtimeEntry(kind) });
|
|
12257
12280
|
try {
|
|
12258
12281
|
if (target === "claude") {
|
|
@@ -14459,7 +14482,7 @@ var Protocol = class {
|
|
|
14459
14482
|
return;
|
|
14460
14483
|
}
|
|
14461
14484
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
14462
|
-
await new Promise((
|
|
14485
|
+
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
14463
14486
|
options?.signal?.throwIfAborted();
|
|
14464
14487
|
}
|
|
14465
14488
|
} catch (error) {
|
|
@@ -14476,7 +14499,7 @@ var Protocol = class {
|
|
|
14476
14499
|
*/
|
|
14477
14500
|
request(request, resultSchema, options) {
|
|
14478
14501
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
14479
|
-
return new Promise((
|
|
14502
|
+
return new Promise((resolve2, reject) => {
|
|
14480
14503
|
const earlyReject = (error) => {
|
|
14481
14504
|
reject(error);
|
|
14482
14505
|
};
|
|
@@ -14554,7 +14577,7 @@ var Protocol = class {
|
|
|
14554
14577
|
if (!parseResult.success) {
|
|
14555
14578
|
reject(parseResult.error);
|
|
14556
14579
|
} else {
|
|
14557
|
-
|
|
14580
|
+
resolve2(parseResult.data);
|
|
14558
14581
|
}
|
|
14559
14582
|
} catch (error) {
|
|
14560
14583
|
reject(error);
|
|
@@ -14815,12 +14838,12 @@ var Protocol = class {
|
|
|
14815
14838
|
}
|
|
14816
14839
|
} catch {
|
|
14817
14840
|
}
|
|
14818
|
-
return new Promise((
|
|
14841
|
+
return new Promise((resolve2, reject) => {
|
|
14819
14842
|
if (signal.aborted) {
|
|
14820
14843
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
14821
14844
|
return;
|
|
14822
14845
|
}
|
|
14823
|
-
const timeoutId = setTimeout(
|
|
14846
|
+
const timeoutId = setTimeout(resolve2, interval);
|
|
14824
14847
|
signal.addEventListener("abort", () => {
|
|
14825
14848
|
clearTimeout(timeoutId);
|
|
14826
14849
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -15696,12 +15719,12 @@ var StdioServerTransport = class {
|
|
|
15696
15719
|
this.onclose?.();
|
|
15697
15720
|
}
|
|
15698
15721
|
send(message) {
|
|
15699
|
-
return new Promise((
|
|
15722
|
+
return new Promise((resolve2) => {
|
|
15700
15723
|
const json = serializeMessage(message);
|
|
15701
15724
|
if (this._stdout.write(json)) {
|
|
15702
|
-
|
|
15725
|
+
resolve2();
|
|
15703
15726
|
} else {
|
|
15704
|
-
this._stdout.once("drain",
|
|
15727
|
+
this._stdout.once("drain", resolve2);
|
|
15705
15728
|
}
|
|
15706
15729
|
});
|
|
15707
15730
|
}
|
|
@@ -15712,7 +15735,7 @@ import { existsSync as existsSync6, readFileSync as readFileSync6 } from "node:f
|
|
|
15712
15735
|
import { basename as basename2, join as join6 } from "node:path";
|
|
15713
15736
|
|
|
15714
15737
|
// src/version.ts
|
|
15715
|
-
var VERSION = true ? "0.1.
|
|
15738
|
+
var VERSION = true ? "0.1.10" : "0.0.0-dev";
|
|
15716
15739
|
function osName() {
|
|
15717
15740
|
return process.platform === "darwin" ? "macos" : process.platform === "win32" ? "windows" : process.platform;
|
|
15718
15741
|
}
|
|
@@ -16110,7 +16133,7 @@ async function pair(server, targets) {
|
|
|
16110
16133
|
if (result.status === "claimed" && result.token) return { token: result.token, connection_id: result.connection_id };
|
|
16111
16134
|
if (result.status === "rejected") throw new Error("\u30A2\u30D7\u30EA\u3067\u300C\u5FC3\u5F53\u305F\u308A\u304C\u306A\u3044\u300D\u304C\u62BC\u3055\u308C\u307E\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6 npx approval-box setup \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
16112
16135
|
if (result.status === "expired" || result.status === "delivered") throw new Error("\u30DA\u30A2\u30EA\u30F3\u30B0\u306E\u671F\u9650\u304C\u5207\u308C\u307E\u3057\u305F\u3002\u3082\u3046\u4E00\u5EA6 npx approval-box setup \u3092\u5B9F\u884C\u3057\u3066\u304F\u3060\u3055\u3044\u3002");
|
|
16113
|
-
await new Promise((
|
|
16136
|
+
await new Promise((resolve2) => setTimeout(resolve2, 2e3));
|
|
16114
16137
|
}
|
|
16115
16138
|
}
|
|
16116
16139
|
async function waitForChecks(api, clients) {
|
|
@@ -16134,7 +16157,7 @@ async function waitForChecks(api, clients) {
|
|
|
16134
16157
|
out("\n\u3059\u3079\u3066\u306EAI\u3067\u78BA\u8A8D\u304C\u6E08\u307F\u307E\u3057\u305F\u3002Approval Box\u3092\u4F7F\u3048\u307E\u3059\u3002");
|
|
16135
16158
|
return;
|
|
16136
16159
|
}
|
|
16137
|
-
await new Promise((
|
|
16160
|
+
await new Promise((resolve2) => setTimeout(resolve2, 3e3));
|
|
16138
16161
|
}
|
|
16139
16162
|
}
|
|
16140
16163
|
async function setup() {
|
|
@@ -16161,7 +16184,8 @@ async function setup() {
|
|
|
16161
16184
|
out(` \u300C${INSTRUCTION_TEXT}\u300D`);
|
|
16162
16185
|
for (const target of targets) {
|
|
16163
16186
|
const file = instructionsFileOf(target);
|
|
16164
|
-
|
|
16187
|
+
const link = file ? managedElsewhere(file) : null;
|
|
16188
|
+
out(` ${LABEL[target]}: ${!file ? "\u4F1A\u8A71\u306E\u59CB\u307E\u308A\u306Ehook\uFF08hooks.json \u306E sessionStart\uFF09\u3067\u6E21\u3057\u307E\u3059" : link ? `${file} \u306F ${link} \u3078\u306E\u53C2\u7167\u3067\u3001\u5225\u306E\u6240\u3067\u7BA1\u7406\u3055\u308C\u3066\u3044\u308B\u306E\u3067\u66F8\u304D\u307E\u305B\u3093\uFF08\u7BA1\u7406\u5143\u306E\u898F\u7BC4\u306B\u4E00\u7BC0\u3092\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044\uFF09` : file}`);
|
|
16165
16189
|
}
|
|
16166
16190
|
const instructions = !flag("no-instructions") && (flag("yes") || !/^n(o)?$/i.test(await ask("\u8DB3\u3057\u307E\u3059\u304B\uFF1F [Y/n] ")));
|
|
16167
16191
|
const cli = installRuntime();
|
|
@@ -16194,6 +16218,7 @@ async function registerTargets() {
|
|
|
16194
16218
|
const result = await register(target, { instructions: flag("instructions") });
|
|
16195
16219
|
const extra = result.steer ? `\uFF08${STEER_LABEL[result.steer.split(":")[0] ?? ""] ?? `\u4F5C\u696D\u4E2D\u306E\u5272\u308A\u8FBC\u307F: ${result.steer}`}\uFF09` : "";
|
|
16196
16220
|
out(` ${LABEL[target]}: ${result.status === "registered" ? "\u767B\u9332\u3057\u307E\u3057\u305F" : `\u5931\u6557 \u2014 ${result.detail}`}${extra}`);
|
|
16221
|
+
if (result.note) out(` \u30FB${result.note}`);
|
|
16197
16222
|
if (result.status === "failed") failed = true;
|
|
16198
16223
|
}
|
|
16199
16224
|
ensureDaemon();
|
|
@@ -16268,7 +16293,11 @@ async function doctor() {
|
|
|
16268
16293
|
if (!r.mcp) problems.push(`${LABEL[target]}: MCP\u304C\u767B\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093 \u2192 npx approval-box setup --only ${target}`);
|
|
16269
16294
|
if (r.hooks === false) problems.push(`${LABEL[target]}: hook\u304C\u767B\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093 \u2192 npx approval-box setup --only ${target}`);
|
|
16270
16295
|
if (r.entry && !existsSync7(r.entry)) problems.push(`${LABEL[target]}: \u767B\u9332\u5148\u306E\u30D5\u30A1\u30A4\u30EB\u304C\u3042\u308A\u307E\u305B\u3093\uFF08${r.entry}\uFF09\u3002node \u3084Approval Box\u3092\u5165\u308C\u76F4\u3057\u305F\u6642\u306B\u8D77\u304D\u307E\u3059 \u2192 npx approval-box setup`);
|
|
16271
|
-
if (r.mcp && r.instructions === false)
|
|
16296
|
+
if (r.mcp && r.instructions === false) {
|
|
16297
|
+
const file = instructionsFileOf(target);
|
|
16298
|
+
const link = file ? managedElsewhere(file) : null;
|
|
16299
|
+
hints.push(link ? `${LABEL[target]}: \u5168\u4F53\u306E\u6307\u793A\uFF08${file} \u2192 ${link}\uFF09\u306BApproval Box\u306E\u4E00\u7BC0\u304C\u3042\u308A\u307E\u305B\u3093\u3002\u5225\u306E\u6240\u3067\u7BA1\u7406\u3055\u308C\u3066\u3044\u308B\u306E\u3067\u3001\u7BA1\u7406\u5143\u306E\u898F\u7BC4\u306B\u300C${INSTRUCTION_TEXT}\u300D\u3092\u8DB3\u3057\u3066\u304F\u3060\u3055\u3044` : `${LABEL[target]}: \u5168\u4F53\u306E\u6307\u793A\u306BApproval Box\u306E\u4E00\u7BC0\u304C\u3042\u308A\u307E\u305B\u3093\u3002AI\u304C\u7533\u8ACB\u3092\u51FA\u3055\u306A\u3044\u6642\u306F \u2192 npx approval-box setup --only ${target}`);
|
|
16300
|
+
}
|
|
16272
16301
|
}
|
|
16273
16302
|
for (const hint of hints) out(`\u30FB${hint}`);
|
|
16274
16303
|
if (!problems.length) out("\u554F\u984C\u306F\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u5C4A\u304B\u306A\u3044\u6642\u306F\u3001AI\u306B\u300CApproval Box\u306Esetup_test\u3092\u5B9F\u884C\u3057\u3066\u300D\u3068\u8A00\u3063\u3066\u3001\u3069\u3053\u3067\u6B62\u307E\u308B\u304B\u3092\u78BA\u304B\u3081\u3066\u304F\u3060\u3055\u3044\u3002");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "approval-box",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
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",
|