@nomad-e/bluma-cli 0.1.70 → 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 +283 -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("`, `")}\`
@@ -18574,6 +18600,7 @@ function buildDiagnosticsSnapshot(feedbackScore) {
18574
18600
  // src/app/ui/components/SlashCommands.tsx
18575
18601
  init_runtime_config();
18576
18602
  import { Fragment as Fragment6, jsx as jsx18, jsxs as jsxs16 } from "react/jsx-runtime";
18603
+ var COMMAND_HEADER_COLOR = BLUMA_TERMINAL.accent;
18577
18604
  var RECOMMENDED_MODELS = [
18578
18605
  "auto",
18579
18606
  "auto"
@@ -18592,7 +18619,7 @@ var SessionLivePanel = ({ sessionId, mode }) => {
18592
18619
  }, [sessionId]);
18593
18620
  if (!session) {
18594
18621
  return /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Box17, { paddingLeft: 1, flexDirection: "column", children: [
18595
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: mode }),
18622
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: mode }),
18596
18623
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18597
18624
  "Unknown session: ",
18598
18625
  sessionId
@@ -18603,7 +18630,7 @@ var SessionLivePanel = ({ sessionId, mode }) => {
18603
18630
  const recent = logs.slice(-16);
18604
18631
  return /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsxs16(Box17, { paddingLeft: 1, flexDirection: "column", children: [
18605
18632
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18606
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: mode }),
18633
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: mode }),
18607
18634
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18608
18635
  " \xB7 ",
18609
18636
  session.sessionId.slice(0, 8)
@@ -18637,7 +18664,7 @@ var SlashCommands = ({
18637
18664
  const outBox = (children) => /* @__PURE__ */ jsx18(ChatBlock, { marginBottom: 1, children: /* @__PURE__ */ jsx18(Box17, { paddingLeft: 1, flexDirection: "column", children }) });
18638
18665
  const usageBox = (title, body) => outBox(
18639
18666
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18640
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: title }),
18667
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: title }),
18641
18668
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: body })
18642
18669
  ] })
18643
18670
  );
@@ -18670,7 +18697,7 @@ var SlashCommands = ({
18670
18697
  return outBox(
18671
18698
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18672
18699
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18673
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Sessions" }),
18700
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Sessions" }),
18674
18701
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18675
18702
  " \xB7 ",
18676
18703
  sessions.length,
@@ -18713,7 +18740,7 @@ var SlashCommands = ({
18713
18740
  const alive = session.status === "running" ? isProcessAlive(session.pid) : false;
18714
18741
  return outBox(
18715
18742
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18716
- /* @__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" }),
18717
18744
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: session.sessionId }),
18718
18745
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18719
18746
  session.kind,
@@ -18738,7 +18765,7 @@ var SlashCommands = ({
18738
18765
  return outBox(
18739
18766
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18740
18767
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18741
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Logs" }),
18768
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Logs" }),
18742
18769
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18743
18770
  " \xB7 ",
18744
18771
  session.sessionId.slice(0, 8)
@@ -18784,7 +18811,7 @@ var SlashCommands = ({
18784
18811
  return outBox(
18785
18812
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18786
18813
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18787
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Tasks" }),
18814
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Tasks" }),
18788
18815
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18789
18816
  " \xB7 ",
18790
18817
  stats.total,
@@ -18839,7 +18866,7 @@ var SlashCommands = ({
18839
18866
  return outBox(
18840
18867
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18841
18868
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18842
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Permissions" }),
18869
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Permissions" }),
18843
18870
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18844
18871
  " \xB7 ",
18845
18872
  policy.isSandbox ? "sandbox" : "local"
@@ -18898,7 +18925,7 @@ var SlashCommands = ({
18898
18925
  return outBox(
18899
18926
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18900
18927
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18901
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Runtime" }),
18928
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Runtime" }),
18902
18929
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 model / effort" })
18903
18930
  ] }),
18904
18931
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -18960,7 +18987,7 @@ var SlashCommands = ({
18960
18987
  ];
18961
18988
  return outBox(
18962
18989
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18963
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Statusline" }),
18990
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Statusline" }),
18964
18991
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: parts.filter(Boolean).join(" \xB7 ") })
18965
18992
  ] })
18966
18993
  );
@@ -18971,7 +18998,7 @@ var SlashCommands = ({
18971
18998
  return outBox(
18972
18999
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
18973
19000
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
18974
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Bridge" }),
19001
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Bridge" }),
18975
19002
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
18976
19003
  " \xB7 ",
18977
19004
  sessions.length,
@@ -18999,7 +19026,7 @@ var SlashCommands = ({
18999
19026
  return outBox(
19000
19027
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19001
19028
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19002
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Plugins" }),
19029
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Plugins" }),
19003
19030
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19004
19031
  " \xB7 ",
19005
19032
  plugins.length,
@@ -19032,7 +19059,7 @@ var SlashCommands = ({
19032
19059
  return outBox(
19033
19060
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19034
19061
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19035
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Diagnostics" }),
19062
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Diagnostics" }),
19036
19063
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 health snapshot" })
19037
19064
  ] }),
19038
19065
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -19116,7 +19143,7 @@ var SlashCommands = ({
19116
19143
  return outBox(
19117
19144
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19118
19145
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19119
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Plugin" }),
19146
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Plugin" }),
19120
19147
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19121
19148
  " \xB7 ",
19122
19149
  plugin.name
@@ -19155,7 +19182,7 @@ var SlashCommands = ({
19155
19182
  return outBox(
19156
19183
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19157
19184
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19158
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Hooks" }),
19185
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Hooks" }),
19159
19186
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19160
19187
  " \xB7 ",
19161
19188
  state.enabled ? "enabled" : "disabled"
@@ -19230,7 +19257,7 @@ var SlashCommands = ({
19230
19257
  const dirs = getPluginDirs();
19231
19258
  return outBox(
19232
19259
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19233
- /* @__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" }),
19234
19261
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19235
19262
  "project: ",
19236
19263
  dirs.project
@@ -19391,7 +19418,7 @@ var SlashCommands = ({
19391
19418
  return outBox(
19392
19419
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19393
19420
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19394
- /* @__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" }),
19395
19422
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \xB7 recommended" })
19396
19423
  ] }),
19397
19424
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", children: RECOMMENDED_MODELS.map((model) => /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
@@ -19405,7 +19432,7 @@ var SlashCommands = ({
19405
19432
  const next = setRuntimeConfig({ model: value });
19406
19433
  return outBox(
19407
19434
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19408
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Model" }),
19435
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Model" }),
19409
19436
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19410
19437
  "set to ",
19411
19438
  next.model
@@ -19424,7 +19451,7 @@ var SlashCommands = ({
19424
19451
  const next = setRuntimeConfig({ reasoningEffort: value });
19425
19452
  return outBox(
19426
19453
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19427
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Effort" }),
19454
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Effort" }),
19428
19455
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19429
19456
  "set to ",
19430
19457
  next.reasoningEffort
@@ -19443,7 +19470,7 @@ var SlashCommands = ({
19443
19470
  const next = setRuntimeConfig({ outputStyle: value });
19444
19471
  return outBox(
19445
19472
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19446
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Style" }),
19473
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Style" }),
19447
19474
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19448
19475
  "set to ",
19449
19476
  next.outputStyle
@@ -19462,7 +19489,7 @@ var SlashCommands = ({
19462
19489
  const next = setRuntimeConfig({ sandboxEnabled: value === "on" });
19463
19490
  return outBox(
19464
19491
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19465
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Sandbox" }),
19492
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Sandbox" }),
19466
19493
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: next.sandboxEnabled ? "on" : "off" })
19467
19494
  ] })
19468
19495
  );
@@ -19475,7 +19502,7 @@ var SlashCommands = ({
19475
19502
  const next = setRuntimeConfig({ workspaceRoot: value });
19476
19503
  return outBox(
19477
19504
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19478
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Worktree" }),
19505
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Worktree" }),
19479
19506
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: next.workspaceRoot })
19480
19507
  ] })
19481
19508
  );
@@ -19489,7 +19516,7 @@ var SlashCommands = ({
19489
19516
  return outBox(
19490
19517
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19491
19518
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19492
- /* @__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" }),
19493
19520
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19494
19521
  " ",
19495
19522
  "\xB7 type any command to execute; use /help",
@@ -19503,7 +19530,7 @@ var SlashCommands = ({
19503
19530
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", marginTop: 1, children: groups.map((group) => /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, flexDirection: "column", children: [
19504
19531
  /* @__PURE__ */ jsx18(Text16, { color: BLUMA_TERMINAL.suggestion, bold: true, children: group.label }),
19505
19532
  /* @__PURE__ */ jsx18(Box17, { flexDirection: "column", marginTop: 0, children: group.commands.map((command) => /* @__PURE__ */ jsxs16(Box17, { flexDirection: "row", flexWrap: "wrap", children: [
19506
- /* @__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, " ") }),
19507
19534
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: command.description })
19508
19535
  ] }, command.name)) })
19509
19536
  ] }, group.category)) }),
@@ -19519,7 +19546,7 @@ var SlashCommands = ({
19519
19546
  if (entries.length === 0) {
19520
19547
  return outBox(
19521
19548
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19522
- /* @__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" }),
19523
19550
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " No agent sessions in this CLI registry. Use the " }),
19524
19551
  /* @__PURE__ */ jsx18(Text16, { bold: true, children: "spawn_agent" }),
19525
19552
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " tool from chat, or " }),
@@ -19530,7 +19557,7 @@ var SlashCommands = ({
19530
19557
  }
19531
19558
  return outBox(
19532
19559
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19533
- /* @__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" }),
19534
19561
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19535
19562
  " ",
19536
19563
  entries.length,
@@ -19674,7 +19701,7 @@ Usage: /features <key> on|off`
19674
19701
  return outBox(
19675
19702
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19676
19703
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19677
- /* @__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)" }),
19678
19705
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19679
19706
  " \xB7 ",
19680
19707
  list.length,
@@ -19734,7 +19761,7 @@ Usage: /features <key> on|off`
19734
19761
  return outBox(
19735
19762
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19736
19763
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
19737
- /* @__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" }),
19738
19765
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 " }),
19739
19766
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19740
19767
  tools.length,
@@ -19790,7 +19817,7 @@ Usage: /features <key> on|off`
19790
19817
  const colSource = 18;
19791
19818
  return outBox(
19792
19819
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19793
- /* @__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" }),
19794
19821
  /* @__PURE__ */ jsxs16(Text16, { color: "gray", children: [
19795
19822
  "Total Native: ",
19796
19823
  tools.length,
@@ -19834,7 +19861,7 @@ Usage: /features <key> on|off`
19834
19861
  const errored = agents.filter((a) => a.status === "error");
19835
19862
  return outBox(
19836
19863
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19837
- /* @__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" }),
19838
19865
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19839
19866
  "Total: ",
19840
19867
  agents.length,
@@ -19868,7 +19895,7 @@ Usage: /features <key> on|off`
19868
19895
  if (cmd === "compact") {
19869
19896
  return outBox(
19870
19897
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19871
- /* @__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" }),
19872
19899
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Auto-compact triggers at 180k tokens (threshold: 150k micro, 180k full)" }),
19873
19900
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Target after compact: 100k tokens" }),
19874
19901
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /compact to manually trigger context compaction." })
@@ -19878,7 +19905,7 @@ Usage: /features <key> on|off`
19878
19905
  if (cmd === "cost") {
19879
19906
  return outBox(
19880
19907
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19881
- /* @__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" }),
19882
19909
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Cost tracking is available via /stats for detailed session statistics." })
19883
19910
  ] })
19884
19911
  );
@@ -19886,7 +19913,7 @@ Usage: /features <key> on|off`
19886
19913
  if (cmd === "export") {
19887
19914
  return outBox(
19888
19915
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19889
- /* @__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" }),
19890
19917
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Session logs are stored in ~/.bluma/sessions/" }),
19891
19918
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /logs to view recent logs for a session." })
19892
19919
  ] })
@@ -19895,7 +19922,7 @@ Usage: /features <key> on|off`
19895
19922
  if (cmd === "memory") {
19896
19923
  return outBox(
19897
19924
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19898
- /* @__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" }),
19899
19926
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Memories are auto-extracted from conversations and stored in ~/.bluma/session_memory.json" }),
19900
19927
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Relevant memories are injected into context automatically." })
19901
19928
  ] })
@@ -19905,7 +19932,7 @@ Usage: /features <key> on|off`
19905
19932
  const mem = process.memoryUsage();
19906
19933
  return outBox(
19907
19934
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19908
- /* @__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" }),
19909
19936
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
19910
19937
  "Heap: ",
19911
19938
  Math.round(mem.heapUsed / 1024 / 1024),
@@ -19969,7 +19996,7 @@ Usage: /features <key> on|off`
19969
19996
  }
19970
19997
  return outBox(
19971
19998
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19972
- /* @__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" }),
19973
20000
  themes.map((t) => /* @__PURE__ */ jsxs16(Text16, { color: "white", children: [
19974
20001
  " ",
19975
20002
  t.name,
@@ -19982,7 +20009,7 @@ Usage: /features <key> on|off`
19982
20009
  if (cmd === "keybindings") {
19983
20010
  return outBox(
19984
20011
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19985
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Keybindings" }),
20012
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Keybindings" }),
19986
20013
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Custom keybindings are configured in ~/.bluma/settings.json" }),
19987
20014
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Ctrl+V / Cmd+V \u2014 Paste image or text" }),
19988
20015
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Ctrl+Shift+I \u2014 Paste image" }),
@@ -19994,7 +20021,7 @@ Usage: /features <key> on|off`
19994
20021
  if (cmd === "vim") {
19995
20022
  return outBox(
19996
20023
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
19997
- /* @__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" }),
19998
20025
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Vim mode provides normal/insert/command modes." }),
19999
20026
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " Escape \u2014 Switch to normal mode" }),
20000
20027
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " i/a/o \u2014 Switch to insert mode" }),
@@ -20323,7 +20350,7 @@ Report the release version, tag, changelog summary, and verification results whe
20323
20350
  return outBox(
20324
20351
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20325
20352
  /* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
20326
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Release" }),
20353
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Release" }),
20327
20354
  /* @__PURE__ */ jsxs16(Text16, { dimColor: true, children: [
20328
20355
  " \xB7 ",
20329
20356
  bumpType,
@@ -20339,32 +20366,15 @@ Report the release version, tag, changelog summary, and verification results whe
20339
20366
  if (cmd === "review") {
20340
20367
  const target = args.join(" ") || "";
20341
20368
  const isPR = target && /^\d+$/.test(target);
20342
- if (!target && !isPR) {
20343
- return outBox(
20344
- /* @__PURE__ */ jsxs16(Fragment6, { children: [
20345
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/review" }),
20346
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Review Coordinator \u2014 spawn a team of specialized QA reviewers in parallel." }),
20347
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Usage: /review [PR-number | file-path | "local changes"]' }),
20348
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " " }),
20349
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent will coordinate a review team:" }),
20350
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Security Reviewer \u2014 vulnerabilities, injection, auth flaws" }),
20351
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Logic & Correctness \u2014 bugs, edge cases, wrong assumptions" }),
20352
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Performance \u2014 N+1 queries, memory leaks, algorithmic issues" }),
20353
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Code Quality \u2014 naming, structure, conventions, readability" }),
20354
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Test Coverage \u2014 missing tests, weak assertions, untested paths" }),
20355
- /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " \u2022 Architecture \u2014 coupling, abstraction leaks, design violations" })
20356
- ] })
20357
- );
20358
- }
20359
20369
  (async () => {
20360
20370
  try {
20361
- 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)";
20362
20372
  await agentRef.current?.processTurn({
20363
20373
  content: `## REVIEW COORDINATOR MODE \u2014 Lead a Team of Senior QA Reviewers
20364
20374
 
20365
- 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.
20366
20376
 
20367
- **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.
20368
20378
 
20369
20379
  **Review Target:** ${reviewTarget}
20370
20380
 
@@ -20378,17 +20388,20 @@ You are now the **Review Coordinator** \u2014 a Principal Engineer leading a tea
20378
20388
  ${target === "local" || target === "local changes" ? `- Run \`git diff HEAD\` for unstaged changes` : ""}
20379
20389
  ${target === "local" || target === "local changes" ? `- Run \`git diff --cached HEAD\` for staged changes` : ""}
20380
20390
  2. Understand the SCOPE: how many files changed, what areas are affected
20381
- 3. Identify which review specialties are most relevant (security? performance? logic?)
20382
20391
 
20383
- #### Step 2: Spawn Parallel Review Workers (your key move)
20384
- 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.
20385
20396
 
20386
- **Worker 1 \u2014 Security Reviewer (ALWAYS spawn):**
20397
+ **Worker 1 \u2014 Security Reviewer:**
20387
20398
  \`\`\`
20388
20399
  spawn_agent({
20389
20400
  task: "SECURITY REVIEW: Thoroughly review ${reviewTarget} for security vulnerabilities.
20390
20401
 
20391
- 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:
20392
20405
  - Injection vulnerabilities (SQL, XSS, command injection, template injection)
20393
20406
  - Authentication/authorization flaws (missing auth checks, privilege escalation)
20394
20407
  - Sensitive data exposure (secrets in logs, PII leaks, hardcoded credentials)
@@ -20405,20 +20418,24 @@ For EACH issue found:
20405
20418
  - How to exploit it (brief)
20406
20419
  - Recommended fix
20407
20420
 
20408
- 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.
20409
20424
 
20410
- Do NOT modify files. Report only.",
20425
+ At the end of your report, list ALL files you reviewed.",
20411
20426
  title: "Security Review",
20412
20427
  agent_type: "reviewer"
20413
20428
  })
20414
20429
  \`\`\`
20415
20430
 
20416
- **Worker 2 \u2014 Logic & Correctness (ALWAYS spawn):**
20431
+ **Worker 2 \u2014 Logic & Correctness:**
20417
20432
  \`\`\`
20418
20433
  spawn_agent({
20419
20434
  task: "LOGIC REVIEW: Thoroughly review ${reviewTarget} for bugs and logic errors.
20420
20435
 
20421
- 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:
20422
20439
  - Logic errors (wrong conditions, off-by-one, inverted boolean, wrong operator)
20423
20440
  - Null/undefined handling (missing null checks, unsafe property access)
20424
20441
  - State management issues (stale state, missing initialization, race conditions)
@@ -20435,50 +20452,24 @@ For EACH issue found:
20435
20452
  - How to trigger the bug
20436
20453
  - Recommended fix
20437
20454
 
20438
- Be RELENTLESS. Question every assumption. If a branch looks untested, flag it.
20455
+ Be RELENTLESS. Question every assumption.
20439
20456
 
20440
- Do NOT modify files. Report only.",
20441
- title: "Logic & Correctness Review",
20442
- agent_type: "reviewer"
20443
- })
20444
- \`\`\`
20457
+ Do NOT modify files. Report only.
20445
20458
 
20446
- **Worker 3 \u2014 Performance (spawn if changes touch data flow, loops, queries, APIs):**
20447
- \`\`\`
20448
- spawn_agent({
20449
- task: "PERFORMANCE REVIEW: Thoroughly review ${reviewTarget} for performance issues.
20450
-
20451
- You are a Performance Engineer. Read every changed line. Look for:
20452
- - N+1 query patterns (looping database calls)
20453
- - Unnecessary computations (repeated calculations, missing memoization)
20454
- - Memory leaks (unclosed resources, growing arrays, event listener accumulation)
20455
- - Algorithmic complexity (O(n\xB2) where O(n) is possible, nested loops on large data)
20456
- - Blocking operations (sync I/O in async context, heavy computation on main thread)
20457
- - Missing caching opportunities (repeated expensive operations)
20458
- - Bundle size issues (large imports, tree-shaking failures)
20459
- - Network inefficiencies (unnecessary requests, missing batching, no pagination)
20460
-
20461
- For EACH issue found:
20462
- - Impact: HIGH / MEDIUM / LOW
20463
- - File:line number
20464
- - Current behavior vs optimized behavior
20465
- - Estimated improvement
20466
- - Recommended fix with code example
20467
-
20468
- Be THOROUGH. Even small inefficiencies add up.
20469
-
20470
- Do NOT modify files. Report only.",
20471
- title: "Performance Review",
20459
+ At the end of your report, list ALL files you reviewed.",
20460
+ title: "Logic & Correctness Review",
20472
20461
  agent_type: "reviewer"
20473
20462
  })
20474
20463
  \`\`\`
20475
20464
 
20476
- **Worker 4 \u2014 Code Quality & Conventions (ALWAYS spawn):**
20465
+ **Worker 3 \u2014 Code Quality:**
20477
20466
  \`\`\`
20478
20467
  spawn_agent({
20479
20468
  task: "CODE QUALITY REVIEW: Thoroughly review ${reviewTarget} for code quality and convention violations.
20480
20469
 
20481
- 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:
20482
20473
  - Naming issues (misleading names, abbreviations, inconsistent casing)
20483
20474
  - Function length and complexity (too long, too many responsibilities, deep nesting)
20484
20475
  - DRY violations (duplicated logic that should be extracted)
@@ -20496,72 +20487,22 @@ For EACH issue found:
20496
20487
 
20497
20488
  Be PICKY about readability. Code is read 10x more than written.
20498
20489
 
20499
- Do NOT modify files. Report only.",
20500
- title: "Code Quality Review",
20501
- agent_type: "reviewer"
20502
- })
20503
- \`\`\`
20490
+ Do NOT modify files. Report only.
20504
20491
 
20505
- **Worker 5 \u2014 Test Coverage (spawn if tests exist or should exist):**
20506
- \`\`\`
20507
- spawn_agent({
20508
- task: "TEST COVERAGE REVIEW: Thoroughly review ${reviewTarget} for test gaps.
20509
-
20510
- You are a QA Lead. Look at:
20511
- - Which files changed and whether they have corresponding tests
20512
- - If tests exist: are they testing the RIGHT things (happy path only? missing edge cases?)
20513
- - Assertion quality (weak assertions, missing error case tests)
20514
- - Untested code paths (branches, error handlers, edge cases)
20515
- - Mock quality (over-mocking, mocking the wrong things, unrealistic mocks)
20516
- - Integration gaps (unit tests but no integration tests, or vice versa)
20517
- - Test naming and organization (unclear test names, giant test files)
20518
-
20519
- For EACH gap found:
20520
- - File:line of untested code
20521
- - What scenario is not tested
20522
- - Why it matters
20523
- - Suggested test case (with code)
20524
-
20525
- Be DEMANDING. Untested code is broken code waiting for the right input.
20526
-
20527
- Do NOT modify files. Report only.",
20528
- title: "Test Coverage Review",
20492
+ At the end of your report, list ALL files you reviewed.",
20493
+ title: "Code Quality Review",
20529
20494
  agent_type: "reviewer"
20530
20495
  })
20531
20496
  \`\`\`
20532
20497
 
20533
- **Worker 6 \u2014 Architecture & Design (spawn for larger changes or new features):**
20534
- \`\`\`
20535
- spawn_agent({
20536
- task: "ARCHITECTURE REVIEW: Thoroughly review ${reviewTarget} for design and architectural issues.
20537
-
20538
- You are a Principal Engineer. Look at the BIG picture:
20539
- - Does this change fit the existing architecture or fight against it?
20540
- - Are there new dependencies that shouldn't exist (circular deps, wrong layer imports)?
20541
- - Is the abstraction level appropriate (too low-level, too abstract, leaky abstractions)?
20542
- - Does this introduce coupling between previously independent modules?
20543
- - Are there better design patterns that should be used?
20544
- - Does this change break any existing contracts or APIs?
20545
- - Is the change appropriately scoped (too big, mixing concerns)?
20546
- - Does this create technical debt (quick hacks that will hurt later)?
20547
-
20548
- For EACH issue found:
20549
- - Severity: ARCHITECTURAL / DESIGN / MINOR
20550
- - File:line number
20551
- - What the design problem is
20552
- - Why it matters long-term
20553
- - Suggested alternative approach
20554
-
20555
- 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).
20556
20500
 
20557
- Do NOT modify files. Report only.",
20558
- title: "Architecture Review",
20559
- agent_type: "reviewer"
20560
- })
20561
- \`\`\`
20562
-
20563
- #### Step 3: Synthesize (you do this \u2014 critical)
20564
- 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
20565
20506
 
20566
20507
  **NEVER write** "the review looks good" \u2014 that's lazy.
20567
20508
  **ALWAYS synthesize**: Group findings by severity, cross-reference between reviewers, identify patterns.
@@ -20572,7 +20513,7 @@ Compile a comprehensive review report:
20572
20513
  **REVIEW REPORT for ${reviewTarget}**
20573
20514
 
20574
20515
  \u{1F534} CRITICAL / BLOCKER (must fix before merge):
20575
- - [List all critical findings from any reviewer]
20516
+ - [List all critical findings]
20576
20517
 
20577
20518
  \u{1F7E1} HIGH / MAJOR (should fix):
20578
20519
  - [List all high findings]
@@ -20581,27 +20522,25 @@ Compile a comprehensive review report:
20581
20522
  - [List all medium findings]
20582
20523
 
20583
20524
  \u2139\uFE0F OBSERVATIONS (no action needed):
20584
- - [List observations, style notes, future considerations]
20525
+ - [List observations, style notes]
20585
20526
 
20586
20527
  \u2705 POSITIVE FINDINGS (what's good):
20587
- - [List well-written code, good patterns, improvements]
20528
+ - [List well-written code, good patterns]
20588
20529
 
20589
20530
  **Review Summary:**
20590
20531
  - Total issues found: X critical, Y high, Z medium
20591
- - Reviewers used: [list workers]
20532
+ - Reviewers used: [list workers or "direct review"]
20592
20533
  - Recommendation: APPROVE / APPROVE WITH COMMENTS / REQUEST CHANGES
20593
20534
  - Confidence level: HIGH / MEDIUM / LOW
20594
20535
 
20595
20536
  ### COORDINATOR RULES
20596
- - **You are the brain, reviewers are the eyes** \u2014 synthesize, don't just copy-paste findings
20597
- - **Spawn workers in parallel** \u2014 all reviewers work simultaneously
20598
- - **Be picky** \u2014 if a reviewer found nothing, they weren't looking hard enough
20599
- - **Cross-reference** \u2014 if Security and Logic both flag the same area, it's definitely a problem
20600
- - **NEVER rubber-stamp** \u2014 your job is to find issues, not approve quickly
20601
- - **NEVER fabricate results** \u2014 wait for workers, read their output, report truth
20602
- - **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
20603
20542
 
20604
- Start coordinating now. Triage the changes, then spawn your review team.`
20543
+ Start coordinating now. Triage the changes, then spawn your 3 reviewers.`
20605
20544
  });
20606
20545
  } catch (e) {
20607
20546
  setHistory((prev) => prev.concat({
@@ -20713,7 +20652,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20713
20652
  if (!messageText) {
20714
20653
  return outBox(
20715
20654
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20716
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/brief" }),
20655
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/brief" }),
20717
20656
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Send a structured message to the user." }),
20718
20657
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /brief <message> [--proactive] [--attach file1 file2]" }),
20719
20658
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " --proactive Mark as proactive notification" }),
@@ -20815,7 +20754,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20815
20754
  if (!target) {
20816
20755
  return outBox(
20817
20756
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20818
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/explain" }),
20757
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/explain" }),
20819
20758
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Explain a file, function, or code snippet." }),
20820
20759
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /explain <file> [line-range or function-name]" })
20821
20760
  ] })
@@ -20866,7 +20805,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20866
20805
  if (!filePath) {
20867
20806
  return outBox(
20868
20807
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20869
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/editor" }),
20808
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/editor" }),
20870
20809
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Open a file in the external editor ($EDITOR or configured editor)." }),
20871
20810
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /editor <file-path>" })
20872
20811
  ] })
@@ -20915,7 +20854,7 @@ Start coordinating now. Triage the changes, then spawn your review team.`
20915
20854
  if (!description) {
20916
20855
  return outBox(
20917
20856
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
20918
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/debug" }),
20857
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/debug" }),
20919
20858
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Debug Coordinator mode \u2014 spawn workers to investigate, fix & verify in parallel." }),
20920
20859
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /debug <describe the problem, symptom, or error>" }),
20921
20860
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " " }),
@@ -21096,7 +21035,7 @@ Start coordinating now. Triage the problem, then spawn your research workers.`
21096
21035
  if (!description) {
21097
21036
  return outBox(
21098
21037
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21099
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/bug" }),
21038
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/bug" }),
21100
21039
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Alias for /debug \u2014 Debug Coordinator mode." }),
21101
21040
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /bug <describe the problem> (or use /debug)" })
21102
21041
  ] })
@@ -21325,7 +21264,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21325
21264
  if (!target) {
21326
21265
  return outBox(
21327
21266
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21328
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/refactor" }),
21267
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/refactor" }),
21329
21268
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Refactor code to improve structure without changing behavior." }),
21330
21269
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /refactor <file or description of refactoring>" })
21331
21270
  ] })
@@ -21361,7 +21300,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21361
21300
  if (!target) {
21362
21301
  return outBox(
21363
21302
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21364
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/document" }),
21303
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/document" }),
21365
21304
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Generate documentation for a file, module, or function." }),
21366
21305
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /document <file or module> [--format jsdoc|markdown|readme]" })
21367
21306
  ] })
@@ -21422,7 +21361,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21422
21361
  const next = setRuntimeConfig({ agentMode: "default" });
21423
21362
  return outBox(
21424
21363
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21425
- /* @__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" }),
21426
21365
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Switched to conversational chat mode." }),
21427
21366
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent will focus on conversation and will not execute code or edit files unless explicitly asked." }),
21428
21367
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /code to switch back to code mode." })
@@ -21433,7 +21372,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21433
21372
  const next = setRuntimeConfig({ agentMode: "default" });
21434
21373
  return outBox(
21435
21374
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21436
- /* @__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" }),
21437
21376
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Switched to code mode." }),
21438
21377
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "The agent can now edit files, run commands, and execute code." }),
21439
21378
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /chat to switch back to conversational mode." })
@@ -21443,7 +21382,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21443
21382
  if (cmd === "terminal") {
21444
21383
  return outBox(
21445
21384
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21446
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Terminal" }),
21385
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Terminal" }),
21447
21386
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Interactive terminal sessions are not yet supported as a slash command." }),
21448
21387
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use the agent's shell_command tool directly in chat instead." }),
21449
21388
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Example: "run npm test and show me the output"' })
@@ -21455,7 +21394,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21455
21394
  if (!filePath) {
21456
21395
  return outBox(
21457
21396
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21458
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/file" }),
21397
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/file" }),
21459
21398
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Create, open, or navigate to a file." }),
21460
21399
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /file <path>" })
21461
21400
  ] })
@@ -21490,7 +21429,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21490
21429
  if (!query) {
21491
21430
  return outBox(
21492
21431
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21493
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "/search" }),
21432
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "/search" }),
21494
21433
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Search the codebase for a pattern." }),
21495
21434
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /search <query> [--files <glob>]" })
21496
21435
  ] })
@@ -21525,7 +21464,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21525
21464
  if (!sub || sub === "show" || sub === "status") {
21526
21465
  return outBox(
21527
21466
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21528
- /* @__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" }),
21529
21468
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /ctx for detailed context inspection." }),
21530
21469
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /compact to manually trigger compaction." }),
21531
21470
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /snip to remove old snippets." }),
@@ -21541,7 +21480,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21541
21480
  if (cmd === "token") {
21542
21481
  return outBox(
21543
21482
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21544
- /* @__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" }),
21545
21484
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Token tracking is available via /stats and /cost for detailed session statistics." }),
21546
21485
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Auto-compact triggers at 180k tokens (threshold: 150k micro, 180k full)." }),
21547
21486
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Target after compact: 100k tokens." })
@@ -21568,7 +21507,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21568
21507
  const limit = parseInt(args[0] || "20", 10);
21569
21508
  return outBox(
21570
21509
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21571
- /* @__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" }),
21572
21511
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Recent commands are tracked in the session conversation." }),
21573
21512
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Use /export to export the full conversation as markdown." }),
21574
21513
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Session logs are stored in ~/.bluma/sessions/" })
@@ -21580,7 +21519,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21580
21519
  if (!sub || sub === "list" || sub === "show") {
21581
21520
  return outBox(
21582
21521
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21583
- /* @__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" }),
21584
21523
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "No custom aliases configured yet." }),
21585
21524
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /alias add <name> <command>" }),
21586
21525
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: " /alias remove <name>" })
@@ -21609,7 +21548,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21609
21548
  if (!name) {
21610
21549
  return outBox(
21611
21550
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21612
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Macros" }),
21551
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Macros" }),
21613
21552
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "No macros configured yet." }),
21614
21553
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /macro <name>" }),
21615
21554
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Macros are defined in ~/.bluma/settings.json under "macros".' })
@@ -21640,7 +21579,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21640
21579
  if (!name) {
21641
21580
  return outBox(
21642
21581
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21643
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Templates" }),
21582
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Templates" }),
21644
21583
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Create a project from a template." }),
21645
21584
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Usage: /template <name>" }),
21646
21585
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Available templates: react, nextjs, node-api, cli, library" })
@@ -21700,7 +21639,7 @@ Read the relevant files, identify optimization opportunities, and suggest specif
21700
21639
  if (cmd === "copy") {
21701
21640
  return outBox(
21702
21641
  /* @__PURE__ */ jsxs16(Fragment6, { children: [
21703
- /* @__PURE__ */ jsx18(Text16, { bold: true, color: BLUMA_TERMINAL.accent, children: "Copy" }),
21642
+ /* @__PURE__ */ jsx18(Text16, { bold: true, color: COMMAND_HEADER_COLOR, children: "Copy" }),
21704
21643
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "Clipboard copy is available via Ctrl+V / Cmd+V paste support." }),
21705
21644
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: "On Linux, ensure wl-clipboard or xclip is installed for clipboard support." }),
21706
21645
  /* @__PURE__ */ jsx18(Text16, { dimColor: true, children: 'Use the agent to copy specific text: "copy the last test output to clipboard"' })
@@ -22375,6 +22314,129 @@ var WorkerOverlay = ({
22375
22314
  ) });
22376
22315
  };
22377
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
+
22378
22440
  // src/app/ui/App.tsx
22379
22441
  import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
22380
22442
  var HISTORY_EMERGENCY_LIMIT = 3;
@@ -22406,6 +22468,7 @@ var AGENT_WORK_COMMANDS = /* @__PURE__ */ new Set([
22406
22468
  "chat"
22407
22469
  ]);
22408
22470
  var BLOCKING_COMMANDS = /* @__PURE__ */ new Set(["init"]);
22471
+ var COMMAND_HEADER_COLOR2 = BLUMA_TERMINAL.accent;
22409
22472
  function nextHistoryId(items) {
22410
22473
  if (items.length === 0) return HEADER_PANEL_HISTORY_ID + 1;
22411
22474
  let maxId = HEADER_PANEL_HISTORY_ID;
@@ -22599,126 +22662,26 @@ var AppComponent = ({ eventBus, sessionId, cliVersion }) => {
22599
22662
  }
22600
22663
  ];
22601
22664
  });
22602
- const initPrompt = `Your task is to initialize the BluMa project memory system.
22603
-
22604
- **Project root:** ${cwd}
22605
-
22606
- The BluMa memory system uses multiple files:
22607
-
22608
- 1. **BLUMA.md** (project root) \u2014 Main project instructions for AI agents
22609
- 2. **.bluma/rules/*.md** \u2014 Granular rules (optional, for specific concerns)
22610
- 3. **BLUMA.local.md** \u2014 Private local instructions (gitignored)
22611
-
22612
- **Step 1: Explore the project**
22613
- - List top-level files and directories
22614
- - Read package.json (name, version, description, scripts, dependencies)
22615
- - Check tsconfig.json, build configs, test configs
22616
- - Look at main entry points
22617
- - Read README.md if it exists
22618
- - Identify test framework and build system
22619
- - Note coding patterns (imports, error handling, naming)
22620
-
22621
- **Step 2: Create BLUMA.md** at ${cwd}/BLUMA.md using this EXACT format:
22622
-
22623
- \`\`\`markdown
22624
- # BLUMA.md
22625
-
22626
- This file provides guidance to BluMa CLI when working with code in this repository.
22627
-
22628
- ## Build & Development Commands
22629
-
22630
- \`\`\`bash
22631
- # Install dependencies
22632
- npm install
22633
-
22634
- # Build the project
22635
- npm run build
22636
-
22637
- # Run in development
22638
- npm start
22639
-
22640
- # Run tests
22641
- npm test
22642
-
22643
- # Run tests in watch mode
22644
- npm run test:watch
22645
-
22646
- # Lint and fix
22647
- npm run lint
22648
- npm run lint:fix
22649
- \`\`\`
22650
-
22651
- ## Code Architecture
22652
-
22653
- <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.>
22654
-
22655
- ## Key Directories
22656
-
22657
- - \`src/\` \u2014 <description>
22658
- - \`tests/\` \u2014 <description>
22659
- - \`scripts/\` \u2014 <description>
22660
-
22661
- ## Key Files
22662
-
22663
- - \`package.json\` \u2014 Project metadata, scripts, dependencies
22664
- - \`tsconfig.json\` \u2014 TypeScript configuration
22665
- - \`src/index.ts\` \u2014 Application entry point
22666
-
22667
- ## Testing
22668
-
22669
- - Test framework: <jest/vitest/etc>
22670
- - Test location: \`tests/\`
22671
- - Run tests: \`npm test\`
22672
-
22673
- ## Code Conventions
22674
-
22675
- - **Language**: TypeScript/JavaScript
22676
- - **Module system**: ES Modules or CommonJS
22677
- - **Indentation**: 2 spaces
22678
- - **Naming**: camelCase functions, PascalCase classes
22679
- - **Error handling**: <patterns>
22680
- - **Git commits**: Conventional Commits (feat:, fix:, docs:)
22681
-
22682
- ## Notes for BluMa
22683
-
22684
- <Important context for effective agent work \u2014 non-obvious patterns, critical files, deployment procedures>
22685
- \`\`\`
22686
-
22687
- **Step 3: Create .bluma/rules/ directory** with an example rule file at ${cwd}/.bluma/rules/coding-standards.md:
22688
-
22689
- \`\`\`markdown
22690
- # Coding Standards
22691
-
22692
- ## TypeScript
22693
- - Use strict mode
22694
- - Prefer interfaces over type aliases
22695
- - Export types explicitly
22696
-
22697
- ## Testing
22698
- - Write tests for all new features
22699
- - Use descriptive test names
22700
- - Mock external dependencies
22701
-
22702
- ## Git
22703
- - Use Conventional Commits
22704
- - One logical change per commit
22705
- \`\`\`
22706
-
22707
- **Step 4: Create BLUMA.local.md** at ${cwd}/BLUMA.local.md (private, project-specific):
22708
-
22709
- \`\`\`markdown
22710
- # BLUMA.local.md
22711
-
22712
- Private instructions for BluMa in this project.
22713
- This file is gitignored and should not be committed.
22714
-
22715
- Add project-specific notes here that are not suitable for the public BLUMA.md.
22716
- \`\`\`
22717
-
22718
- **Step 5: Add BLUMA.local.md to .gitignore** if .gitignore exists.
22719
-
22720
- IMPORTANT: Use the file_write tool to create all these files. Be thorough but concise. Infer conventions from the actual codebase.`;
22721
- 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
+ }
22722
22685
  return;
22723
22686
  }
22724
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.70",
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",