@nomad-e/bluma-cli 0.1.69 → 0.1.71

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 (2) hide show
  1. package/dist/main.js +285 -320
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -10267,7 +10267,7 @@ async function createProjectZip(projectDir, zipPath) {
10267
10267
  }
10268
10268
  return zipPath;
10269
10269
  }
10270
- async function uploadToSeverino(zipPath, severinoUrl, name, apiKey) {
10270
+ async function uploadToSeverino(zipPath, severinoUrl, name, apiKey, appId) {
10271
10271
  const deployUrl = `${severinoUrl.replace(/\/$/, "")}/api/v1/deploy`;
10272
10272
  const curlArgs = [
10273
10273
  "-X",
@@ -10279,6 +10279,9 @@ async function uploadToSeverino(zipPath, severinoUrl, name, apiKey) {
10279
10279
  if (name) {
10280
10280
  curlArgs.push("-F", `name=${name}`);
10281
10281
  }
10282
+ if (appId) {
10283
+ curlArgs.push("-F", `appId=${appId}`);
10284
+ }
10282
10285
  if (apiKey) {
10283
10286
  curlArgs.push("-H", `Authorization: Bearer ${apiKey}`);
10284
10287
  curlArgs.push("-H", `X-API-Key: ${apiKey}`);
@@ -10304,13 +10307,15 @@ async function uploadToSeverino(zipPath, severinoUrl, name, apiKey) {
10304
10307
  };
10305
10308
  }
10306
10309
  const data = response.data || {};
10310
+ const resolvedAppId = appId || data.appId;
10307
10311
  return {
10308
10312
  success: true,
10309
- appId: data.appId,
10313
+ appId: resolvedAppId,
10310
10314
  name: data.name,
10311
10315
  status: data.status || "building",
10312
- url: severinoUrl.replace(/\/$/, "") + `/app/${data.appId}`,
10313
- message: data.message || "Deploy iniciado"
10316
+ url: severinoUrl.replace(/\/$/, "") + `/app/${resolvedAppId}`,
10317
+ message: data.message || "Deploy iniciado",
10318
+ isRedeploy: !!appId
10314
10319
  };
10315
10320
  } catch (parseError) {
10316
10321
  throw new Error(`Failed to parse response: ${parseError.message}`);
@@ -10322,6 +10327,7 @@ async function deployApp(args) {
10322
10327
  const {
10323
10328
  projectDir,
10324
10329
  name,
10330
+ appId,
10325
10331
  severinoUrl = envSeverinoUrl,
10326
10332
  apiKey = envApiKey
10327
10333
  } = args;
@@ -10376,7 +10382,7 @@ async function deployApp(args) {
10376
10382
  }
10377
10383
  console.log(`[deploy-app] ZIP size: ${zipSizeMB.toFixed(2)}MB`);
10378
10384
  console.log(`[deploy-app] Uploading to ${severinoUrl}...`);
10379
- const deployResult = await uploadToSeverino(zipPath, severinoUrl, appName, apiKey);
10385
+ const deployResult = await uploadToSeverino(zipPath, severinoUrl, appName, apiKey, appId);
10380
10386
  try {
10381
10387
  await fs24.unlink(zipPath);
10382
10388
  await fs24.rmdir(tempDir);
@@ -12134,9 +12140,13 @@ function loadProjectMemory(cwd) {
12134
12140
  const gitRoot = findGitRoot(cwd) || cwd;
12135
12141
  const dirs = [];
12136
12142
  let currentDir = cwd;
12137
- while (currentDir !== path31.dirname(currentDir) && currentDir.startsWith(gitRoot)) {
12143
+ const MAX_TRAVERSAL_DEPTH = 20;
12144
+ let depth = 0;
12145
+ const normalizedGitRoot = path31.resolve(gitRoot);
12146
+ while (currentDir !== path31.dirname(currentDir) && path31.resolve(currentDir).startsWith(normalizedGitRoot) && depth < MAX_TRAVERSAL_DEPTH) {
12138
12147
  dirs.push(currentDir);
12139
12148
  currentDir = path31.dirname(currentDir);
12149
+ depth++;
12140
12150
  }
12141
12151
  if (!dirs.includes(gitRoot)) {
12142
12152
  dirs.push(gitRoot);
@@ -12221,17 +12231,29 @@ function getGitUserContext(cwd = process.cwd()) {
12221
12231
 
12222
12232
  // src/app/agent/core/prompt/workspace_snapshot.ts
12223
12233
  var LIMITS = {
12234
+ /** README.md: generous limit to capture full project overview */
12224
12235
  readme: 1e4,
12236
+ /** BLUMA.md: project memory instructions */
12225
12237
  blumaMd: 12e3,
12238
+ /** CONTRIBUTING.md: contribution guidelines */
12226
12239
  contributing: 4e3,
12240
+ /** CHANGELOG.md: recent version history */
12227
12241
  changelog: 4e3,
12242
+ /** pyproject.toml: Python project config */
12228
12243
  pyproject: 3500,
12244
+ /** tsconfig.json: TypeScript compiler options */
12229
12245
  tsconfig: 2e3,
12246
+ /** Dockerfile / docker-compose: container config */
12230
12247
  dockerfile: 2e3,
12248
+ /** CI/CD config: GitHub Actions, GitLab CI, etc. */
12231
12249
  ciConfig: 2e3,
12250
+ /** git status: max lines of changed files */
12232
12251
  gitStatusLines: 48,
12252
+ /** git log: recent commit history */
12233
12253
  gitLogLines: 14,
12254
+ /** git diff --stat: summary of changes */
12234
12255
  diffStatLines: 28,
12256
+ /** top-level directory entries */
12235
12257
  topDirEntries: 96
12236
12258
  };
12237
12259
  function safeReadFile(filePath, maxChars) {
@@ -12240,6 +12262,7 @@ function safeReadFile(filePath, maxChars) {
12240
12262
  const st = fs30.statSync(filePath);
12241
12263
  if (!st.isFile()) return null;
12242
12264
  const raw = fs30.readFileSync(filePath, "utf8");
12265
+ if (raw.includes("\0")) return null;
12243
12266
  if (raw.length <= maxChars) return raw;
12244
12267
  return `${raw.slice(0, maxChars)}
12245
12268
 
@@ -12504,7 +12527,10 @@ function buildWorkspaceSnapshot(cwd) {
12504
12527
  if (fs30.existsSync(envPath)) {
12505
12528
  try {
12506
12529
  const raw = fs30.readFileSync(envPath, "utf-8");
12507
- const keys = raw.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).map((l) => l.split("=")[0]?.trim()).filter(Boolean);
12530
+ const keys = raw.split("\n").map((l) => l.trim()).filter((l) => l && !l.startsWith("#")).map((l) => {
12531
+ const eqIndex = l.indexOf("=");
12532
+ return eqIndex >= 0 ? l.slice(0, eqIndex).trim() : l.trim();
12533
+ }).filter((key) => /^[A-Z_][A-Z0-9_]*$/.test(key)).filter(Boolean);
12508
12534
  if (keys.length > 0) {
12509
12535
  parts.push(`### Environment variables (from ${envFile})
12510
12536
  \`${keys.slice(0, 30).join("`, `")}\`
@@ -13798,6 +13824,8 @@ Use **both** API **reasoning** (when available) **and** the \`message\` tool. Re
13798
13824
  - **Stay audible:** Your **default** in multi-step work is to call \`message\` with \`message_type: "info"\` **early and often** \u2014 not optional polish. **Bias toward sending \`info\`** after discoveries, failures, and before long tool chains; **several \`info\` calls per turn** is normal and expected. Do **not** hide behind tools or reasoning only; \`info\` is how the user follows along.
13799
13825
  - **Ask when uncertain:** Use \`ask_user_question\` when you encounter ambiguity, need clarification, or face multiple valid approaches. Do not assume \u2014 ask the user to make decisions about their preferences, requirements, or implementation choices. This tool is your primary mechanism for resolving uncertainty.
13800
13826
  - **Team-first mindset:** For any non-trivial task, prefer spawning parallel workers over doing it yourself. One AI is good; a coordinated team of 3-7 workers is exponentially better. Break work into research \u2192 implementation \u2192 verification phases, each handled by specialist workers. You are the PO \u2014 orchestrate, synthesize, verify, deliver.
13827
+ - **Engineer mindset \u2014 question anomalies:** When something seems wrong (memory loss, unexpected behavior, aggressive defaults), **investigate deeply**. Do not accept "it's working as designed". Trace the code, find the root cause, and **have courage to revert** if a feature breaks core functionality. Protect the session, memory, and stability above all.
13828
+ - **Courage to reverse:** If you discover a path is wrong (e.g., a "feature" that destroys context, a default that's too aggressive), **stop immediately**, explain why it's broken, and revert/remove it. Better to undo a bad change than to let it cause harm. This is what separates a **thinking engineer** from a **blind executor**.
13801
13829
  - Large efforts: \`todo\`; parallel subtasks: \`spawn_agent\` with a clear scope + \`wait_agent\` / \`list_agents\`.
13802
13830
  - Respect the existing repo, \`<workspace_snapshot>\`, README/BluMa.md \u2014 no generic greenfield templates.
13803
13831
  - \`coding_memory\` for stable facts; chat history may be compressed.
@@ -18572,6 +18600,7 @@ function buildDiagnosticsSnapshot(feedbackScore) {
18572
18600
  // src/app/ui/components/SlashCommands.tsx
18573
18601
  init_runtime_config();
18574
18602
  import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
18603
+ var COMMAND_HEADER_COLOR = BLUMA_TERMINAL.accent;
18575
18604
  var RECOMMENDED_MODELS = [
18576
18605
  "auto",
18577
18606
  "auto"
@@ -18590,7 +18619,7 @@ var SessionLivePanel = ({ sessionId, mode }) => {
18590
18619
  }, [sessionId]);
18591
18620
  if (!session) {
18592
18621
  return /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Box17, { paddingLeft: 1, flexDirection: "column", children: [
18593
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: mode }),
18622
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: mode }),
18594
18623
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18595
18624
  "Unknown session: ",
18596
18625
  sessionId
@@ -18601,7 +18630,7 @@ var SessionLivePanel = ({ sessionId, mode }) => {
18601
18630
  const recent = logs.slice(-16);
18602
18631
  return /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Box17, { paddingLeft: 1, flexDirection: "column", children: [
18603
18632
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18604
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: mode }),
18633
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: mode }),
18605
18634
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18606
18635
  " \xB7 ",
18607
18636
  session.sessionId.slice(0, 8)
@@ -18635,7 +18664,7 @@ var SlashCommands = ({
18635
18664
  const outBox = (children) => /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Box17, { paddingLeft: 1, flexDirection: "column", children }) });
18636
18665
  const usageBox = (title, body) => outBox(
18637
18666
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18638
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: title }),
18667
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: title }),
18639
18668
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: body })
18640
18669
  ] })
18641
18670
  );
@@ -18668,7 +18697,7 @@ var SlashCommands = ({
18668
18697
  return outBox(
18669
18698
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18670
18699
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18671
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Sessions" }),
18700
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Sessions" }),
18672
18701
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18673
18702
  " \xB7 ",
18674
18703
  sessions.length,
@@ -18711,7 +18740,7 @@ var SlashCommands = ({
18711
18740
  const alive = session.status === "running" ? isProcessAlive(session.pid) : false;
18712
18741
  return outBox(
18713
18742
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18714
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Session status" }),
18743
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Session status" }),
18715
18744
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: session.sessionId }),
18716
18745
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18717
18746
  session.kind,
@@ -18736,7 +18765,7 @@ var SlashCommands = ({
18736
18765
  return outBox(
18737
18766
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18738
18767
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18739
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Logs" }),
18768
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Logs" }),
18740
18769
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18741
18770
  " \xB7 ",
18742
18771
  session.sessionId.slice(0, 8)
@@ -18782,7 +18811,7 @@ var SlashCommands = ({
18782
18811
  return outBox(
18783
18812
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18784
18813
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18785
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Tasks" }),
18814
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Tasks" }),
18786
18815
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18787
18816
  " \xB7 ",
18788
18817
  stats.total,
@@ -18837,7 +18866,7 @@ var SlashCommands = ({
18837
18866
  return outBox(
18838
18867
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18839
18868
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18840
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Permissions" }),
18869
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Permissions" }),
18841
18870
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18842
18871
  " \xB7 ",
18843
18872
  policy.isSandbox ? "sandbox" : "local"
@@ -18896,7 +18925,7 @@ var SlashCommands = ({
18896
18925
  return outBox(
18897
18926
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18898
18927
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18899
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Runtime" }),
18928
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Runtime" }),
18900
18929
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 model / effort" })
18901
18930
  ] }),
18902
18931
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -18958,7 +18987,7 @@ var SlashCommands = ({
18958
18987
  ];
18959
18988
  return outBox(
18960
18989
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18961
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Statusline" }),
18990
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Statusline" }),
18962
18991
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: parts.filter(Boolean).join(" \xB7 ") })
18963
18992
  ] })
18964
18993
  );
@@ -18969,7 +18998,7 @@ var SlashCommands = ({
18969
18998
  return outBox(
18970
18999
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18971
19000
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18972
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Bridge" }),
19001
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Bridge" }),
18973
19002
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18974
19003
  " \xB7 ",
18975
19004
  sessions.length,
@@ -18997,7 +19026,7 @@ var SlashCommands = ({
18997
19026
  return outBox(
18998
19027
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18999
19028
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19000
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Plugins" }),
19029
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Plugins" }),
19001
19030
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19002
19031
  " \xB7 ",
19003
19032
  plugins.length,
@@ -19030,7 +19059,7 @@ var SlashCommands = ({
19030
19059
  return outBox(
19031
19060
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19032
19061
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19033
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Diagnostics" }),
19062
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Diagnostics" }),
19034
19063
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 health snapshot" })
19035
19064
  ] }),
19036
19065
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -19114,7 +19143,7 @@ var SlashCommands = ({
19114
19143
  return outBox(
19115
19144
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19116
19145
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19117
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Plugin" }),
19146
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Plugin" }),
19118
19147
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19119
19148
  " \xB7 ",
19120
19149
  plugin.name
@@ -19153,7 +19182,7 @@ var SlashCommands = ({
19153
19182
  return outBox(
19154
19183
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19155
19184
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19156
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Hooks" }),
19185
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Hooks" }),
19157
19186
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19158
19187
  " \xB7 ",
19159
19188
  state.enabled ? "enabled" : "disabled"
@@ -19228,7 +19257,7 @@ var SlashCommands = ({
19228
19257
  const dirs = getPluginDirs();
19229
19258
  return outBox(
19230
19259
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19231
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Plugin paths" }),
19260
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Plugin paths" }),
19232
19261
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19233
19262
  "project: ",
19234
19263
  dirs.project
@@ -19389,7 +19418,7 @@ var SlashCommands = ({
19389
19418
  return outBox(
19390
19419
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19391
19420
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19392
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Model picker" }),
19421
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Model picker" }),
19393
19422
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 recommended" })
19394
19423
  ] }),
19395
19424
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", children: RECOMMENDED_MODELS.map((model) => /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -19403,7 +19432,7 @@ var SlashCommands = ({
19403
19432
  const next = setRuntimeConfig({ model: value });
19404
19433
  return outBox(
19405
19434
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19406
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Model" }),
19435
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Model" }),
19407
19436
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19408
19437
  "set to ",
19409
19438
  next.model
@@ -19422,7 +19451,7 @@ var SlashCommands = ({
19422
19451
  const next = setRuntimeConfig({ reasoningEffort: value });
19423
19452
  return outBox(
19424
19453
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19425
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Effort" }),
19454
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Effort" }),
19426
19455
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19427
19456
  "set to ",
19428
19457
  next.reasoningEffort
@@ -19441,7 +19470,7 @@ var SlashCommands = ({
19441
19470
  const next = setRuntimeConfig({ outputStyle: value });
19442
19471
  return outBox(
19443
19472
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19444
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Style" }),
19473
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Style" }),
19445
19474
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19446
19475
  "set to ",
19447
19476
  next.outputStyle
@@ -19460,7 +19489,7 @@ var SlashCommands = ({
19460
19489
  const next = setRuntimeConfig({ sandboxEnabled: value === "on" });
19461
19490
  return outBox(
19462
19491
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19463
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Sandbox" }),
19492
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Sandbox" }),
19464
19493
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: next.sandboxEnabled ? "on" : "off" })
19465
19494
  ] })
19466
19495
  );
@@ -19473,7 +19502,7 @@ var SlashCommands = ({
19473
19502
  const next = setRuntimeConfig({ workspaceRoot: value });
19474
19503
  return outBox(
19475
19504
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19476
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Worktree" }),
19505
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Worktree" }),
19477
19506
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: next.workspaceRoot })
19478
19507
  ] })
19479
19508
  );
@@ -19487,7 +19516,7 @@ var SlashCommands = ({
19487
19516
  return outBox(
19488
19517
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19489
19518
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19490
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Slash commands \xB7 organized view" }),
19519
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Slash commands \xB7 organized view" }),
19491
19520
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19492
19521
  " ",
19493
19522
  "\xB7 type any command to execute; use /help",
@@ -19501,7 +19530,7 @@ var SlashCommands = ({
19501
19530
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", marginTop: 1, children: groups.map((group) => /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, flexDirection: "column", children: [
19502
19531
  /* @__PURE__ */ jsx18(Text16, { color: BLUMA_TERMINAL.suggestion, bold: true, children: group.label }),
19503
19532
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", marginTop: 0, children: group.commands.map((command) => /* @__PURE__ */ jsxs16(Box17, { flexDirection: "row", flexWrap: "wrap", children: [
19504
- /* @__PURE__ */ jsx18(Text16, { color: BLUMA_TERMINAL.accent, bold: true, children: command.name.padEnd(16, " ") }),
19533
+ /* @__PURE__ */ jsx18(Text16, { color: COMMAND_HEADER_COLOR, bold: true, children: command.name.padEnd(16, " ") }),
19505
19534
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: command.description })
19506
19535
  ] }, command.name)) })
19507
19536
  ] }, group.category)) }),
@@ -19517,7 +19546,7 @@ var SlashCommands = ({
19517
19546
  if (entries.length === 0) {
19518
19547
  return outBox(
19519
19548
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19520
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Worker agents" }),
19549
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Worker agents" }),
19521
19550
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " No agent sessions in this CLI registry. Use the " }),
19522
19551
  /* @__PURE__ */ jsx18(Text16, { bold: true, children: "spawn_agent" }),
19523
19552
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " tool from chat, or " }),
@@ -19528,7 +19557,7 @@ var SlashCommands = ({
19528
19557
  }
19529
19558
  return outBox(
19530
19559
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19531
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Worker agents" }),
19560
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Worker agents" }),
19532
19561
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19533
19562
  " ",
19534
19563
  entries.length,
@@ -19672,7 +19701,7 @@ Usage: /features <key> on|off`
19672
19701
  return outBox(
19673
19702
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19674
19703
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19675
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Skills (load_skill)" }),
19704
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Skills (load_skill)" }),
19676
19705
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19677
19706
  " \xB7 ",
19678
19707
  list.length,
@@ -19732,7 +19761,7 @@ Usage: /features <key> on|off`
19732
19761
  return outBox(
19733
19762
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19734
19763
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19735
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "MCP Tools" }),
19764
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "MCP Tools" }),
19736
19765
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 " }),
19737
19766
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19738
19767
  tools.length,
@@ -19788,7 +19817,7 @@ Usage: /features <key> on|off`
19788
19817
  const colSource = 18;
19789
19818
  return outBox(
19790
19819
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19791
- /* @__PURE__ */ jsx18(Text16, { color: BLUMA_TERMINAL.accent, bold: true, children: "Native Tools" }),
19820
+ /* @__PURE__ */ jsx18(Text16, { color: COMMAND_HEADER_COLOR, bold: true, children: "Native Tools" }),
19792
19821
  /* @__PURE__ */ jsxs16(Text16, { color: "gray", children: [
19793
19822
  "Total Native: ",
19794
19823
  tools.length,
@@ -19832,7 +19861,7 @@ Usage: /features <key> on|off`
19832
19861
  const errored = agents.filter((a) => a.status === "error");
19833
19862
  return outBox(
19834
19863
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19835
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Debug Workers" }),
19864
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Debug Workers" }),
19836
19865
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19837
19866
  "Total: ",
19838
19867
  agents.length,
@@ -19866,7 +19895,7 @@ Usage: /features <key> on|off`
19866
19895
  if (cmd === "compact") {
19867
19896
  return outBox(
19868
19897
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19869
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Context Compaction" }),
19898
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Context Compaction" }),
19870
19899
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Auto-compact triggers at 180k tokens (threshold: 150k micro, 180k full)" }),
19871
19900
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Target after compact: 100k tokens" }),
19872
19901
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /compact to manually trigger context compaction." })
@@ -19876,7 +19905,7 @@ Usage: /features <key> on|off`
19876
19905
  if (cmd === "cost") {
19877
19906
  return outBox(
19878
19907
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19879
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Session Cost" }),
19908
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Session Cost" }),
19880
19909
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Cost tracking is available via /stats for detailed session statistics." })
19881
19910
  ] })
19882
19911
  );
@@ -19884,7 +19913,7 @@ Usage: /features <key> on|off`
19884
19913
  if (cmd === "export") {
19885
19914
  return outBox(
19886
19915
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19887
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Export Session" }),
19916
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Export Session" }),
19888
19917
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Session logs are stored in ~/.bluma/sessions/" }),
19889
19918
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /logs to view recent logs for a session." })
19890
19919
  ] })
@@ -19893,7 +19922,7 @@ Usage: /features <key> on|off`
19893
19922
  if (cmd === "memory") {
19894
19923
  return outBox(
19895
19924
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19896
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Session Memory" }),
19925
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Session Memory" }),
19897
19926
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Memories are auto-extracted from conversations and stored in ~/.bluma/session_memory.json" }),
19898
19927
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Relevant memories are injected into context automatically." })
19899
19928
  ] })
@@ -19903,7 +19932,7 @@ Usage: /features <key> on|off`
19903
19932
  const mem = process.memoryUsage();
19904
19933
  return outBox(
19905
19934
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19906
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Session Statistics" }),
19935
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Session Statistics" }),
19907
19936
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19908
19937
  "Heap: ",
19909
19938
  Math.round(mem.heapUsed / 1024 / 1024),
@@ -19967,7 +19996,7 @@ Usage: /features <key> on|off`
19967
19996
  }
19968
19997
  return outBox(
19969
19998
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19970
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Available Themes" }),
19999
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Available Themes" }),
19971
20000
  themes.map((t) => /* @__PURE__ */ jsxs16(Text16, { color: "white", children: [
19972
20001
  " ",
19973
20002
  t.name,
@@ -19980,7 +20009,7 @@ Usage: /features <key> on|off`
19980
20009
  if (cmd === "keybindings") {
19981
20010
  return outBox(
19982
20011
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19983
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Keybindings" }),
20012
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Keybindings" }),
19984
20013
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Custom keybindings are configured in ~/.bluma/settings.json" }),
19985
20014
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Ctrl+V / Cmd+V \u2014 Paste image or text" }),
19986
20015
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Ctrl+Shift+I \u2014 Paste image" }),
@@ -19992,7 +20021,7 @@ Usage: /features <key> on|off`
19992
20021
  if (cmd === "vim") {
19993
20022
  return outBox(
19994
20023
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19995
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Vim Mode" }),
20024
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Vim Mode" }),
19996
20025
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Vim mode provides normal/insert/command modes." }),
19997
20026
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Escape \u2014 Switch to normal mode" }),
19998
20027
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " i/a/o \u2014 Switch to insert mode" }),
@@ -20321,7 +20350,7 @@ Report the release version, tag, changelog summary, and verification results whe
20321
20350
  return outBox(
20322
20351
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20323
20352
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
20324
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Release" }),
20353
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Release" }),
20325
20354
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
20326
20355
  " \xB7 ",
20327
20356
  bumpType,
@@ -20337,32 +20366,15 @@ Report the release version, tag, changelog summary, and verification results whe
20337
20366
  if (cmd === "review") {
20338
20367
  const target = args.join(" ") || "";
20339
20368
  const isPR = target && /^\d+$/.test(target);
20340
- if (!target && !isPR) {
20341
- return outBox(
20342
- /* @__PURE__ */ jsxs16(Fragment6, { children: [
20343
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/review" }),
20344
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Review Coordinator \u2014 spawn a team of specialized QA reviewers in parallel." }),
20345
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Usage: /review [PR-number | file-path | "local changes"]' }),
20346
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " " }),
20347
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent will coordinate a review team:" }),
20348
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Security Reviewer \u2014 vulnerabilities, injection, auth flaws" }),
20349
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Logic & Correctness \u2014 bugs, edge cases, wrong assumptions" }),
20350
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Performance \u2014 N+1 queries, memory leaks, algorithmic issues" }),
20351
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Code Quality \u2014 naming, structure, conventions, readability" }),
20352
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Test Coverage \u2014 missing tests, weak assertions, untested paths" }),
20353
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Architecture \u2014 coupling, abstraction leaks, design violations" })
20354
- ] })
20355
- );
20356
- }
20357
20369
  (async () => {
20358
20370
  try {
20359
- const reviewTarget = isPR ? `PR #${target}` : target === "local" || target === "local changes" ? "current local changes (git diff HEAD)" : `the file/module: ${target}`;
20371
+ const reviewTarget = isPR ? `PR #${target}` : target === "local" || target === "local changes" ? "current local changes (git diff HEAD)" : target ? `the file/module: ${target}` : "current local changes (git diff HEAD)";
20360
20372
  await agentRef.current?.processTurn({
20361
20373
  content: `## REVIEW COORDINATOR MODE \u2014 Lead a Team of Senior QA Reviewers
20362
20374
 
20363
- You are now the **Review Coordinator** \u2014 a Principal Engineer leading a team of senior, picky QA reviewers. Your job is to orchestrate a **thorough, line-by-line code review** where NOTHING slips through. Each reviewer is "chato" (picky) about their specialty \u2014 the kind of engineer the company refuses to lose.
20375
+ You are now the **Review Coordinator** \u2014 a Principal Engineer leading a team of senior, picky QA reviewers. Your job is to orchestrate a **thorough, line-by-line code review** where NOTHING slips through.
20364
20376
 
20365
- **NEVER be afraid to coordinate.** Spawning specialized reviewers is how you catch bugs that a single reviewer would miss. A coordinated review catches 3-5x more issues than a solo review.
20377
+ **NEVER be afraid to coordinate.** Spawning specialized reviewers is how you catch bugs that a single reviewer would miss.
20366
20378
 
20367
20379
  **Review Target:** ${reviewTarget}
20368
20380
 
@@ -20376,17 +20388,20 @@ You are now the **Review Coordinator** \u2014 a Principal Engineer leading a tea
20376
20388
  ${target === "local" || target === "local changes" ? `- Run \`git diff HEAD\` for unstaged changes` : ""}
20377
20389
  ${target === "local" || target === "local changes" ? `- Run \`git diff --cached HEAD\` for staged changes` : ""}
20378
20390
  2. Understand the SCOPE: how many files changed, what areas are affected
20379
- 3. Identify which review specialties are most relevant (security? performance? logic?)
20380
20391
 
20381
- #### Step 2: Spawn Parallel Review Workers (your key move)
20382
- Launch **4-6 review workers in parallel** \u2014 each focused on a different area. Every reviewer reads the code LINE BY LINE in their specialty.
20392
+ #### Step 2: Spawn 3 Parallel Review Workers
20393
+ Launch exactly **3 workers in parallel** \u2014 one for each core area.
20394
+
20395
+ **IMPORTANT:** Each worker MUST read EVERY changed file line by line. Do NOT report until you have examined all files. List each file you reviewed in your report.
20383
20396
 
20384
- **Worker 1 \u2014 Security Reviewer (ALWAYS spawn):**
20397
+ **Worker 1 \u2014 Security Reviewer:**
20385
20398
  \`\`\`
20386
20399
  spawn_agent({
20387
20400
  task: "SECURITY REVIEW: Thoroughly review ${reviewTarget} for security vulnerabilities.
20388
20401
 
20389
- You are a Senior Security Engineer. Read every changed line. Look for:
20402
+ You are a Senior Security Engineer. Read EVERY changed file line by line. Do NOT report until you have examined all files.
20403
+
20404
+ Look for:
20390
20405
  - Injection vulnerabilities (SQL, XSS, command injection, template injection)
20391
20406
  - Authentication/authorization flaws (missing auth checks, privilege escalation)
20392
20407
  - Sensitive data exposure (secrets in logs, PII leaks, hardcoded credentials)
@@ -20403,20 +20418,24 @@ For EACH issue found:
20403
20418
  - How to exploit it (brief)
20404
20419
  - Recommended fix
20405
20420
 
20406
- Be PICKY. If something looks suspicious, flag it. Better a false positive than a missed vulnerability.
20421
+ Be PICKY. If something looks suspicious, flag it.
20422
+
20423
+ Do NOT modify files. Report only.
20407
20424
 
20408
- Do NOT modify files. Report only.",
20425
+ At the end of your report, list ALL files you reviewed.",
20409
20426
  title: "Security Review",
20410
20427
  agent_type: "reviewer"
20411
20428
  })
20412
20429
  \`\`\`
20413
20430
 
20414
- **Worker 2 \u2014 Logic & Correctness (ALWAYS spawn):**
20431
+ **Worker 2 \u2014 Logic & Correctness:**
20415
20432
  \`\`\`
20416
20433
  spawn_agent({
20417
20434
  task: "LOGIC REVIEW: Thoroughly review ${reviewTarget} for bugs and logic errors.
20418
20435
 
20419
- You are a Senior QA Engineer who finds bugs for a living. Read every changed line. Look for:
20436
+ You are a Senior QA Engineer who finds bugs for a living. Read EVERY changed file line by line. Do NOT report until you have examined all files.
20437
+
20438
+ Look for:
20420
20439
  - Logic errors (wrong conditions, off-by-one, inverted boolean, wrong operator)
20421
20440
  - Null/undefined handling (missing null checks, unsafe property access)
20422
20441
  - State management issues (stale state, missing initialization, race conditions)
@@ -20433,50 +20452,24 @@ For EACH issue found:
20433
20452
  - How to trigger the bug
20434
20453
  - Recommended fix
20435
20454
 
20436
- Be RELENTLESS. Question every assumption. If a branch looks untested, flag it.
20455
+ Be RELENTLESS. Question every assumption.
20437
20456
 
20438
- Do NOT modify files. Report only.",
20439
- title: "Logic & Correctness Review",
20440
- agent_type: "reviewer"
20441
- })
20442
- \`\`\`
20457
+ Do NOT modify files. Report only.
20443
20458
 
20444
- **Worker 3 \u2014 Performance (spawn if changes touch data flow, loops, queries, APIs):**
20445
- \`\`\`
20446
- spawn_agent({
20447
- task: "PERFORMANCE REVIEW: Thoroughly review ${reviewTarget} for performance issues.
20448
-
20449
- You are a Performance Engineer. Read every changed line. Look for:
20450
- - N+1 query patterns (looping database calls)
20451
- - Unnecessary computations (repeated calculations, missing memoization)
20452
- - Memory leaks (unclosed resources, growing arrays, event listener accumulation)
20453
- - Algorithmic complexity (O(n\xB2) where O(n) is possible, nested loops on large data)
20454
- - Blocking operations (sync I/O in async context, heavy computation on main thread)
20455
- - Missing caching opportunities (repeated expensive operations)
20456
- - Bundle size issues (large imports, tree-shaking failures)
20457
- - Network inefficiencies (unnecessary requests, missing batching, no pagination)
20458
-
20459
- For EACH issue found:
20460
- - Impact: HIGH / MEDIUM / LOW
20461
- - File:line number
20462
- - Current behavior vs optimized behavior
20463
- - Estimated improvement
20464
- - Recommended fix with code example
20465
-
20466
- Be THOROUGH. Even small inefficiencies add up.
20467
-
20468
- Do NOT modify files. Report only.",
20469
- title: "Performance Review",
20459
+ At the end of your report, list ALL files you reviewed.",
20460
+ title: "Logic & Correctness Review",
20470
20461
  agent_type: "reviewer"
20471
20462
  })
20472
20463
  \`\`\`
20473
20464
 
20474
- **Worker 4 \u2014 Code Quality & Conventions (ALWAYS spawn):**
20465
+ **Worker 3 \u2014 Code Quality:**
20475
20466
  \`\`\`
20476
20467
  spawn_agent({
20477
20468
  task: "CODE QUALITY REVIEW: Thoroughly review ${reviewTarget} for code quality and convention violations.
20478
20469
 
20479
- You are a Staff Engineer obsessed with clean code. Read every changed line. Look for:
20470
+ You are a Staff Engineer obsessed with clean code. Read EVERY changed file line by line. Do NOT report until you have examined all files.
20471
+
20472
+ Look for:
20480
20473
  - Naming issues (misleading names, abbreviations, inconsistent casing)
20481
20474
  - Function length and complexity (too long, too many responsibilities, deep nesting)
20482
20475
  - DRY violations (duplicated logic that should be extracted)
@@ -20494,72 +20487,22 @@ For EACH issue found:
20494
20487
 
20495
20488
  Be PICKY about readability. Code is read 10x more than written.
20496
20489
 
20497
- Do NOT modify files. Report only.",
20498
- title: "Code Quality Review",
20499
- agent_type: "reviewer"
20500
- })
20501
- \`\`\`
20490
+ Do NOT modify files. Report only.
20502
20491
 
20503
- **Worker 5 \u2014 Test Coverage (spawn if tests exist or should exist):**
20504
- \`\`\`
20505
- spawn_agent({
20506
- task: "TEST COVERAGE REVIEW: Thoroughly review ${reviewTarget} for test gaps.
20507
-
20508
- You are a QA Lead. Look at:
20509
- - Which files changed and whether they have corresponding tests
20510
- - If tests exist: are they testing the RIGHT things (happy path only? missing edge cases?)
20511
- - Assertion quality (weak assertions, missing error case tests)
20512
- - Untested code paths (branches, error handlers, edge cases)
20513
- - Mock quality (over-mocking, mocking the wrong things, unrealistic mocks)
20514
- - Integration gaps (unit tests but no integration tests, or vice versa)
20515
- - Test naming and organization (unclear test names, giant test files)
20516
-
20517
- For EACH gap found:
20518
- - File:line of untested code
20519
- - What scenario is not tested
20520
- - Why it matters
20521
- - Suggested test case (with code)
20522
-
20523
- Be DEMANDING. Untested code is broken code waiting for the right input.
20524
-
20525
- Do NOT modify files. Report only.",
20526
- title: "Test Coverage Review",
20492
+ At the end of your report, list ALL files you reviewed.",
20493
+ title: "Code Quality Review",
20527
20494
  agent_type: "reviewer"
20528
20495
  })
20529
20496
  \`\`\`
20530
20497
 
20531
- **Worker 6 \u2014 Architecture & Design (spawn for larger changes or new features):**
20532
- \`\`\`
20533
- spawn_agent({
20534
- task: "ARCHITECTURE REVIEW: Thoroughly review ${reviewTarget} for design and architectural issues.
20535
-
20536
- You are a Principal Engineer. Look at the BIG picture:
20537
- - Does this change fit the existing architecture or fight against it?
20538
- - Are there new dependencies that shouldn't exist (circular deps, wrong layer imports)?
20539
- - Is the abstraction level appropriate (too low-level, too abstract, leaky abstractions)?
20540
- - Does this introduce coupling between previously independent modules?
20541
- - Are there better design patterns that should be used?
20542
- - Does this change break any existing contracts or APIs?
20543
- - Is the change appropriately scoped (too big, mixing concerns)?
20544
- - Does this create technical debt (quick hacks that will hurt later)?
20545
-
20546
- For EACH issue found:
20547
- - Severity: ARCHITECTURAL / DESIGN / MINOR
20548
- - File:line number
20549
- - What the design problem is
20550
- - Why it matters long-term
20551
- - Suggested alternative approach
20552
-
20553
- Be VISIONARY. Think about what this code will look like in 6 months.
20498
+ #### Step 3: Wait for Workers + Synthesize
20499
+ Wait for ALL 3 workers to complete. Use wait_agent with a large timeout (600000ms).
20554
20500
 
20555
- Do NOT modify files. Report only.",
20556
- title: "Architecture Review",
20557
- agent_type: "reviewer"
20558
- })
20559
- \`\`\`
20560
-
20561
- #### Step 3: Synthesize (you do this \u2014 critical)
20562
- Wait for ALL review workers to complete. Read every finding carefully.
20501
+ **If workers fail or sessions disappear:**
20502
+ - This can happen with fast-completing workers
20503
+ - Simply perform the review yourself by reading the changed files
20504
+ - Report: "Workers completed/unavailable \u2014 performing review directly"
20505
+ - Do NOT waste time retrying \u2014 just do the review
20563
20506
 
20564
20507
  **NEVER write** "the review looks good" \u2014 that's lazy.
20565
20508
  **ALWAYS synthesize**: Group findings by severity, cross-reference between reviewers, identify patterns.
@@ -20570,7 +20513,7 @@ Compile a comprehensive review report:
20570
20513
  **REVIEW REPORT for ${reviewTarget}**
20571
20514
 
20572
20515
  \u{1F534} CRITICAL / BLOCKER (must fix before merge):
20573
- - [List all critical findings from any reviewer]
20516
+ - [List all critical findings]
20574
20517
 
20575
20518
  \u{1F7E1} HIGH / MAJOR (should fix):
20576
20519
  - [List all high findings]
@@ -20579,27 +20522,25 @@ Compile a comprehensive review report:
20579
20522
  - [List all medium findings]
20580
20523
 
20581
20524
  \u2139\uFE0F OBSERVATIONS (no action needed):
20582
- - [List observations, style notes, future considerations]
20525
+ - [List observations, style notes]
20583
20526
 
20584
20527
  \u2705 POSITIVE FINDINGS (what's good):
20585
- - [List well-written code, good patterns, improvements]
20528
+ - [List well-written code, good patterns]
20586
20529
 
20587
20530
  **Review Summary:**
20588
20531
  - Total issues found: X critical, Y high, Z medium
20589
- - Reviewers used: [list workers]
20532
+ - Reviewers used: [list workers or "direct review"]
20590
20533
  - Recommendation: APPROVE / APPROVE WITH COMMENTS / REQUEST CHANGES
20591
20534
  - Confidence level: HIGH / MEDIUM / LOW
20592
20535
 
20593
20536
  ### COORDINATOR RULES
20594
- - **You are the brain, reviewers are the eyes** \u2014 synthesize, don't just copy-paste findings
20595
- - **Spawn workers in parallel** \u2014 all reviewers work simultaneously
20596
- - **Be picky** \u2014 if a reviewer found nothing, they weren't looking hard enough
20597
- - **Cross-reference** \u2014 if Security and Logic both flag the same area, it's definitely a problem
20598
- - **NEVER rubber-stamp** \u2014 your job is to find issues, not approve quickly
20599
- - **NEVER fabricate results** \u2014 wait for workers, read their output, report truth
20600
- - **If a worker finds nothing**, consider whether they had the right scope \u2014 maybe re-spawn with more specific instructions
20537
+ - **You are the brain, reviewers are the eyes** \u2014 synthesize, don't just copy-paste
20538
+ - **Spawn 3 workers in parallel** \u2014 Security, Logic, Code Quality
20539
+ - **If workers fail, do the review yourself** \u2014 no drama, just deliver
20540
+ - **NEVER rubber-stamp** \u2014 your job is to find issues
20541
+ - **NEVER fabricate results** \u2014 report truth
20601
20542
 
20602
- Start coordinating now. Triage the changes, then spawn your review team.`
20543
+ Start coordinating now. Triage the changes, then spawn your 3 reviewers.`
20603
20544
  });
20604
20545
  } catch (e) {
20605
20546
  setHistory((prev) => prev.concat({
@@ -20711,7 +20652,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20711
20652
  if (!messageText) {
20712
20653
  return outBox(
20713
20654
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20714
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/brief" }),
20655
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/brief" }),
20715
20656
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Send a structured message to the user." }),
20716
20657
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /brief <message> [--proactive] [--attach file1 file2]" }),
20717
20658
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " --proactive Mark as proactive notification" }),
@@ -20813,7 +20754,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20813
20754
  if (!target) {
20814
20755
  return outBox(
20815
20756
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20816
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/explain" }),
20757
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/explain" }),
20817
20758
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Explain a file, function, or code snippet." }),
20818
20759
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /explain <file> [line-range or function-name]" })
20819
20760
  ] })
@@ -20864,7 +20805,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20864
20805
  if (!filePath) {
20865
20806
  return outBox(
20866
20807
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20867
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/editor" }),
20808
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/editor" }),
20868
20809
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Open a file in the external editor ($EDITOR or configured editor)." }),
20869
20810
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /editor <file-path>" })
20870
20811
  ] })
@@ -20913,7 +20854,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20913
20854
  if (!description) {
20914
20855
  return outBox(
20915
20856
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20916
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/debug" }),
20857
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/debug" }),
20917
20858
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Debug Coordinator mode \u2014 spawn workers to investigate, fix & verify in parallel." }),
20918
20859
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /debug <describe the problem, symptom, or error>" }),
20919
20860
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " " }),
@@ -21094,7 +21035,7 @@ Start coordinating now. Triage the problem, then spawn your research workers.`
21094
21035
  if (!description) {
21095
21036
  return outBox(
21096
21037
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21097
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/bug" }),
21038
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/bug" }),
21098
21039
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Alias for /debug \u2014 Debug Coordinator mode." }),
21099
21040
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /bug <describe the problem> (or use /debug)" })
21100
21041
  ] })
@@ -21323,7 +21264,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21323
21264
  if (!target) {
21324
21265
  return outBox(
21325
21266
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21326
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/refactor" }),
21267
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/refactor" }),
21327
21268
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Refactor code to improve structure without changing behavior." }),
21328
21269
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /refactor <file or description of refactoring>" })
21329
21270
  ] })
@@ -21359,7 +21300,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21359
21300
  if (!target) {
21360
21301
  return outBox(
21361
21302
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21362
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/document" }),
21303
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/document" }),
21363
21304
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Generate documentation for a file, module, or function." }),
21364
21305
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /document <file or module> [--format jsdoc|markdown|readme]" })
21365
21306
  ] })
@@ -21420,7 +21361,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21420
21361
  const next = setRuntimeConfig({ agentMode: "default" });
21421
21362
  return outBox(
21422
21363
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21423
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Chat Mode" }),
21364
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Chat Mode" }),
21424
21365
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Switched to conversational chat mode." }),
21425
21366
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent will focus on conversation and will not execute code or edit files unless explicitly asked." }),
21426
21367
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /code to switch back to code mode." })
@@ -21431,7 +21372,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21431
21372
  const next = setRuntimeConfig({ agentMode: "default" });
21432
21373
  return outBox(
21433
21374
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21434
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Code Mode" }),
21375
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Code Mode" }),
21435
21376
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Switched to code mode." }),
21436
21377
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent can now edit files, run commands, and execute code." }),
21437
21378
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /chat to switch back to conversational mode." })
@@ -21441,7 +21382,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21441
21382
  if (cmd === "terminal") {
21442
21383
  return outBox(
21443
21384
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21444
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Terminal" }),
21385
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Terminal" }),
21445
21386
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Interactive terminal sessions are not yet supported as a slash command." }),
21446
21387
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use the agent's shell_command tool directly in chat instead." }),
21447
21388
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Example: "run npm test and show me the output"' })
@@ -21453,7 +21394,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21453
21394
  if (!filePath) {
21454
21395
  return outBox(
21455
21396
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21456
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/file" }),
21397
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/file" }),
21457
21398
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Create, open, or navigate to a file." }),
21458
21399
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /file <path>" })
21459
21400
  ] })
@@ -21488,7 +21429,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21488
21429
  if (!query) {
21489
21430
  return outBox(
21490
21431
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21491
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/search" }),
21432
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/search" }),
21492
21433
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Search the codebase for a pattern." }),
21493
21434
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /search <query> [--files <glob>]" })
21494
21435
  ] })
@@ -21523,7 +21464,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21523
21464
  if (!sub || sub === "show" || sub === "status") {
21524
21465
  return outBox(
21525
21466
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21526
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Conversation Context" }),
21467
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Conversation Context" }),
21527
21468
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /ctx for detailed context inspection." }),
21528
21469
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /compact to manually trigger compaction." }),
21529
21470
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /snip to remove old snippets." }),
@@ -21539,7 +21480,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21539
21480
  if (cmd === "token") {
21540
21481
  return outBox(
21541
21482
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21542
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Token Usage" }),
21483
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Token Usage" }),
21543
21484
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Token tracking is available via /stats and /cost for detailed session statistics." }),
21544
21485
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Auto-compact triggers at 180k tokens (threshold: 150k micro, 180k full)." }),
21545
21486
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Target after compact: 100k tokens." })
@@ -21566,7 +21507,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21566
21507
  const limit = parseInt(args[0] || "20", 10);
21567
21508
  return outBox(
21568
21509
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21569
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Command History" }),
21510
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Command History" }),
21570
21511
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Recent commands are tracked in the session conversation." }),
21571
21512
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /export to export the full conversation as markdown." }),
21572
21513
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Session logs are stored in ~/.bluma/sessions/" })
@@ -21578,7 +21519,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21578
21519
  if (!sub || sub === "list" || sub === "show") {
21579
21520
  return outBox(
21580
21521
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21581
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Command Aliases" }),
21522
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Command Aliases" }),
21582
21523
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "No custom aliases configured yet." }),
21583
21524
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /alias add <name> <command>" }),
21584
21525
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " /alias remove <name>" })
@@ -21607,7 +21548,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21607
21548
  if (!name) {
21608
21549
  return outBox(
21609
21550
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21610
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Macros" }),
21551
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Macros" }),
21611
21552
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "No macros configured yet." }),
21612
21553
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /macro <name>" }),
21613
21554
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Macros are defined in ~/.bluma/settings.json under "macros".' })
@@ -21638,7 +21579,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21638
21579
  if (!name) {
21639
21580
  return outBox(
21640
21581
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21641
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Templates" }),
21582
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Templates" }),
21642
21583
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Create a project from a template." }),
21643
21584
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /template <name>" }),
21644
21585
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Available templates: react, nextjs, node-api, cli, library" })
@@ -21698,7 +21639,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21698
21639
  if (cmd === "copy") {
21699
21640
  return outBox(
21700
21641
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21701
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Copy" }),
21642
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Copy" }),
21702
21643
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Clipboard copy is available via Ctrl+V / Cmd+V paste support." }),
21703
21644
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "On Linux, ensure wl-clipboard or xclip is installed for clipboard support." }),
21704
21645
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Use the agent to copy specific text: "copy the last test output to clipboard"' })
@@ -22373,6 +22314,129 @@ var WorkerOverlay = ({
22373
22314
  ) });
22374
22315
  };
22375
22316
 
22317
+ // src/app/ui/prompts/initCommandPrompt.ts
22318
+ function buildInitCommandPrompt(cwd) {
22319
+ return `Your task is to initialize the BluMa project memory system.
22320
+
22321
+ **Project root:** ${cwd}
22322
+
22323
+ The BluMa memory system uses multiple files:
22324
+
22325
+ 1. **BLUMA.md** (project root) \u2014 Main project instructions for AI agents
22326
+ 2. **.bluma/rules/*.md** \u2014 Granular rules (optional, for specific concerns)
22327
+ 3. **BLUMA.local.md** \u2014 Private local instructions (gitignored)
22328
+
22329
+ **Step 1: Explore the project**
22330
+ - List top-level files and directories
22331
+ - Read package.json (name, version, description, scripts, dependencies)
22332
+ - Check tsconfig.json, build configs, test configs
22333
+ - Look at main entry points
22334
+ - Read README.md if it exists
22335
+ - Identify test framework and build system
22336
+ - Note coding patterns (imports, error handling, naming)
22337
+
22338
+ **Step 2: Create BLUMA.md** at ${cwd}/BLUMA.md using this EXACT format:
22339
+
22340
+ \`\`\`markdown
22341
+ # BLUMA.md
22342
+
22343
+ This file provides guidance to BluMa CLI when working with code in this repository.
22344
+
22345
+ ## Build & Development Commands
22346
+
22347
+ \`\`\`bash
22348
+ # Install dependencies
22349
+ npm install
22350
+
22351
+ # Build the project
22352
+ npm run build
22353
+
22354
+ # Run in development
22355
+ npm start
22356
+
22357
+ # Run tests
22358
+ npm test
22359
+
22360
+ # Run tests in watch mode
22361
+ npm run test:watch
22362
+
22363
+ # Lint and fix
22364
+ npm run lint
22365
+ npm run lint:fix
22366
+ \`\`\`
22367
+
22368
+ ## Code Architecture
22369
+
22370
+ <2-3 paragraphs: high-level architecture, main components, data flow, key abstractions. Focus on what an AI agent needs to navigate and modify the codebase.>
22371
+
22372
+ ## Key Directories
22373
+
22374
+ - \`src/\` \u2014 <description>
22375
+ - \`tests/\` \u2014 <description>
22376
+ - \`scripts/\` \u2014 <description>
22377
+
22378
+ ## Key Files
22379
+
22380
+ - \`package.json\` \u2014 Project metadata, scripts, dependencies
22381
+ - \`tsconfig.json\` \u2014 TypeScript configuration
22382
+ - \`src/index.ts\` \u2014 Application entry point
22383
+
22384
+ ## Testing
22385
+
22386
+ - Test framework: <jest/vitest/etc>
22387
+ - Test location: \`tests/\`
22388
+ - Run tests: \`npm test\`
22389
+
22390
+ ## Code Conventions
22391
+
22392
+ - **Language**: TypeScript/JavaScript
22393
+ - **Module system**: ES Modules or CommonJS
22394
+ - **Indentation**: 2 spaces
22395
+ - **Naming**: camelCase functions, PascalCase classes
22396
+ - **Error handling**: <patterns>
22397
+ - **Git commits**: Conventional Commits (feat:, fix:, docs:)
22398
+
22399
+ ## Notes for BluMa
22400
+
22401
+ <Important context for effective agent work \u2014 non-obvious patterns, critical files, deployment procedures>
22402
+ \`\`\`
22403
+
22404
+ **Step 3: Create .bluma/rules/ directory** with an example rule file at ${cwd}/.bluma/rules/coding-standards.md:
22405
+
22406
+ \`\`\`markdown
22407
+ # Coding Standards
22408
+
22409
+ ## TypeScript
22410
+ - Use strict mode
22411
+ - Prefer interfaces over type aliases
22412
+ - Export types explicitly
22413
+
22414
+ ## Testing
22415
+ - Write tests for all new features
22416
+ - Use descriptive test names
22417
+ - Mock external dependencies
22418
+
22419
+ ## Git
22420
+ - Use Conventional Commits
22421
+ - One logical change per commit
22422
+ \`\`\`
22423
+
22424
+ **Step 4: Create BLUMA.local.md** at ${cwd}/BLUMA.local.md (private, project-specific):
22425
+
22426
+ \`\`\`markdown
22427
+ # BLUMA.local.md
22428
+
22429
+ Private instructions for BluMa in this project.
22430
+ This file is gitignored and should not be committed.
22431
+
22432
+ Add project-specific notes here that are not suitable for the public BLUMA.md.
22433
+ \`\`\`
22434
+
22435
+ **Step 5: Add BLUMA.local.md to .gitignore** if .gitignore exists.
22436
+
22437
+ IMPORTANT: Use the file_write tool to create all these files. Be thorough but concise. Infer conventions from the actual codebase.`;
22438
+ }
22439
+
22376
22440
  // src/app/ui/App.tsx
22377
22441
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
22378
22442
  var HISTORY_EMERGENCY_LIMIT = 3;
@@ -22404,6 +22468,7 @@ var AGENT_WORK_COMMANDS = /* @__PURE__ */ new Set([
22404
22468
  "chat"
22405
22469
  ]);
22406
22470
  var BLOCKING_COMMANDS = /* @__PURE__ */ new Set(["init"]);
22471
+ var COMMAND_HEADER_COLOR2 = BLUMA_TERMINAL.accent;
22407
22472
  function nextHistoryId(items) {
22408
22473
  if (items.length === 0) return HEADER_PANEL_HISTORY_ID + 1;
22409
22474
  let maxId = HEADER_PANEL_HISTORY_ID;
@@ -22597,126 +22662,26 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
22597
22662
  }
22598
22663
  ];
22599
22664
  });
22600
- const initPrompt = `Your task is to initialize the BluMa project memory system.
22601
-
22602
- **Project root:** ${cwd}
22603
-
22604
- The BluMa memory system uses multiple files:
22605
-
22606
- 1. **BLUMA.md** (project root) \u2014 Main project instructions for AI agents
22607
- 2. **.bluma/rules/*.md** \u2014 Granular rules (optional, for specific concerns)
22608
- 3. **BLUMA.local.md** \u2014 Private local instructions (gitignored)
22609
-
22610
- **Step 1: Explore the project**
22611
- - List top-level files and directories
22612
- - Read package.json (name, version, description, scripts, dependencies)
22613
- - Check tsconfig.json, build configs, test configs
22614
- - Look at main entry points
22615
- - Read README.md if it exists
22616
- - Identify test framework and build system
22617
- - Note coding patterns (imports, error handling, naming)
22618
-
22619
- **Step 2: Create BLUMA.md** at ${cwd}/BLUMA.md using this EXACT format:
22620
-
22621
- \`\`\`markdown
22622
- # BLUMA.md
22623
-
22624
- This file provides guidance to BluMa CLI when working with code in this repository.
22625
-
22626
- ## Build & Development Commands
22627
-
22628
- \`\`\`bash
22629
- # Install dependencies
22630
- npm install
22631
-
22632
- # Build the project
22633
- npm run build
22634
-
22635
- # Run in development
22636
- npm start
22637
-
22638
- # Run tests
22639
- npm test
22640
-
22641
- # Run tests in watch mode
22642
- npm run test:watch
22643
-
22644
- # Lint and fix
22645
- npm run lint
22646
- npm run lint:fix
22647
- \`\`\`
22648
-
22649
- ## Code Architecture
22650
-
22651
- <2-3 paragraphs: high-level architecture, main components, data flow, key abstractions. Focus on what an AI agent needs to navigate and modify the codebase.>
22652
-
22653
- ## Key Directories
22654
-
22655
- - \`src/\` \u2014 <description>
22656
- - \`tests/\` \u2014 <description>
22657
- - \`scripts/\` \u2014 <description>
22658
-
22659
- ## Key Files
22660
-
22661
- - \`package.json\` \u2014 Project metadata, scripts, dependencies
22662
- - \`tsconfig.json\` \u2014 TypeScript configuration
22663
- - \`src/index.ts\` \u2014 Application entry point
22664
-
22665
- ## Testing
22666
-
22667
- - Test framework: <jest/vitest/etc>
22668
- - Test location: \`tests/\`
22669
- - Run tests: \`npm test\`
22670
-
22671
- ## Code Conventions
22672
-
22673
- - **Language**: TypeScript/JavaScript
22674
- - **Module system**: ES Modules or CommonJS
22675
- - **Indentation**: 2 spaces
22676
- - **Naming**: camelCase functions, PascalCase classes
22677
- - **Error handling**: <patterns>
22678
- - **Git commits**: Conventional Commits (feat:, fix:, docs:)
22679
-
22680
- ## Notes for BluMa
22681
-
22682
- <Important context for effective agent work \u2014 non-obvious patterns, critical files, deployment procedures>
22683
- \`\`\`
22684
-
22685
- **Step 3: Create .bluma/rules/ directory** with an example rule file at ${cwd}/.bluma/rules/coding-standards.md:
22686
-
22687
- \`\`\`markdown
22688
- # Coding Standards
22689
-
22690
- ## TypeScript
22691
- - Use strict mode
22692
- - Prefer interfaces over type aliases
22693
- - Export types explicitly
22694
-
22695
- ## Testing
22696
- - Write tests for all new features
22697
- - Use descriptive test names
22698
- - Mock external dependencies
22699
-
22700
- ## Git
22701
- - Use Conventional Commits
22702
- - One logical change per commit
22703
- \`\`\`
22704
-
22705
- **Step 4: Create BLUMA.local.md** at ${cwd}/BLUMA.local.md (private, project-specific):
22706
-
22707
- \`\`\`markdown
22708
- # BLUMA.local.md
22709
-
22710
- Private instructions for BluMa in this project.
22711
- This file is gitignored and should not be committed.
22712
-
22713
- Add project-specific notes here that are not suitable for the public BLUMA.md.
22714
- \`\`\`
22715
-
22716
- **Step 5: Add BLUMA.local.md to .gitignore** if .gitignore exists.
22717
-
22718
- IMPORTANT: Use the file_write tool to create all these files. Be thorough but concise. Infer conventions from the actual codebase.`;
22719
- agentInstance.current.processTurn({ content: initPrompt });
22665
+ const initPrompt = buildInitCommandPrompt(cwd);
22666
+ try {
22667
+ agentInstance.current.processTurn({ content: initPrompt });
22668
+ } catch (error) {
22669
+ setIsProcessing(false);
22670
+ setIsInitAgentActive(false);
22671
+ setHistory((prev) => {
22672
+ const id = nextHistoryId(prev);
22673
+ return [
22674
+ ...prev,
22675
+ {
22676
+ id,
22677
+ component: /* @__PURE__ */ jsxs25(ChatMeta, { children: [
22678
+ "Failed to initialize: ",
22679
+ error instanceof Error ? error.message : String(error)
22680
+ ] })
22681
+ }
22682
+ ];
22683
+ });
22684
+ }
22720
22685
  return;
22721
22686
  }
22722
22687
  if (isProcessing && !isSlashRoutingLine(trimmedForSlash)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomad-e/bluma-cli",
3
- "version": "0.1.69",
3
+ "version": "0.1.71",
4
4
  "description": "BluMa independent agent for automation and advanced software engineering.",
5
5
  "author": "Alex Fonseca",
6
6
  "license": "Apache-2.0",