bashbros 0.1.4 → 0.1.5
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 +45 -44
- package/dist/{chunk-LZYW7XQO.js → chunk-25TREQ6V.js} +131 -5
- package/dist/chunk-25TREQ6V.js.map +1 -0
- package/dist/{chunk-RTZ4QWG2.js → chunk-2CI2MRKI.js} +19 -3
- package/dist/chunk-2CI2MRKI.js.map +1 -0
- package/dist/chunk-5BBPRDWL.js +186 -0
- package/dist/chunk-5BBPRDWL.js.map +1 -0
- package/dist/{chunk-7OEWYFN3.js → chunk-6QVMBCSX.js} +7 -306
- package/dist/chunk-6QVMBCSX.js.map +1 -0
- package/dist/{chunk-RDNSS3ME.js → chunk-6SLR5WPD.js} +173 -5
- package/dist/chunk-6SLR5WPD.js.map +1 -0
- package/dist/{chunk-KYDMPE4N.js → chunk-AZVT6AZY.js} +20 -2
- package/dist/chunk-AZVT6AZY.js.map +1 -0
- package/dist/{chunk-CG6VEHJM.js → chunk-C4GZNBFF.js} +2 -2
- package/dist/{chunk-EMLEJVJZ.js → chunk-JOIAG54E.js} +1 -107
- package/dist/chunk-JOIAG54E.js.map +1 -0
- package/dist/{chunk-QWZGB4V3.js → chunk-PAZIDRXK.js} +42 -181
- package/dist/chunk-PAZIDRXK.js.map +1 -0
- package/dist/chunk-PLSHJHHR.js +293 -0
- package/dist/chunk-PLSHJHHR.js.map +1 -0
- package/dist/chunk-R5I5DEXE.js +228 -0
- package/dist/chunk-R5I5DEXE.js.map +1 -0
- package/dist/cli.js +157 -122
- package/dist/cli.js.map +1 -1
- package/dist/{config-I5NCK3RJ.js → config-IXBXMIUA.js} +2 -2
- package/dist/{db-ETWTBXAE.js → db-GJALN3R7.js} +2 -2
- package/dist/{display-UH7KEHOW.js → display-UDIACHTP.js} +3 -3
- package/dist/{engine-EGPAS2EX.js → engine-4WNPXVMS.js} +3 -2
- package/dist/index.d.ts +57 -57
- package/dist/index.js +17 -8
- package/dist/index.js.map +1 -1
- package/dist/{ollama-5JVKNFOV.js → ollama-TNMD5WHW.js} +2 -2
- package/dist/server-3CMTP4W4.js +13 -0
- package/dist/{setup-YS27MOPE.js → setup-U4R5QJMV.js} +2 -2
- package/dist/static/index.html +75 -28
- package/dist/{writer-3NAVABN6.js → writer-OMHUMJR5.js} +3 -3
- package/dist/writer-OMHUMJR5.js.map +1 -0
- package/package.json +2 -1
- package/dist/chunk-7OEWYFN3.js.map +0 -1
- package/dist/chunk-EMLEJVJZ.js.map +0 -1
- package/dist/chunk-KYDMPE4N.js.map +0 -1
- package/dist/chunk-LZYW7XQO.js.map +0 -1
- package/dist/chunk-QWZGB4V3.js.map +0 -1
- package/dist/chunk-RDNSS3ME.js.map +0 -1
- package/dist/chunk-RTZ4QWG2.js.map +0 -1
- /package/dist/{chunk-CG6VEHJM.js.map → chunk-C4GZNBFF.js.map} +0 -0
- /package/dist/{config-I5NCK3RJ.js.map → config-IXBXMIUA.js.map} +0 -0
- /package/dist/{db-ETWTBXAE.js.map → db-GJALN3R7.js.map} +0 -0
- /package/dist/{display-UH7KEHOW.js.map → display-UDIACHTP.js.map} +0 -0
- /package/dist/{engine-EGPAS2EX.js.map → engine-4WNPXVMS.js.map} +0 -0
- /package/dist/{ollama-5JVKNFOV.js.map → ollama-TNMD5WHW.js.map} +0 -0
- /package/dist/{writer-3NAVABN6.js.map → server-3CMTP4W4.js.map} +0 -0
- /package/dist/{setup-YS27MOPE.js.map → setup-U4R5QJMV.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
formatAllAgentsInfo,
|
|
4
4
|
formatPermissionsTable
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-C4GZNBFF.js";
|
|
6
6
|
import {
|
|
7
7
|
GeminiCLIHooks
|
|
8
8
|
} from "./chunk-T5ONCUHZ.js";
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "./chunk-ID2O2QTI.js";
|
|
19
19
|
import {
|
|
20
20
|
DashboardWriter
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-AZVT6AZY.js";
|
|
22
22
|
import {
|
|
23
23
|
ContextStore
|
|
24
24
|
} from "./chunk-J6ONXY6N.js";
|
|
@@ -32,24 +32,26 @@ import {
|
|
|
32
32
|
ReportGenerator,
|
|
33
33
|
UndoStack,
|
|
34
34
|
getBashgymIntegration
|
|
35
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-6QVMBCSX.js";
|
|
36
|
+
import "./chunk-5BBPRDWL.js";
|
|
36
37
|
import {
|
|
37
38
|
ClaudeCodeHooks,
|
|
38
39
|
gateCommand
|
|
39
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-25TREQ6V.js";
|
|
40
41
|
import {
|
|
41
42
|
MoltbotHooks
|
|
42
43
|
} from "./chunk-J37RHCFJ.js";
|
|
43
44
|
import "./chunk-SG752FZC.js";
|
|
44
|
-
import "./chunk-
|
|
45
|
+
import "./chunk-JOIAG54E.js";
|
|
45
46
|
import "./chunk-4XZ64P4V.js";
|
|
46
47
|
import "./chunk-LJE4EPIU.js";
|
|
47
48
|
import {
|
|
48
49
|
findConfig,
|
|
49
50
|
getDefaultConfig,
|
|
50
51
|
loadConfig
|
|
51
|
-
} from "./chunk-
|
|
52
|
-
import "./chunk-
|
|
52
|
+
} from "./chunk-2CI2MRKI.js";
|
|
53
|
+
import "./chunk-PAZIDRXK.js";
|
|
54
|
+
import "./chunk-R5I5DEXE.js";
|
|
53
55
|
import {
|
|
54
56
|
allowForSession
|
|
55
57
|
} from "./chunk-FRMAIRQ2.js";
|
|
@@ -58,7 +60,7 @@ import {
|
|
|
58
60
|
} from "./chunk-DEAF6PYM.js";
|
|
59
61
|
import {
|
|
60
62
|
DashboardDB
|
|
61
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-6SLR5WPD.js";
|
|
62
64
|
import "./chunk-7OCVIDC7.js";
|
|
63
65
|
|
|
64
66
|
// src/cli.ts
|
|
@@ -1040,7 +1042,7 @@ var EgressPatternMatcher = class {
|
|
|
1040
1042
|
// src/policy/ward/egress.ts
|
|
1041
1043
|
var DashboardDB2 = null;
|
|
1042
1044
|
try {
|
|
1043
|
-
const dbModule = await import("./db-
|
|
1045
|
+
const dbModule = await import("./db-GJALN3R7.js");
|
|
1044
1046
|
DashboardDB2 = dbModule.DashboardDB;
|
|
1045
1047
|
} catch {
|
|
1046
1048
|
}
|
|
@@ -2121,6 +2123,27 @@ var DashboardServer = class {
|
|
|
2121
2123
|
res.status(500).json({ error: "Failed to fetch tool use stats" });
|
|
2122
2124
|
}
|
|
2123
2125
|
});
|
|
2126
|
+
this.app.get("/api/prompts", (req, res) => {
|
|
2127
|
+
try {
|
|
2128
|
+
const filter = {};
|
|
2129
|
+
if (req.query.sessionId) filter.sessionId = req.query.sessionId;
|
|
2130
|
+
if (req.query.since) filter.since = new Date(req.query.since);
|
|
2131
|
+
if (req.query.limit) filter.limit = parseInt(req.query.limit, 10);
|
|
2132
|
+
if (req.query.offset) filter.offset = parseInt(req.query.offset, 10);
|
|
2133
|
+
const prompts = this.db.getUserPrompts(filter);
|
|
2134
|
+
res.json(prompts);
|
|
2135
|
+
} catch (error) {
|
|
2136
|
+
res.status(500).json({ error: "Failed to fetch prompts" });
|
|
2137
|
+
}
|
|
2138
|
+
});
|
|
2139
|
+
this.app.get("/api/prompts/stats", (_req, res) => {
|
|
2140
|
+
try {
|
|
2141
|
+
const stats = this.db.getUserPromptStats();
|
|
2142
|
+
res.json(stats);
|
|
2143
|
+
} catch (error) {
|
|
2144
|
+
res.status(500).json({ error: "Failed to fetch prompt stats" });
|
|
2145
|
+
}
|
|
2146
|
+
});
|
|
2124
2147
|
this.app.get("/api/bro/status", (_req, res) => {
|
|
2125
2148
|
try {
|
|
2126
2149
|
const status = this.db.getLatestBroStatus();
|
|
@@ -2652,7 +2675,8 @@ program.command("doctor").description("Check your BashBros configuration").actio
|
|
|
2652
2675
|
console.log(chalk5.cyan(logo));
|
|
2653
2676
|
await runDoctor();
|
|
2654
2677
|
});
|
|
2655
|
-
program.command("allow <command>").description("Allow a specific command").option("--once", "Allow only for current session").option("--persist", "Add to config permanently").action(async (command, options) => {
|
|
2678
|
+
program.command("allow <command>").description("Allow a specific command").option("--once", "Allow only for current session").option("--session", "Allow only for current session (alias for --once)").option("--persist", "Add to config permanently").action(async (command, options) => {
|
|
2679
|
+
if (options.session) options.once = true;
|
|
2656
2680
|
await handleAllow(command, options);
|
|
2657
2681
|
});
|
|
2658
2682
|
program.command("audit").description("View recent command history").option("-n, --lines <number>", "Number of lines to show", "50").option("--violations", "Show only blocked commands").action(async (options) => {
|
|
@@ -2670,7 +2694,7 @@ program.command("scan").description("Scan your system and project environment").
|
|
|
2670
2694
|
console.log(bro.getSystemContext());
|
|
2671
2695
|
console.log();
|
|
2672
2696
|
console.log(chalk5.bold("\n## Agent Configurations\n"));
|
|
2673
|
-
const { formatAgentSummary } = await import("./display-
|
|
2697
|
+
const { formatAgentSummary } = await import("./display-UDIACHTP.js");
|
|
2674
2698
|
const agents = await getAllAgentConfigs();
|
|
2675
2699
|
console.log(formatAgentSummary(agents));
|
|
2676
2700
|
console.log();
|
|
@@ -2745,70 +2769,6 @@ program.command("tasks").description("List background tasks").option("-a, --all"
|
|
|
2745
2769
|
console.log();
|
|
2746
2770
|
}
|
|
2747
2771
|
});
|
|
2748
|
-
program.command("explain <command>").description("Ask Bash Bro to explain a command").action(async (command) => {
|
|
2749
|
-
const bro = new BashBro();
|
|
2750
|
-
await bro.initialize();
|
|
2751
|
-
if (!bro.isOllamaAvailable()) {
|
|
2752
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2753
|
-
return;
|
|
2754
|
-
}
|
|
2755
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is thinking...\n"));
|
|
2756
|
-
const explanation = await bro.aiExplain(command);
|
|
2757
|
-
console.log(explanation);
|
|
2758
|
-
});
|
|
2759
|
-
program.command("fix <command>").description("Ask Bash Bro to fix a failed command").option("-e, --error <message>", "Error message from the failed command").action(async (command, options) => {
|
|
2760
|
-
const bro = new BashBro();
|
|
2761
|
-
await bro.initialize();
|
|
2762
|
-
if (!bro.isOllamaAvailable()) {
|
|
2763
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2764
|
-
return;
|
|
2765
|
-
}
|
|
2766
|
-
const error = options.error || "Command failed";
|
|
2767
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is analyzing...\n"));
|
|
2768
|
-
const fixed = await bro.aiFix(command, error);
|
|
2769
|
-
if (fixed) {
|
|
2770
|
-
console.log(chalk5.green("Suggested fix:"));
|
|
2771
|
-
console.log(chalk5.cyan(` ${fixed}`));
|
|
2772
|
-
} else {
|
|
2773
|
-
console.log(chalk5.yellow("Could not suggest a fix."));
|
|
2774
|
-
}
|
|
2775
|
-
});
|
|
2776
|
-
program.command("ai <prompt>").description("Ask Bash Bro anything").action(async (prompt) => {
|
|
2777
|
-
const bro = new BashBro();
|
|
2778
|
-
await bro.initialize();
|
|
2779
|
-
if (!bro.isOllamaAvailable()) {
|
|
2780
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2781
|
-
return;
|
|
2782
|
-
}
|
|
2783
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is thinking...\n"));
|
|
2784
|
-
const suggestion = await bro.aiSuggest(prompt);
|
|
2785
|
-
if (suggestion) {
|
|
2786
|
-
console.log(chalk5.cyan(suggestion));
|
|
2787
|
-
} else {
|
|
2788
|
-
console.log(chalk5.dim("No suggestion available."));
|
|
2789
|
-
}
|
|
2790
|
-
});
|
|
2791
|
-
program.command("script <description>").description("Generate a shell script from description").option("-o, --output <file>", "Save script to file").action(async (description, options) => {
|
|
2792
|
-
const bro = new BashBro();
|
|
2793
|
-
await bro.initialize();
|
|
2794
|
-
if (!bro.isOllamaAvailable()) {
|
|
2795
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2796
|
-
return;
|
|
2797
|
-
}
|
|
2798
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is generating script...\n"));
|
|
2799
|
-
const script = await bro.aiGenerateScript(description);
|
|
2800
|
-
if (script) {
|
|
2801
|
-
console.log(chalk5.cyan(script));
|
|
2802
|
-
if (options.output) {
|
|
2803
|
-
const { writeFileSync: writeFileSync5 } = await import("fs");
|
|
2804
|
-
writeFileSync5(options.output, script, { mode: 493 });
|
|
2805
|
-
console.log(chalk5.green(`
|
|
2806
|
-
\u2713 Saved to ${options.output}`));
|
|
2807
|
-
}
|
|
2808
|
-
} else {
|
|
2809
|
-
console.log(chalk5.yellow("Could not generate script."));
|
|
2810
|
-
}
|
|
2811
|
-
});
|
|
2812
2772
|
program.command("safety <command>").description("Analyze a command for security risks").action(async (command) => {
|
|
2813
2773
|
const bro = new BashBro();
|
|
2814
2774
|
await bro.initialize();
|
|
@@ -2838,42 +2798,9 @@ program.command("safety <command>").description("Analyze a command for security
|
|
|
2838
2798
|
}
|
|
2839
2799
|
}
|
|
2840
2800
|
});
|
|
2841
|
-
program.command("help-ai <topic>").alias("h").description("Get AI help for a command or topic").action(async (topic) => {
|
|
2842
|
-
const bro = new BashBro();
|
|
2843
|
-
await bro.initialize();
|
|
2844
|
-
if (!bro.isOllamaAvailable()) {
|
|
2845
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2846
|
-
return;
|
|
2847
|
-
}
|
|
2848
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is looking that up...\n"));
|
|
2849
|
-
const help = await bro.aiHelp(topic);
|
|
2850
|
-
console.log(help);
|
|
2851
|
-
});
|
|
2852
|
-
program.command("do <description>").description("Convert natural language to a command").option("-x, --execute", "Execute the command after showing it").action(async (description, options) => {
|
|
2853
|
-
const bro = new BashBro();
|
|
2854
|
-
await bro.initialize();
|
|
2855
|
-
if (!bro.isOllamaAvailable()) {
|
|
2856
|
-
console.log(chalk5.yellow("Ollama not available. Start Ollama to use AI features."));
|
|
2857
|
-
return;
|
|
2858
|
-
}
|
|
2859
|
-
console.log(chalk5.dim("\u{1F91D} Bash Bro is translating...\n"));
|
|
2860
|
-
const command = await bro.aiToCommand(description);
|
|
2861
|
-
if (command) {
|
|
2862
|
-
console.log(chalk5.bold("Command:"));
|
|
2863
|
-
console.log(chalk5.cyan(` $ ${command}`));
|
|
2864
|
-
if (options.execute) {
|
|
2865
|
-
console.log();
|
|
2866
|
-
console.log(chalk5.dim("Executing..."));
|
|
2867
|
-
const output = await bro.execute(command);
|
|
2868
|
-
console.log(output);
|
|
2869
|
-
}
|
|
2870
|
-
} else {
|
|
2871
|
-
console.log(chalk5.yellow("Could not translate to a command."));
|
|
2872
|
-
}
|
|
2873
|
-
});
|
|
2874
2801
|
program.command("models").description("List available Ollama models").action(async () => {
|
|
2875
2802
|
console.log(chalk5.cyan(logo));
|
|
2876
|
-
const { OllamaClient } = await import("./ollama-
|
|
2803
|
+
const { OllamaClient } = await import("./ollama-TNMD5WHW.js");
|
|
2877
2804
|
const ollama = new OllamaClient();
|
|
2878
2805
|
const available = await ollama.isAvailable();
|
|
2879
2806
|
if (!available) {
|
|
@@ -2918,6 +2845,7 @@ hookCmd.command("status").description("Check Claude Code hook status").action(()
|
|
|
2918
2845
|
console.log(` Claude Code: ${status.claudeInstalled ? chalk5.green("installed") : chalk5.yellow("not found")}`);
|
|
2919
2846
|
console.log(` BashBros hooks: ${status.hooksInstalled ? chalk5.green("active") : chalk5.dim("not installed")}`);
|
|
2920
2847
|
console.log(` All-tools recording: ${status.allToolsInstalled ? chalk5.green("active") : chalk5.dim("not installed")}`);
|
|
2848
|
+
console.log(` Prompt recording: ${status.promptHookInstalled ? chalk5.green("active") : chalk5.dim("not installed")}`);
|
|
2921
2849
|
if (status.hooks.length > 0) {
|
|
2922
2850
|
console.log(` Active hooks: ${status.hooks.join(", ")}`);
|
|
2923
2851
|
}
|
|
@@ -2941,6 +2869,24 @@ hookCmd.command("uninstall-all-tools").description("Remove all-tools recording h
|
|
|
2941
2869
|
process.exit(1);
|
|
2942
2870
|
}
|
|
2943
2871
|
});
|
|
2872
|
+
hookCmd.command("install-prompt").description("Install hook to record user prompt submissions").action(() => {
|
|
2873
|
+
const result = ClaudeCodeHooks.installPromptHook();
|
|
2874
|
+
if (result.success) {
|
|
2875
|
+
console.log(chalk5.green("\u2713"), result.message);
|
|
2876
|
+
} else {
|
|
2877
|
+
console.log(chalk5.red("\u2717"), result.message);
|
|
2878
|
+
process.exit(1);
|
|
2879
|
+
}
|
|
2880
|
+
});
|
|
2881
|
+
hookCmd.command("uninstall-prompt").description("Remove prompt recording hook").action(() => {
|
|
2882
|
+
const result = ClaudeCodeHooks.uninstallPromptHook();
|
|
2883
|
+
if (result.success) {
|
|
2884
|
+
console.log(chalk5.green("\u2713"), result.message);
|
|
2885
|
+
} else {
|
|
2886
|
+
console.log(chalk5.red("\u2717"), result.message);
|
|
2887
|
+
process.exit(1);
|
|
2888
|
+
}
|
|
2889
|
+
});
|
|
2944
2890
|
var moltbotCmd = program.command("moltbot").alias("clawdbot").description("Manage Moltbot/Clawdbot integration");
|
|
2945
2891
|
moltbotCmd.command("install").description("Install BashBros hooks into Moltbot").action(() => {
|
|
2946
2892
|
const result = MoltbotHooks.install();
|
|
@@ -3048,7 +2994,7 @@ program.command("agent-info [agent]").description("Show detailed info about inst
|
|
|
3048
2994
|
return;
|
|
3049
2995
|
}
|
|
3050
2996
|
const info = await getAgentConfigInfo(agent);
|
|
3051
|
-
const { formatAgentInfo: formatAgentInfo2 } = await import("./display-
|
|
2997
|
+
const { formatAgentInfo: formatAgentInfo2 } = await import("./display-UDIACHTP.js");
|
|
3052
2998
|
console.log();
|
|
3053
2999
|
console.log(formatAgentInfo2(info));
|
|
3054
3000
|
if (options.raw && info.configExists && info.configPath) {
|
|
@@ -3112,7 +3058,7 @@ program.command("gate [command]").description("Check if a command should be allo
|
|
|
3112
3058
|
const result = await gateCommand(command);
|
|
3113
3059
|
if (!result.allowed) {
|
|
3114
3060
|
try {
|
|
3115
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3061
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3116
3062
|
const { RiskScorer: RiskScorer2 } = await import("./risk-scorer-Y6KF2XCZ.js");
|
|
3117
3063
|
const scorer = new RiskScorer2();
|
|
3118
3064
|
const risk = scorer.score(command);
|
|
@@ -3133,7 +3079,7 @@ program.command("gate [command]").description("Check if a command should be allo
|
|
|
3133
3079
|
const { allowForSession: allowForSession2 } = await import("./session-Y4MICATZ.js");
|
|
3134
3080
|
const { readFileSync: readFileSync6, writeFileSync: writeFileSync5 } = await import("fs");
|
|
3135
3081
|
const { parse: parse4, stringify: stringify5 } = await import("yaml");
|
|
3136
|
-
const { findConfig: findConfig2 } = await import("./config-
|
|
3082
|
+
const { findConfig: findConfig2 } = await import("./config-IXBXMIUA.js");
|
|
3137
3083
|
console.error();
|
|
3138
3084
|
console.error(chalk5.red("\u{1F6E1}\uFE0F BashBros blocked a command"));
|
|
3139
3085
|
console.error();
|
|
@@ -3195,7 +3141,15 @@ program.command("gate [command]").description("Check if a command should be allo
|
|
|
3195
3141
|
process.exit(2);
|
|
3196
3142
|
}
|
|
3197
3143
|
} else {
|
|
3198
|
-
|
|
3144
|
+
const baseCmd = command.split(/\s+/)[0];
|
|
3145
|
+
process.stderr.write(`[BashBros] Blocked: '${command.slice(0, 80)}'
|
|
3146
|
+
`);
|
|
3147
|
+
process.stderr.write(`[BashBros] Reason: ${result.reason}
|
|
3148
|
+
`);
|
|
3149
|
+
process.stderr.write(`[BashBros] To allow for this session: bashbros allow "${baseCmd} *" --once
|
|
3150
|
+
`);
|
|
3151
|
+
process.stderr.write(`[BashBros] To allow permanently: add "${baseCmd} *" to .bashbros.yml commands.allow
|
|
3152
|
+
`);
|
|
3199
3153
|
process.exit(2);
|
|
3200
3154
|
}
|
|
3201
3155
|
}
|
|
@@ -3218,7 +3172,7 @@ program.command("record-tool").description("Record a Claude Code tool execution
|
|
|
3218
3172
|
try {
|
|
3219
3173
|
const event = JSON.parse(eventJson);
|
|
3220
3174
|
const events = Array.isArray(event) ? event : [event];
|
|
3221
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3175
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3222
3176
|
const writer = new DashboardWriter2();
|
|
3223
3177
|
const firstEvent = events[0] || {};
|
|
3224
3178
|
const hookSessionId = extractHookSessionId(firstEvent);
|
|
@@ -3280,6 +3234,83 @@ program.command("record-tool").description("Record a Claude Code tool execution
|
|
|
3280
3234
|
console.error(`[BashBros] Error recording tool: ${e instanceof Error ? e.message : e}`);
|
|
3281
3235
|
}
|
|
3282
3236
|
});
|
|
3237
|
+
program.command("record-prompt").description("Record a user prompt submission (used by UserPromptSubmit hook)").option("--marker <marker>", "Hook marker (ignored, used for identification)").action(async () => {
|
|
3238
|
+
try {
|
|
3239
|
+
const chunks = [];
|
|
3240
|
+
for await (const chunk of process.stdin) {
|
|
3241
|
+
chunks.push(chunk);
|
|
3242
|
+
}
|
|
3243
|
+
const stdinData = Buffer.concat(chunks).toString("utf-8").trim();
|
|
3244
|
+
if (!stdinData) return;
|
|
3245
|
+
const event = JSON.parse(stdinData);
|
|
3246
|
+
const promptText = typeof event.prompt === "string" ? event.prompt : "";
|
|
3247
|
+
if (!promptText) return;
|
|
3248
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3249
|
+
const writer = new DashboardWriter2();
|
|
3250
|
+
const hookSessionId = extractHookSessionId(event);
|
|
3251
|
+
writer.ensureHookSession(hookSessionId, event.cwd || process.cwd(), extractRepoName(event));
|
|
3252
|
+
writer.recordUserPrompt({
|
|
3253
|
+
promptText,
|
|
3254
|
+
cwd: event.cwd || process.cwd()
|
|
3255
|
+
});
|
|
3256
|
+
writer.close();
|
|
3257
|
+
} catch (e) {
|
|
3258
|
+
process.stderr.write(`[BashBros] Error recording prompt: ${e instanceof Error ? e.message : e}
|
|
3259
|
+
`);
|
|
3260
|
+
}
|
|
3261
|
+
});
|
|
3262
|
+
program.command("session-start").description("Initialize a session (used by SessionStart hook)").option("--marker <marker>", "Hook marker (ignored, used for identification)").action(async () => {
|
|
3263
|
+
try {
|
|
3264
|
+
const chunks = [];
|
|
3265
|
+
for await (const chunk of process.stdin) {
|
|
3266
|
+
chunks.push(chunk);
|
|
3267
|
+
}
|
|
3268
|
+
const stdinData = Buffer.concat(chunks).toString("utf-8").trim();
|
|
3269
|
+
const event = stdinData ? JSON.parse(stdinData) : {};
|
|
3270
|
+
const hookSessionId = extractHookSessionId(event);
|
|
3271
|
+
const workingDir = event.cwd || process.cwd();
|
|
3272
|
+
const repoName = extractRepoName(event);
|
|
3273
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3274
|
+
const writer = new DashboardWriter2();
|
|
3275
|
+
writer.ensureHookSession(hookSessionId, workingDir, repoName);
|
|
3276
|
+
const cfg = loadConfig();
|
|
3277
|
+
if (cfg.sessionStart.enabled && cfg.sessionStart.collectMetadata) {
|
|
3278
|
+
const metadata = {
|
|
3279
|
+
node_version: process.version,
|
|
3280
|
+
agent: "claude-code"
|
|
3281
|
+
};
|
|
3282
|
+
try {
|
|
3283
|
+
const { execSync } = await import("child_process");
|
|
3284
|
+
const opts = { encoding: "utf-8", timeout: 3e3, cwd: workingDir, stdio: ["pipe", "pipe", "pipe"] };
|
|
3285
|
+
metadata.git_branch = execSync("git rev-parse --abbrev-ref HEAD", opts).trim();
|
|
3286
|
+
metadata.git_dirty = execSync("git status --porcelain", opts).trim().length > 0;
|
|
3287
|
+
} catch {
|
|
3288
|
+
}
|
|
3289
|
+
metadata.config_profile = cfg.profile;
|
|
3290
|
+
if (cfg.sessionStart.ollamaStatus) {
|
|
3291
|
+
try {
|
|
3292
|
+
const resp = await fetch("http://127.0.0.1:11434/api/tags", { signal: AbortSignal.timeout(2e3) });
|
|
3293
|
+
metadata.ollama_available = resp.ok;
|
|
3294
|
+
} catch {
|
|
3295
|
+
metadata.ollama_available = false;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
writer.updateSessionMetadata(metadata);
|
|
3299
|
+
}
|
|
3300
|
+
if (cfg.sessionStart.enabled && cfg.sessionStart.preloadContext) {
|
|
3301
|
+
try {
|
|
3302
|
+
const { ContextStore: ContextStore2 } = await import("./store-WJ5Y7MOE.js");
|
|
3303
|
+
const store = new ContextStore2(workingDir);
|
|
3304
|
+
store.listMemoryFiles();
|
|
3305
|
+
} catch {
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
writer.close();
|
|
3309
|
+
} catch (e) {
|
|
3310
|
+
process.stderr.write(`[BashBros] Error in session-start: ${e instanceof Error ? e.message : e}
|
|
3311
|
+
`);
|
|
3312
|
+
}
|
|
3313
|
+
});
|
|
3283
3314
|
program.command("record [rawInput]").description("Record a command execution (used by hooks)").option("-o, --output <output>", "Command output").option("-e, --exit-code <code>", "Exit code", "0").action(async (rawInput, options) => {
|
|
3284
3315
|
let command = "";
|
|
3285
3316
|
let stdinData = "";
|
|
@@ -3317,7 +3348,7 @@ program.command("record [rawInput]").description("Record a command execution (us
|
|
|
3317
3348
|
console.error(chalk5.yellow(`\u26A0 Loop detected: ${loopAlert.message}`));
|
|
3318
3349
|
}
|
|
3319
3350
|
try {
|
|
3320
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3351
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3321
3352
|
const writer = new DashboardWriter2();
|
|
3322
3353
|
const hookSessionId = extractHookSessionId(hookEvent);
|
|
3323
3354
|
writer.ensureHookSession(hookSessionId, process.cwd(), extractRepoName(hookEvent));
|
|
@@ -3380,7 +3411,7 @@ program.command("session-end").description("Generate session report (used by hoo
|
|
|
3380
3411
|
} catch {
|
|
3381
3412
|
}
|
|
3382
3413
|
try {
|
|
3383
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3414
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3384
3415
|
const writer = new DashboardWriter2();
|
|
3385
3416
|
if (hookSessionId) {
|
|
3386
3417
|
writer.endHookSession(hookSessionId);
|
|
@@ -3445,7 +3476,7 @@ program.command("session-end").description("Generate session report (used by hoo
|
|
|
3445
3476
|
});
|
|
3446
3477
|
program.command("report").description("Generate a session report").option("-f, --format <format>", "Output format (text, markdown, json)", "text").option("--no-cost", "Hide cost estimate").option("--no-risk", "Hide risk distribution").action(async (options) => {
|
|
3447
3478
|
try {
|
|
3448
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3479
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3449
3480
|
const writer = new DashboardWriter2();
|
|
3450
3481
|
const db = writer.getDB();
|
|
3451
3482
|
const since = new Date(Date.now() - 24 * 60 * 60 * 1e3);
|
|
@@ -3589,6 +3620,10 @@ program.command("dashboard").description("Start the BashBros dashboard").option(
|
|
|
3589
3620
|
process.exit(0);
|
|
3590
3621
|
});
|
|
3591
3622
|
});
|
|
3623
|
+
program.command("mcp").description("Start MCP server for Claude Code integration (stdio)").action(async () => {
|
|
3624
|
+
const { startMCPServer } = await import("./server-3CMTP4W4.js");
|
|
3625
|
+
await startMCPServer();
|
|
3626
|
+
});
|
|
3592
3627
|
var wardCmd = program.command("ward").description("Network and connector security");
|
|
3593
3628
|
wardCmd.command("status").description("Show ward security status").action(async () => {
|
|
3594
3629
|
console.log(chalk5.cyan(logo));
|
|
@@ -3840,7 +3875,7 @@ program.command("gemini-gate").description("Gate command for Gemini CLI hooks (i
|
|
|
3840
3875
|
const result = await gateCommand(command);
|
|
3841
3876
|
if (!result.allowed) {
|
|
3842
3877
|
try {
|
|
3843
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3878
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3844
3879
|
const writer = new DashboardWriter2();
|
|
3845
3880
|
const hookSessionId = extractHookSessionId(event);
|
|
3846
3881
|
writer.ensureHookSession(hookSessionId, process.cwd(), extractRepoName(event));
|
|
@@ -3880,7 +3915,7 @@ program.command("gemini-record").description("Record command for Gemini CLI hook
|
|
|
3880
3915
|
`);
|
|
3881
3916
|
}
|
|
3882
3917
|
try {
|
|
3883
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3918
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3884
3919
|
const writer = new DashboardWriter2();
|
|
3885
3920
|
const hookSessionId = extractHookSessionId(event);
|
|
3886
3921
|
writer.ensureHookSession(hookSessionId, process.cwd(), extractRepoName(event));
|
|
@@ -3923,7 +3958,7 @@ program.command("copilot-gate").description("Gate command for Copilot CLI hooks
|
|
|
3923
3958
|
const result = await gateCommand(command);
|
|
3924
3959
|
if (!result.allowed) {
|
|
3925
3960
|
try {
|
|
3926
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
3961
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3927
3962
|
const writer = new DashboardWriter2();
|
|
3928
3963
|
const hookSessionId = extractHookSessionId(event);
|
|
3929
3964
|
writer.ensureHookSession(hookSessionId, process.cwd(), extractRepoName(event));
|
|
@@ -3963,7 +3998,7 @@ program.command("copilot-record").description("Record command for Copilot CLI ho
|
|
|
3963
3998
|
`);
|
|
3964
3999
|
}
|
|
3965
4000
|
try {
|
|
3966
|
-
const { DashboardWriter: DashboardWriter2 } = await import("./writer-
|
|
4001
|
+
const { DashboardWriter: DashboardWriter2 } = await import("./writer-OMHUMJR5.js");
|
|
3967
4002
|
const writer = new DashboardWriter2();
|
|
3968
4003
|
const hookSessionId = extractHookSessionId(event);
|
|
3969
4004
|
writer.ensureHookSession(hookSessionId, process.cwd(), extractRepoName(event));
|
|
@@ -3976,7 +4011,7 @@ program.command("copilot-record").description("Record command for Copilot CLI ho
|
|
|
3976
4011
|
});
|
|
3977
4012
|
program.command("setup").description("Install BashBros hooks for multiple agents at once").action(async () => {
|
|
3978
4013
|
console.log(chalk5.cyan(logo));
|
|
3979
|
-
const { runSetup } = await import("./setup-
|
|
4014
|
+
const { runSetup } = await import("./setup-U4R5QJMV.js");
|
|
3980
4015
|
await runSetup();
|
|
3981
4016
|
});
|
|
3982
4017
|
program.parse();
|