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.
Files changed (53) hide show
  1. package/README.md +45 -44
  2. package/dist/{chunk-LZYW7XQO.js → chunk-25TREQ6V.js} +131 -5
  3. package/dist/chunk-25TREQ6V.js.map +1 -0
  4. package/dist/{chunk-RTZ4QWG2.js → chunk-2CI2MRKI.js} +19 -3
  5. package/dist/chunk-2CI2MRKI.js.map +1 -0
  6. package/dist/chunk-5BBPRDWL.js +186 -0
  7. package/dist/chunk-5BBPRDWL.js.map +1 -0
  8. package/dist/{chunk-7OEWYFN3.js → chunk-6QVMBCSX.js} +7 -306
  9. package/dist/chunk-6QVMBCSX.js.map +1 -0
  10. package/dist/{chunk-RDNSS3ME.js → chunk-6SLR5WPD.js} +173 -5
  11. package/dist/chunk-6SLR5WPD.js.map +1 -0
  12. package/dist/{chunk-KYDMPE4N.js → chunk-AZVT6AZY.js} +20 -2
  13. package/dist/chunk-AZVT6AZY.js.map +1 -0
  14. package/dist/{chunk-CG6VEHJM.js → chunk-C4GZNBFF.js} +2 -2
  15. package/dist/{chunk-EMLEJVJZ.js → chunk-JOIAG54E.js} +1 -107
  16. package/dist/chunk-JOIAG54E.js.map +1 -0
  17. package/dist/{chunk-QWZGB4V3.js → chunk-PAZIDRXK.js} +42 -181
  18. package/dist/chunk-PAZIDRXK.js.map +1 -0
  19. package/dist/chunk-PLSHJHHR.js +293 -0
  20. package/dist/chunk-PLSHJHHR.js.map +1 -0
  21. package/dist/chunk-R5I5DEXE.js +228 -0
  22. package/dist/chunk-R5I5DEXE.js.map +1 -0
  23. package/dist/cli.js +157 -122
  24. package/dist/cli.js.map +1 -1
  25. package/dist/{config-I5NCK3RJ.js → config-IXBXMIUA.js} +2 -2
  26. package/dist/{db-ETWTBXAE.js → db-GJALN3R7.js} +2 -2
  27. package/dist/{display-UH7KEHOW.js → display-UDIACHTP.js} +3 -3
  28. package/dist/{engine-EGPAS2EX.js → engine-4WNPXVMS.js} +3 -2
  29. package/dist/index.d.ts +57 -57
  30. package/dist/index.js +17 -8
  31. package/dist/index.js.map +1 -1
  32. package/dist/{ollama-5JVKNFOV.js → ollama-TNMD5WHW.js} +2 -2
  33. package/dist/server-3CMTP4W4.js +13 -0
  34. package/dist/{setup-YS27MOPE.js → setup-U4R5QJMV.js} +2 -2
  35. package/dist/static/index.html +75 -28
  36. package/dist/{writer-3NAVABN6.js → writer-OMHUMJR5.js} +3 -3
  37. package/dist/writer-OMHUMJR5.js.map +1 -0
  38. package/package.json +2 -1
  39. package/dist/chunk-7OEWYFN3.js.map +0 -1
  40. package/dist/chunk-EMLEJVJZ.js.map +0 -1
  41. package/dist/chunk-KYDMPE4N.js.map +0 -1
  42. package/dist/chunk-LZYW7XQO.js.map +0 -1
  43. package/dist/chunk-QWZGB4V3.js.map +0 -1
  44. package/dist/chunk-RDNSS3ME.js.map +0 -1
  45. package/dist/chunk-RTZ4QWG2.js.map +0 -1
  46. /package/dist/{chunk-CG6VEHJM.js.map → chunk-C4GZNBFF.js.map} +0 -0
  47. /package/dist/{config-I5NCK3RJ.js.map → config-IXBXMIUA.js.map} +0 -0
  48. /package/dist/{db-ETWTBXAE.js.map → db-GJALN3R7.js.map} +0 -0
  49. /package/dist/{display-UH7KEHOW.js.map → display-UDIACHTP.js.map} +0 -0
  50. /package/dist/{engine-EGPAS2EX.js.map → engine-4WNPXVMS.js.map} +0 -0
  51. /package/dist/{ollama-5JVKNFOV.js.map → ollama-TNMD5WHW.js.map} +0 -0
  52. /package/dist/{writer-3NAVABN6.js.map → server-3CMTP4W4.js.map} +0 -0
  53. /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-CG6VEHJM.js";
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-KYDMPE4N.js";
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-7OEWYFN3.js";
35
+ } from "./chunk-6QVMBCSX.js";
36
+ import "./chunk-5BBPRDWL.js";
36
37
  import {
37
38
  ClaudeCodeHooks,
38
39
  gateCommand
39
- } from "./chunk-LZYW7XQO.js";
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-EMLEJVJZ.js";
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-RTZ4QWG2.js";
52
- import "./chunk-QWZGB4V3.js";
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-RDNSS3ME.js";
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-ETWTBXAE.js");
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-UH7KEHOW.js");
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-5JVKNFOV.js");
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-UH7KEHOW.js");
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-3NAVABN6.js");
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-I5NCK3RJ.js");
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
- console.error(`Blocked: ${result.reason}`);
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-3NAVABN6.js");
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-YS27MOPE.js");
4014
+ const { runSetup } = await import("./setup-U4R5QJMV.js");
3980
4015
  await runSetup();
3981
4016
  });
3982
4017
  program.parse();