agentapprove 0.1.8 → 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 +1 -1
- package/dist/cli.js +256 -49
- package/package.json +10 -8
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ agentapprove --no-e2e # Skip end-to-end encryption setup
|
|
|
95
95
|
- Node.js 18+
|
|
96
96
|
- macOS, Linux, or Windows (with Git Bash / Git for Windows)
|
|
97
97
|
- System tools: `curl`, `jq`, `openssl` (included with Git Bash on Windows)
|
|
98
|
-
- Agent Approve iOS app and active subscription ($
|
|
98
|
+
- Agent Approve iOS app and active subscription ($14.99/month, 7-day free trial)
|
|
99
99
|
|
|
100
100
|
## Links
|
|
101
101
|
|
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
33
33
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
34
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
35
35
|
|
|
36
|
-
// node_modules/sisteransi/src/index.js
|
|
36
|
+
// ../../node_modules/.bun/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
|
|
37
37
|
var require_src = __commonJS((exports, module) => {
|
|
38
38
|
var ESC = "\x1B";
|
|
39
39
|
var CSI = `${ESC}[`;
|
|
@@ -91,7 +91,7 @@ var require_src = __commonJS((exports, module) => {
|
|
|
91
91
|
module.exports = { cursor, scroll, erase, beep };
|
|
92
92
|
});
|
|
93
93
|
|
|
94
|
-
// node_modules/picocolors/picocolors.js
|
|
94
|
+
// ../../node_modules/.bun/picocolors@1.1.1/node_modules/picocolors/picocolors.js
|
|
95
95
|
var require_picocolors = __commonJS((exports, module) => {
|
|
96
96
|
var p = process || {};
|
|
97
97
|
var argv = p.argv || [];
|
|
@@ -161,7 +161,7 @@ var require_picocolors = __commonJS((exports, module) => {
|
|
|
161
161
|
module.exports.createColors = createColors;
|
|
162
162
|
});
|
|
163
163
|
|
|
164
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRMode.js
|
|
164
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMode.js
|
|
165
165
|
var require_QRMode = __commonJS((exports, module) => {
|
|
166
166
|
module.exports = {
|
|
167
167
|
MODE_NUMBER: 1 << 0,
|
|
@@ -171,7 +171,7 @@ var require_QRMode = __commonJS((exports, module) => {
|
|
|
171
171
|
};
|
|
172
172
|
});
|
|
173
173
|
|
|
174
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js
|
|
174
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QR8bitByte.js
|
|
175
175
|
var require_QR8bitByte = __commonJS((exports, module) => {
|
|
176
176
|
var QRMode = require_QRMode();
|
|
177
177
|
function QR8bitByte(data) {
|
|
@@ -191,7 +191,7 @@ var require_QR8bitByte = __commonJS((exports, module) => {
|
|
|
191
191
|
module.exports = QR8bitByte;
|
|
192
192
|
});
|
|
193
193
|
|
|
194
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRMath.js
|
|
194
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMath.js
|
|
195
195
|
var require_QRMath = __commonJS((exports, module) => {
|
|
196
196
|
var QRMath = {
|
|
197
197
|
glog: function(n) {
|
|
@@ -227,7 +227,7 @@ var require_QRMath = __commonJS((exports, module) => {
|
|
|
227
227
|
module.exports = QRMath;
|
|
228
228
|
});
|
|
229
229
|
|
|
230
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js
|
|
230
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRPolynomial.js
|
|
231
231
|
var require_QRPolynomial = __commonJS((exports, module) => {
|
|
232
232
|
var QRMath = require_QRMath();
|
|
233
233
|
function QRPolynomial(num, shift) {
|
|
@@ -277,7 +277,7 @@ var require_QRPolynomial = __commonJS((exports, module) => {
|
|
|
277
277
|
module.exports = QRPolynomial;
|
|
278
278
|
});
|
|
279
279
|
|
|
280
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRMaskPattern.js
|
|
280
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRMaskPattern.js
|
|
281
281
|
var require_QRMaskPattern = __commonJS((exports, module) => {
|
|
282
282
|
module.exports = {
|
|
283
283
|
PATTERN000: 0,
|
|
@@ -291,7 +291,7 @@ var require_QRMaskPattern = __commonJS((exports, module) => {
|
|
|
291
291
|
};
|
|
292
292
|
});
|
|
293
293
|
|
|
294
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js
|
|
294
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRUtil.js
|
|
295
295
|
var require_QRUtil = __commonJS((exports, module) => {
|
|
296
296
|
var QRMode = require_QRMode();
|
|
297
297
|
var QRPolynomial = require_QRPolynomial();
|
|
@@ -517,7 +517,7 @@ var require_QRUtil = __commonJS((exports, module) => {
|
|
|
517
517
|
module.exports = QRUtil;
|
|
518
518
|
});
|
|
519
519
|
|
|
520
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js
|
|
520
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRErrorCorrectLevel.js
|
|
521
521
|
var require_QRErrorCorrectLevel = __commonJS((exports, module) => {
|
|
522
522
|
module.exports = {
|
|
523
523
|
L: 1,
|
|
@@ -527,7 +527,7 @@ var require_QRErrorCorrectLevel = __commonJS((exports, module) => {
|
|
|
527
527
|
};
|
|
528
528
|
});
|
|
529
529
|
|
|
530
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js
|
|
530
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRRSBlock.js
|
|
531
531
|
var require_QRRSBlock = __commonJS((exports, module) => {
|
|
532
532
|
var QRErrorCorrectLevel = require_QRErrorCorrectLevel();
|
|
533
533
|
function QRRSBlock(totalCount, dataCount) {
|
|
@@ -730,7 +730,7 @@ var require_QRRSBlock = __commonJS((exports, module) => {
|
|
|
730
730
|
module.exports = QRRSBlock;
|
|
731
731
|
});
|
|
732
732
|
|
|
733
|
-
// node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js
|
|
733
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/QRBitBuffer.js
|
|
734
734
|
var require_QRBitBuffer = __commonJS((exports, module) => {
|
|
735
735
|
function QRBitBuffer() {
|
|
736
736
|
this.buffer = [];
|
|
@@ -763,7 +763,7 @@ var require_QRBitBuffer = __commonJS((exports, module) => {
|
|
|
763
763
|
module.exports = QRBitBuffer;
|
|
764
764
|
});
|
|
765
765
|
|
|
766
|
-
// node_modules/qrcode-terminal/vendor/QRCode/index.js
|
|
766
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/vendor/QRCode/index.js
|
|
767
767
|
var require_QRCode = __commonJS((exports, module) => {
|
|
768
768
|
var QR8bitByte = require_QR8bitByte();
|
|
769
769
|
var QRUtil = require_QRUtil();
|
|
@@ -1084,7 +1084,7 @@ var require_QRCode = __commonJS((exports, module) => {
|
|
|
1084
1084
|
module.exports = QRCode;
|
|
1085
1085
|
});
|
|
1086
1086
|
|
|
1087
|
-
// node_modules/qrcode-terminal/lib/main.js
|
|
1087
|
+
// ../../node_modules/.bun/qrcode-terminal@0.12.0/node_modules/qrcode-terminal/lib/main.js
|
|
1088
1088
|
var require_main = __commonJS((exports, module) => {
|
|
1089
1089
|
var QRCode = require_QRCode();
|
|
1090
1090
|
var QRErrorCorrectLevel = require_QRErrorCorrectLevel();
|
|
@@ -1178,7 +1178,7 @@ var require_main = __commonJS((exports, module) => {
|
|
|
1178
1178
|
};
|
|
1179
1179
|
});
|
|
1180
1180
|
|
|
1181
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
1181
|
+
// ../../node_modules/.bun/@clack+core@0.3.5/node_modules/@clack/core/dist/index.mjs
|
|
1182
1182
|
var import_sisteransi = __toESM(require_src(), 1);
|
|
1183
1183
|
import { stdin as $, stdout as k } from "node:process";
|
|
1184
1184
|
import * as f from "node:readline";
|
|
@@ -1592,7 +1592,7 @@ function OD({ input: e = $, output: u = k, overwrite: F = true, hideCursor: t =
|
|
|
1592
1592
|
};
|
|
1593
1593
|
}
|
|
1594
1594
|
|
|
1595
|
-
// node_modules/@clack/prompts/dist/index.mjs
|
|
1595
|
+
// ../../node_modules/.bun/@clack+prompts@0.8.2/node_modules/@clack/prompts/dist/index.mjs
|
|
1596
1596
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
1597
1597
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
1598
1598
|
import h from "node:process";
|
|
@@ -1836,7 +1836,7 @@ var ve = async (s, n) => {
|
|
|
1836
1836
|
return t;
|
|
1837
1837
|
};
|
|
1838
1838
|
|
|
1839
|
-
// node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
1839
|
+
// ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
1840
1840
|
var ANSI_BACKGROUND_OFFSET = 10;
|
|
1841
1841
|
var wrapAnsi16 = (offset = 0) => (code) => `\x1B[${code + offset}m`;
|
|
1842
1842
|
var wrapAnsi256 = (offset = 0) => (code) => `\x1B[${38 + offset};5;${code}m`;
|
|
@@ -2013,7 +2013,7 @@ function assembleStyles() {
|
|
|
2013
2013
|
var ansiStyles = assembleStyles();
|
|
2014
2014
|
var ansi_styles_default = ansiStyles;
|
|
2015
2015
|
|
|
2016
|
-
// node_modules/chalk/source/vendor/supports-color/index.js
|
|
2016
|
+
// ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
|
|
2017
2017
|
import process2 from "node:process";
|
|
2018
2018
|
import os from "node:os";
|
|
2019
2019
|
import tty from "node:tty";
|
|
@@ -2145,7 +2145,7 @@ var supportsColor = {
|
|
|
2145
2145
|
};
|
|
2146
2146
|
var supports_color_default = supportsColor;
|
|
2147
2147
|
|
|
2148
|
-
// node_modules/chalk/source/utilities.js
|
|
2148
|
+
// ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js
|
|
2149
2149
|
function stringReplaceAll(string, substring, replacer) {
|
|
2150
2150
|
let index = string.indexOf(substring);
|
|
2151
2151
|
if (index === -1) {
|
|
@@ -2178,7 +2178,7 @@ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
|
|
|
2178
2178
|
return returnValue;
|
|
2179
2179
|
}
|
|
2180
2180
|
|
|
2181
|
-
// node_modules/chalk/source/index.js
|
|
2181
|
+
// ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js
|
|
2182
2182
|
var { stdout: stdoutColor, stderr: stderrColor } = supports_color_default;
|
|
2183
2183
|
var GENERATOR = Symbol("GENERATOR");
|
|
2184
2184
|
var STYLER = Symbol("STYLER");
|
|
@@ -2332,7 +2332,7 @@ import { homedir, hostname, platform } from "os";
|
|
|
2332
2332
|
import { join, dirname, basename } from "path";
|
|
2333
2333
|
import { execSync, spawnSync } from "child_process";
|
|
2334
2334
|
import { randomBytes, createHash } from "crypto";
|
|
2335
|
-
var VERSION = "0.1.
|
|
2335
|
+
var VERSION = "0.1.10";
|
|
2336
2336
|
function getApiUrl() {
|
|
2337
2337
|
return process.env.AGENTAPPROVE_API || "https://api.agentapprove.com";
|
|
2338
2338
|
}
|
|
@@ -2380,6 +2380,9 @@ function getCommand() {
|
|
|
2380
2380
|
}
|
|
2381
2381
|
return filtered[0] || "install";
|
|
2382
2382
|
}
|
|
2383
|
+
var OPENCODE_PLUGIN_VERSION = "0.1.6";
|
|
2384
|
+
var OPENCLAW_PLUGIN_VERSION = "0.2.5";
|
|
2385
|
+
var OPENCLAW_PLUGIN_SPEC = `@agentapprove/openclaw@${OPENCLAW_PLUGIN_VERSION}`;
|
|
2383
2386
|
var AGENTS = {
|
|
2384
2387
|
"claude-code": {
|
|
2385
2388
|
name: "Claude Code",
|
|
@@ -2435,7 +2438,7 @@ var AGENTS = {
|
|
|
2435
2438
|
]
|
|
2436
2439
|
},
|
|
2437
2440
|
"vscode-agent": {
|
|
2438
|
-
name: "VS Code
|
|
2441
|
+
name: "VS Code GitHub Copilot",
|
|
2439
2442
|
configPath: join(homedir(), ".agentapprove", "hooks", "vscode-hooks.json"),
|
|
2440
2443
|
hooksKey: "hooks",
|
|
2441
2444
|
hooks: [
|
|
@@ -2450,7 +2453,7 @@ var AGENTS = {
|
|
|
2450
2453
|
]
|
|
2451
2454
|
},
|
|
2452
2455
|
"copilot-cli": {
|
|
2453
|
-
name: "Copilot CLI",
|
|
2456
|
+
name: "GitHub Copilot CLI",
|
|
2454
2457
|
configPath: join(homedir(), ".agentapprove", "copilot-cli-hooks.json"),
|
|
2455
2458
|
hooksKey: "hooks",
|
|
2456
2459
|
hooks: [
|
|
@@ -2470,6 +2473,18 @@ var AGENTS = {
|
|
|
2470
2473
|
{ name: "agentapprove", file: "@agentapprove/openclaw", description: "Tool approval + event monitoring", isApprovalHook: true, isPlugin: true }
|
|
2471
2474
|
]
|
|
2472
2475
|
},
|
|
2476
|
+
codex: {
|
|
2477
|
+
name: "OpenAI Codex",
|
|
2478
|
+
configPath: join(homedir(), ".codex", "hooks.json"),
|
|
2479
|
+
hooksKey: "hooks",
|
|
2480
|
+
hooks: [
|
|
2481
|
+
{ name: "SessionStart", file: "codex-session-start.sh", description: "Session started", hasMatcher: true },
|
|
2482
|
+
{ name: "PreToolUse", file: "codex-pre-tool.sh", description: "Tool approval", hasMatcher: true, isApprovalHook: true, timeout: 300 },
|
|
2483
|
+
{ name: "PostToolUse", file: "codex-post-tool.sh", description: "Tool completion logging", hasMatcher: true },
|
|
2484
|
+
{ name: "UserPromptSubmit", file: "codex-user-prompt.sh", description: "User prompt submitted", hasMatcher: false },
|
|
2485
|
+
{ name: "Stop", file: "codex-stop.sh", description: "Agent stopped (iOS input)", hasMatcher: false, timeout: 600 }
|
|
2486
|
+
]
|
|
2487
|
+
},
|
|
2473
2488
|
opencode: {
|
|
2474
2489
|
name: "OpenCode",
|
|
2475
2490
|
configPath: getOpenCodeConfigPath(),
|
|
@@ -2594,6 +2609,15 @@ function readJsoncConfig(configPath) {
|
|
|
2594
2609
|
return {};
|
|
2595
2610
|
}
|
|
2596
2611
|
}
|
|
2612
|
+
function getGithubHookEnv(agentId) {
|
|
2613
|
+
if (agentId === "vscode-agent") {
|
|
2614
|
+
return { AGENTAPPROVE_GITHUB_VARIANT: "vscode" };
|
|
2615
|
+
}
|
|
2616
|
+
if (agentId === "copilot-cli") {
|
|
2617
|
+
return { AGENTAPPROVE_GITHUB_VARIANT: "github" };
|
|
2618
|
+
}
|
|
2619
|
+
return;
|
|
2620
|
+
}
|
|
2597
2621
|
function addToVSCodeHookLocations() {
|
|
2598
2622
|
const hookLocation = "~/.agentapprove/hooks";
|
|
2599
2623
|
const modified = [];
|
|
@@ -2650,6 +2674,10 @@ function detectInstalledAgents() {
|
|
|
2650
2674
|
if (existsSync(join(homedir(), ".openclaw"))) {
|
|
2651
2675
|
installed.push(id);
|
|
2652
2676
|
}
|
|
2677
|
+
} else if (id === "codex") {
|
|
2678
|
+
if (existsSync(join(homedir(), ".codex"))) {
|
|
2679
|
+
installed.push(id);
|
|
2680
|
+
}
|
|
2653
2681
|
} else if (id === "opencode") {
|
|
2654
2682
|
if (existsSync(getOpenCodeConfigDir())) {
|
|
2655
2683
|
installed.push(id);
|
|
@@ -2814,6 +2842,87 @@ function writeJsonConfig(configPath, config) {
|
|
|
2814
2842
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + `
|
|
2815
2843
|
`);
|
|
2816
2844
|
}
|
|
2845
|
+
function ensureCodexFeatureFlag(configPath = join(homedir(), ".codex", "config.toml")) {
|
|
2846
|
+
const dir = dirname(configPath);
|
|
2847
|
+
if (!existsSync(dir)) {
|
|
2848
|
+
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
2849
|
+
}
|
|
2850
|
+
const sectionHeader = "[features]";
|
|
2851
|
+
const desiredLine = "codex_hooks = true";
|
|
2852
|
+
if (!existsSync(configPath)) {
|
|
2853
|
+
writeFileSync(configPath, `${sectionHeader}
|
|
2854
|
+
${desiredLine}
|
|
2855
|
+
`, { mode: 384 });
|
|
2856
|
+
return { updated: true, backupPath: null };
|
|
2857
|
+
}
|
|
2858
|
+
const original = readFileSync(configPath, "utf-8");
|
|
2859
|
+
const lines = original.split(/\r?\n/);
|
|
2860
|
+
const updatedLines = [];
|
|
2861
|
+
let inFeatures = false;
|
|
2862
|
+
let foundFeatures = false;
|
|
2863
|
+
let foundKey = false;
|
|
2864
|
+
let changed = false;
|
|
2865
|
+
for (const line of lines) {
|
|
2866
|
+
const sectionMatch = line.match(/^\s*\[([^\]]+)\]\s*$/);
|
|
2867
|
+
if (sectionMatch) {
|
|
2868
|
+
if (inFeatures && !foundKey) {
|
|
2869
|
+
updatedLines.push(desiredLine);
|
|
2870
|
+
foundKey = true;
|
|
2871
|
+
changed = true;
|
|
2872
|
+
}
|
|
2873
|
+
inFeatures = sectionMatch[1] === "features";
|
|
2874
|
+
foundFeatures ||= inFeatures;
|
|
2875
|
+
updatedLines.push(line);
|
|
2876
|
+
continue;
|
|
2877
|
+
}
|
|
2878
|
+
if (inFeatures && /^\s*codex_hooks\s*=/.test(line)) {
|
|
2879
|
+
if (line.trim() !== desiredLine) {
|
|
2880
|
+
updatedLines.push(desiredLine);
|
|
2881
|
+
changed = true;
|
|
2882
|
+
} else {
|
|
2883
|
+
updatedLines.push(line);
|
|
2884
|
+
}
|
|
2885
|
+
foundKey = true;
|
|
2886
|
+
continue;
|
|
2887
|
+
}
|
|
2888
|
+
updatedLines.push(line);
|
|
2889
|
+
}
|
|
2890
|
+
if (inFeatures && !foundKey) {
|
|
2891
|
+
updatedLines.push(desiredLine);
|
|
2892
|
+
changed = true;
|
|
2893
|
+
}
|
|
2894
|
+
if (!foundFeatures) {
|
|
2895
|
+
const hasContent = updatedLines.some((line) => line.trim() !== "");
|
|
2896
|
+
if (hasContent) {
|
|
2897
|
+
updatedLines.push("");
|
|
2898
|
+
}
|
|
2899
|
+
updatedLines.push(sectionHeader, desiredLine);
|
|
2900
|
+
changed = true;
|
|
2901
|
+
}
|
|
2902
|
+
if (!changed) {
|
|
2903
|
+
return { updated: false, backupPath: null };
|
|
2904
|
+
}
|
|
2905
|
+
const backupPath = backupConfig(configPath);
|
|
2906
|
+
writeFileSync(configPath, `${updatedLines.join(`
|
|
2907
|
+
`).replace(/\n*$/, `
|
|
2908
|
+
`)}`, { mode: 384 });
|
|
2909
|
+
return { updated: true, backupPath };
|
|
2910
|
+
}
|
|
2911
|
+
function disableCodexFeatureFlag(configPath = join(homedir(), ".codex", "config.toml")) {
|
|
2912
|
+
if (!existsSync(configPath)) {
|
|
2913
|
+
return { updated: false, backupPath: null };
|
|
2914
|
+
}
|
|
2915
|
+
const original = readFileSync(configPath, "utf-8");
|
|
2916
|
+
const updated = original.split(/\r?\n/).filter((line) => !/^\s*codex_hooks\s*=/.test(line)).join(`
|
|
2917
|
+
`).replace(/\n*$/, `
|
|
2918
|
+
`);
|
|
2919
|
+
if (updated === original) {
|
|
2920
|
+
return { updated: false, backupPath: null };
|
|
2921
|
+
}
|
|
2922
|
+
const backupPath = backupConfig(configPath);
|
|
2923
|
+
writeFileSync(configPath, updated, { mode: 384 });
|
|
2924
|
+
return { updated: true, backupPath };
|
|
2925
|
+
}
|
|
2817
2926
|
async function createPairingSession(configuredAgents, e2eKeyId) {
|
|
2818
2927
|
try {
|
|
2819
2928
|
const machineHostname = hostname();
|
|
@@ -3069,10 +3178,11 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3069
3178
|
plugins.entries = {};
|
|
3070
3179
|
}
|
|
3071
3180
|
const entries = plugins.entries;
|
|
3072
|
-
entries.
|
|
3181
|
+
entries.openclaw = {
|
|
3073
3182
|
enabled: mode === "approval",
|
|
3074
3183
|
config: {
|
|
3075
3184
|
apiUrl: API_URL,
|
|
3185
|
+
apiVersion: "v001",
|
|
3076
3186
|
timeout: 300,
|
|
3077
3187
|
failBehavior: "ask",
|
|
3078
3188
|
privacyTier: "full"
|
|
@@ -3087,7 +3197,7 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3087
3197
|
}
|
|
3088
3198
|
hooks.internal.enabled = true;
|
|
3089
3199
|
writeJsonConfig(agent.configPath, config);
|
|
3090
|
-
installedHooks.push("
|
|
3200
|
+
installedHooks.push("openclaw");
|
|
3091
3201
|
return { success: true, backupPath, hooks: installedHooks };
|
|
3092
3202
|
}
|
|
3093
3203
|
if (agentId === "opencode") {
|
|
@@ -3147,6 +3257,34 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3147
3257
|
hookArray.push(hookEntry);
|
|
3148
3258
|
}
|
|
3149
3259
|
installedHooks.push(hook.name);
|
|
3260
|
+
} else if (agentId === "codex") {
|
|
3261
|
+
if (!hooksConfig[hook.name]) {
|
|
3262
|
+
hooksConfig[hook.name] = [];
|
|
3263
|
+
}
|
|
3264
|
+
const hookArray = hooksConfig[hook.name];
|
|
3265
|
+
const hasMatcher = hook.hasMatcher ?? true;
|
|
3266
|
+
const hookTimeout = hook.timeout;
|
|
3267
|
+
const existingIdx = hookArray.findIndex((h2) => h2.hooks?.some((hookScript) => {
|
|
3268
|
+
if (typeof hookScript === "string")
|
|
3269
|
+
return hookScript.includes("agentapprove");
|
|
3270
|
+
if (typeof hookScript === "object" && hookScript.command)
|
|
3271
|
+
return hookScript.command.includes("agentapprove");
|
|
3272
|
+
return false;
|
|
3273
|
+
}));
|
|
3274
|
+
const hookObject = {
|
|
3275
|
+
type: "command",
|
|
3276
|
+
command: hookCommand
|
|
3277
|
+
};
|
|
3278
|
+
if (hookTimeout) {
|
|
3279
|
+
hookObject.timeout = hookTimeout;
|
|
3280
|
+
}
|
|
3281
|
+
const hookEntry = hasMatcher ? { matcher: "*", hooks: [hookObject] } : { hooks: [hookObject] };
|
|
3282
|
+
if (existingIdx >= 0) {
|
|
3283
|
+
hookArray[existingIdx] = hookEntry;
|
|
3284
|
+
} else {
|
|
3285
|
+
hookArray.push(hookEntry);
|
|
3286
|
+
}
|
|
3287
|
+
installedHooks.push(hook.name);
|
|
3150
3288
|
} else if (agentId === "cursor") {
|
|
3151
3289
|
if (typeof config["version"] !== "number") {
|
|
3152
3290
|
config["version"] = 1;
|
|
@@ -3231,6 +3369,10 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3231
3369
|
type: "command",
|
|
3232
3370
|
command: hookCommand
|
|
3233
3371
|
};
|
|
3372
|
+
const hookEnv = getGithubHookEnv(agentId);
|
|
3373
|
+
if (hookEnv) {
|
|
3374
|
+
hookEntry.env = hookEnv;
|
|
3375
|
+
}
|
|
3234
3376
|
if (hook.isApprovalHook) {
|
|
3235
3377
|
hookEntry.timeout = 300;
|
|
3236
3378
|
}
|
|
@@ -3256,6 +3398,10 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3256
3398
|
type: "command",
|
|
3257
3399
|
bash: isWindows() ? toGitBashPath(hookPath) : hookPath
|
|
3258
3400
|
};
|
|
3401
|
+
const hookEnv = getGithubHookEnv(agentId);
|
|
3402
|
+
if (hookEnv) {
|
|
3403
|
+
hookEntry.env = hookEnv;
|
|
3404
|
+
}
|
|
3259
3405
|
if (hook.isApprovalHook) {
|
|
3260
3406
|
hookEntry.timeoutSec = 300;
|
|
3261
3407
|
}
|
|
@@ -3268,7 +3414,7 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3268
3414
|
const approvalHooks = agent.hooks.filter((h2) => h2.isApprovalHook);
|
|
3269
3415
|
for (const hook of approvalHooks) {
|
|
3270
3416
|
if (hooksConfig[hook.name]) {
|
|
3271
|
-
if (agentId === "claude-code" || agentId === "gemini-cli") {
|
|
3417
|
+
if (agentId === "claude-code" || agentId === "gemini-cli" || agentId === "codex") {
|
|
3272
3418
|
const hookArray = hooksConfig[hook.name];
|
|
3273
3419
|
if (Array.isArray(hookArray)) {
|
|
3274
3420
|
const cleaned = hookArray.filter((h2) => {
|
|
@@ -3332,14 +3478,17 @@ async function installHooksForAgent(agentId, hooksDir, mode = "approval") {
|
|
|
3332
3478
|
} else if (agentId === "openclaw") {
|
|
3333
3479
|
const pluginsObj = hooksConfig;
|
|
3334
3480
|
const entries = pluginsObj?.entries;
|
|
3335
|
-
if (entries?.
|
|
3336
|
-
entries.
|
|
3481
|
+
if (entries?.openclaw && typeof entries.openclaw === "object") {
|
|
3482
|
+
entries.openclaw.enabled = false;
|
|
3337
3483
|
}
|
|
3338
3484
|
}
|
|
3339
3485
|
}
|
|
3340
3486
|
}
|
|
3341
3487
|
}
|
|
3342
3488
|
writeJsonConfig(agent.configPath, config);
|
|
3489
|
+
if (agentId === "codex") {
|
|
3490
|
+
ensureCodexFeatureFlag();
|
|
3491
|
+
}
|
|
3343
3492
|
return { success: true, backupPath, hooks: installedHooks };
|
|
3344
3493
|
}
|
|
3345
3494
|
function getManualInstructions(agentId, hooksDir) {
|
|
@@ -3353,13 +3502,39 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3353
3502
|
const hookTimeout = hook.timeout;
|
|
3354
3503
|
const hookPath = join(hooksDir, hook.file);
|
|
3355
3504
|
const hookCmd = buildHookCommand(hookPath, agentId);
|
|
3356
|
-
const
|
|
3505
|
+
const hookObject = {
|
|
3506
|
+
type: "command",
|
|
3507
|
+
command: hookCmd
|
|
3508
|
+
};
|
|
3357
3509
|
if (hookTimeout) {
|
|
3358
|
-
|
|
3510
|
+
hookObject.timeout = hookTimeout;
|
|
3359
3511
|
}
|
|
3512
|
+
const entry = hasMatcher ? { matcher: "*", hooks: [hookObject] } : { hooks: [hookObject] };
|
|
3360
3513
|
hooksObj[hook.name] = [entry];
|
|
3361
3514
|
}
|
|
3362
3515
|
return JSON.stringify({ hooks: hooksObj }, null, 2);
|
|
3516
|
+
} else if (agentId === "codex") {
|
|
3517
|
+
const hooksObj = {};
|
|
3518
|
+
for (const hook of agent.hooks) {
|
|
3519
|
+
const hasMatcher = hook.hasMatcher ?? true;
|
|
3520
|
+
const hookTimeout = hook.timeout;
|
|
3521
|
+
const hookPath = join(hooksDir, hook.file);
|
|
3522
|
+
const hookCmd = buildHookCommand(hookPath, agentId);
|
|
3523
|
+
const hookObject = {
|
|
3524
|
+
type: "command",
|
|
3525
|
+
command: hookCmd
|
|
3526
|
+
};
|
|
3527
|
+
if (hookTimeout) {
|
|
3528
|
+
hookObject.timeout = hookTimeout;
|
|
3529
|
+
}
|
|
3530
|
+
const entry = hasMatcher ? { matcher: "*", hooks: [hookObject] } : { hooks: [hookObject] };
|
|
3531
|
+
hooksObj[hook.name] = [entry];
|
|
3532
|
+
}
|
|
3533
|
+
return `${JSON.stringify({ hooks: hooksObj }, null, 2)}
|
|
3534
|
+
|
|
3535
|
+
Also ensure ~/.codex/config.toml contains:
|
|
3536
|
+
[features]
|
|
3537
|
+
codex_hooks = true`;
|
|
3363
3538
|
} else if (agentId === "cursor") {
|
|
3364
3539
|
const hooksObj = {};
|
|
3365
3540
|
for (const hook of agent.hooks) {
|
|
@@ -3397,6 +3572,9 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3397
3572
|
type: "command",
|
|
3398
3573
|
command: hookCmd
|
|
3399
3574
|
};
|
|
3575
|
+
const hookEnv = getGithubHookEnv(agentId);
|
|
3576
|
+
if (hookEnv)
|
|
3577
|
+
entry.env = hookEnv;
|
|
3400
3578
|
if (isApproval)
|
|
3401
3579
|
entry.timeout = 300;
|
|
3402
3580
|
if (hookTimeout)
|
|
@@ -3413,6 +3591,9 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3413
3591
|
type: "command",
|
|
3414
3592
|
bash: isWindows() ? toGitBashPath(hookPath) : hookPath
|
|
3415
3593
|
};
|
|
3594
|
+
const hookEnv = getGithubHookEnv(agentId);
|
|
3595
|
+
if (hookEnv)
|
|
3596
|
+
entry.env = hookEnv;
|
|
3416
3597
|
if (isApproval)
|
|
3417
3598
|
entry.timeoutSec = 300;
|
|
3418
3599
|
hooksObj[hook.name] = [entry];
|
|
@@ -3422,10 +3603,11 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3422
3603
|
const configJson = JSON.stringify({
|
|
3423
3604
|
plugins: {
|
|
3424
3605
|
entries: {
|
|
3425
|
-
|
|
3606
|
+
openclaw: {
|
|
3426
3607
|
enabled: true,
|
|
3427
3608
|
config: {
|
|
3428
3609
|
apiUrl: API_URL,
|
|
3610
|
+
apiVersion: "v001",
|
|
3429
3611
|
timeout: 300,
|
|
3430
3612
|
failBehavior: "ask",
|
|
3431
3613
|
privacyTier: "full"
|
|
@@ -3440,12 +3622,14 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3440
3622
|
return [
|
|
3441
3623
|
"Install the Agent Approve plugin for OpenClaw:",
|
|
3442
3624
|
"",
|
|
3443
|
-
|
|
3625
|
+
` openclaw plugins install ${OPENCLAW_PLUGIN_SPEC}`,
|
|
3444
3626
|
"",
|
|
3445
3627
|
"Then add to your OpenClaw config (~/.openclaw/openclaw.json):",
|
|
3446
3628
|
"",
|
|
3447
3629
|
configJson,
|
|
3448
3630
|
"",
|
|
3631
|
+
'Hosted installs can also set config.token/config.apiUrl/etc. with OpenClaw env substitution such as "${AGENTAPPROVE_TOKEN}".',
|
|
3632
|
+
"",
|
|
3449
3633
|
"Restart the OpenClaw gateway to activate."
|
|
3450
3634
|
].join(`
|
|
3451
3635
|
`);
|
|
@@ -3461,7 +3645,7 @@ function getManualInstructions(agentId, hooksDir) {
|
|
|
3461
3645
|
"",
|
|
3462
3646
|
"Then add the dependency to your OpenCode package.json (same directory):",
|
|
3463
3647
|
"",
|
|
3464
|
-
|
|
3648
|
+
` { "dependencies": { "@agentapprove/opencode": "${OPENCODE_PLUGIN_VERSION}" } }`,
|
|
3465
3649
|
"",
|
|
3466
3650
|
"OpenCode will auto-install the plugin on next start."
|
|
3467
3651
|
].join(`
|
|
@@ -3507,6 +3691,11 @@ var HOOK_FILES = [
|
|
|
3507
3691
|
"gemini-session-start.sh",
|
|
3508
3692
|
"gemini-session-end.sh",
|
|
3509
3693
|
"gemini-stop.sh",
|
|
3694
|
+
"codex-session-start.sh",
|
|
3695
|
+
"codex-pre-tool.sh",
|
|
3696
|
+
"codex-post-tool.sh",
|
|
3697
|
+
"codex-user-prompt.sh",
|
|
3698
|
+
"codex-stop.sh",
|
|
3510
3699
|
"github-session-start.sh",
|
|
3511
3700
|
"github-session-end.sh",
|
|
3512
3701
|
"github-user-prompt.sh",
|
|
@@ -3550,7 +3739,7 @@ async function copyHookScripts(hooksDir, token) {
|
|
|
3550
3739
|
}
|
|
3551
3740
|
function installOpenClawPluginViaCli() {
|
|
3552
3741
|
try {
|
|
3553
|
-
execSync(
|
|
3742
|
+
execSync(`openclaw plugins install ${OPENCLAW_PLUGIN_SPEC}`, { stdio: "pipe" });
|
|
3554
3743
|
return { success: true };
|
|
3555
3744
|
} catch (err) {
|
|
3556
3745
|
const message = err instanceof Error ? err.message : "unknown error";
|
|
@@ -3789,7 +3978,7 @@ E2E Key: ${keyId}`;
|
|
|
3789
3978
|
Privacy: ${existingConfig.privacy || "unknown"}${e2eLine}`, "Existing configuration found");
|
|
3790
3979
|
} else {
|
|
3791
3980
|
me(`Approve AI agent actions from your iPhone or Apple Watch.
|
|
3792
|
-
Installs hooks for Claude Code, Cursor, Gemini CLI, VS Code, and Copilot CLI.`, "About");
|
|
3981
|
+
Installs hooks for Claude Code, Cursor, Gemini CLI, VS Code GitHub Copilot, and GitHub Copilot CLI.`, "About");
|
|
3793
3982
|
}
|
|
3794
3983
|
const installedAgents = detectInstalledAgents();
|
|
3795
3984
|
const agentOptions = Object.entries(AGENTS).map(([id, agent]) => ({
|
|
@@ -4088,6 +4277,9 @@ AGENTAPPROVE_E2E_MODE=${installMode}
|
|
|
4088
4277
|
for (const agentId of selectedAgents) {
|
|
4089
4278
|
const agent = AGENTS[agentId];
|
|
4090
4279
|
filesToModify.push(agent.configPath);
|
|
4280
|
+
if (agentId === "codex") {
|
|
4281
|
+
filesToModify.push(join(homedir(), ".codex", "config.toml"));
|
|
4282
|
+
}
|
|
4091
4283
|
if (agentId === "opencode") {
|
|
4092
4284
|
filesToModify.push(join(getOpenCodeConfigDir(), "package.json"));
|
|
4093
4285
|
}
|
|
@@ -4135,16 +4327,19 @@ Backups will be created with timestamp`, "Files to be modified");
|
|
|
4135
4327
|
}
|
|
4136
4328
|
}
|
|
4137
4329
|
}
|
|
4330
|
+
if (agentId === "codex") {
|
|
4331
|
+
v2.info(source_default.dim(" Updated ~/.codex/config.toml to enable codex_hooks"));
|
|
4332
|
+
}
|
|
4138
4333
|
if (agentId === "copilot-cli") {
|
|
4139
|
-
v2.info(source_default.dim(` To use with Copilot CLI, copy to your repo:
|
|
4334
|
+
v2.info(source_default.dim(` To use with GitHub Copilot CLI, copy to your repo:
|
|
4140
4335
|
` + ` cp ${agent.configPath} .github/hooks/agentapprove.json`));
|
|
4141
4336
|
}
|
|
4142
4337
|
} else {
|
|
4143
4338
|
spinner.stop(`${agent.name} configuration failed`);
|
|
4144
4339
|
if (agentId === "openclaw") {
|
|
4145
|
-
v2.warn(`Could not install
|
|
4340
|
+
v2.warn(`Could not install ${OPENCLAW_PLUGIN_SPEC} via OpenClaw CLI.
|
|
4146
4341
|
` + ` Error: ${result.error || "unknown"}
|
|
4147
|
-
` + ` Install manually: openclaw plugins install
|
|
4342
|
+
` + ` Install manually: openclaw plugins install ${OPENCLAW_PLUGIN_SPEC}
|
|
4148
4343
|
` + ` Then re-run: npx agentapprove`);
|
|
4149
4344
|
}
|
|
4150
4345
|
}
|
|
@@ -4213,8 +4408,8 @@ async function statusCommand() {
|
|
|
4213
4408
|
}
|
|
4214
4409
|
if (agentId === "openclaw") {
|
|
4215
4410
|
const entries = config.plugins?.entries;
|
|
4216
|
-
if (entries?.
|
|
4217
|
-
console.log(` ${source_default.green("✓")} ${agent.name}:
|
|
4411
|
+
if (entries?.openclaw) {
|
|
4412
|
+
console.log(` ${source_default.green("✓")} ${agent.name}: openclaw plugin`);
|
|
4218
4413
|
}
|
|
4219
4414
|
continue;
|
|
4220
4415
|
}
|
|
@@ -4282,9 +4477,7 @@ async function uninstallCommand() {
|
|
|
4282
4477
|
if (!existsSync(agent.configPath))
|
|
4283
4478
|
continue;
|
|
4284
4479
|
const config = readJsonConfig(agent.configPath);
|
|
4285
|
-
const hooksConfig = config[agent.hooksKey];
|
|
4286
|
-
if (!hooksConfig && agentId !== "opencode")
|
|
4287
|
-
continue;
|
|
4480
|
+
const hooksConfig = config[agent.hooksKey] ?? {};
|
|
4288
4481
|
let modified = false;
|
|
4289
4482
|
if (agentId === "opencode") {
|
|
4290
4483
|
const pluginArray = config.plugin;
|
|
@@ -4312,9 +4505,15 @@ async function uninstallCommand() {
|
|
|
4312
4505
|
}
|
|
4313
4506
|
} catch {}
|
|
4314
4507
|
} else if (agentId === "openclaw") {
|
|
4315
|
-
const
|
|
4316
|
-
|
|
4317
|
-
|
|
4508
|
+
const pluginsConfig = hooksConfig;
|
|
4509
|
+
const entries = pluginsConfig.entries;
|
|
4510
|
+
const installs = pluginsConfig.installs;
|
|
4511
|
+
if (entries && entries.openclaw) {
|
|
4512
|
+
delete entries.openclaw;
|
|
4513
|
+
modified = true;
|
|
4514
|
+
}
|
|
4515
|
+
if (installs && installs.openclaw) {
|
|
4516
|
+
delete installs.openclaw;
|
|
4318
4517
|
modified = true;
|
|
4319
4518
|
}
|
|
4320
4519
|
} else {
|
|
@@ -4349,6 +4548,12 @@ async function uninstallCommand() {
|
|
|
4349
4548
|
writeJsonConfig(agent.configPath, config);
|
|
4350
4549
|
console.log(` ${source_default.green("✓")} Removed hooks from ${agent.name}`);
|
|
4351
4550
|
}
|
|
4551
|
+
if (agentId === "codex" && modified && Object.keys(hooksConfig).length === 0) {
|
|
4552
|
+
const codexFlag = disableCodexFeatureFlag();
|
|
4553
|
+
if (codexFlag.updated) {
|
|
4554
|
+
console.log(` ${source_default.green("✓")} Disabled codex_hooks in ~/.codex/config.toml`);
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4352
4557
|
}
|
|
4353
4558
|
const envPath = join(getAgentApproveDir(), "env");
|
|
4354
4559
|
if (existsSync(envPath)) {
|
|
@@ -4407,7 +4612,7 @@ async function initRepoCommand() {
|
|
|
4407
4612
|
const cliHooksPath = join(getAgentApproveDir(), "copilot-cli-hooks.json");
|
|
4408
4613
|
if (!existsSync(cliHooksPath)) {
|
|
4409
4614
|
console.log(source_default.yellow(`
|
|
4410
|
-
Copilot CLI hooks not found. Run the installer first with Copilot CLI selected.`));
|
|
4615
|
+
GitHub Copilot CLI hooks not found. Run the installer first with GitHub Copilot CLI selected.`));
|
|
4411
4616
|
console.log(source_default.dim(` npx agentapprove install
|
|
4412
4617
|
`));
|
|
4413
4618
|
process.exit(1);
|
|
@@ -4430,7 +4635,7 @@ async function initRepoCommand() {
|
|
|
4430
4635
|
const targetDir = join(repoRoot, ".github", "hooks");
|
|
4431
4636
|
const targetFile = join(targetDir, "agentapprove.json");
|
|
4432
4637
|
console.log(source_default.cyan(`
|
|
4433
|
-
Installing Copilot CLI hooks to ${targetFile}
|
|
4638
|
+
Installing GitHub Copilot CLI hooks to ${targetFile}
|
|
4434
4639
|
`));
|
|
4435
4640
|
if (existsSync(targetFile)) {
|
|
4436
4641
|
console.log(source_default.yellow(" agentapprove.json already exists in .github/hooks/"));
|
|
@@ -4447,7 +4652,7 @@ async function initRepoCommand() {
|
|
|
4447
4652
|
mkdirSync(targetDir, { recursive: true });
|
|
4448
4653
|
}
|
|
4449
4654
|
copyFileSync(cliHooksPath, targetFile);
|
|
4450
|
-
console.log(source_default.green(` ✓ Copied Copilot CLI hooks to .github/hooks/agentapprove.json`));
|
|
4655
|
+
console.log(source_default.green(` ✓ Copied GitHub Copilot CLI hooks to .github/hooks/agentapprove.json`));
|
|
4451
4656
|
console.log(source_default.dim(` Commit this file so Copilot coding agent uses your hooks.
|
|
4452
4657
|
`));
|
|
4453
4658
|
}
|
|
@@ -4463,7 +4668,7 @@ ${source_default.yellow("Commands:")}
|
|
|
4463
4668
|
${source_default.green("install")} Run the installation wizard (default)
|
|
4464
4669
|
${source_default.green("pair")} Link a new iOS device with existing E2E keys
|
|
4465
4670
|
${source_default.green("refresh")} Generate a new token (when expired)
|
|
4466
|
-
${source_default.green("init-repo")} Add Copilot CLI hooks to current repo (.github/hooks/)
|
|
4671
|
+
${source_default.green("init-repo")} Add GitHub Copilot CLI hooks to current repo (.github/hooks/)
|
|
4467
4672
|
${source_default.green("status")} Show current configuration and installed hooks
|
|
4468
4673
|
${source_default.green("disable")} Temporarily disable hooks
|
|
4469
4674
|
${source_default.green("enable")} Re-enable hooks after disabling
|
|
@@ -4539,6 +4744,7 @@ Session: ${session.sessionCode}`, "Scan with Agent Approve iOS app");
|
|
|
4539
4744
|
failBehavior,
|
|
4540
4745
|
configSetAt
|
|
4541
4746
|
});
|
|
4747
|
+
await storeTokenInKeychain(token);
|
|
4542
4748
|
pushConfigToCloud({
|
|
4543
4749
|
apiUrl,
|
|
4544
4750
|
token,
|
|
@@ -4711,6 +4917,7 @@ ${noteLabel}`, "Scan with Agent Approve iOS app");
|
|
|
4711
4917
|
failBehavior: existingConfig?.failBehavior || "ask",
|
|
4712
4918
|
configSetAt
|
|
4713
4919
|
});
|
|
4920
|
+
await storeTokenInKeychain(result.token);
|
|
4714
4921
|
const hooksDir = join(getAgentApproveDir(), "hooks");
|
|
4715
4922
|
if (existsSync(hooksDir)) {
|
|
4716
4923
|
const updateSpinner = _2();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentapprove",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Approve AI agent actions from your iPhone or Apple Watch",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"dev": "bun --watch src/cli.ts",
|
|
11
11
|
"build": "bun build src/cli.ts --outdir dist --target node",
|
|
12
|
+
"pack:check": "bun run build && node ../../scripts/check-publish-packlist.mjs",
|
|
12
13
|
"start": "bun src/cli.ts",
|
|
13
14
|
"test": "bun test",
|
|
14
|
-
"prepublishOnly": "bun run
|
|
15
|
+
"prepublishOnly": "bun run pack:check"
|
|
15
16
|
},
|
|
16
17
|
"files": [
|
|
17
18
|
"dist/**/*"
|
|
@@ -43,13 +44,14 @@
|
|
|
43
44
|
"node": ">=18"
|
|
44
45
|
},
|
|
45
46
|
"dependencies": {
|
|
46
|
-
"@clack/prompts": "
|
|
47
|
-
"chalk": "
|
|
48
|
-
"qrcode-terminal": "
|
|
47
|
+
"@clack/prompts": "0.8.2",
|
|
48
|
+
"chalk": "5.6.2",
|
|
49
|
+
"qrcode-terminal": "0.12.0"
|
|
49
50
|
},
|
|
50
51
|
"devDependencies": {
|
|
51
|
-
"@
|
|
52
|
-
"@types/
|
|
53
|
-
"
|
|
52
|
+
"@socketsecurity/bun-security-scanner": "1.1.2",
|
|
53
|
+
"@types/node": "22.19.3",
|
|
54
|
+
"@types/qrcode-terminal": "0.12.2",
|
|
55
|
+
"typescript": "5.9.3"
|
|
54
56
|
}
|
|
55
57
|
}
|