bankai-cli 0.6.11 → 0.6.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 +3 -0
- package/dist/main.js +136 -54
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/main.js
CHANGED
|
@@ -6,15 +6,31 @@ import { createRequire } from "module";
|
|
|
6
6
|
|
|
7
7
|
// src/commands/run.ts
|
|
8
8
|
import { spawn } from "child_process";
|
|
9
|
+
import { readFileSync, writeFileSync, appendFileSync, mkdirSync } from "fs";
|
|
10
|
+
import { join } from "path";
|
|
11
|
+
import { homedir } from "os";
|
|
9
12
|
import chalk2 from "chalk";
|
|
10
13
|
|
|
11
14
|
// src/registry/builtin.ts
|
|
12
15
|
var builtinAgents = [
|
|
13
16
|
{
|
|
14
|
-
type: "
|
|
17
|
+
type: "settings",
|
|
15
18
|
cmd: "claude",
|
|
16
19
|
displayName: "Claude Code",
|
|
17
|
-
lines: ["claude --dangerously-skip-permissions"]
|
|
20
|
+
lines: ["claude --dangerously-skip-permissions"],
|
|
21
|
+
targets: [
|
|
22
|
+
{
|
|
23
|
+
kind: "json",
|
|
24
|
+
scope: "global",
|
|
25
|
+
filePath: "~/.claude/settings.json",
|
|
26
|
+
merge: {
|
|
27
|
+
sandbox: {
|
|
28
|
+
enabled: false
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
description: "Global (~/.claude/settings.json) \u2014 disable sandbox"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
18
34
|
},
|
|
19
35
|
{
|
|
20
36
|
type: "cli",
|
|
@@ -32,7 +48,7 @@ var builtinAgents = [
|
|
|
32
48
|
type: "cli",
|
|
33
49
|
cmd: "gemini",
|
|
34
50
|
displayName: "Gemini CLI",
|
|
35
|
-
lines: ["gemini --yolo"],
|
|
51
|
+
lines: ["gemini --yolo --sandbox=false"],
|
|
36
52
|
cmdAliases: ["gemini-cli"]
|
|
37
53
|
},
|
|
38
54
|
{
|
|
@@ -60,10 +76,18 @@ var builtinAgents = [
|
|
|
60
76
|
displayName: "Kimi Code",
|
|
61
77
|
lines: ["kimi --yolo"]
|
|
62
78
|
},
|
|
79
|
+
{
|
|
80
|
+
type: "cli",
|
|
81
|
+
cmd: "opencode",
|
|
82
|
+
displayName: "OpenCode",
|
|
83
|
+
lines: ["OPENCODE_YOLO=true opencode"],
|
|
84
|
+
cmdAliases: ["opencode-yolo"]
|
|
85
|
+
},
|
|
63
86
|
{
|
|
64
87
|
type: "settings",
|
|
65
88
|
cmd: "cursor-agent",
|
|
66
89
|
displayName: "Cursor Agent CLI",
|
|
90
|
+
lines: ["cursor-agent --yolo"],
|
|
67
91
|
targets: [
|
|
68
92
|
{
|
|
69
93
|
kind: "json",
|
|
@@ -78,7 +102,8 @@ var builtinAgents = [
|
|
|
78
102
|
"Delete(**)",
|
|
79
103
|
"Grep(**)",
|
|
80
104
|
"LS(**)"
|
|
81
|
-
]
|
|
105
|
+
],
|
|
106
|
+
deny: []
|
|
82
107
|
}
|
|
83
108
|
},
|
|
84
109
|
description: "Project (.cursor/cli.json)"
|
|
@@ -96,7 +121,8 @@ var builtinAgents = [
|
|
|
96
121
|
"Delete(**)",
|
|
97
122
|
"Grep(**)",
|
|
98
123
|
"LS(**)"
|
|
99
|
-
]
|
|
124
|
+
],
|
|
125
|
+
deny: []
|
|
100
126
|
}
|
|
101
127
|
},
|
|
102
128
|
description: "Global (~/.cursor/cli-config.json)"
|
|
@@ -176,7 +202,8 @@ var SettingsAgentDefSchema = z.object({
|
|
|
176
202
|
cmd: z.string().min(1),
|
|
177
203
|
displayName: z.string().optional(),
|
|
178
204
|
cmdAliases: z.array(z.string().min(1)).optional(),
|
|
179
|
-
targets: z.array(SettingsTargetSchema).min(1)
|
|
205
|
+
targets: z.array(SettingsTargetSchema).min(1),
|
|
206
|
+
lines: z.array(z.string().min(1)).optional()
|
|
180
207
|
});
|
|
181
208
|
var AgentDefSchema = z.preprocess(
|
|
182
209
|
(val) => typeof val === "object" && val !== null && !("type" in val) ? { ...val, type: "cli" } : val,
|
|
@@ -254,8 +281,6 @@ function resolveAll(customFilePath) {
|
|
|
254
281
|
|
|
255
282
|
// src/commands/apply.ts
|
|
256
283
|
import chalk from "chalk";
|
|
257
|
-
import select from "@inquirer/select";
|
|
258
|
-
import confirm from "@inquirer/confirm";
|
|
259
284
|
|
|
260
285
|
// src/settings.ts
|
|
261
286
|
import fs2 from "fs";
|
|
@@ -278,6 +303,18 @@ function deepMerge(base, overlay) {
|
|
|
278
303
|
baseVal,
|
|
279
304
|
overVal
|
|
280
305
|
);
|
|
306
|
+
} else if (Array.isArray(baseVal) && Array.isArray(overVal)) {
|
|
307
|
+
if (overVal.length === 0) {
|
|
308
|
+
result[key] = [];
|
|
309
|
+
} else {
|
|
310
|
+
const merged = [...baseVal];
|
|
311
|
+
for (const item of overVal) {
|
|
312
|
+
if (!merged.some((existing) => JSON.stringify(existing) === JSON.stringify(item))) {
|
|
313
|
+
merged.push(item);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
result[key] = merged;
|
|
317
|
+
}
|
|
281
318
|
} else {
|
|
282
319
|
result[key] = overVal;
|
|
283
320
|
}
|
|
@@ -292,8 +329,9 @@ function isDeepSubset(haystack, needle) {
|
|
|
292
329
|
return Object.keys(n).every((key) => isDeepSubset(h[key], n[key]));
|
|
293
330
|
}
|
|
294
331
|
if (Array.isArray(needle) && Array.isArray(haystack)) {
|
|
295
|
-
|
|
296
|
-
|
|
332
|
+
return needle.every(
|
|
333
|
+
(needleItem) => haystack.some((haystackItem) => isDeepSubset(haystackItem, needleItem))
|
|
334
|
+
);
|
|
297
335
|
}
|
|
298
336
|
return JSON.stringify(haystack) === JSON.stringify(needle);
|
|
299
337
|
}
|
|
@@ -429,6 +467,7 @@ function setNestedValue(obj, path3, value) {
|
|
|
429
467
|
|
|
430
468
|
// src/commands/apply.ts
|
|
431
469
|
async function applySettingsAgent(agent) {
|
|
470
|
+
let anyFailed = false;
|
|
432
471
|
const name = agent.displayName ?? agent.cmd;
|
|
433
472
|
console.log(chalk.bold.cyan(`# ${name}`));
|
|
434
473
|
console.log(chalk.dim("This agent uses settings files instead of CLI flags.\n"));
|
|
@@ -444,60 +483,38 @@ async function applySettingsAgent(agent) {
|
|
|
444
483
|
for (const s of statuses) {
|
|
445
484
|
console.log(chalk.green(` \u2713 ${s.target.description ?? s.target.kind}`));
|
|
446
485
|
}
|
|
447
|
-
return;
|
|
486
|
+
return false;
|
|
448
487
|
}
|
|
449
488
|
for (const s of statuses) {
|
|
450
|
-
const
|
|
489
|
+
const label = s.target.description ?? s.target.kind;
|
|
451
490
|
if (s.applied) {
|
|
452
|
-
console.log(chalk.green(` \u2713 ${
|
|
491
|
+
console.log(chalk.green(` \u2713 ${label} (already applied)`));
|
|
453
492
|
} else {
|
|
454
|
-
console.log(chalk.yellow(` \u25CB ${
|
|
493
|
+
console.log(chalk.yellow(` \u25CB ${label} (not applied)`));
|
|
455
494
|
}
|
|
456
495
|
}
|
|
457
496
|
console.log();
|
|
458
497
|
const unapplied = statuses.filter((s) => !s.applied);
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
}))
|
|
469
|
-
});
|
|
470
|
-
target = chosen;
|
|
471
|
-
}
|
|
472
|
-
const label = target.description ?? target.kind;
|
|
473
|
-
const ok = await confirm({
|
|
474
|
-
message: `Apply settings to ${label}?`,
|
|
475
|
-
default: true
|
|
476
|
-
});
|
|
477
|
-
if (!ok) {
|
|
478
|
-
console.log(chalk.dim("Cancelled."));
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
try {
|
|
482
|
-
applySettings(target);
|
|
483
|
-
console.log(chalk.green(`
|
|
484
|
-
\u2713 Applied settings to ${label}`));
|
|
485
|
-
if (target.kind === "sqlite") {
|
|
486
|
-
console.log(chalk.yellow("\nRestart the application for changes to take effect."));
|
|
498
|
+
for (const s of unapplied) {
|
|
499
|
+
const label = s.target.description ?? s.target.kind;
|
|
500
|
+
try {
|
|
501
|
+
applySettings(s.target);
|
|
502
|
+
console.log(chalk.green(` \u2713 Applied: ${label}`));
|
|
503
|
+
} catch (err) {
|
|
504
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
505
|
+
console.error(chalk.yellow(` \u26A0 Failed: ${label} \u2014 ${msg} (continuing anyway)`));
|
|
506
|
+
anyFailed = true;
|
|
487
507
|
}
|
|
488
|
-
} catch (err) {
|
|
489
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
490
|
-
console.error(chalk.red(`
|
|
491
|
-
Failed to apply settings: ${msg}`));
|
|
492
|
-
process.exitCode = 1;
|
|
493
508
|
}
|
|
509
|
+
return anyFailed;
|
|
494
510
|
}
|
|
495
511
|
|
|
496
512
|
// src/commands/run.ts
|
|
497
513
|
function execAgent(line, extraArgs = []) {
|
|
498
514
|
const [cmd, ...args2] = line.split(/\s+/);
|
|
515
|
+
const { GH_TOKEN, ...cleanEnv } = process.env;
|
|
499
516
|
return new Promise((resolve) => {
|
|
500
|
-
const child = spawn(cmd, [...args2, ...extraArgs], { stdio: "inherit", shell: true });
|
|
517
|
+
const child = spawn(cmd, [...args2, ...extraArgs], { stdio: "inherit", shell: true, env: cleanEnv });
|
|
501
518
|
child.on("close", (code) => resolve(code ?? 1));
|
|
502
519
|
child.on("error", (err) => {
|
|
503
520
|
console.error(chalk2.red(`Failed to start: ${err.message}`));
|
|
@@ -505,6 +522,35 @@ function execAgent(line, extraArgs = []) {
|
|
|
505
522
|
});
|
|
506
523
|
});
|
|
507
524
|
}
|
|
525
|
+
function ensureCursorAgentTrust() {
|
|
526
|
+
const cwd = process.cwd();
|
|
527
|
+
const slug = cwd.replace(/^\//, "").replace(/[/.]/g, "-");
|
|
528
|
+
const dir = join(homedir(), ".cursor", "projects", slug);
|
|
529
|
+
const file = join(dir, ".workspace-trusted");
|
|
530
|
+
try {
|
|
531
|
+
readFileSync(file, "utf-8");
|
|
532
|
+
return;
|
|
533
|
+
} catch {
|
|
534
|
+
mkdirSync(dir, { recursive: true });
|
|
535
|
+
}
|
|
536
|
+
const content = JSON.stringify({ trustedAt: (/* @__PURE__ */ new Date()).toISOString(), workspacePath: cwd });
|
|
537
|
+
writeFileSync(file, content);
|
|
538
|
+
}
|
|
539
|
+
function ensureCodexTrust() {
|
|
540
|
+
const configPath = join(homedir(), ".codex", "config.toml");
|
|
541
|
+
const cwd = process.cwd();
|
|
542
|
+
const key = `[projects."${cwd}"]`;
|
|
543
|
+
try {
|
|
544
|
+
const content = readFileSync(configPath, "utf-8");
|
|
545
|
+
if (content.match(new RegExp(`^\\[projects\\."${cwd.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"\\]`, "m"))) return;
|
|
546
|
+
} catch {
|
|
547
|
+
mkdirSync(join(homedir(), ".codex"), { recursive: true });
|
|
548
|
+
}
|
|
549
|
+
appendFileSync(configPath, `
|
|
550
|
+
${key}
|
|
551
|
+
trust_level = "trusted"
|
|
552
|
+
`);
|
|
553
|
+
}
|
|
508
554
|
async function runAgent(cmd, extraArgs = []) {
|
|
509
555
|
const agent = resolveAgent(cmd);
|
|
510
556
|
if (!agent) {
|
|
@@ -516,10 +562,13 @@ Run ${chalk2.yellow("bankai agents")} to see available agents, or ${chalk2.yello
|
|
|
516
562
|
return;
|
|
517
563
|
}
|
|
518
564
|
if (agent.type === "settings") {
|
|
519
|
-
|
|
520
|
-
const
|
|
521
|
-
|
|
565
|
+
if (agent.cmd === "cursor-agent") ensureCursorAgentTrust();
|
|
566
|
+
const settingsFailed = await applySettingsAgent(agent);
|
|
567
|
+
const line = agent.lines?.[0] ?? agent.cmd;
|
|
568
|
+
const code = await execAgent(line, extraArgs);
|
|
569
|
+
process.exitCode = code || (settingsFailed ? 1 : 0);
|
|
522
570
|
} else {
|
|
571
|
+
if (agent.cmd === "codex") ensureCodexTrust();
|
|
523
572
|
const line = agent.lines[0];
|
|
524
573
|
const code = await execAgent(line, extraArgs);
|
|
525
574
|
process.exitCode = code;
|
|
@@ -665,7 +714,7 @@ function removeAgentCommand(cmd) {
|
|
|
665
714
|
|
|
666
715
|
// src/commands/select.ts
|
|
667
716
|
import chalk8 from "chalk";
|
|
668
|
-
import
|
|
717
|
+
import select from "@inquirer/select";
|
|
669
718
|
|
|
670
719
|
// src/ui/fade.ts
|
|
671
720
|
import chalk7 from "chalk";
|
|
@@ -769,7 +818,7 @@ async function selectAgent() {
|
|
|
769
818
|
const agents = installed.length > 0 ? installed : all;
|
|
770
819
|
const label = installed.length > 0 ? "Detected agents on this system" : "No agents detected \u2014 showing all supported agents";
|
|
771
820
|
console.log(chalk8.dim(label));
|
|
772
|
-
const chosen = await
|
|
821
|
+
const chosen = await select({
|
|
773
822
|
message: "Select an agent:",
|
|
774
823
|
choices: agents.map((a) => ({
|
|
775
824
|
name: a.displayName ?? a.cmd,
|
|
@@ -779,6 +828,31 @@ async function selectAgent() {
|
|
|
779
828
|
await runAgent(chosen);
|
|
780
829
|
}
|
|
781
830
|
|
|
831
|
+
// src/argv.ts
|
|
832
|
+
var RESERVED_TOP_LEVEL_COMMANDS = /* @__PURE__ */ new Set(["agents", "add", "edit", "remove", "help"]);
|
|
833
|
+
var RESERVED_TOP_LEVEL_FLAGS = /* @__PURE__ */ new Set(["-h", "--help", "-V", "--version"]);
|
|
834
|
+
function stripLeadingSeparator(args2) {
|
|
835
|
+
return args2[0] === "--" ? args2.slice(1) : args2;
|
|
836
|
+
}
|
|
837
|
+
function extractDirectAgentInvocation(argv) {
|
|
838
|
+
if (argv.length === 0) return null;
|
|
839
|
+
const [first, ...rest] = argv;
|
|
840
|
+
if (RESERVED_TOP_LEVEL_FLAGS.has(first)) return null;
|
|
841
|
+
if (RESERVED_TOP_LEVEL_COMMANDS.has(first)) return null;
|
|
842
|
+
if (first === "-a" || first === "--agent") {
|
|
843
|
+
const [cmd, ...extraArgs] = rest;
|
|
844
|
+
if (!cmd || cmd.startsWith("-")) return null;
|
|
845
|
+
return { cmd, extraArgs: stripLeadingSeparator(extraArgs) };
|
|
846
|
+
}
|
|
847
|
+
if (first.startsWith("--agent=")) {
|
|
848
|
+
const cmd = first.slice("--agent=".length).trim();
|
|
849
|
+
if (!cmd || cmd.startsWith("-")) return null;
|
|
850
|
+
return { cmd, extraArgs: stripLeadingSeparator(rest) };
|
|
851
|
+
}
|
|
852
|
+
if (first.startsWith("-")) return null;
|
|
853
|
+
return { cmd: first, extraArgs: stripLeadingSeparator(rest) };
|
|
854
|
+
}
|
|
855
|
+
|
|
782
856
|
// src/main.ts
|
|
783
857
|
var require2 = createRequire(import.meta.url);
|
|
784
858
|
var { version } = require2("../package.json");
|
|
@@ -807,7 +881,15 @@ program.command("remove <cmd>").description("Remove a custom agent").action((cmd
|
|
|
807
881
|
var args = process.argv.slice(2);
|
|
808
882
|
var isTopLevelHelp = args.length <= 1 && (args.includes("--help") || args.includes("-h"));
|
|
809
883
|
if (isTopLevelHelp) await showFade();
|
|
810
|
-
|
|
884
|
+
var directInvocation = extractDirectAgentInvocation(args);
|
|
885
|
+
var run = async () => {
|
|
886
|
+
if (directInvocation) {
|
|
887
|
+
await runAgent(directInvocation.cmd, directInvocation.extraArgs);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
await program.parseAsync();
|
|
891
|
+
};
|
|
892
|
+
run().catch((err) => {
|
|
811
893
|
if (err?.name === "ExitPromptError") {
|
|
812
894
|
process.exit(130);
|
|
813
895
|
}
|