@braingrid/cli 0.2.52 → 0.2.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  isGhInstalled,
12
12
  isHomebrewInstalled,
13
13
  isWingetAvailable
14
- } from "./chunk-S3D6P3QC.js";
14
+ } from "./chunk-NEDKD2DE.js";
15
15
 
16
16
  // src/cli.ts
17
17
  import { existsSync } from "fs";
@@ -228,7 +228,7 @@ async function axiosWithRetry(config2, options) {
228
228
 
229
229
  // src/build-config.ts
230
230
  var BUILD_ENV = true ? "production" : process.env.NODE_ENV === "test" ? "development" : "production";
231
- var CLI_VERSION = true ? "0.2.52" : "0.0.0-test";
231
+ var CLI_VERSION = true ? "0.2.54" : "0.0.0-test";
232
232
  var PRODUCTION_CONFIG = {
233
233
  apiUrl: "https://app.braingrid.ai",
234
234
  workosAuthUrl: "https://auth.braingrid.ai",
@@ -312,42 +312,6 @@ function getConfig() {
312
312
  };
313
313
  }
314
314
 
315
- // src/utils/jwt.ts
316
- function decodeJWT(token) {
317
- try {
318
- const parts = token.split(".");
319
- if (parts.length !== 3) {
320
- return null;
321
- }
322
- const payload = parts[1];
323
- const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
324
- const padded = base64 + "==".substring(0, (4 - base64.length % 4) % 4);
325
- const decoded = Buffer.from(padded, "base64").toString("utf-8");
326
- return JSON.parse(decoded);
327
- } catch {
328
- return null;
329
- }
330
- }
331
- function isJWTExpired(token) {
332
- const payload = decodeJWT(token);
333
- if (!payload || !payload.exp) {
334
- return true;
335
- }
336
- return Date.now() >= payload.exp * 1e3;
337
- }
338
- function extractUserFromJWT(payload) {
339
- return {
340
- id: payload.sub || "",
341
- email: payload.email || "",
342
- // Try different naming conventions for first name
343
- firstName: payload.firstName || payload.first_name || payload.given_name || (payload.name ? payload.name.split(" ")[0] : ""),
344
- // Try different naming conventions for last name
345
- lastName: payload.lastName || payload.last_name || payload.family_name || (payload.name ? payload.name.split(" ").slice(1).join(" ") : ""),
346
- // Try different naming conventions for organization
347
- organizationId: payload.organizationId || payload.organization_id || payload.org_id || payload.org || "default"
348
- };
349
- }
350
-
351
315
  // src/utils/logger.ts
352
316
  import fs from "fs";
353
317
  import os from "os";
@@ -356,7 +320,7 @@ var Logger = class {
356
320
  constructor(config2 = {}) {
357
321
  const isDebugMode = process.env.DEBUG === "true";
358
322
  this.config = {
359
- logToFile: false,
323
+ logToFile: true,
360
324
  logLevel: isDebugMode ? "debug" : "info",
361
325
  // Set log level to debug when DEBUG=true
362
326
  maxFileSize: 10 * 1024 * 1024,
@@ -368,7 +332,11 @@ var Logger = class {
368
332
  };
369
333
  this.logFilePath = this.config.logFilePath || path.join(os.homedir(), ".braingrid", "logs", "braingrid-cli.log");
370
334
  if (this.config.logToFile) {
371
- this.ensureLogDirectory();
335
+ try {
336
+ this.ensureLogDirectory();
337
+ } catch {
338
+ this.config.logToFile = false;
339
+ }
372
340
  }
373
341
  }
374
342
  ensureLogDirectory() {
@@ -385,8 +353,9 @@ var Logger = class {
385
353
  const timestamp = entry.timestamp.toISOString();
386
354
  const level = entry.level.toUpperCase().padEnd(5);
387
355
  const type = entry.type.toUpperCase().padEnd(7);
356
+ const sessionStr = this.config.sessionId ? ` [${this.config.sessionId}]` : "";
388
357
  const contextStr = entry.context ? ` | ${JSON.stringify(entry.context)}` : "";
389
- return `[${timestamp}] ${level} [${type}] ${entry.message}${contextStr}`;
358
+ return `[${timestamp}] ${level}${sessionStr} [${type}] ${entry.message}${contextStr}`;
390
359
  }
391
360
  writeToFile(entry) {
392
361
  if (!this.config.logToFile) return;
@@ -508,6 +477,45 @@ function getLogger(config2) {
508
477
  return loggerInstance;
509
478
  }
510
479
 
480
+ // src/utils/jwt.ts
481
+ function decodeJWT(token) {
482
+ try {
483
+ const parts = token.split(".");
484
+ if (parts.length !== 3) {
485
+ return null;
486
+ }
487
+ const payload = parts[1];
488
+ const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
489
+ const padded = base64 + "==".substring(0, (4 - base64.length % 4) % 4);
490
+ const decoded = Buffer.from(padded, "base64").toString("utf-8");
491
+ return JSON.parse(decoded);
492
+ } catch (error) {
493
+ getLogger().debug("[JWT] Failed to decode token", {
494
+ error: error instanceof Error ? error.message : String(error)
495
+ });
496
+ return null;
497
+ }
498
+ }
499
+ function isJWTExpired(token) {
500
+ const payload = decodeJWT(token);
501
+ if (!payload || !payload.exp) {
502
+ return true;
503
+ }
504
+ return Date.now() >= payload.exp * 1e3;
505
+ }
506
+ function extractUserFromJWT(payload) {
507
+ return {
508
+ id: payload.sub || "",
509
+ email: payload.email || "",
510
+ // Try different naming conventions for first name
511
+ firstName: payload.firstName || payload.first_name || payload.given_name || (payload.name ? payload.name.split(" ")[0] : ""),
512
+ // Try different naming conventions for last name
513
+ lastName: payload.lastName || payload.last_name || payload.family_name || (payload.name ? payload.name.split(" ").slice(1).join(" ") : ""),
514
+ // Try different naming conventions for organization
515
+ organizationId: payload.organizationId || payload.organization_id || payload.org_id || payload.org || "default"
516
+ };
517
+ }
518
+
511
519
  // src/services/credential-store.ts
512
520
  import crypto from "crypto";
513
521
  import Conf from "conf";
@@ -1164,11 +1172,17 @@ var BraingridAuth = class {
1164
1172
  }
1165
1173
  }
1166
1174
  return true;
1167
- } catch {
1175
+ } catch (error) {
1176
+ this.logger.debug("[AUTH] isAuthenticated error", {
1177
+ error: error instanceof Error ? error.message : String(error)
1178
+ });
1168
1179
  try {
1169
1180
  const session = await this.getStoredSession();
1170
1181
  return session !== null && !this.isSessionExpired(session);
1171
- } catch {
1182
+ } catch (error2) {
1183
+ this.logger.debug("[AUTH] isAuthenticated fallback failed", {
1184
+ error: error2 instanceof Error ? error2.message : String(error2)
1185
+ });
1172
1186
  return false;
1173
1187
  }
1174
1188
  }
@@ -1204,7 +1218,10 @@ var BraingridAuth = class {
1204
1218
  session.user = user;
1205
1219
  await this.storeSession(session);
1206
1220
  return user;
1207
- } catch {
1221
+ } catch (error) {
1222
+ this.logger.debug("[AUTH] getCurrentUser failed", {
1223
+ error: error instanceof Error ? error.message : String(error)
1224
+ });
1208
1225
  return null;
1209
1226
  }
1210
1227
  }
@@ -1212,7 +1229,10 @@ var BraingridAuth = class {
1212
1229
  try {
1213
1230
  const session = await this.getStoredSession();
1214
1231
  return session !== null && !this.isSessionExpired(session);
1215
- } catch {
1232
+ } catch (error) {
1233
+ this.logger.debug("[AUTH] hasStoredSession failed", {
1234
+ error: error instanceof Error ? error.message : String(error)
1235
+ });
1216
1236
  return false;
1217
1237
  }
1218
1238
  }
@@ -1233,7 +1253,10 @@ var BraingridAuth = class {
1233
1253
  updated_at: new Date(session.updated_at),
1234
1254
  login_time: session.login_time ? new Date(session.login_time) : void 0
1235
1255
  };
1236
- } catch {
1256
+ } catch (error) {
1257
+ this.logger.debug("[AUTH] Failed to parse stored session", {
1258
+ error: error instanceof Error ? error.message : String(error)
1259
+ });
1237
1260
  return null;
1238
1261
  }
1239
1262
  }
@@ -1576,7 +1599,10 @@ var BraingridAuth = class {
1576
1599
  async getStoredGitHubToken() {
1577
1600
  try {
1578
1601
  return await credentialStore.getPassword(KEYCHAIN_SERVICE, GITHUB_KEYCHAIN_ACCOUNT);
1579
- } catch {
1602
+ } catch (error) {
1603
+ this.logger.debug("[AUTH] Failed to retrieve GitHub token", {
1604
+ error: error instanceof Error ? error.message : String(error)
1605
+ });
1580
1606
  return null;
1581
1607
  }
1582
1608
  }
@@ -1613,7 +1639,10 @@ var BraingridAuth = class {
1613
1639
  user,
1614
1640
  scopes
1615
1641
  };
1616
- } catch {
1642
+ } catch (error) {
1643
+ this.logger.debug("[AUTH] GitHub token validation failed", {
1644
+ error: error instanceof Error ? error.message : String(error)
1645
+ });
1617
1646
  return { valid: false };
1618
1647
  }
1619
1648
  }
@@ -1822,9 +1851,25 @@ function formatError(error, context) {
1822
1851
  return formatAxiosError(error, context);
1823
1852
  }
1824
1853
  if (error instanceof Error) {
1825
- return chalk2.red(`\u274C ${error.message}`);
1854
+ const logger4 = getLogger();
1855
+ if (error.stack) {
1856
+ logger4.debug("[ERROR] Stack trace", { stack: error.stack });
1857
+ }
1858
+ const prefix2 = context ? `Error ${context}: ` : "";
1859
+ return chalk2.red(`\u274C ${prefix2}${error.message}`);
1860
+ }
1861
+ if (error && typeof error === "object") {
1862
+ try {
1863
+ const serialized = JSON.stringify(error);
1864
+ if (serialized !== "{}") {
1865
+ const prefix2 = context ? `Error ${context}: ` : "";
1866
+ return chalk2.red(`\u274C ${prefix2}${serialized}`);
1867
+ }
1868
+ } catch {
1869
+ }
1826
1870
  }
1827
- return chalk2.red(`\u274C ${String(error)}`);
1871
+ const prefix = context ? `Error ${context}: ` : "";
1872
+ return chalk2.red(`\u274C ${prefix}${String(error)}`);
1828
1873
  }
1829
1874
  function isAxiosError(error) {
1830
1875
  return typeof error === "object" && error !== null && "isAxiosError" in error && error.isAxiosError === true;
@@ -2331,7 +2376,7 @@ async function handleCompletion(shellArg, opts) {
2331
2376
  // src/handlers/init.handlers.ts
2332
2377
  import { access as access3 } from "fs/promises";
2333
2378
  import { confirm as confirm2, input, select as select3 } from "@inquirer/prompts";
2334
- import chalk11 from "chalk";
2379
+ import chalk12 from "chalk";
2335
2380
 
2336
2381
  // src/utils/axios-with-auth.ts
2337
2382
  import axios4 from "axios";
@@ -2629,9 +2674,56 @@ var ProjectService = class {
2629
2674
  };
2630
2675
 
2631
2676
  // src/services/setup-service.ts
2632
- import * as fs2 from "fs/promises";
2633
- import * as path2 from "path";
2677
+ import * as fs3 from "fs/promises";
2678
+ import * as path3 from "path";
2634
2679
  import axios5 from "axios";
2680
+
2681
+ // src/utils/cli-logger.ts
2682
+ import * as fs2 from "fs";
2683
+ import * as path2 from "path";
2684
+ var logFile = null;
2685
+ var logStream = null;
2686
+ function initLogger(logPath) {
2687
+ if (logStream) {
2688
+ logStream.end();
2689
+ }
2690
+ const dir = path2.dirname(logPath);
2691
+ fs2.mkdirSync(dir, { recursive: true });
2692
+ logFile = logPath;
2693
+ logStream = fs2.createWriteStream(logPath, { flags: "a" });
2694
+ }
2695
+ function log(level, component, event, details = "") {
2696
+ if (!logStream) return;
2697
+ const now = /* @__PURE__ */ new Date();
2698
+ const ts = now.toLocaleTimeString("en-US", { hour12: false });
2699
+ const line = `${ts} [${level.padEnd(5)}] ${component} | ${event} | ${details}
2700
+ `;
2701
+ logStream.write(line);
2702
+ }
2703
+ function closeLogger() {
2704
+ logStream?.end();
2705
+ logStream = null;
2706
+ logFile = null;
2707
+ }
2708
+ function flushLogger() {
2709
+ return new Promise((resolve2) => {
2710
+ if (!logStream) {
2711
+ resolve2();
2712
+ return;
2713
+ }
2714
+ if (logStream.writableLength === 0) {
2715
+ resolve2();
2716
+ return;
2717
+ }
2718
+ const timeout = setTimeout(resolve2, 1e3);
2719
+ logStream.once("drain", () => {
2720
+ clearTimeout(timeout);
2721
+ resolve2();
2722
+ });
2723
+ });
2724
+ }
2725
+
2726
+ // src/services/setup-service.ts
2635
2727
  var GITHUB_OWNER = "BrainGridAI";
2636
2728
  var GITHUB_REPO = "braingrid";
2637
2729
  var GITHUB_API_BASE = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/contents`;
@@ -2664,6 +2756,12 @@ async function githubGet(url) {
2664
2756
  return await axios5.get(url, { headers });
2665
2757
  } catch (error) {
2666
2758
  if (axios5.isAxiosError(error) && error.response?.status === 401 && cachedHeaders?.Authorization) {
2759
+ log(
2760
+ "WARN",
2761
+ "github-api",
2762
+ "auth_fallback",
2763
+ "dropping expired token, retrying unauthenticated"
2764
+ );
2667
2765
  delete cachedHeaders.Authorization;
2668
2766
  return axios5.get(url, { headers: cachedHeaders });
2669
2767
  }
@@ -2683,6 +2781,7 @@ async function withRetry(fn, retries = MAX_RETRIES, delay = INITIAL_RETRY_DELAY)
2683
2781
  if (!isNetworkError) {
2684
2782
  throw error;
2685
2783
  }
2784
+ log("WARN", "github-api", "retry", `attempt=${MAX_RETRIES - retries + 1} delay=${delay}ms`);
2686
2785
  await new Promise((resolve2) => setTimeout(resolve2, delay));
2687
2786
  return withRetry(fn, retries - 1, delay * 2);
2688
2787
  }
@@ -2712,6 +2811,7 @@ function parseGitHubError(error) {
2712
2811
  }
2713
2812
  async function fetchFileFromGitHub(filePath) {
2714
2813
  return withRetry(async () => {
2814
+ log("INFO", "github-api", "fetch", `path=${filePath}`);
2715
2815
  try {
2716
2816
  const { data: response } = await githubGet(
2717
2817
  `${GITHUB_API_BASE}/${filePath}`
@@ -2768,9 +2868,9 @@ async function listGitHubDirectory(dirPath) {
2768
2868
  async function copyFileFromGitHub(sourcePath, targetPath) {
2769
2869
  try {
2770
2870
  const content = await fetchFileFromGitHub(sourcePath);
2771
- const parentDir = path2.dirname(targetPath);
2772
- await fs2.mkdir(parentDir, { recursive: true });
2773
- await fs2.writeFile(targetPath, content, { encoding: "utf8", mode: 420 });
2871
+ const parentDir = path3.dirname(targetPath);
2872
+ await fs3.mkdir(parentDir, { recursive: true });
2873
+ await fs3.writeFile(targetPath, content, { encoding: "utf8", mode: 420 });
2774
2874
  } catch (error) {
2775
2875
  const errorMessage = error instanceof Error ? error.message : String(error);
2776
2876
  throw new Error(`Failed to copy file ${sourcePath} to ${targetPath}: ${errorMessage}`);
@@ -2781,7 +2881,7 @@ async function injectContentIntoFile(targetPath, content) {
2781
2881
  let fileContent;
2782
2882
  let fileExists3 = false;
2783
2883
  try {
2784
- fileContent = await fs2.readFile(targetPath, "utf8");
2884
+ fileContent = await fs3.readFile(targetPath, "utf8");
2785
2885
  fileExists3 = true;
2786
2886
  } catch {
2787
2887
  fileContent = "";
@@ -2803,7 +2903,7 @@ async function injectContentIntoFile(targetPath, content) {
2803
2903
  const newContent = `${before}${BEGIN_MARKER}
2804
2904
  ${cleanContent}
2805
2905
  ${END_MARKER}${after}`;
2806
- await fs2.writeFile(targetPath, newContent, { encoding: "utf8" });
2906
+ await fs3.writeFile(targetPath, newContent, { encoding: "utf8" });
2807
2907
  } else {
2808
2908
  const newContent = `${fileContent}
2809
2909
 
@@ -2811,16 +2911,16 @@ ${BEGIN_MARKER}
2811
2911
  ${cleanContent}
2812
2912
  ${END_MARKER}
2813
2913
  `;
2814
- await fs2.writeFile(targetPath, newContent, { encoding: "utf8" });
2914
+ await fs3.writeFile(targetPath, newContent, { encoding: "utf8" });
2815
2915
  }
2816
2916
  } else {
2817
- const parentDir = path2.dirname(targetPath);
2818
- await fs2.mkdir(parentDir, { recursive: true });
2917
+ const parentDir = path3.dirname(targetPath);
2918
+ await fs3.mkdir(parentDir, { recursive: true });
2819
2919
  const newContent = `${BEGIN_MARKER}
2820
2920
  ${cleanContent}
2821
2921
  ${END_MARKER}
2822
2922
  `;
2823
- await fs2.writeFile(targetPath, newContent, { encoding: "utf8", mode: 420 });
2923
+ await fs3.writeFile(targetPath, newContent, { encoding: "utf8", mode: 420 });
2824
2924
  }
2825
2925
  } catch (error) {
2826
2926
  const errorMessage = error instanceof Error ? error.message : String(error);
@@ -2829,9 +2929,9 @@ ${END_MARKER}
2829
2929
  }
2830
2930
  async function installStatusLineScript(scriptContent, targetPath = ".claude/statusline.sh") {
2831
2931
  try {
2832
- const parentDir = path2.dirname(targetPath);
2833
- await fs2.mkdir(parentDir, { recursive: true });
2834
- await fs2.writeFile(targetPath, scriptContent, { encoding: "utf8", mode: 493 });
2932
+ const parentDir = path3.dirname(targetPath);
2933
+ await fs3.mkdir(parentDir, { recursive: true });
2934
+ await fs3.writeFile(targetPath, scriptContent, { encoding: "utf8", mode: 493 });
2835
2935
  } catch (error) {
2836
2936
  const errorMessage = error instanceof Error ? error.message : String(error);
2837
2937
  throw new Error(`Failed to install status line script to ${targetPath}: ${errorMessage}`);
@@ -2839,9 +2939,9 @@ async function installStatusLineScript(scriptContent, targetPath = ".claude/stat
2839
2939
  }
2840
2940
  async function installHookScript(scriptContent, targetPath) {
2841
2941
  try {
2842
- const parentDir = path2.dirname(targetPath);
2843
- await fs2.mkdir(parentDir, { recursive: true });
2844
- await fs2.writeFile(targetPath, scriptContent, { encoding: "utf8", mode: 493 });
2942
+ const parentDir = path3.dirname(targetPath);
2943
+ await fs3.mkdir(parentDir, { recursive: true });
2944
+ await fs3.writeFile(targetPath, scriptContent, { encoding: "utf8", mode: 493 });
2845
2945
  } catch (error) {
2846
2946
  const errorMessage = error instanceof Error ? error.message : String(error);
2847
2947
  throw new Error(`Failed to install hook script to ${targetPath}: ${errorMessage}`);
@@ -2850,11 +2950,17 @@ async function installHookScript(scriptContent, targetPath) {
2850
2950
  async function copyBraingridReadme(targetPath = ".braingrid/README.md") {
2851
2951
  try {
2852
2952
  const content = await fetchFileFromGitHub("claude-code/README.md");
2853
- const parentDir = path2.dirname(targetPath);
2854
- await fs2.mkdir(parentDir, { recursive: true });
2855
- await fs2.writeFile(targetPath, content, { encoding: "utf8", mode: 420 });
2953
+ const parentDir = path3.dirname(targetPath);
2954
+ await fs3.mkdir(parentDir, { recursive: true });
2955
+ await fs3.writeFile(targetPath, content, { encoding: "utf8", mode: 420 });
2856
2956
  return true;
2857
- } catch {
2957
+ } catch (error) {
2958
+ log(
2959
+ "WARN",
2960
+ "setup",
2961
+ "readme_failed",
2962
+ `error=${error instanceof Error ? error.message : String(error)}`
2963
+ );
2858
2964
  return false;
2859
2965
  }
2860
2966
  }
@@ -2920,7 +3026,7 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", stat
2920
3026
  try {
2921
3027
  let settings = {};
2922
3028
  try {
2923
- const content2 = await fs2.readFile(settingsPath, "utf8");
3029
+ const content2 = await fs3.readFile(settingsPath, "utf8");
2924
3030
  settings = JSON.parse(content2);
2925
3031
  } catch {
2926
3032
  }
@@ -2966,10 +3072,10 @@ async function updateClaudeSettings(settingsPath = ".claude/settings.json", stat
2966
3072
  ...existingHooks,
2967
3073
  ...mergedByType
2968
3074
  };
2969
- const parentDir = path2.dirname(settingsPath);
2970
- await fs2.mkdir(parentDir, { recursive: true });
3075
+ const parentDir = path3.dirname(settingsPath);
3076
+ await fs3.mkdir(parentDir, { recursive: true });
2971
3077
  const content = JSON.stringify(settings, null, " ");
2972
- await fs2.writeFile(settingsPath, content, { encoding: "utf8" });
3078
+ await fs3.writeFile(settingsPath, content, { encoding: "utf8" });
2973
3079
  } catch (error) {
2974
3080
  const errorMessage = error instanceof Error ? error.message : String(error);
2975
3081
  throw new Error(`Failed to update Claude settings at ${settingsPath}: ${errorMessage}`);
@@ -3177,7 +3283,7 @@ function getManualInstallInstructions() {
3177
3283
 
3178
3284
  // src/utils/github-repo.ts
3179
3285
  import { exec as exec3 } from "child_process";
3180
- import path3 from "path";
3286
+ import path4 from "path";
3181
3287
  import { promisify as promisify3 } from "util";
3182
3288
  var execAsync4 = promisify3(exec3);
3183
3289
  async function initGitRepo() {
@@ -3197,7 +3303,7 @@ async function isGhAuthenticated() {
3197
3303
  }
3198
3304
  }
3199
3305
  function getCurrentDirectoryName() {
3200
- return path3.basename(process.cwd());
3306
+ return path4.basename(process.cwd());
3201
3307
  }
3202
3308
  async function createGitHubRepoWithGh(name, isPrivate) {
3203
3309
  try {
@@ -3220,7 +3326,7 @@ async function createGitHubRepoWithGh(name, isPrivate) {
3220
3326
  }
3221
3327
  }
3222
3328
  async function canUseGhAutomation() {
3223
- const { isGhInstalled: isGhInstalled2 } = await import("./gh-installer-DWTEK33P.js");
3329
+ const { isGhInstalled: isGhInstalled2 } = await import("./gh-installer-T7E7SYVI.js");
3224
3330
  const ghInstalled = await isGhInstalled2();
3225
3331
  if (!ghInstalled) {
3226
3332
  return false;
@@ -3230,11 +3336,11 @@ async function canUseGhAutomation() {
3230
3336
 
3231
3337
  // src/utils/gitignore.ts
3232
3338
  import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
3233
- import path4 from "path";
3339
+ import path5 from "path";
3234
3340
  async function addBraingridTempToGitignore() {
3235
3341
  const gitRoot = await getGitRoot();
3236
3342
  if (!gitRoot) return;
3237
- const gitignorePath = path4.join(gitRoot, ".gitignore");
3343
+ const gitignorePath = path5.join(gitRoot, ".gitignore");
3238
3344
  const entry = ".braingrid/temp/";
3239
3345
  let content = "";
3240
3346
  try {
@@ -3252,9 +3358,195 @@ ${entry}
3252
3358
  await writeFile2(gitignorePath, newContent, "utf8");
3253
3359
  }
3254
3360
 
3361
+ // src/utils/jq-installer.ts
3362
+ import { exec as exec4 } from "child_process";
3363
+ import { promisify as promisify4 } from "util";
3364
+ import chalk7 from "chalk";
3365
+ var execAsync5 = promisify4(exec4);
3366
+ async function isJqInstalled() {
3367
+ return isCliInstalled("jq");
3368
+ }
3369
+ async function getJqVersion() {
3370
+ return getCliVersion("jq", "--version", (output) => {
3371
+ const match = output.match(/jq-([\d.]+)/);
3372
+ return match ? match[1] : output.trim();
3373
+ });
3374
+ }
3375
+ async function installViaHomebrew2() {
3376
+ console.log(chalk7.blue("\u{1F4E6} Installing jq via Homebrew..."));
3377
+ try {
3378
+ await execAsync5("brew install jq", {
3379
+ timeout: 3e5
3380
+ // 5 minutes
3381
+ });
3382
+ const version = await getJqVersion();
3383
+ if (!version) {
3384
+ return {
3385
+ success: false,
3386
+ message: chalk7.red("\u274C jq installation completed but jq command not found")
3387
+ };
3388
+ }
3389
+ return {
3390
+ success: true,
3391
+ message: chalk7.green(`\u2705 jq installed successfully (version ${version})!`),
3392
+ version
3393
+ };
3394
+ } catch (error) {
3395
+ const errorMsg = error instanceof Error ? error.message : String(error);
3396
+ return {
3397
+ success: false,
3398
+ message: chalk7.red("\u274C Failed to install jq via Homebrew\n\n") + chalk7.dim("Error: ") + errorMsg + "\n\n" + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3399
+ };
3400
+ }
3401
+ }
3402
+ async function installViaWebi() {
3403
+ console.log(chalk7.blue("\u{1F4E6} Installing jq via Webi..."));
3404
+ console.log(chalk7.dim("This will install jq to ~/.local/bin/\n"));
3405
+ try {
3406
+ await execAsync5("curl -sS https://webi.sh/jq | sh", {
3407
+ timeout: 3e5
3408
+ // 5 minutes
3409
+ });
3410
+ const version = await getJqVersion();
3411
+ if (!version) {
3412
+ return {
3413
+ success: true,
3414
+ message: chalk7.green("\u2705 jq installed successfully!\n") + chalk7.dim(
3415
+ "Note: You may need to restart your terminal for the jq command to be available."
3416
+ )
3417
+ };
3418
+ }
3419
+ return {
3420
+ success: true,
3421
+ message: chalk7.green(`\u2705 jq installed successfully (version ${version})!`),
3422
+ version
3423
+ };
3424
+ } catch (error) {
3425
+ const errorMsg = error instanceof Error ? error.message : String(error);
3426
+ return {
3427
+ success: false,
3428
+ message: chalk7.red("\u274C Failed to install jq via Webi\n\n") + chalk7.dim("Error: ") + errorMsg + "\n\n" + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3429
+ };
3430
+ }
3431
+ }
3432
+ async function installJqMacOS() {
3433
+ const hasHomebrew = await isHomebrewInstalled();
3434
+ if (hasHomebrew) {
3435
+ return installViaHomebrew2();
3436
+ }
3437
+ return installViaWebi();
3438
+ }
3439
+ async function installJqWindows() {
3440
+ const hasWinget = await isWingetAvailable();
3441
+ if (!hasWinget) {
3442
+ return {
3443
+ success: false,
3444
+ message: chalk7.red("\u274C winget is not available on this system\n\n") + chalk7.dim("winget is included in Windows 10 (version 1809+) and Windows 11.\n") + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3445
+ };
3446
+ }
3447
+ console.log(chalk7.blue("\u{1F4E6} Installing jq via winget..."));
3448
+ try {
3449
+ await execAsync5("winget install --id jqlang.jq --silent", {
3450
+ timeout: 3e5
3451
+ // 5 minutes
3452
+ });
3453
+ const version = await getJqVersion();
3454
+ if (!version) {
3455
+ return {
3456
+ success: false,
3457
+ message: chalk7.red("\u274C jq installation completed but jq command not found")
3458
+ };
3459
+ }
3460
+ return {
3461
+ success: true,
3462
+ message: chalk7.green(`\u2705 jq installed successfully (version ${version})!`),
3463
+ version
3464
+ };
3465
+ } catch (error) {
3466
+ const errorMsg = error instanceof Error ? error.message : String(error);
3467
+ return {
3468
+ success: false,
3469
+ message: chalk7.red("\u274C Failed to install jq via winget\n\n") + chalk7.dim("Error: ") + errorMsg + "\n\n" + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3470
+ };
3471
+ }
3472
+ }
3473
+ async function installJqLinux() {
3474
+ const packageManager = await detectLinuxPackageManager();
3475
+ if (!packageManager) {
3476
+ return {
3477
+ success: false,
3478
+ message: chalk7.red("\u274C Could not detect a supported package manager\n\n") + chalk7.dim("Supported package managers: apt, dnf, yum, pacman\n") + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3479
+ };
3480
+ }
3481
+ console.log(chalk7.blue(`\u{1F4E6} Installing jq via ${packageManager.name}...`));
3482
+ console.log(chalk7.dim("This may prompt for your sudo password.\n"));
3483
+ try {
3484
+ let installCommand;
3485
+ switch (packageManager.name) {
3486
+ case "apt":
3487
+ installCommand = "sudo apt update && sudo apt install jq -y";
3488
+ break;
3489
+ case "dnf":
3490
+ installCommand = "sudo dnf install jq -y";
3491
+ break;
3492
+ case "yum":
3493
+ installCommand = "sudo yum install jq -y";
3494
+ break;
3495
+ case "pacman":
3496
+ installCommand = "sudo pacman -S --noconfirm jq";
3497
+ break;
3498
+ default:
3499
+ return {
3500
+ success: false,
3501
+ message: chalk7.red(`\u274C Unsupported package manager: ${packageManager.name}`)
3502
+ };
3503
+ }
3504
+ await execAsync5(installCommand, {
3505
+ timeout: 3e5
3506
+ // 5 minutes
3507
+ });
3508
+ const version = await getJqVersion();
3509
+ if (!version) {
3510
+ return {
3511
+ success: false,
3512
+ message: chalk7.red("\u274C jq installation completed but jq command not found")
3513
+ };
3514
+ }
3515
+ return {
3516
+ success: true,
3517
+ message: chalk7.green(`\u2705 jq installed successfully (version ${version})!`),
3518
+ version
3519
+ };
3520
+ } catch (error) {
3521
+ const errorMsg = error instanceof Error ? error.message : String(error);
3522
+ return {
3523
+ success: false,
3524
+ message: chalk7.red("\u274C Failed to install jq\n\n") + chalk7.dim("Error: ") + errorMsg + "\n\n" + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3525
+ };
3526
+ }
3527
+ }
3528
+ async function installJq() {
3529
+ const platform = process.platform;
3530
+ switch (platform) {
3531
+ case "darwin":
3532
+ return installJqMacOS();
3533
+ case "win32":
3534
+ return installJqWindows();
3535
+ case "linux":
3536
+ return installJqLinux();
3537
+ default:
3538
+ return {
3539
+ success: false,
3540
+ message: chalk7.red(`\u274C Unsupported platform: ${platform}
3541
+
3542
+ `) + chalk7.dim("Please install jq manually from: ") + chalk7.cyan("https://jqlang.github.io/jq/download/")
3543
+ };
3544
+ }
3545
+ }
3546
+
3255
3547
  // src/utils/local-store.ts
3256
- import fs3 from "fs";
3257
- import path5 from "path";
3548
+ import fs4 from "fs";
3549
+ import path6 from "path";
3258
3550
 
3259
3551
  // src/types/local-project.ts
3260
3552
  import { z } from "zod";
@@ -3284,28 +3576,28 @@ async function getDefaultCwd() {
3284
3576
  }
3285
3577
  async function getBraingridDir(cwd) {
3286
3578
  const dir = cwd ?? await getDefaultCwd();
3287
- return path5.join(dir, BRAINGRID_DIR);
3579
+ return path6.join(dir, BRAINGRID_DIR);
3288
3580
  }
3289
3581
  async function getProjectConfigPath(cwd) {
3290
3582
  const braingridDir = await getBraingridDir(cwd);
3291
- return path5.join(braingridDir, PROJECT_CONFIG_FILE);
3583
+ return path6.join(braingridDir, PROJECT_CONFIG_FILE);
3292
3584
  }
3293
3585
  async function projectConfigExists(cwd) {
3294
3586
  const configPath = await getProjectConfigPath(cwd);
3295
- return fs3.existsSync(configPath);
3587
+ return fs4.existsSync(configPath);
3296
3588
  }
3297
3589
  async function ensureBraingridDir(cwd) {
3298
3590
  const dir = await getBraingridDir(cwd);
3299
- if (!fs3.existsSync(dir)) {
3300
- fs3.mkdirSync(dir, { recursive: true });
3591
+ if (!fs4.existsSync(dir)) {
3592
+ fs4.mkdirSync(dir, { recursive: true });
3301
3593
  }
3302
3594
  }
3303
3595
  async function loadProjectConfig(cwd) {
3304
3596
  const configPath = await getProjectConfigPath(cwd);
3305
- if (!fs3.existsSync(configPath)) {
3597
+ if (!fs4.existsSync(configPath)) {
3306
3598
  throw new Error(`Project not initialized. Run 'braingrid init' to initialize this repository.`);
3307
3599
  }
3308
- const content = fs3.readFileSync(configPath, "utf8");
3600
+ const content = fs4.readFileSync(configPath, "utf8");
3309
3601
  const data = JSON.parse(content);
3310
3602
  return LocalProjectConfigSchema.parse(data);
3311
3603
  }
@@ -3313,7 +3605,7 @@ async function saveProjectConfig(config2, cwd) {
3313
3605
  await ensureBraingridDir(cwd);
3314
3606
  const configPath = await getProjectConfigPath(cwd);
3315
3607
  const content = JSON.stringify(config2, null, 2);
3316
- fs3.writeFileSync(configPath, content, "utf8");
3608
+ fs4.writeFileSync(configPath, content, "utf8");
3317
3609
  }
3318
3610
  async function getLocalProjectId(cwd) {
3319
3611
  try {
@@ -3358,7 +3650,7 @@ async function getRepositoryId(repositoryService, owner, name) {
3358
3650
  }
3359
3651
 
3360
3652
  // src/utils/spinner.ts
3361
- import chalk7 from "chalk";
3653
+ import chalk8 from "chalk";
3362
3654
  var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3363
3655
  async function waitWithSpinner(message, checkFn, intervalMs = 3e3, maxAttempts = 60) {
3364
3656
  let frameIndex = 0;
@@ -3366,7 +3658,7 @@ async function waitWithSpinner(message, checkFn, intervalMs = 3e3, maxAttempts =
3366
3658
  const updateSpinner = () => {
3367
3659
  const frame = SPINNER_FRAMES[frameIndex];
3368
3660
  frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;
3369
- process.stdout.write(`\r${chalk7.cyan(frame)} ${message}...`);
3661
+ process.stdout.write(`\r${chalk8.cyan(frame)} ${message}...`);
3370
3662
  };
3371
3663
  spinnerInterval = setInterval(updateSpinner, 100);
3372
3664
  try {
@@ -3390,7 +3682,7 @@ async function waitWithSpinner(message, checkFn, intervalMs = 3e3, maxAttempts =
3390
3682
  throw error;
3391
3683
  }
3392
3684
  }
3393
- function showSpinner(message, color = chalk7.cyan) {
3685
+ function showSpinner(message, color = chalk8.cyan) {
3394
3686
  let frameIndex = 0;
3395
3687
  const interval = setInterval(() => {
3396
3688
  const frame = SPINNER_FRAMES[frameIndex];
@@ -3404,7 +3696,7 @@ function showSpinner(message, color = chalk7.cyan) {
3404
3696
  }
3405
3697
 
3406
3698
  // src/utils/update-checker.ts
3407
- import chalk8 from "chalk";
3699
+ import chalk9 from "chalk";
3408
3700
 
3409
3701
  // src/utils/version.ts
3410
3702
  import axios6 from "axios";
@@ -3496,7 +3788,7 @@ async function checkAndShowUpdateWarning() {
3496
3788
  try {
3497
3789
  const { available, currentVersion, latestVersion } = await isUpdateAvailable();
3498
3790
  if (available && latestVersion) {
3499
- const warning = "\n" + chalk8.yellow(`\u26A0\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}`) + "\n" + chalk8.dim(` Run \`${getUpdateCommand()}\` to update`) + "\n";
3791
+ const warning = "\n" + chalk9.yellow(`\u26A0\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}`) + "\n" + chalk9.dim(` Run \`${getUpdateCommand()}\` to update`) + "\n";
3500
3792
  console.log(warning);
3501
3793
  }
3502
3794
  } catch {
@@ -3504,13 +3796,13 @@ async function checkAndShowUpdateWarning() {
3504
3796
  }
3505
3797
 
3506
3798
  // src/handlers/setup.handlers.ts
3507
- import * as fs4 from "fs/promises";
3508
- import * as path6 from "path";
3799
+ import * as fs5 from "fs/promises";
3800
+ import * as path7 from "path";
3509
3801
  import { select } from "@inquirer/prompts";
3510
- import chalk9 from "chalk";
3802
+ import chalk10 from "chalk";
3511
3803
  async function fileExists(filePath) {
3512
3804
  try {
3513
- await fs4.access(filePath);
3805
+ await fs5.access(filePath);
3514
3806
  return true;
3515
3807
  } catch {
3516
3808
  return false;
@@ -3523,7 +3815,7 @@ async function getFileList(sourcePaths, targetPaths) {
3523
3815
  const items = await listGitHubDirectory(sourceDir);
3524
3816
  for (const item of items) {
3525
3817
  if (item.type === "file") {
3526
- const itemTargetPath = path6.join(targetDir, item.name);
3818
+ const itemTargetPath = path7.join(targetDir, item.name);
3527
3819
  const exists = await fileExists(itemTargetPath);
3528
3820
  operations.push({
3529
3821
  type: "copy",
@@ -3533,13 +3825,19 @@ async function getFileList(sourcePaths, targetPaths) {
3533
3825
  dirIndex
3534
3826
  });
3535
3827
  } else if (item.type === "dir") {
3536
- const itemTargetPath = path6.join(targetDir, item.name);
3828
+ const itemTargetPath = path7.join(targetDir, item.name);
3537
3829
  await processDirectory(item.path, itemTargetPath, dirIndex);
3538
3830
  }
3539
3831
  }
3540
3832
  } catch (error) {
3833
+ log(
3834
+ "WARN",
3835
+ "setup",
3836
+ "list_dir_failed",
3837
+ `source=${sourceDir} error=${error instanceof Error ? error.message : String(error)}`
3838
+ );
3541
3839
  console.warn(
3542
- chalk9.yellow(`\u26A0\uFE0F Could not list directory: ${sourceDir}`),
3840
+ chalk10.yellow(`\u26A0\uFE0F Could not list directory: ${sourceDir}`),
3543
3841
  error instanceof Error ? error.message : String(error)
3544
3842
  );
3545
3843
  }
@@ -3550,28 +3848,28 @@ async function getFileList(sourcePaths, targetPaths) {
3550
3848
  return operations;
3551
3849
  }
3552
3850
  function displayInstallationPlan(operations, injectionFile) {
3553
- console.log(chalk9.bold("\n\u{1F4CB} Installation Plan:\n"));
3554
- console.log(chalk9.cyan(" Content Injection:"));
3555
- console.log(chalk9.dim(` ${injectionFile}`));
3851
+ console.log(chalk10.bold("\n\u{1F4CB} Installation Plan:\n"));
3852
+ console.log(chalk10.cyan(" Content Injection:"));
3853
+ console.log(chalk10.dim(` ${injectionFile}`));
3556
3854
  const newFiles = operations.filter((op) => !op.exists);
3557
3855
  const existingFiles = operations.filter((op) => op.exists);
3558
3856
  if (newFiles.length > 0) {
3559
- console.log(chalk9.cyan("\n New Files:"));
3857
+ console.log(chalk10.cyan("\n New Files:"));
3560
3858
  for (const op of newFiles) {
3561
- console.log(chalk9.dim(` ${op.targetPath}`));
3859
+ console.log(chalk10.dim(` ${op.targetPath}`));
3562
3860
  }
3563
3861
  }
3564
3862
  if (existingFiles.length > 0) {
3565
- console.log(chalk9.yellow("\n Existing Files (will prompt):"));
3863
+ console.log(chalk10.yellow("\n Existing Files (will prompt):"));
3566
3864
  for (const op of existingFiles) {
3567
- console.log(chalk9.dim(` ${op.targetPath}`));
3865
+ console.log(chalk10.dim(` ${op.targetPath}`));
3568
3866
  }
3569
3867
  }
3570
3868
  console.log("");
3571
3869
  }
3572
3870
  async function promptForConflict(filePath) {
3573
3871
  const answer = await select({
3574
- message: chalk9.yellow(`File exists: ${filePath}`),
3872
+ message: chalk10.yellow(`File exists: ${filePath}`),
3575
3873
  choices: [
3576
3874
  { name: "[A]ll - Overwrite all remaining", value: "all" },
3577
3875
  { name: "[O]verwrite - Replace this file", value: "overwrite" },
@@ -3591,6 +3889,7 @@ async function installFiles(operations, force, dirCount) {
3591
3889
  if (response === "quit") {
3592
3890
  return { installedPerDir, skipped, cancelled: true };
3593
3891
  } else if (response === "skip") {
3892
+ log("INFO", "setup", "skip_file", `target=${operation.targetPath} reason=user_skip`);
3594
3893
  skipped++;
3595
3894
  continue;
3596
3895
  } else if (response === "all") {
@@ -3599,12 +3898,19 @@ async function installFiles(operations, force, dirCount) {
3599
3898
  }
3600
3899
  try {
3601
3900
  await copyFileFromGitHub(operation.sourcePath, operation.targetPath);
3901
+ log("INFO", "setup", "copy_file", `target=${operation.targetPath}`);
3602
3902
  if (operation.dirIndex !== void 0) {
3603
3903
  installedPerDir[operation.dirIndex]++;
3604
3904
  }
3605
3905
  } catch (error) {
3906
+ log(
3907
+ "ERROR",
3908
+ "setup",
3909
+ "copy_file_failed",
3910
+ `target=${operation.targetPath} error=${error instanceof Error ? error.message : String(error)}`
3911
+ );
3606
3912
  console.error(
3607
- chalk9.red(`Failed to copy ${operation.targetPath}:`),
3913
+ chalk10.red(`Failed to copy ${operation.targetPath}:`),
3608
3914
  error instanceof Error ? error.message : String(error)
3609
3915
  );
3610
3916
  skipped++;
@@ -3613,7 +3919,14 @@ async function installFiles(operations, force, dirCount) {
3613
3919
  return { installedPerDir, skipped, cancelled: false };
3614
3920
  }
3615
3921
  async function _handleSetup(config2, opts) {
3616
- console.log(chalk9.bold(`\u{1F680} Setting up ${config2.name} integration...
3922
+ initLogger(".braingrid/temp/setup-debug.log");
3923
+ log(
3924
+ "INFO",
3925
+ "setup",
3926
+ "start",
3927
+ `integration=${config2.name} force=${opts.force} dry_run=${opts.dryRun}`
3928
+ );
3929
+ console.log(chalk10.bold(`\u{1F680} Setting up ${config2.name} integration...
3617
3930
  `));
3618
3931
  const operations = await getFileList(config2.sourceDirs, config2.targetDirs);
3619
3932
  const injectionFileExists = await fileExists(config2.injection.targetFile);
@@ -3630,7 +3943,7 @@ async function _handleSetup(config2, opts) {
3630
3943
  if (opts.dryRun) {
3631
3944
  return {
3632
3945
  success: true,
3633
- message: chalk9.green("\u2705 Dry-run complete. No files were modified.\n\n") + chalk9.dim(`Would install ${operations.length} files.`)
3946
+ message: chalk10.green("\u2705 Dry-run complete. No files were modified.\n\n") + chalk10.dim(`Would install ${operations.length} files.`)
3634
3947
  };
3635
3948
  }
3636
3949
  const copyOps = operations.filter((op) => op.type === "copy");
@@ -3639,20 +3952,30 @@ async function _handleSetup(config2, opts) {
3639
3952
  const totalInstalled = result.installedPerDir.reduce((a, b) => a + b, 0);
3640
3953
  return {
3641
3954
  success: false,
3642
- message: chalk9.yellow("\u26A0\uFE0F Installation cancelled.\n\n") + chalk9.dim(`Installed: ${totalInstalled}, Skipped: ${result.skipped}`),
3955
+ message: chalk10.yellow("\u26A0\uFE0F Installation cancelled.\n\n") + chalk10.dim(`Installed: ${totalInstalled}, Skipped: ${result.skipped}`),
3643
3956
  code: "CANCELLED"
3644
3957
  };
3645
3958
  }
3646
3959
  try {
3647
3960
  const content = await fetchFileFromGitHub(config2.injection.sourceFile);
3648
3961
  await injectContentIntoFile(config2.injection.targetFile, content);
3962
+ log("INFO", "setup", "inject", `target=${config2.injection.targetFile}`);
3649
3963
  } catch (error) {
3964
+ log(
3965
+ "ERROR",
3966
+ "setup",
3967
+ "inject_failed",
3968
+ `target=${config2.injection.targetFile} error=${error instanceof Error ? error.message : String(error)}`
3969
+ );
3650
3970
  console.error(
3651
- chalk9.red(`Failed to inject content into ${config2.injection.targetFile}:`),
3971
+ chalk10.red(`Failed to inject content into ${config2.injection.targetFile}:`),
3652
3972
  error instanceof Error ? error.message : String(error)
3653
3973
  );
3654
3974
  }
3655
- await copyBraingridReadme();
3975
+ const readmeCopied = await copyBraingridReadme();
3976
+ if (readmeCopied) {
3977
+ log("INFO", "setup", "readme", "path=.braingrid/README.md");
3978
+ }
3656
3979
  return {
3657
3980
  success: true,
3658
3981
  data: {
@@ -3667,14 +3990,14 @@ function buildSuccessMessage(config2, installedPerDir, extras) {
3667
3990
  const count = installedPerDir[i] ?? 0;
3668
3991
  if (count === 0) continue;
3669
3992
  const { label } = config2.dirLabels[i];
3670
- dirLines += chalk9.dim(` ${label}: ${count}
3993
+ dirLines += chalk10.dim(` ${label}: ${count}
3671
3994
  `);
3672
3995
  }
3673
- return chalk9.green(`\u2705 ${config2.name} integration installed successfully!
3996
+ return chalk10.green(`\u2705 ${config2.name} integration installed successfully!
3674
3997
 
3675
- `) + chalk9.dim("Files installed:\n") + dirLines + extras + chalk9.dim(` Content injected into: ${config2.injection.targetFile}
3998
+ `) + chalk10.dim("Files installed:\n") + dirLines + extras + chalk10.dim(` Content injected into: ${config2.injection.targetFile}
3676
3999
 
3677
- `) + chalk9.dim("Next, try:\n") + chalk9.dim(" /build REQ-X \u2192 build a requirement\n") + chalk9.dim(' /specify "add two-factor auth" \u2192 specify a requirement\n') + chalk9.dim(" Learn more: ") + chalk9.cyan(config2.docsUrl);
4000
+ `) + chalk10.dim("Next, try:\n") + chalk10.dim(" /build REQ-X \u2192 build a requirement\n") + chalk10.dim(' /specify "add two-factor auth" \u2192 specify a requirement\n') + chalk10.dim(" Learn more: ") + chalk10.cyan(config2.docsUrl);
3678
4001
  }
3679
4002
  function isSetupResult(result) {
3680
4003
  return "data" in result && result.success === true && !("message" in result);
@@ -3720,17 +4043,31 @@ async function handleSetupClaudeCode(opts) {
3720
4043
  const scriptContent = await fetchFileFromGitHub("claude-code/statusline.sh");
3721
4044
  await installStatusLineScript(scriptContent);
3722
4045
  statusLineInstalled = true;
4046
+ log("INFO", "setup", "statusline", "path=.claude/statusline.sh");
3723
4047
  } catch (error) {
4048
+ log(
4049
+ "ERROR",
4050
+ "setup",
4051
+ "statusline_failed",
4052
+ `error=${error instanceof Error ? error.message : String(error)}`
4053
+ );
3724
4054
  console.error(
3725
- chalk9.yellow("\u26A0\uFE0F Failed to install status line script:"),
4055
+ chalk10.yellow("\u26A0\uFE0F Failed to install status line script:"),
3726
4056
  error instanceof Error ? error.message : String(error)
3727
4057
  );
3728
4058
  }
3729
4059
  try {
3730
4060
  await updateClaudeSettings();
4061
+ log("INFO", "setup", "settings", "path=.claude/settings.json");
3731
4062
  } catch (error) {
4063
+ log(
4064
+ "ERROR",
4065
+ "setup",
4066
+ "settings_failed",
4067
+ `error=${error instanceof Error ? error.message : String(error)}`
4068
+ );
3732
4069
  console.error(
3733
- chalk9.yellow("\u26A0\uFE0F Failed to update Claude settings:"),
4070
+ chalk10.yellow("\u26A0\uFE0F Failed to update Claude settings:"),
3734
4071
  error instanceof Error ? error.message : String(error)
3735
4072
  );
3736
4073
  }
@@ -3746,25 +4083,44 @@ async function handleSetupClaudeCode(opts) {
3746
4083
  const content = await fetchFileFromGitHub(`claude-code/hooks/${script}`);
3747
4084
  await installHookScript(content, `.claude/hooks/${script}`);
3748
4085
  installedHooks.push(script);
4086
+ log("INFO", "setup", "hook", `script=${script}`);
3749
4087
  } catch (error) {
4088
+ log(
4089
+ "ERROR",
4090
+ "setup",
4091
+ "hook_failed",
4092
+ `script=${script} error=${error instanceof Error ? error.message : String(error)}`
4093
+ );
3750
4094
  console.error(
3751
- chalk9.yellow(`\u26A0\uFE0F Failed to install hook ${script}:`),
4095
+ chalk10.yellow(`\u26A0\uFE0F Failed to install hook ${script}:`),
3752
4096
  error instanceof Error ? error.message : String(error)
3753
4097
  );
3754
4098
  }
3755
4099
  }
3756
- const statusLineMessage = statusLineInstalled ? chalk9.dim(" Status line: .claude/statusline.sh\n") : "";
3757
- const hooksMessage = installedHooks.map((s) => chalk9.dim(` Hook script: .claude/hooks/${s}
4100
+ const statusLineMessage = statusLineInstalled ? chalk10.dim(" Status line: .claude/statusline.sh\n") : "";
4101
+ const hooksMessage = installedHooks.map((s) => chalk10.dim(` Hook script: .claude/hooks/${s}
3758
4102
  `)).join("");
4103
+ const totalInstalled = displayPerDir.reduce((a, b) => a + b, 0);
4104
+ log(
4105
+ "INFO",
4106
+ "setup",
4107
+ "complete",
4108
+ `installed=${totalInstalled} skipped=${setupResult.data.skipped} hooks=${installedHooks.length}`
4109
+ );
4110
+ await flushLogger();
4111
+ closeLogger();
3759
4112
  return {
3760
4113
  success: true,
3761
4114
  message: buildSuccessMessage(config2, displayPerDir, statusLineMessage + hooksMessage)
3762
4115
  };
3763
4116
  } catch (error) {
3764
4117
  const errorMessage = error instanceof Error ? error.message : String(error);
4118
+ log("ERROR", "setup", "fatal", `error=${errorMessage}`);
4119
+ await flushLogger();
4120
+ closeLogger();
3765
4121
  return {
3766
4122
  success: false,
3767
- message: chalk9.red(`\u274C Setup failed: ${errorMessage}`)
4123
+ message: chalk10.red(`\u274C Setup failed: ${errorMessage}`)
3768
4124
  };
3769
4125
  }
3770
4126
  }
@@ -3788,16 +4144,23 @@ async function handleSetupCursor(opts) {
3788
4144
  if (!isSetupResult(setupResult)) {
3789
4145
  return setupResult;
3790
4146
  }
3791
- const { installedPerDir } = setupResult.data;
4147
+ const { installedPerDir, skipped } = setupResult.data;
4148
+ const totalInstalled = installedPerDir.reduce((a, b) => a + b, 0);
4149
+ log("INFO", "setup", "complete", `installed=${totalInstalled} skipped=${skipped}`);
4150
+ await flushLogger();
4151
+ closeLogger();
3792
4152
  return {
3793
4153
  success: true,
3794
4154
  message: buildSuccessMessage(config2, installedPerDir, "")
3795
4155
  };
3796
4156
  } catch (error) {
3797
4157
  const errorMessage = error instanceof Error ? error.message : String(error);
4158
+ log("ERROR", "setup", "fatal", `error=${errorMessage}`);
4159
+ await flushLogger();
4160
+ closeLogger();
3798
4161
  return {
3799
4162
  success: false,
3800
- message: chalk9.red(`\u274C Setup failed: ${errorMessage}`)
4163
+ message: chalk10.red(`\u274C Setup failed: ${errorMessage}`)
3801
4164
  };
3802
4165
  }
3803
4166
  }
@@ -3805,7 +4168,7 @@ async function handleSetupCursor(opts) {
3805
4168
  // src/handlers/update.handlers.ts
3806
4169
  import { execSync as execSync3 } from "child_process";
3807
4170
  import { confirm } from "@inquirer/prompts";
3808
- import chalk10 from "chalk";
4171
+ import chalk11 from "chalk";
3809
4172
 
3810
4173
  // src/utils/package-manager.ts
3811
4174
  import { execSync as execSync2 } from "child_process";
@@ -3921,7 +4284,7 @@ function runSetupSubprocess(subcommand) {
3921
4284
  return output.toString();
3922
4285
  } catch (error) {
3923
4286
  const msg = error instanceof Error ? error.message : String(error);
3924
- return chalk10.yellow(`\u26A0\uFE0F Setup ${subcommand} failed: ${msg}`);
4287
+ return chalk11.yellow(`\u26A0\uFE0F Setup ${subcommand} failed: ${msg}`);
3925
4288
  }
3926
4289
  }
3927
4290
  async function promptForIdeUpdates() {
@@ -3954,17 +4317,17 @@ ${runSetupSubprocess("cursor")}`;
3954
4317
  async function handleUpdate(opts) {
3955
4318
  try {
3956
4319
  const currentVersion = getCurrentVersion();
3957
- let output = chalk10.bold.cyan("\n\u{1F504} BrainGrid CLI Update\n\n");
3958
- output += `${chalk10.bold("Current version:")} ${currentVersion}
4320
+ let output = chalk11.bold.cyan("\n\u{1F504} BrainGrid CLI Update\n\n");
4321
+ output += `${chalk11.bold("Current version:")} ${currentVersion}
3959
4322
  `;
3960
- output += chalk10.dim("Checking for updates...\n");
4323
+ output += chalk11.dim("Checking for updates...\n");
3961
4324
  const latestVersion = await getLatestVersion();
3962
- output += `${chalk10.bold("Latest version:")} ${latestVersion}
4325
+ output += `${chalk11.bold("Latest version:")} ${latestVersion}
3963
4326
 
3964
4327
  `;
3965
4328
  const comparison = compareVersions(currentVersion, latestVersion);
3966
4329
  if (comparison === 0) {
3967
- output += chalk10.green("\u2705 You are already on the latest version!\n");
4330
+ output += chalk11.green("\u2705 You are already on the latest version!\n");
3968
4331
  console.log(output);
3969
4332
  await copyBraingridReadme();
3970
4333
  await addBraingridTempToGitignore();
@@ -3976,32 +4339,32 @@ async function handleUpdate(opts) {
3976
4339
  };
3977
4340
  }
3978
4341
  if (comparison > 0) {
3979
- output += chalk10.yellow("\u26A0\uFE0F You are on a newer version than what is published.\n");
3980
- output += chalk10.dim(" This is expected if you are developing locally.\n");
4342
+ output += chalk11.yellow("\u26A0\uFE0F You are on a newer version than what is published.\n");
4343
+ output += chalk11.dim(" This is expected if you are developing locally.\n");
3981
4344
  return {
3982
4345
  success: true,
3983
4346
  message: output,
3984
4347
  data: { currentVersion, latestVersion, upToDate: false }
3985
4348
  };
3986
4349
  }
3987
- output += chalk10.yellow(`\u2B06\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}
4350
+ output += chalk11.yellow(`\u2B06\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}
3988
4351
 
3989
4352
  `);
3990
4353
  if (opts.check) {
3991
- output += chalk10.dim("Run ") + chalk10.cyan("braingrid update") + chalk10.dim(" to update\n");
4354
+ output += chalk11.dim("Run ") + chalk11.cyan("braingrid update") + chalk11.dim(" to update\n");
3992
4355
  return {
3993
4356
  success: true,
3994
4357
  message: output,
3995
4358
  data: { currentVersion, latestVersion, upToDate: false }
3996
4359
  };
3997
4360
  }
3998
- output += chalk10.dim("Detecting package manager...\n");
4361
+ output += chalk11.dim("Detecting package manager...\n");
3999
4362
  const packageManager = await detectPackageManager(PACKAGE_NAME);
4000
- output += `${chalk10.bold("Package manager:")} ${packageManager}
4363
+ output += `${chalk11.bold("Package manager:")} ${packageManager}
4001
4364
 
4002
4365
  `;
4003
4366
  const updateCommand = getUpdateCommand2(packageManager, PACKAGE_NAME);
4004
- output += `${chalk10.dim("Running: ") + chalk10.cyan(updateCommand)}
4367
+ output += `${chalk11.dim("Running: ") + chalk11.cyan(updateCommand)}
4005
4368
 
4006
4369
  `;
4007
4370
  console.log(output);
@@ -4011,7 +4374,7 @@ async function handleUpdate(opts) {
4011
4374
  const setupOutput = await promptForIdeUpdates();
4012
4375
  return {
4013
4376
  success: true,
4014
- message: chalk10.green("\n\u2705 Successfully updated BrainGrid CLI!\n") + setupOutput,
4377
+ message: chalk11.green("\n\u2705 Successfully updated BrainGrid CLI!\n") + setupOutput,
4015
4378
  data: { currentVersion, latestVersion, packageManager }
4016
4379
  };
4017
4380
  } catch (error) {
@@ -4049,12 +4412,12 @@ function getServices() {
4049
4412
  function promptToAddOrganization(owner, webUrl) {
4050
4413
  return {
4051
4414
  success: false,
4052
- message: chalk11.yellow("\u26A0\uFE0F No projects found for this repository.\n\n") + chalk11.dim(`Repository: ${owner}/*
4415
+ message: chalk12.yellow("\u26A0\uFE0F No projects found for this repository.\n\n") + chalk12.dim(`Repository: ${owner}/*
4053
4416
 
4054
- `) + chalk11.dim(`You have GitHub connected, but not for the "${owner}" organization.
4417
+ `) + chalk12.dim(`You have GitHub connected, but not for the "${owner}" organization.
4055
4418
 
4056
- `) + chalk11.dim("To connect ") + chalk11.cyan(owner) + chalk11.dim(":\n") + chalk11.dim(" 1. Visit: ") + chalk11.cyan(`${webUrl}/integrations`) + chalk11.dim("\n") + chalk11.dim(' 2. Click "Add GitHub Organization"\n') + chalk11.dim(` 3. Select "${owner}"
4057
- `) + chalk11.dim(" 4. Run ") + chalk11.cyan("braingrid init") + chalk11.dim(" again")
4419
+ `) + chalk12.dim("To connect ") + chalk12.cyan(owner) + chalk12.dim(":\n") + chalk12.dim(" 1. Visit: ") + chalk12.cyan(`${webUrl}/integrations`) + chalk12.dim("\n") + chalk12.dim(' 2. Click "Add GitHub Organization"\n') + chalk12.dim(` 3. Select "${owner}"
4420
+ `) + chalk12.dim(" 4. Run ") + chalk12.cyan("braingrid init") + chalk12.dim(" again")
4058
4421
  };
4059
4422
  }
4060
4423
  async function promptToCreateProject(gitInfo, projectService, repositoryService) {
@@ -4062,20 +4425,20 @@ async function promptToCreateProject(gitInfo, projectService, repositoryService)
4062
4425
  if (!gitInfo.owner || !gitInfo.name) {
4063
4426
  return {
4064
4427
  success: false,
4065
- message: chalk11.red("\u274C Repository information is incomplete")
4428
+ message: chalk12.red("\u274C Repository information is incomplete")
4066
4429
  };
4067
4430
  }
4068
4431
  const repositoryId = await getRepositoryId(repositoryService, gitInfo.owner, gitInfo.name);
4069
4432
  if (!repositoryId) {
4070
4433
  return {
4071
4434
  success: false,
4072
- message: chalk11.yellow("\u26A0\uFE0F Repository accessible but could not retrieve details.\n\n") + chalk11.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}
4435
+ message: chalk12.yellow("\u26A0\uFE0F Repository accessible but could not retrieve details.\n\n") + chalk12.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}
4073
4436
 
4074
- `) + chalk11.dim("Please try again or create a project manually at: ") + chalk11.cyan(webUrl)
4437
+ `) + chalk12.dim("Please try again or create a project manually at: ") + chalk12.cyan(webUrl)
4075
4438
  };
4076
4439
  }
4077
4440
  console.log(
4078
- chalk11.yellow("\u26A0\uFE0F Repository accessible but no project exists.\n\n") + chalk11.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}
4441
+ chalk12.yellow("\u26A0\uFE0F Repository accessible but no project exists.\n\n") + chalk12.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}
4079
4442
  `)
4080
4443
  );
4081
4444
  const shouldCreate = await confirm2({
@@ -4085,7 +4448,7 @@ async function promptToCreateProject(gitInfo, projectService, repositoryService)
4085
4448
  if (!shouldCreate) {
4086
4449
  return {
4087
4450
  success: false,
4088
- message: chalk11.dim("\nProject creation cancelled.\n\n") + chalk11.dim("Create a project at ") + chalk11.cyan(webUrl) + chalk11.dim(" and link it to this repository, or use:\n") + chalk11.cyan(
4451
+ message: chalk12.dim("\nProject creation cancelled.\n\n") + chalk12.dim("Create a project at ") + chalk12.cyan(webUrl) + chalk12.dim(" and link it to this repository, or use:\n") + chalk12.cyan(
4089
4452
  `braingrid project create --name "${gitInfo.name}" --repositories "${gitInfo.owner}/${gitInfo.name}"`
4090
4453
  )
4091
4454
  };
@@ -4096,9 +4459,9 @@ async function promptToCreateProject(gitInfo, projectService, repositoryService)
4096
4459
  description: `Project for ${gitInfo.owner}/${gitInfo.name}`,
4097
4460
  repository_id: repositoryId
4098
4461
  });
4099
- console.log(chalk11.green(`
4462
+ console.log(chalk12.green(`
4100
4463
  \u2705 Created project ${project2.short_id}: ${project2.name}`));
4101
- console.log(chalk11.green(`\u2705 Linked repository ${gitInfo.owner}/${gitInfo.name}
4464
+ console.log(chalk12.green(`\u2705 Linked repository ${gitInfo.owner}/${gitInfo.name}
4102
4465
  `));
4103
4466
  return { success: true, message: "", data: project2 };
4104
4467
  } catch (error) {
@@ -4112,18 +4475,18 @@ async function promptToGrantRepositoryAccess(gitInfo, webUrl, repositoryService,
4112
4475
  if (!gitInfo.owner || !gitInfo.name) {
4113
4476
  return {
4114
4477
  success: false,
4115
- message: chalk11.red("\u274C Repository information is incomplete")
4478
+ message: chalk12.red("\u274C Repository information is incomplete")
4116
4479
  };
4117
4480
  }
4118
4481
  const owner = gitInfo.owner;
4119
4482
  const name = gitInfo.name;
4120
4483
  console.log(
4121
- chalk11.yellow("\u26A0\uFE0F Repository found but BrainGrid needs access.\n\n") + chalk11.dim(`Repository: ${owner}/${name}
4484
+ chalk12.yellow("\u26A0\uFE0F Repository found but BrainGrid needs access.\n\n") + chalk12.dim(`Repository: ${owner}/${name}
4122
4485
 
4123
- `) + chalk11.dim("Please grant BrainGrid access to this repository:\n") + chalk11.dim(" 1. Visit: ") + chalk11.cyan(`${webUrl}/integrations`) + chalk11.dim("\n") + chalk11.dim(
4486
+ `) + chalk12.dim("Please grant BrainGrid access to this repository:\n") + chalk12.dim(" 1. Visit: ") + chalk12.cyan(`${webUrl}/integrations`) + chalk12.dim("\n") + chalk12.dim(
4124
4487
  ` 2. Click on your "${owner}" installation "Add/Remove" to grant BrainGrid access to your repository
4125
4488
  `
4126
- ) + chalk11.dim(` 3. Select "${name}" and save
4489
+ ) + chalk12.dim(` 3. Select "${name}" and save
4127
4490
 
4128
4491
  `)
4129
4492
  );
@@ -4136,10 +4499,10 @@ async function promptToGrantRepositoryAccess(gitInfo, webUrl, repositoryService,
4136
4499
  if (!accessGranted) {
4137
4500
  return {
4138
4501
  success: false,
4139
- message: chalk11.yellow("\n\u26A0\uFE0F Repository access not detected within 3 minutes.\n\n") + chalk11.dim("Please grant access at: ") + chalk11.cyan(`${webUrl}/integrations`) + chalk11.dim(" and run ") + chalk11.cyan("braingrid init") + chalk11.dim(" again.")
4502
+ message: chalk12.yellow("\n\u26A0\uFE0F Repository access not detected within 3 minutes.\n\n") + chalk12.dim("Please grant access at: ") + chalk12.cyan(`${webUrl}/integrations`) + chalk12.dim(" and run ") + chalk12.cyan("braingrid init") + chalk12.dim(" again.")
4140
4503
  };
4141
4504
  }
4142
- console.log(chalk11.green("\u2705 Repository access granted!\n"));
4505
+ console.log(chalk12.green("\u2705 Repository access granted!\n"));
4143
4506
  return promptToCreateProject(gitInfo, projectService, repositoryService);
4144
4507
  }
4145
4508
  async function handleNoProjectForRepository(owner, name, gitInfo, githubService, repositoryService, projectService, config2) {
@@ -4147,16 +4510,22 @@ async function handleNoProjectForRepository(owner, name, gitInfo, githubService,
4147
4510
  try {
4148
4511
  const installationsResponse = await githubService.listInstallations({ limit: 100 });
4149
4512
  allInstallations = installationsResponse.installations;
4150
- } catch {
4513
+ } catch (error) {
4514
+ log(
4515
+ "WARN",
4516
+ "init",
4517
+ "list_installations_failed",
4518
+ `error=${error instanceof Error ? error.message : String(error)}`
4519
+ );
4151
4520
  allInstallations = [];
4152
4521
  }
4153
4522
  const webUrl = config2.getWebAppUrl();
4154
4523
  if (allInstallations.length === 0) {
4155
4524
  return {
4156
4525
  success: false,
4157
- message: chalk11.yellow("\u26A0\uFE0F No projects found for this repository.\n\n") + chalk11.dim(`Repository: ${owner}/${name}
4526
+ message: chalk12.yellow("\u26A0\uFE0F No projects found for this repository.\n\n") + chalk12.dim(`Repository: ${owner}/${name}
4158
4527
 
4159
- `) + chalk11.dim("It looks like you haven't connected your GitHub account yet.\n") + chalk11.dim("Please connect GitHub at: ") + chalk11.cyan(`${webUrl}/integrations`) + chalk11.dim("\n\nOnce connected, create a project and link it to this repository.")
4528
+ `) + chalk12.dim("It looks like you haven't connected your GitHub account yet.\n") + chalk12.dim("Please connect GitHub at: ") + chalk12.cyan(`${webUrl}/integrations`) + chalk12.dim("\n\nOnce connected, create a project and link it to this repository.")
4160
4529
  };
4161
4530
  }
4162
4531
  const ownerInstallation = findInstallationForOwner(owner, allInstallations);
@@ -4172,28 +4541,28 @@ async function handleNoProjectForRepository(owner, name, gitInfo, githubService,
4172
4541
  function showSetupInstructions(scenario) {
4173
4542
  let message = "";
4174
4543
  if (scenario === "no-git") {
4175
- message += chalk11.dim("To initialize BrainGrid locally:\n\n");
4176
- message += chalk11.dim(" 1. Initialize git:\n");
4177
- message += chalk11.cyan(" git init\n\n");
4544
+ message += chalk12.dim("To initialize BrainGrid locally:\n\n");
4545
+ message += chalk12.dim(" 1. Initialize git:\n");
4546
+ message += chalk12.cyan(" git init\n\n");
4178
4547
  } else {
4179
- message += chalk11.dim("To connect to GitHub:\n\n");
4548
+ message += chalk12.dim("To connect to GitHub:\n\n");
4180
4549
  }
4181
- message += chalk11.dim(" 2. Create GitHub repository:\n");
4182
- message += chalk11.dim(" \u2022 Install GitHub CLI: ") + chalk11.cyan("https://cli.github.com\n");
4183
- message += chalk11.dim(" Then: ") + chalk11.cyan("gh repo create --private --source=.\n");
4184
- message += chalk11.dim(" \u2022 Or manually: ") + chalk11.cyan("https://github.com/new\n\n");
4550
+ message += chalk12.dim(" 2. Create GitHub repository:\n");
4551
+ message += chalk12.dim(" \u2022 Install GitHub CLI: ") + chalk12.cyan("https://cli.github.com\n");
4552
+ message += chalk12.dim(" Then: ") + chalk12.cyan("gh repo create --private --source=.\n");
4553
+ message += chalk12.dim(" \u2022 Or manually: ") + chalk12.cyan("https://github.com/new\n\n");
4185
4554
  if (scenario === "no-git") {
4186
- message += chalk11.dim(" 3. Run: ") + chalk11.cyan("braingrid init\n\n");
4555
+ message += chalk12.dim(" 3. Run: ") + chalk12.cyan("braingrid init\n\n");
4187
4556
  } else {
4188
- message += chalk11.dim(" 3. Add remote and run init:\n");
4189
- message += chalk11.cyan(" git remote add origin <url>\n");
4190
- message += chalk11.cyan(" braingrid init\n\n");
4557
+ message += chalk12.dim(" 3. Add remote and run init:\n");
4558
+ message += chalk12.cyan(" git remote add origin <url>\n");
4559
+ message += chalk12.cyan(" braingrid init\n\n");
4191
4560
  }
4192
- message += chalk11.bold("Or use BrainGrid without local initialization:\n\n");
4193
- message += chalk11.dim(" All commands support the --project flag:\n");
4194
- message += chalk11.cyan(" braingrid requirement list --project PROJ-123\n");
4195
- message += chalk11.cyan(' braingrid task create --project PROJ-123 --title "Task"\n\n');
4196
- message += `${chalk11.dim(" Note: Without local init, you must specify --project for each command.")}
4561
+ message += chalk12.bold("Or use BrainGrid without local initialization:\n\n");
4562
+ message += chalk12.dim(" All commands support the --project flag:\n");
4563
+ message += chalk12.cyan(" braingrid requirement list --project PROJ-123\n");
4564
+ message += chalk12.cyan(' braingrid task create --project PROJ-123 --title "Task"\n\n');
4565
+ message += `${chalk12.dim(" Note: Without local init, you must specify --project for each command.")}
4197
4566
  `;
4198
4567
  return message;
4199
4568
  }
@@ -4210,10 +4579,10 @@ async function handleNoGitRepository() {
4210
4579
  if (!gitInitSuccess) {
4211
4580
  return {
4212
4581
  success: false,
4213
- message: chalk11.red("\u274C Failed to initialize git repository")
4582
+ message: chalk12.red("\u274C Failed to initialize git repository")
4214
4583
  };
4215
4584
  }
4216
- console.log(chalk11.green("\u2705 Initialized git repository"));
4585
+ console.log(chalk12.green("\u2705 Initialized git repository"));
4217
4586
  const dirName = getCurrentDirectoryName();
4218
4587
  const isPrivate = await select3({
4219
4588
  message: "Repository visibility:",
@@ -4227,16 +4596,16 @@ async function handleNoGitRepository() {
4227
4596
  message: "Repository name:",
4228
4597
  default: dirName
4229
4598
  });
4230
- console.log(chalk11.dim("\nCreating repository...\n"));
4599
+ console.log(chalk12.dim("\nCreating repository...\n"));
4231
4600
  const repo = await createGitHubRepoWithGh(repoName, isPrivate);
4232
4601
  if (!repo) {
4233
4602
  return {
4234
4603
  success: false,
4235
- message: chalk11.red("\u274C Failed to create GitHub repository\n\n") + showSetupInstructions("no-git")
4604
+ message: chalk12.red("\u274C Failed to create GitHub repository\n\n") + showSetupInstructions("no-git")
4236
4605
  };
4237
4606
  }
4238
- console.log(chalk11.green(`\u2705 Created repository: ${repo.url}`));
4239
- console.log(chalk11.green("\u2705 Added remote origin\n"));
4607
+ console.log(chalk12.green(`\u2705 Created repository: ${repo.url}`));
4608
+ console.log(chalk12.green("\u2705 Added remote origin\n"));
4240
4609
  return {
4241
4610
  success: true,
4242
4611
  message: "continue-init",
@@ -4247,7 +4616,7 @@ async function handleNoGitRepository() {
4247
4616
  }
4248
4617
  return {
4249
4618
  success: false,
4250
- message: chalk11.yellow("\u26A0\uFE0F This directory is not a git repository.\n\n") + showSetupInstructions("no-git")
4619
+ message: chalk12.yellow("\u26A0\uFE0F This directory is not a git repository.\n\n") + showSetupInstructions("no-git")
4251
4620
  };
4252
4621
  }
4253
4622
  async function handleNoGitRemote() {
@@ -4271,16 +4640,16 @@ async function handleNoGitRemote() {
4271
4640
  message: "Repository name:",
4272
4641
  default: dirName
4273
4642
  });
4274
- console.log(chalk11.dim("\nCreating repository...\n"));
4643
+ console.log(chalk12.dim("\nCreating repository...\n"));
4275
4644
  const repo = await createGitHubRepoWithGh(repoName, isPrivate);
4276
4645
  if (!repo) {
4277
4646
  return {
4278
4647
  success: false,
4279
- message: chalk11.red("\u274C Failed to create GitHub repository\n\n") + showSetupInstructions("no-remote")
4648
+ message: chalk12.red("\u274C Failed to create GitHub repository\n\n") + showSetupInstructions("no-remote")
4280
4649
  };
4281
4650
  }
4282
- console.log(chalk11.green(`\u2705 Created repository: ${repo.url}`));
4283
- console.log(chalk11.green("\u2705 Added remote origin\n"));
4651
+ console.log(chalk12.green(`\u2705 Created repository: ${repo.url}`));
4652
+ console.log(chalk12.green("\u2705 Added remote origin\n"));
4284
4653
  return {
4285
4654
  success: true,
4286
4655
  message: "continue-init",
@@ -4291,16 +4660,19 @@ async function handleNoGitRemote() {
4291
4660
  }
4292
4661
  return {
4293
4662
  success: false,
4294
- message: chalk11.yellow("\u26A0\uFE0F Git repository detected but no GitHub remote configured.\n\n") + showSetupInstructions("no-remote")
4663
+ message: chalk12.yellow("\u26A0\uFE0F Git repository detected but no GitHub remote configured.\n\n") + showSetupInstructions("no-remote")
4295
4664
  };
4296
4665
  }
4297
4666
  async function handleInit(opts) {
4298
4667
  try {
4668
+ const initStartTime = Date.now();
4669
+ initLogger(".braingrid/temp/init-debug.log");
4670
+ log("INFO", "init", "start", `force=${opts.force} project=${opts.project || "auto-detect"}`);
4299
4671
  const updateInfo = await isUpdateAvailable();
4300
4672
  if (updateInfo.available && updateInfo.latestVersion) {
4301
4673
  console.log(
4302
- chalk11.yellow(`
4303
- \u26A0\uFE0F A new version of BrainGrid CLI is available: `) + chalk11.dim(`${updateInfo.currentVersion} \u2192 `) + chalk11.green(updateInfo.latestVersion) + "\n"
4674
+ chalk12.yellow(`
4675
+ \u26A0\uFE0F A new version of BrainGrid CLI is available: `) + chalk12.dim(`${updateInfo.currentVersion} \u2192 `) + chalk12.green(updateInfo.latestVersion) + "\n"
4304
4676
  );
4305
4677
  const shouldUpdate = await confirm2({
4306
4678
  message: "Would you like to update now?",
@@ -4311,11 +4683,17 @@ async function handleInit(opts) {
4311
4683
  console.log(result.message);
4312
4684
  return {
4313
4685
  success: true,
4314
- message: chalk11.dim("\nRun `braingrid init` again after the update completes.")
4686
+ message: chalk12.dim("\nRun `braingrid init` again after the update completes.")
4315
4687
  };
4316
4688
  }
4317
4689
  console.log();
4318
4690
  }
4691
+ log(
4692
+ "INFO",
4693
+ "init",
4694
+ "update_check",
4695
+ `available=${updateInfo.available} current=${updateInfo.currentVersion}${updateInfo.latestVersion ? ` latest=${updateInfo.latestVersion}` : ""}`
4696
+ );
4319
4697
  const config2 = getConfig();
4320
4698
  const { projectService, githubService, repositoryService, auth } = getServices();
4321
4699
  if (!await isGitInstalled()) {
@@ -4326,7 +4704,7 @@ async function handleInit(opts) {
4326
4704
  if (!shouldInstall) {
4327
4705
  return {
4328
4706
  success: false,
4329
- message: chalk11.yellow("\u26A0\uFE0F Git installation cancelled.\n\n") + getManualInstallInstructions()
4707
+ message: chalk12.yellow("\u26A0\uFE0F Git installation cancelled.\n\n") + getManualInstallInstructions()
4330
4708
  };
4331
4709
  }
4332
4710
  console.log();
@@ -4340,16 +4718,18 @@ async function handleInit(opts) {
4340
4718
  console.log(installResult.message);
4341
4719
  console.log();
4342
4720
  if (!await isGitInstalled()) {
4721
+ log("ERROR", "init", "git_check", "installed=false post_install=true");
4343
4722
  return {
4344
4723
  success: false,
4345
- message: chalk11.red("\u274C Git installation completed but git command not found\n\n") + chalk11.dim("You may need to restart your terminal or add Git to your PATH.\n") + getManualInstallInstructions()
4724
+ message: chalk12.red("\u274C Git installation completed but git command not found\n\n") + chalk12.dim("You may need to restart your terminal or add Git to your PATH.\n") + getManualInstallInstructions()
4346
4725
  };
4347
4726
  }
4348
4727
  }
4728
+ log("INFO", "init", "git_check", "installed=true");
4349
4729
  if (!await isGhInstalled()) {
4350
- console.log(chalk11.blue("\n\u{1F4A1} GitHub CLI is highly recommended for working with BrainGrid."));
4730
+ console.log(chalk12.blue("\n\u{1F4A1} GitHub CLI is highly recommended for working with BrainGrid."));
4351
4731
  console.log(
4352
- chalk11.dim(" It enables seamless GitHub integration and repository management.\n")
4732
+ chalk12.dim(" It enables seamless GitHub integration and repository management.\n")
4353
4733
  );
4354
4734
  const shouldInstallGh = await confirm2({
4355
4735
  message: "Would you like to install GitHub CLI now?",
@@ -4363,30 +4743,60 @@ async function handleInit(opts) {
4363
4743
  console.log();
4364
4744
  } else {
4365
4745
  console.log(ghInstallResult.message);
4366
- console.log(chalk11.dim("You can install it manually later.\n"));
4746
+ console.log(chalk12.dim("You can install it manually later.\n"));
4747
+ }
4748
+ } else {
4749
+ console.log(chalk12.dim("Skipping GitHub CLI installation.\n"));
4750
+ }
4751
+ }
4752
+ log("INFO", "init", "gh_check", `installed=${await isGhInstalled()}`);
4753
+ if (!await isJqInstalled()) {
4754
+ console.log(chalk12.blue("\n\u{1F4A1} jq is required for BrainGrid hooks to parse JSON data."));
4755
+ console.log(chalk12.dim(" All IDE integrations (Claude Code, Cursor) use jq.\n"));
4756
+ const shouldInstallJq = await confirm2({
4757
+ message: "Would you like to install jq now?",
4758
+ default: true
4759
+ });
4760
+ if (shouldInstallJq) {
4761
+ console.log();
4762
+ const jqInstallResult = await installJq();
4763
+ if (jqInstallResult.success) {
4764
+ console.log(jqInstallResult.message);
4765
+ console.log();
4766
+ } else {
4767
+ console.log(jqInstallResult.message);
4768
+ console.log(chalk12.dim("You can install it manually later.\n"));
4367
4769
  }
4368
4770
  } else {
4369
- console.log(chalk11.dim("Skipping GitHub CLI installation.\n"));
4771
+ console.log(chalk12.dim("Skipping jq installation.\n"));
4370
4772
  }
4371
4773
  }
4774
+ log("INFO", "init", "jq_check", `installed=${await isJqInstalled()}`);
4372
4775
  if (await projectConfigExists() && !opts.force) {
4373
4776
  try {
4374
4777
  const existing = await loadProjectConfig();
4375
4778
  return {
4376
4779
  success: false,
4377
- message: chalk11.yellow("\u26A0\uFE0F Already initialized.\n\n") + chalk11.dim(`Project: ${existing.project_name} (${existing.project_short_id})
4378
- `) + chalk11.dim(`Repository: ${existing.repository?.full_name || "N/A"}
4780
+ message: chalk12.yellow("\u26A0\uFE0F Already initialized.\n\n") + chalk12.dim(`Project: ${existing.project_name} (${existing.project_short_id})
4781
+ `) + chalk12.dim(`Repository: ${existing.repository?.full_name || "N/A"}
4379
4782
 
4380
- `) + chalk11.dim("Use --force to reinitialize")
4783
+ `) + chalk12.dim("Use --force to reinitialize")
4381
4784
  };
4382
- } catch {
4785
+ } catch (error) {
4786
+ log(
4787
+ "ERROR",
4788
+ "init",
4789
+ "config_load",
4790
+ `error=${error instanceof Error ? error.message : String(error)}`
4791
+ );
4383
4792
  return {
4384
4793
  success: false,
4385
- message: chalk11.yellow("\u26A0\uFE0F Invalid project configuration found.\n") + chalk11.dim("Use --force to reinitialize")
4794
+ message: chalk12.yellow("\u26A0\uFE0F Invalid project configuration found.\n") + chalk12.dim("Use --force to reinitialize")
4386
4795
  };
4387
4796
  }
4388
4797
  }
4389
4798
  const isAuthenticated = await auth.isAuthenticated();
4799
+ log("INFO", "init", "auth_check", `authenticated=${isAuthenticated}`);
4390
4800
  if (!isAuthenticated) {
4391
4801
  const shouldLogin = await confirm2({
4392
4802
  message: "You need to be authenticated. Would you like to log in / sign up now?",
@@ -4395,21 +4805,24 @@ async function handleInit(opts) {
4395
4805
  if (!shouldLogin) {
4396
4806
  return {
4397
4807
  success: false,
4398
- message: chalk11.yellow("\u26A0\uFE0F Authentication required.\n") + chalk11.dim("Run ") + chalk11.cyan("braingrid login") + chalk11.dim(" when you're ready to authenticate.")
4808
+ message: chalk12.yellow("\u26A0\uFE0F Authentication required.\n") + chalk12.dim("Run ") + chalk12.cyan("braingrid login") + chalk12.dim(" when you're ready to authenticate.")
4399
4809
  };
4400
4810
  }
4811
+ log("WARN", "init", "login_required", "prompted=true");
4401
4812
  console.log();
4402
4813
  const loginResult = await handleLogin();
4403
4814
  if (!loginResult.success) {
4815
+ log("ERROR", "init", "login_failed", "error=login handler returned failure");
4404
4816
  return {
4405
4817
  success: false,
4406
- message: chalk11.red("\u274C Login failed.\n") + chalk11.dim("Please try running ") + chalk11.cyan("braingrid login") + chalk11.dim(" again.")
4818
+ message: chalk12.red("\u274C Login failed.\n") + chalk12.dim("Please try running ") + chalk12.cyan("braingrid login") + chalk12.dim(" again.")
4407
4819
  };
4408
4820
  }
4409
4821
  if (!await auth.isAuthenticated()) {
4822
+ log("ERROR", "init", "login_failed", "error=login not completed");
4410
4823
  return {
4411
4824
  success: false,
4412
- message: chalk11.red("\u274C Login was not completed.\n") + chalk11.dim("Please try running ") + chalk11.cyan("braingrid login") + chalk11.dim(" again.")
4825
+ message: chalk12.red("\u274C Login was not completed.\n") + chalk12.dim("Please try running ") + chalk12.cyan("braingrid login") + chalk12.dim(" again.")
4413
4826
  };
4414
4827
  }
4415
4828
  console.log();
@@ -4418,39 +4831,45 @@ async function handleInit(opts) {
4418
4831
  if (!session) {
4419
4832
  return {
4420
4833
  success: false,
4421
- message: chalk11.red("\u274C No session found. Please run `braingrid login` first.")
4834
+ message: chalk12.red("\u274C No session found. Please run `braingrid login` first.")
4422
4835
  };
4423
4836
  }
4424
4837
  if (session.organization_id === "default") {
4425
- console.log(chalk11.yellow("\u26A0\uFE0F Organization ID not set, validating session...\n"));
4838
+ console.log(chalk12.yellow("\u26A0\uFE0F Organization ID not set, validating session...\n"));
4426
4839
  const isValid = await auth.isAuthenticated();
4427
4840
  if (!isValid) {
4428
4841
  return {
4429
4842
  success: false,
4430
- message: chalk11.red("\u274C Session validation failed. Please run `braingrid login` again.")
4843
+ message: chalk12.red("\u274C Session validation failed. Please run `braingrid login` again.")
4431
4844
  };
4432
4845
  }
4433
4846
  const updatedSession = await auth.getStoredSession();
4434
4847
  if (!updatedSession || updatedSession.organization_id === "default") {
4435
4848
  return {
4436
4849
  success: false,
4437
- message: chalk11.red("\u274C Unable to retrieve organization information.\n\n") + chalk11.dim("This may indicate an issue with your account setup.\n") + chalk11.dim("Please contact support or try logging in again with ") + chalk11.cyan("braingrid logout") + chalk11.dim(" and ") + chalk11.cyan("braingrid login")
4850
+ message: chalk12.red("\u274C Unable to retrieve organization information.\n\n") + chalk12.dim("This may indicate an issue with your account setup.\n") + chalk12.dim("Please contact support or try logging in again with ") + chalk12.cyan("braingrid logout") + chalk12.dim(" and ") + chalk12.cyan("braingrid login")
4438
4851
  };
4439
4852
  }
4440
4853
  Object.assign(session, updatedSession);
4441
- console.log(chalk11.green("\u2705 Organization ID updated successfully\n"));
4854
+ console.log(chalk12.green("\u2705 Organization ID updated successfully\n"));
4442
4855
  }
4443
4856
  let gitInfo = await getGitRepositoryInfo();
4444
4857
  let project2;
4445
4858
  if (opts.project) {
4446
4859
  try {
4447
4860
  project2 = await projectService.getProject(opts.project);
4448
- } catch {
4861
+ } catch (error) {
4862
+ log(
4863
+ "ERROR",
4864
+ "init",
4865
+ "project_fetch",
4866
+ `project=${opts.project} error=${error instanceof Error ? error.message : String(error)}`
4867
+ );
4449
4868
  return {
4450
4869
  success: false,
4451
- message: chalk11.red(`\u274C Project not found: ${opts.project}
4870
+ message: chalk12.red(`\u274C Project not found: ${opts.project}
4452
4871
 
4453
- `) + chalk11.dim("Make sure the project ID is correct and you have access to it.")
4872
+ `) + chalk12.dim("Make sure the project ID is correct and you have access to it.")
4454
4873
  };
4455
4874
  }
4456
4875
  } else {
@@ -4461,7 +4880,7 @@ async function handleInit(opts) {
4461
4880
  if (!gitInfo || !gitInfo.owner || !gitInfo.name) {
4462
4881
  return {
4463
4882
  success: false,
4464
- message: chalk11.red("\u274C Failed to get repository information after setup")
4883
+ message: chalk12.red("\u274C Failed to get repository information after setup")
4465
4884
  };
4466
4885
  }
4467
4886
  } else {
@@ -4475,7 +4894,7 @@ async function handleInit(opts) {
4475
4894
  if (!gitInfo || !gitInfo.owner || !gitInfo.name) {
4476
4895
  return {
4477
4896
  success: false,
4478
- message: chalk11.red("\u274C Failed to get repository information after setup")
4897
+ message: chalk12.red("\u274C Failed to get repository information after setup")
4479
4898
  };
4480
4899
  }
4481
4900
  } else {
@@ -4485,7 +4904,7 @@ async function handleInit(opts) {
4485
4904
  if (!gitInfo) {
4486
4905
  return {
4487
4906
  success: false,
4488
- message: chalk11.red("\u274C Repository information is missing")
4907
+ message: chalk12.red("\u274C Repository information is missing")
4489
4908
  };
4490
4909
  }
4491
4910
  const owner = gitInfo.owner;
@@ -4493,7 +4912,7 @@ async function handleInit(opts) {
4493
4912
  if (!owner || !name) {
4494
4913
  return {
4495
4914
  success: false,
4496
- message: chalk11.red("\u274C Repository information is incomplete")
4915
+ message: chalk12.red("\u274C Repository information is incomplete")
4497
4916
  };
4498
4917
  }
4499
4918
  let response;
@@ -4532,8 +4951,9 @@ async function handleInit(opts) {
4532
4951
  }
4533
4952
  project2 = response.projects[0];
4534
4953
  }
4535
- const projectInfo = chalk11.bold("\n\u{1F4E6} BrainGrid Project Found\n\n") + chalk11.dim("Project: ") + chalk11.cyan(project2.name) + "\n" + chalk11.dim("ID: ") + chalk11.gray(project2.short_id) + "\n" + (project2.description ? `${chalk11.dim("Description: ") + chalk11.gray(project2.description)}
4536
- ` : "") + chalk11.dim("Repository: ") + chalk11.gray(project2.repository?.full_name || "N/A") + "\n\n";
4954
+ log("INFO", "init", "project_found", `id=${project2.short_id} name=${project2.name}`);
4955
+ const projectInfo = chalk12.bold("\n\u{1F4E6} BrainGrid Project Found\n\n") + chalk12.dim("Project: ") + chalk12.cyan(project2.name) + "\n" + chalk12.dim("ID: ") + chalk12.gray(project2.short_id) + "\n" + (project2.description ? `${chalk12.dim("Description: ") + chalk12.gray(project2.description)}
4956
+ ` : "") + chalk12.dim("Repository: ") + chalk12.gray(project2.repository?.full_name || "N/A") + "\n\n";
4537
4957
  console.log(projectInfo);
4538
4958
  if (!opts.force) {
4539
4959
  const shouldInit = await confirm2({
@@ -4543,7 +4963,7 @@ async function handleInit(opts) {
4543
4963
  if (!shouldInit) {
4544
4964
  return {
4545
4965
  success: false,
4546
- message: chalk11.yellow("Initialization cancelled.")
4966
+ message: chalk12.yellow("Initialization cancelled.")
4547
4967
  };
4548
4968
  }
4549
4969
  }
@@ -4565,12 +4985,19 @@ async function handleInit(opts) {
4565
4985
  created_at: project2.created_at
4566
4986
  };
4567
4987
  await saveProjectConfig(localConfig);
4988
+ log("INFO", "init", "config_saved", "path=.braingrid/project.json");
4568
4989
  await addBraingridTempToGitignore();
4569
4990
  await copyBraingridReadme();
4570
4991
  console.log(
4571
- chalk11.green("\u2705 Repository initialized successfully!\n\n") + chalk11.dim("Project: ") + chalk11.cyan(project2.name) + chalk11.dim(` (${project2.short_id})`) + "\n" + chalk11.dim("Config: ") + chalk11.gray(".braingrid/project.json") + "\n"
4992
+ chalk12.green("\u2705 Repository initialized successfully!\n\n") + chalk12.dim("Project: ") + chalk12.cyan(project2.name) + chalk12.dim(` (${project2.short_id})`) + "\n" + chalk12.dim("Config: ") + chalk12.gray(".braingrid/project.json") + "\n"
4572
4993
  );
4573
4994
  const installedIDEs = await detectInstalledIDEs();
4995
+ log(
4996
+ "INFO",
4997
+ "init",
4998
+ "ide_detect",
4999
+ `claude_code=${installedIDEs.claudeCode} cursor=${installedIDEs.cursor}`
5000
+ );
4574
5001
  if (installedIDEs.claudeCode) {
4575
5002
  const claudeSetupExists = await fileExists2(".claude/commands/specify.md");
4576
5003
  console.log("");
@@ -4579,6 +5006,7 @@ async function handleInit(opts) {
4579
5006
  default: true
4580
5007
  });
4581
5008
  if (setupClaude) {
5009
+ log("INFO", "init", "setup_claude", `force=${claudeSetupExists}`);
4582
5010
  console.log("");
4583
5011
  try {
4584
5012
  const result = await handleSetupClaudeCode({
@@ -4587,15 +5015,21 @@ async function handleInit(opts) {
4587
5015
  if (result.success) {
4588
5016
  console.log(result.message);
4589
5017
  } else {
4590
- console.log(chalk11.yellow("\u26A0\uFE0F Claude Code setup was not completed."));
5018
+ console.log(chalk12.yellow("\u26A0\uFE0F Claude Code setup was not completed."));
4591
5019
  console.log(
4592
- chalk11.dim("You can run ") + chalk11.cyan("braingrid setup claude-code") + chalk11.dim(" later.")
5020
+ chalk12.dim("You can run ") + chalk12.cyan("braingrid setup claude-code") + chalk12.dim(" later.")
4593
5021
  );
4594
5022
  }
4595
- } catch {
4596
- console.log(chalk11.yellow("\u26A0\uFE0F Claude Code setup encountered an error."));
5023
+ } catch (error) {
5024
+ log(
5025
+ "ERROR",
5026
+ "init",
5027
+ "setup_claude_failed",
5028
+ `error=${error instanceof Error ? error.message : String(error)}`
5029
+ );
5030
+ console.log(chalk12.yellow("\u26A0\uFE0F Claude Code setup encountered an error."));
4597
5031
  console.log(
4598
- chalk11.dim("You can run ") + chalk11.cyan("braingrid setup claude-code") + chalk11.dim(" later.")
5032
+ chalk12.dim("You can run ") + chalk12.cyan("braingrid setup claude-code") + chalk12.dim(" later.")
4599
5033
  );
4600
5034
  }
4601
5035
  console.log("");
@@ -4609,6 +5043,7 @@ async function handleInit(opts) {
4609
5043
  default: true
4610
5044
  });
4611
5045
  if (setupCursor) {
5046
+ log("INFO", "init", "setup_cursor", `force=${cursorSetupExists}`);
4612
5047
  console.log("");
4613
5048
  try {
4614
5049
  const result = await handleSetupCursor({
@@ -4617,28 +5052,44 @@ async function handleInit(opts) {
4617
5052
  if (result.success) {
4618
5053
  console.log(result.message);
4619
5054
  } else {
4620
- console.log(chalk11.yellow("\u26A0\uFE0F Cursor setup was not completed."));
5055
+ console.log(chalk12.yellow("\u26A0\uFE0F Cursor setup was not completed."));
4621
5056
  console.log(
4622
- chalk11.dim("You can run ") + chalk11.cyan("braingrid setup cursor") + chalk11.dim(" later.")
5057
+ chalk12.dim("You can run ") + chalk12.cyan("braingrid setup cursor") + chalk12.dim(" later.")
4623
5058
  );
4624
5059
  }
4625
- } catch {
4626
- console.log(chalk11.yellow("\u26A0\uFE0F Cursor setup encountered an error."));
5060
+ } catch (error) {
5061
+ log(
5062
+ "ERROR",
5063
+ "init",
5064
+ "setup_cursor_failed",
5065
+ `error=${error instanceof Error ? error.message : String(error)}`
5066
+ );
5067
+ console.log(chalk12.yellow("\u26A0\uFE0F Cursor setup encountered an error."));
4627
5068
  console.log(
4628
- chalk11.dim("You can run ") + chalk11.cyan("braingrid setup cursor") + chalk11.dim(" later.")
5069
+ chalk12.dim("You can run ") + chalk12.cyan("braingrid setup cursor") + chalk12.dim(" later.")
4629
5070
  );
4630
5071
  }
4631
5072
  console.log("");
4632
5073
  }
4633
5074
  }
5075
+ const initDuration = Math.round((Date.now() - initStartTime) / 1e3);
5076
+ log("INFO", "init", "complete", `project=${project2.short_id} duration=${initDuration}s`);
5077
+ await flushLogger();
5078
+ closeLogger();
4634
5079
  return {
4635
5080
  success: true,
4636
- message: chalk11.dim(
4637
- "You can now use project-scoped commands without specifying a project ID."
4638
- ),
5081
+ message: chalk12.dim("You can now use project-scoped commands without specifying a project ID.") + "\n" + chalk12.dim("Debug log: .braingrid/temp/init-debug.log"),
4639
5082
  data: localConfig
4640
5083
  };
4641
5084
  } catch (error) {
5085
+ log(
5086
+ "ERROR",
5087
+ "init",
5088
+ "fatal",
5089
+ `error=${error instanceof Error ? error.message : String(error)}`
5090
+ );
5091
+ await flushLogger();
5092
+ closeLogger();
4642
5093
  return {
4643
5094
  success: false,
4644
5095
  message: formatError(error, "initializing repository")
@@ -4647,10 +5098,10 @@ async function handleInit(opts) {
4647
5098
  }
4648
5099
 
4649
5100
  // src/handlers/project.handlers.ts
4650
- import chalk14 from "chalk";
5101
+ import chalk15 from "chalk";
4651
5102
 
4652
5103
  // src/utils/formatting.ts
4653
- import chalk12 from "chalk";
5104
+ import chalk13 from "chalk";
4654
5105
 
4655
5106
  // src/utils/id-normalization.ts
4656
5107
  function normalizeId(prefix, input2) {
@@ -4692,7 +5143,7 @@ function getWebUiUrl(apiUrl) {
4692
5143
  }
4693
5144
  function formatTasksListOutput(tasks, format, verbose, options) {
4694
5145
  if (tasks.length === 0) {
4695
- return chalk12.yellow("No tasks found.");
5146
+ return chalk13.yellow("No tasks found.");
4696
5147
  }
4697
5148
  switch (format) {
4698
5149
  case "json":
@@ -4722,7 +5173,7 @@ function formatTasksListOutput(tasks, format, verbose, options) {
4722
5173
  }
4723
5174
  }
4724
5175
  function formatTasksListTable(tasks) {
4725
- let output = chalk12.bold(`\u{1F4CB} Tasks (${tasks.length})
5176
+ let output = chalk13.bold(`\u{1F4CB} Tasks (${tasks.length})
4726
5177
 
4727
5178
  `);
4728
5179
  output += "ID Short ID Status Title Assigned To Blocked\n";
@@ -4742,58 +5193,58 @@ function formatTasksListTable(tasks) {
4742
5193
  return output;
4743
5194
  }
4744
5195
  function formatTasksListVerbose(tasks, options) {
4745
- let output = chalk12.bold(`\u{1F4CB} Tasks (${tasks.length})
5196
+ let output = chalk13.bold(`\u{1F4CB} Tasks (${tasks.length})
4746
5197
 
4747
5198
  `);
4748
- const divider = chalk12.gray("\u2500".repeat(50));
5199
+ const divider = chalk13.gray("\u2500".repeat(50));
4749
5200
  for (let i = 0; i < tasks.length; i++) {
4750
5201
  const task2 = tasks[i];
4751
5202
  const statusEmoji = getTaskStatusEmoji(task2.status);
4752
- output += `${statusEmoji} ${chalk12.bold(task2.title)}
5203
+ output += `${statusEmoji} ${chalk13.bold(task2.title)}
4753
5204
  `;
4754
- output += `${chalk12.bold("Short ID:")} TASK-${task2.number}
5205
+ output += `${chalk13.bold("Short ID:")} TASK-${task2.number}
4755
5206
  `;
4756
- output += `${chalk12.bold("ID:")} ${task2.id}
5207
+ output += `${chalk13.bold("ID:")} ${task2.id}
4757
5208
  `;
4758
5209
  if (options?.apiUrl && options?.requirementId) {
4759
5210
  const webUiUrl = getWebUiUrl(options.apiUrl);
4760
- output += `${chalk12.bold("URL:")} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks
5211
+ output += `${chalk13.bold("URL:")} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks
4761
5212
  `;
4762
5213
  }
4763
- output += `${chalk12.bold("Project:")} ${options?.projectShortId || "N/A"}
5214
+ output += `${chalk13.bold("Project:")} ${options?.projectShortId || "N/A"}
4764
5215
  `;
4765
- output += `${chalk12.bold("Requirement:")} ${options?.requirementShortId || "N/A"}
5216
+ output += `${chalk13.bold("Requirement:")} ${options?.requirementShortId || "N/A"}
4766
5217
  `;
4767
- output += `${chalk12.bold("Status:")} ${task2.status}
5218
+ output += `${chalk13.bold("Status:")} ${task2.status}
4768
5219
  `;
4769
5220
  if (task2.assigned_to) {
4770
- output += `${chalk12.bold("Assigned to:")} ${task2.assigned_to}
5221
+ output += `${chalk13.bold("Assigned to:")} ${task2.assigned_to}
4771
5222
  `;
4772
5223
  } else {
4773
- output += `${chalk12.bold("Assigned to:")} Unassigned
5224
+ output += `${chalk13.bold("Assigned to:")} Unassigned
4774
5225
  `;
4775
5226
  }
4776
5227
  if (task2.created_at) {
4777
- output += `${chalk12.bold("Created:")} ${new Date(task2.created_at).toLocaleString()}
5228
+ output += `${chalk13.bold("Created:")} ${new Date(task2.created_at).toLocaleString()}
4778
5229
  `;
4779
5230
  }
4780
5231
  if (task2.updated_at) {
4781
- output += `${chalk12.bold("Updated:")} ${new Date(task2.updated_at).toLocaleString()}
5232
+ output += `${chalk13.bold("Updated:")} ${new Date(task2.updated_at).toLocaleString()}
4782
5233
  `;
4783
5234
  }
4784
5235
  if (task2.started_at) {
4785
- output += `${chalk12.bold("Started:")} ${new Date(task2.started_at).toLocaleString()}
5236
+ output += `${chalk13.bold("Started:")} ${new Date(task2.started_at).toLocaleString()}
4786
5237
  `;
4787
5238
  }
4788
5239
  if (task2.finished_at) {
4789
- output += `${chalk12.bold("Finished:")} ${new Date(task2.finished_at).toLocaleString()}
5240
+ output += `${chalk13.bold("Finished:")} ${new Date(task2.finished_at).toLocaleString()}
4790
5241
  `;
4791
5242
  }
4792
5243
  if (task2.content) {
4793
5244
  output += `
4794
5245
  ${divider}
4795
5246
  `;
4796
- output += `${chalk12.bold("Content:")}
5247
+ output += `${chalk13.bold("Content:")}
4797
5248
  ${task2.content}
4798
5249
  `;
4799
5250
  output += `${divider}
@@ -4801,12 +5252,12 @@ ${task2.content}
4801
5252
  }
4802
5253
  if (task2.blocked_by && task2.blocked_by.length > 0) {
4803
5254
  output += `
4804
- ${chalk12.bold("Blocked by:")} ${task2.blocked_by.join(", ")}
5255
+ ${chalk13.bold("Blocked by:")} ${task2.blocked_by.join(", ")}
4805
5256
  `;
4806
5257
  }
4807
5258
  if (i < tasks.length - 1) {
4808
5259
  output += `
4809
- ${chalk12.gray("\u2550".repeat(50))}
5260
+ ${chalk13.gray("\u2550".repeat(50))}
4810
5261
 
4811
5262
  `;
4812
5263
  }
@@ -5019,57 +5470,57 @@ function getRequirementStatusEmoji(status) {
5019
5470
  }
5020
5471
  function formatRequirementOutput(requirement2, options) {
5021
5472
  const statusEmoji = getRequirementStatusEmoji(requirement2.status);
5022
- const divider = chalk12.gray("\u2500".repeat(50));
5473
+ const divider = chalk13.gray("\u2500".repeat(50));
5023
5474
  let message = "";
5024
5475
  if (options?.successMessage) {
5025
- message += chalk12.green(`\u2705 ${options.successMessage}
5476
+ message += chalk13.green(`\u2705 ${options.successMessage}
5026
5477
 
5027
5478
  `);
5028
5479
  }
5029
- message += `${statusEmoji} ${chalk12.bold(requirement2.name)}
5480
+ message += `${statusEmoji} ${chalk13.bold(requirement2.name)}
5030
5481
 
5031
5482
  `;
5032
- message += `${chalk12.bold("Short ID:")} ${requirement2.short_id || "N/A"}
5483
+ message += `${chalk13.bold("Short ID:")} ${requirement2.short_id || "N/A"}
5033
5484
  `;
5034
- message += `${chalk12.bold("ID:")} ${requirement2.id}
5485
+ message += `${chalk13.bold("ID:")} ${requirement2.id}
5035
5486
  `;
5036
5487
  if (options?.apiUrl) {
5037
5488
  const webUiUrl = getWebUiUrl(options.apiUrl);
5038
- message += `${chalk12.bold("URL:")} ${webUiUrl}/requirements/overview?id=${requirement2.id}
5489
+ message += `${chalk13.bold("URL:")} ${webUiUrl}/requirements/overview?id=${requirement2.id}
5039
5490
  `;
5040
5491
  }
5041
- message += `${chalk12.bold("Project:")} ${options?.projectShortId || "N/A"}
5492
+ message += `${chalk13.bold("Project:")} ${options?.projectShortId || "N/A"}
5042
5493
  `;
5043
5494
  if (requirement2.branch) {
5044
- message += `${chalk12.bold("Branch:")} ${requirement2.branch}
5495
+ message += `${chalk13.bold("Branch:")} ${requirement2.branch}
5045
5496
  `;
5046
5497
  }
5047
- message += `${chalk12.bold("Status:")} ${requirement2.status}
5498
+ message += `${chalk13.bold("Status:")} ${requirement2.status}
5048
5499
  `;
5049
5500
  if (requirement2.tags && requirement2.tags.length > 0) {
5050
5501
  const tagNames = requirement2.tags.map((tag) => tag.name).join(", ");
5051
- message += `${chalk12.bold("Tags:")} ${tagNames}
5502
+ message += `${chalk13.bold("Tags:")} ${tagNames}
5052
5503
  `;
5053
5504
  }
5054
5505
  if (requirement2.assignee) {
5055
5506
  const assigneeName = requirement2.assignee.first_name || requirement2.assignee.last_name ? `${requirement2.assignee.first_name || ""} ${requirement2.assignee.last_name || ""}`.trim() : requirement2.assignee.email;
5056
- message += `${chalk12.bold("Assigned to:")} ${assigneeName} (${requirement2.assignee.email})
5507
+ message += `${chalk13.bold("Assigned to:")} ${assigneeName} (${requirement2.assignee.email})
5057
5508
  `;
5058
5509
  } else {
5059
- message += `${chalk12.bold("Assigned to:")} Unassigned
5510
+ message += `${chalk13.bold("Assigned to:")} Unassigned
5060
5511
  `;
5061
5512
  }
5062
- message += `${chalk12.bold("Created:")} ${new Date(requirement2.created_at).toLocaleString()}
5513
+ message += `${chalk13.bold("Created:")} ${new Date(requirement2.created_at).toLocaleString()}
5063
5514
  `;
5064
5515
  if (options?.showUpdated) {
5065
- message += `${chalk12.bold("Updated:")} ${new Date(requirement2.updated_at).toLocaleString()}
5516
+ message += `${chalk13.bold("Updated:")} ${new Date(requirement2.updated_at).toLocaleString()}
5066
5517
  `;
5067
5518
  }
5068
5519
  if (options?.showDescription && requirement2.description) {
5069
5520
  message += `
5070
5521
  ${divider}
5071
5522
  `;
5072
- message += `${chalk12.bold("Description:")}
5523
+ message += `${chalk13.bold("Description:")}
5073
5524
  ${requirement2.description}
5074
5525
  `;
5075
5526
  message += `${divider}
@@ -5079,7 +5530,7 @@ ${requirement2.description}
5079
5530
  message += `
5080
5531
  ${divider}
5081
5532
  `;
5082
- message += `${chalk12.bold("Content:")}
5533
+ message += `${chalk13.bold("Content:")}
5083
5534
  ${requirement2.content}
5084
5535
  `;
5085
5536
  message += `${divider}
@@ -5087,7 +5538,7 @@ ${requirement2.content}
5087
5538
  }
5088
5539
  if (options?.showTaskList) {
5089
5540
  message += `
5090
- ${chalk12.bold("Tasks:")}
5541
+ ${chalk13.bold("Tasks:")}
5091
5542
  `;
5092
5543
  if (requirement2.tasks && requirement2.tasks.length > 0) {
5093
5544
  for (const task2 of requirement2.tasks) {
@@ -5103,7 +5554,7 @@ ${chalk12.bold("Tasks:")}
5103
5554
  const completedTasks = tasks.filter((task2) => task2.status === "COMPLETED").length;
5104
5555
  const totalTasks = tasks.length;
5105
5556
  message += `
5106
- ${chalk12.bold("Tasks:")} ${completedTasks}/${totalTasks} completed
5557
+ ${chalk13.bold("Tasks:")} ${completedTasks}/${totalTasks} completed
5107
5558
  `;
5108
5559
  message += `${divider}
5109
5560
  `;
@@ -5126,59 +5577,59 @@ function getTaskStatusEmoji(status) {
5126
5577
  }
5127
5578
  function formatTaskOutput(task2, options) {
5128
5579
  const statusEmoji = getTaskStatusEmoji(task2.status);
5129
- const divider = chalk12.gray("\u2500".repeat(50));
5580
+ const divider = chalk13.gray("\u2500".repeat(50));
5130
5581
  let message = "";
5131
5582
  if (options?.successMessage) {
5132
- message += chalk12.green(`\u2705 ${options.successMessage}
5583
+ message += chalk13.green(`\u2705 ${options.successMessage}
5133
5584
 
5134
5585
  `);
5135
5586
  }
5136
- message += `${statusEmoji} ${chalk12.bold(task2.title)}
5587
+ message += `${statusEmoji} ${chalk13.bold(task2.title)}
5137
5588
 
5138
5589
  `;
5139
- message += `${chalk12.bold("Short ID:")} TASK-${task2.number}
5590
+ message += `${chalk13.bold("Short ID:")} TASK-${task2.number}
5140
5591
  `;
5141
- message += `${chalk12.bold("ID:")} ${task2.id}
5592
+ message += `${chalk13.bold("ID:")} ${task2.id}
5142
5593
  `;
5143
5594
  if (options?.apiUrl && options?.requirementId) {
5144
5595
  const webUiUrl = getWebUiUrl(options.apiUrl);
5145
- message += `${chalk12.bold("URL:")} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks
5596
+ message += `${chalk13.bold("URL:")} ${webUiUrl}/requirements/overview?id=${options.requirementId}&tab=tasks
5146
5597
  `;
5147
5598
  }
5148
- message += `${chalk12.bold("Project:")} ${options?.projectShortId || "N/A"}
5599
+ message += `${chalk13.bold("Project:")} ${options?.projectShortId || "N/A"}
5149
5600
  `;
5150
- message += `${chalk12.bold("Requirement:")} ${options?.requirementShortId || "N/A"}
5601
+ message += `${chalk13.bold("Requirement:")} ${options?.requirementShortId || "N/A"}
5151
5602
  `;
5152
- message += `${chalk12.bold("Status:")} ${task2.status}
5603
+ message += `${chalk13.bold("Status:")} ${task2.status}
5153
5604
  `;
5154
5605
  if (task2.assigned_to) {
5155
- message += `${chalk12.bold("Assigned to:")} ${task2.assigned_to}
5606
+ message += `${chalk13.bold("Assigned to:")} ${task2.assigned_to}
5156
5607
  `;
5157
5608
  } else {
5158
- message += `${chalk12.bold("Assigned to:")} Unassigned
5609
+ message += `${chalk13.bold("Assigned to:")} Unassigned
5159
5610
  `;
5160
5611
  }
5161
5612
  if (task2.created_at) {
5162
- message += `${chalk12.bold("Created:")} ${new Date(task2.created_at).toLocaleString()}
5613
+ message += `${chalk13.bold("Created:")} ${new Date(task2.created_at).toLocaleString()}
5163
5614
  `;
5164
5615
  }
5165
5616
  if (task2.updated_at) {
5166
- message += `${chalk12.bold("Updated:")} ${new Date(task2.updated_at).toLocaleString()}
5617
+ message += `${chalk13.bold("Updated:")} ${new Date(task2.updated_at).toLocaleString()}
5167
5618
  `;
5168
5619
  }
5169
5620
  if (task2.started_at) {
5170
- message += `${chalk12.bold("Started:")} ${new Date(task2.started_at).toLocaleString()}
5621
+ message += `${chalk13.bold("Started:")} ${new Date(task2.started_at).toLocaleString()}
5171
5622
  `;
5172
5623
  }
5173
5624
  if (task2.finished_at) {
5174
- message += `${chalk12.bold("Finished:")} ${new Date(task2.finished_at).toLocaleString()}
5625
+ message += `${chalk13.bold("Finished:")} ${new Date(task2.finished_at).toLocaleString()}
5175
5626
  `;
5176
5627
  }
5177
5628
  if (options?.showContent && task2.content) {
5178
5629
  message += `
5179
5630
  ${divider}
5180
5631
  `;
5181
- message += `${chalk12.bold("Content:")}
5632
+ message += `${chalk13.bold("Content:")}
5182
5633
  ${task2.content}
5183
5634
  `;
5184
5635
  message += `${divider}
@@ -5186,7 +5637,7 @@ ${task2.content}
5186
5637
  }
5187
5638
  if (task2.blocked_by && task2.blocked_by.length > 0) {
5188
5639
  message += `
5189
- ${chalk12.bold("Blocked by:")} ${task2.blocked_by.join(", ")}
5640
+ ${chalk13.bold("Blocked by:")} ${task2.blocked_by.join(", ")}
5190
5641
  `;
5191
5642
  }
5192
5643
  return message;
@@ -5769,9 +6220,9 @@ function formatProjectShowXml(project2) {
5769
6220
  }
5770
6221
  function formatRequirementTreeView(requirements, tasksMap) {
5771
6222
  if (requirements.length === 0) {
5772
- return chalk12.yellow("No requirements found.\n");
6223
+ return chalk13.yellow("No requirements found.\n");
5773
6224
  }
5774
- let output = chalk12.bold.cyan(`\u{1F4CB} Requirements (Tree View)
6225
+ let output = chalk13.bold.cyan(`\u{1F4CB} Requirements (Tree View)
5775
6226
 
5776
6227
  `);
5777
6228
  for (let i = 0; i < requirements.length; i++) {
@@ -5784,12 +6235,12 @@ function formatRequirementTreeView(requirements, tasksMap) {
5784
6235
  if (shortId.startsWith("REQ-REQ-")) {
5785
6236
  shortId = shortId.replace("REQ-REQ-", "REQ-");
5786
6237
  }
5787
- const branchInfo = req.branch ? chalk12.gray(` (branch: ${req.branch})`) : "";
5788
- output += `${reqPrefix}${chalk12.bold(shortId)} ${reqStatusEmoji} ${req.name}${branchInfo}
6238
+ const branchInfo = req.branch ? chalk13.gray(` (branch: ${req.branch})`) : "";
6239
+ output += `${reqPrefix}${chalk13.bold(shortId)} ${reqStatusEmoji} ${req.name}${branchInfo}
5789
6240
  `;
5790
6241
  const tasks = tasksMap.get(req.id) || [];
5791
6242
  if (tasks.length === 0) {
5792
- output += `${childPrefix}\u2514\u2500\u2500 ${chalk12.gray("(no tasks yet)")}
6243
+ output += `${childPrefix}\u2514\u2500\u2500 ${chalk13.gray("(no tasks yet)")}
5793
6244
  `;
5794
6245
  } else {
5795
6246
  for (let j = 0; j < tasks.length; j++) {
@@ -5797,7 +6248,7 @@ function formatRequirementTreeView(requirements, tasksMap) {
5797
6248
  const isLastTask = j === tasks.length - 1;
5798
6249
  const taskPrefix = isLastTask ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
5799
6250
  const taskStatusEmoji = getRequirementStatusEmoji(task2.status);
5800
- const blockedInfo = task2.blocked_by && task2.blocked_by.length > 0 ? chalk12.yellow(` [Blocked by: ${task2.blocked_by.length}]`) : "";
6251
+ const blockedInfo = task2.blocked_by && task2.blocked_by.length > 0 ? chalk13.yellow(` [Blocked by: ${task2.blocked_by.length}]`) : "";
5801
6252
  output += `${childPrefix}${taskPrefix}${task2.number} ${taskStatusEmoji} ${task2.title}${blockedInfo}
5802
6253
  `;
5803
6254
  }
@@ -5812,7 +6263,7 @@ function parseProjectId(input2) {
5812
6263
  }
5813
6264
 
5814
6265
  // src/utils/workspace-manager.ts
5815
- import chalk13 from "chalk";
6266
+ import chalk14 from "chalk";
5816
6267
  var WorkspaceManager = class {
5817
6268
  constructor() {
5818
6269
  this.activeRequirementId = null;
@@ -5852,13 +6303,13 @@ var WorkspaceManager = class {
5852
6303
  const msg = error instanceof Error ? error.message : String(error);
5853
6304
  return {
5854
6305
  success: false,
5855
- error: chalk13.red("\u274C Found .braingrid/project.json but failed to load it:") + "\n" + chalk13.dim(` ${msg}`) + "\n\n" + chalk13.dim("Try re-initializing with:\n") + chalk13.cyan(" braingrid init --force")
6306
+ error: chalk14.red("\u274C Found .braingrid/project.json but failed to load it:") + "\n" + chalk14.dim(` ${msg}`) + "\n\n" + chalk14.dim("Try re-initializing with:\n") + chalk14.cyan(" braingrid init --force")
5856
6307
  };
5857
6308
  }
5858
6309
  }
5859
6310
  return {
5860
6311
  success: false,
5861
- error: chalk13.red("\u274C No project specified and no local project found.") + "\n\n" + chalk13.dim("To initialize this workspace, run:\n") + chalk13.cyan(" braingrid init") + "\n\n" + chalk13.dim("Or specify a project explicitly:\n") + chalk13.cyan(" braingrid <command> -p PROJ-123")
6312
+ error: chalk14.red("\u274C No project specified and no local project found.") + "\n\n" + chalk14.dim("To initialize this workspace, run:\n") + chalk14.cyan(" braingrid init") + "\n\n" + chalk14.dim("Or specify a project explicitly:\n") + chalk14.cyan(" braingrid <command> -p PROJ-123")
5862
6313
  };
5863
6314
  }
5864
6315
  /**
@@ -5892,9 +6343,9 @@ var WorkspaceManager = class {
5892
6343
  }
5893
6344
  return {
5894
6345
  success: false,
5895
- error: chalk13.red("\u274C No requirement specified.") + "\n\n" + chalk13.dim("Unable to auto-detect requirement from branch name.\n") + chalk13.dim("Please provide a requirement ID explicitly:\n") + chalk13.cyan(" braingrid requirement show REQ-123") + "\n" + chalk13.dim(" or\n") + chalk13.cyan(" braingrid task list -r REQ-123") + "\n\n" + chalk13.dim(
6346
+ error: chalk14.red("\u274C No requirement specified.") + "\n\n" + chalk14.dim("Unable to auto-detect requirement from branch name.\n") + chalk14.dim("Please provide a requirement ID explicitly:\n") + chalk14.cyan(" braingrid requirement show REQ-123") + "\n" + chalk14.dim(" or\n") + chalk14.cyan(" braingrid task list -r REQ-123") + "\n\n" + chalk14.dim(
5896
6347
  "Tip: Name your branch with a requirement ID (e.g., feature/REQ-123-description)\n"
5897
- ) + chalk13.dim("to enable auto-detection.")
6348
+ ) + chalk14.dim("to enable auto-detection.")
5898
6349
  };
5899
6350
  }
5900
6351
  /**
@@ -5953,19 +6404,19 @@ async function handleProjectList(opts) {
5953
6404
  if (!isAuthenticated) {
5954
6405
  return {
5955
6406
  success: false,
5956
- message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6407
+ message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
5957
6408
  };
5958
6409
  }
5959
6410
  const format = opts.format || "table";
5960
6411
  if (!["table", "json", "xml", "markdown"].includes(format)) {
5961
6412
  return {
5962
6413
  success: false,
5963
- message: chalk14.red(
6414
+ message: chalk15.red(
5964
6415
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
5965
6416
  )
5966
6417
  };
5967
6418
  }
5968
- const stop = showSpinner("Loading projects", chalk14.gray);
6419
+ const stop = showSpinner("Loading projects", chalk15.gray);
5969
6420
  try {
5970
6421
  const response = await projectService.listProjects({
5971
6422
  page: opts.page ? parseInt(opts.page, 10) : 1,
@@ -5992,11 +6443,11 @@ async function handleProjectList(opts) {
5992
6443
  if (response.projects.length === 0) {
5993
6444
  return {
5994
6445
  success: true,
5995
- message: chalk14.yellow("No projects found."),
6446
+ message: chalk15.yellow("No projects found."),
5996
6447
  data: response
5997
6448
  };
5998
6449
  }
5999
- output = chalk14.bold("\u{1F4CB} Projects\n\n");
6450
+ output = chalk15.bold("\u{1F4CB} Projects\n\n");
6000
6451
  output += "ID Short ID Name Created\n";
6001
6452
  output += `${"\u2500".repeat(100)}
6002
6453
  `;
@@ -6035,21 +6486,21 @@ async function handleProjectShow(opts) {
6035
6486
  if (!isAuthenticated) {
6036
6487
  return {
6037
6488
  success: false,
6038
- message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6489
+ message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
6039
6490
  };
6040
6491
  }
6041
6492
  const format = opts.format || "table";
6042
6493
  if (!["table", "json", "xml", "markdown"].includes(format)) {
6043
6494
  return {
6044
6495
  success: false,
6045
- message: chalk14.red(
6496
+ message: chalk15.red(
6046
6497
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
6047
6498
  )
6048
6499
  };
6049
6500
  }
6050
6501
  if (opts.id) {
6051
6502
  const normalizedId = parseProjectId(opts.id);
6052
- const stop2 = showSpinner("Loading project", chalk14.gray);
6503
+ const stop2 = showSpinner("Loading project", chalk15.gray);
6053
6504
  try {
6054
6505
  const project2 = await projectService.getProject(normalizedId);
6055
6506
  stop2();
@@ -6068,23 +6519,23 @@ async function handleProjectShow(opts) {
6068
6519
  break;
6069
6520
  }
6070
6521
  default: {
6071
- output = chalk14.bold(`
6522
+ output = chalk15.bold(`
6072
6523
  \u{1F4C1} Project: ${project2.name}
6073
6524
 
6074
6525
  `);
6075
- output += `${chalk14.bold("ID:")} ${project2.id}
6526
+ output += `${chalk15.bold("ID:")} ${project2.id}
6076
6527
  `;
6077
- output += `${chalk14.bold("Short ID:")} ${project2.short_id}
6528
+ output += `${chalk15.bold("Short ID:")} ${project2.short_id}
6078
6529
  `;
6079
- output += `${chalk14.bold("Name:")} ${project2.name}
6530
+ output += `${chalk15.bold("Name:")} ${project2.name}
6080
6531
  `;
6081
6532
  if (project2.description) {
6082
- output += `${chalk14.bold("Description:")} ${project2.description}
6533
+ output += `${chalk15.bold("Description:")} ${project2.description}
6083
6534
  `;
6084
6535
  }
6085
- output += `${chalk14.bold("Created:")} ${new Date(project2.created_at).toLocaleString()}
6536
+ output += `${chalk15.bold("Created:")} ${new Date(project2.created_at).toLocaleString()}
6086
6537
  `;
6087
- output += `${chalk14.bold("Updated:")} ${new Date(project2.updated_at).toLocaleString()}
6538
+ output += `${chalk15.bold("Updated:")} ${new Date(project2.updated_at).toLocaleString()}
6088
6539
  `;
6089
6540
  break;
6090
6541
  }
@@ -6104,13 +6555,13 @@ async function handleProjectShow(opts) {
6104
6555
  if (parts.length !== 2) {
6105
6556
  return {
6106
6557
  success: false,
6107
- message: chalk14.red(
6558
+ message: chalk15.red(
6108
6559
  "\u274C Invalid repository format. Use: --repository owner/name (e.g., --repository microsoft/vscode)"
6109
6560
  )
6110
6561
  };
6111
6562
  }
6112
6563
  const [repositoryOwner, repositoryName] = parts;
6113
- const stop2 = showSpinner("Loading projects", chalk14.gray);
6564
+ const stop2 = showSpinner("Loading projects", chalk15.gray);
6114
6565
  try {
6115
6566
  const response = await projectService.listProjects({
6116
6567
  repository_owner: repositoryOwner,
@@ -6136,14 +6587,14 @@ async function handleProjectShow(opts) {
6136
6587
  break;
6137
6588
  }
6138
6589
  default: {
6139
- const repoDisplay = chalk14.cyan(`${repositoryOwner}/${repositoryName}`);
6590
+ const repoDisplay = chalk15.cyan(`${repositoryOwner}/${repositoryName}`);
6140
6591
  if (response.projects.length === 0) {
6141
6592
  return {
6142
6593
  success: true,
6143
- message: chalk14.yellow(`No projects found for repository ${repoDisplay}`)
6594
+ message: chalk15.yellow(`No projects found for repository ${repoDisplay}`)
6144
6595
  };
6145
6596
  }
6146
- output = chalk14.bold(`\u{1F4CB} Projects for ${repoDisplay}
6597
+ output = chalk15.bold(`\u{1F4CB} Projects for ${repoDisplay}
6147
6598
 
6148
6599
  `);
6149
6600
  output += "ID Short ID Name Created\n";
@@ -6178,7 +6629,7 @@ async function handleProjectShow(opts) {
6178
6629
  message: workspace.error
6179
6630
  };
6180
6631
  }
6181
- const stop = showSpinner("Loading project", chalk14.gray);
6632
+ const stop = showSpinner("Loading project", chalk15.gray);
6182
6633
  try {
6183
6634
  const project2 = await projectService.getProject(workspace.projectId);
6184
6635
  stop();
@@ -6197,23 +6648,23 @@ async function handleProjectShow(opts) {
6197
6648
  break;
6198
6649
  }
6199
6650
  default: {
6200
- output = chalk14.bold(`
6651
+ output = chalk15.bold(`
6201
6652
  \u{1F4C1} Project: ${project2.name}
6202
6653
 
6203
6654
  `);
6204
- output += `${chalk14.bold("ID:")} ${project2.id}
6655
+ output += `${chalk15.bold("ID:")} ${project2.id}
6205
6656
  `;
6206
- output += `${chalk14.bold("Short ID:")} ${project2.short_id}
6657
+ output += `${chalk15.bold("Short ID:")} ${project2.short_id}
6207
6658
  `;
6208
- output += `${chalk14.bold("Name:")} ${project2.name}
6659
+ output += `${chalk15.bold("Name:")} ${project2.name}
6209
6660
  `;
6210
6661
  if (project2.description) {
6211
- output += `${chalk14.bold("Description:")} ${project2.description}
6662
+ output += `${chalk15.bold("Description:")} ${project2.description}
6212
6663
  `;
6213
6664
  }
6214
- output += `${chalk14.bold("Created:")} ${new Date(project2.created_at).toLocaleString()}
6665
+ output += `${chalk15.bold("Created:")} ${new Date(project2.created_at).toLocaleString()}
6215
6666
  `;
6216
- output += `${chalk14.bold("Updated:")} ${new Date(project2.updated_at).toLocaleString()}
6667
+ output += `${chalk15.bold("Updated:")} ${new Date(project2.updated_at).toLocaleString()}
6217
6668
  `;
6218
6669
  break;
6219
6670
  }
@@ -6241,7 +6692,7 @@ async function handleProjectCreate(opts) {
6241
6692
  if (!isAuthenticated) {
6242
6693
  return {
6243
6694
  success: false,
6244
- message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6695
+ message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
6245
6696
  };
6246
6697
  }
6247
6698
  let repositoryId;
@@ -6252,21 +6703,21 @@ async function handleProjectCreate(opts) {
6252
6703
  if (parts.length !== 2) {
6253
6704
  return {
6254
6705
  success: false,
6255
- message: chalk14.red(
6706
+ message: chalk15.red(
6256
6707
  "\u274C Invalid repository format. Use: --repository owner/name (e.g., microsoft/vscode)"
6257
6708
  )
6258
6709
  };
6259
6710
  }
6260
6711
  const [owner, name] = parts;
6261
6712
  const repositoryService = new RepositoryService(config2.apiUrl, auth);
6262
- const stop2 = showSpinner(`Looking up repository ${opts.repository}`, chalk14.gray);
6713
+ const stop2 = showSpinner(`Looking up repository ${opts.repository}`, chalk15.gray);
6263
6714
  try {
6264
6715
  const repoId = await getRepositoryId(repositoryService, owner, name);
6265
6716
  stop2();
6266
6717
  if (!repoId) {
6267
6718
  return {
6268
6719
  success: false,
6269
- message: chalk14.red(
6720
+ message: chalk15.red(
6270
6721
  `\u274C Repository '${opts.repository}' not found. Please check the name or ensure you have access.`
6271
6722
  )
6272
6723
  };
@@ -6276,7 +6727,7 @@ async function handleProjectCreate(opts) {
6276
6727
  stop2();
6277
6728
  }
6278
6729
  }
6279
- const stop = showSpinner("Creating project", chalk14.gray);
6730
+ const stop = showSpinner("Creating project", chalk15.gray);
6280
6731
  try {
6281
6732
  const project2 = await projectService.createProject({
6282
6733
  name: opts.name,
@@ -6284,9 +6735,9 @@ async function handleProjectCreate(opts) {
6284
6735
  repository_id: repositoryId
6285
6736
  });
6286
6737
  stop();
6287
- let message = chalk14.green(`\u2705 Created project ${project2.short_id}: ${project2.name}`);
6738
+ let message = chalk15.green(`\u2705 Created project ${project2.short_id}: ${project2.name}`);
6288
6739
  if (opts.repository && repositoryId) {
6289
- message += chalk14.gray(` (linked to ${opts.repository})`);
6740
+ message += chalk15.gray(` (linked to ${opts.repository})`);
6290
6741
  }
6291
6742
  return {
6292
6743
  success: true,
@@ -6310,19 +6761,19 @@ async function handleProjectUpdate(id, opts) {
6310
6761
  if (!isAuthenticated) {
6311
6762
  return {
6312
6763
  success: false,
6313
- message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6764
+ message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
6314
6765
  };
6315
6766
  }
6316
6767
  if (!opts.name && !opts.description) {
6317
6768
  return {
6318
6769
  success: false,
6319
- message: chalk14.red(
6770
+ message: chalk15.red(
6320
6771
  "\u274C Please provide at least one field to update (--name or --description)"
6321
6772
  )
6322
6773
  };
6323
6774
  }
6324
6775
  const normalizedId = parseProjectId(id);
6325
- const stop = showSpinner("Updating project", chalk14.gray);
6776
+ const stop = showSpinner("Updating project", chalk15.gray);
6326
6777
  try {
6327
6778
  const project2 = await projectService.updateProject(normalizedId, {
6328
6779
  name: opts.name,
@@ -6331,7 +6782,7 @@ async function handleProjectUpdate(id, opts) {
6331
6782
  stop();
6332
6783
  return {
6333
6784
  success: true,
6334
- message: chalk14.green(`\u2705 Updated project ${project2.short_id}: ${project2.name}`),
6785
+ message: chalk15.green(`\u2705 Updated project ${project2.short_id}: ${project2.name}`),
6335
6786
  data: project2
6336
6787
  };
6337
6788
  } finally {
@@ -6351,25 +6802,25 @@ async function handleProjectDelete(id, opts) {
6351
6802
  if (!isAuthenticated) {
6352
6803
  return {
6353
6804
  success: false,
6354
- message: chalk14.red("\u274C Not authenticated. Please run `braingrid login` first.")
6805
+ message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
6355
6806
  };
6356
6807
  }
6357
6808
  if (!opts.force) {
6358
6809
  return {
6359
6810
  success: false,
6360
- message: chalk14.yellow(
6811
+ message: chalk15.yellow(
6361
6812
  "\u26A0\uFE0F Deleting a project is permanent. Use --force to confirm deletion."
6362
6813
  )
6363
6814
  };
6364
6815
  }
6365
6816
  const normalizedId = parseProjectId(id);
6366
- const stop = showSpinner("Deleting project", chalk14.gray);
6817
+ const stop = showSpinner("Deleting project", chalk15.gray);
6367
6818
  try {
6368
6819
  await projectService.deleteProject(normalizedId);
6369
6820
  stop();
6370
6821
  return {
6371
6822
  success: true,
6372
- message: chalk14.green(`\u2705 Deleted project ${id}`)
6823
+ message: chalk15.green(`\u2705 Deleted project ${id}`)
6373
6824
  };
6374
6825
  } finally {
6375
6826
  stop();
@@ -6383,7 +6834,7 @@ async function handleProjectDelete(id, opts) {
6383
6834
  }
6384
6835
 
6385
6836
  // src/handlers/requirement.handlers.ts
6386
- import chalk15 from "chalk";
6837
+ import chalk16 from "chalk";
6387
6838
 
6388
6839
  // src/services/requirement-service.ts
6389
6840
  var RequirementService = class {
@@ -6533,14 +6984,14 @@ async function handleRequirementList(opts) {
6533
6984
  if (!isAuthenticated) {
6534
6985
  return {
6535
6986
  success: false,
6536
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
6987
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
6537
6988
  };
6538
6989
  }
6539
6990
  const format = opts.format || "table";
6540
6991
  if (!opts.tree && !["table", "json", "xml", "markdown"].includes(format)) {
6541
6992
  return {
6542
6993
  success: false,
6543
- message: chalk15.red(
6994
+ message: chalk16.red(
6544
6995
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
6545
6996
  )
6546
6997
  };
@@ -6553,7 +7004,7 @@ async function handleRequirementList(opts) {
6553
7004
  };
6554
7005
  }
6555
7006
  const projectId = workspace.projectId;
6556
- stopSpinner = showSpinner("Loading requirements", chalk15.gray);
7007
+ stopSpinner = showSpinner("Loading requirements", chalk16.gray);
6557
7008
  const response = await requirementService.listProjectRequirements(projectId, {
6558
7009
  status: opts.status,
6559
7010
  page: opts.page ? parseInt(opts.page, 10) : 1,
@@ -6565,10 +7016,10 @@ async function handleRequirementList(opts) {
6565
7016
  if (response.requirements.length === 0) {
6566
7017
  return {
6567
7018
  success: true,
6568
- message: chalk15.yellow("No requirements found.")
7019
+ message: chalk16.yellow("No requirements found.")
6569
7020
  };
6570
7021
  }
6571
- stopSpinner = showSpinner("Loading tasks for tree view", chalk15.gray);
7022
+ stopSpinner = showSpinner("Loading tasks for tree view", chalk16.gray);
6572
7023
  const tasksMap = /* @__PURE__ */ new Map();
6573
7024
  const taskPromises = response.requirements.map(async (req) => {
6574
7025
  try {
@@ -6591,7 +7042,7 @@ Page ${response.pagination.page} of ${Math.ceil(response.pagination.total / resp
6591
7042
  finalOutput += ` (${response.pagination.total} total)`;
6592
7043
  if (response.pagination?.has_more) {
6593
7044
  finalOutput += `
6594
- ${chalk15.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.")}`;
7045
+ ${chalk16.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.")}`;
6595
7046
  }
6596
7047
  return {
6597
7048
  success: true,
@@ -6617,10 +7068,10 @@ ${chalk15.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.
6617
7068
  if (response.requirements.length === 0) {
6618
7069
  return {
6619
7070
  success: true,
6620
- message: chalk15.yellow("No requirements found.")
7071
+ message: chalk16.yellow("No requirements found.")
6621
7072
  };
6622
7073
  }
6623
- output = chalk15.bold("\u{1F4CB} Requirements\n\n");
7074
+ output = chalk16.bold("\u{1F4CB} Requirements\n\n");
6624
7075
  output += "Short ID Status Name Branch Progress\n";
6625
7076
  output += `${"\u2500".repeat(90)}
6626
7077
  `;
@@ -6642,7 +7093,7 @@ ${chalk15.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.
6642
7093
  }
6643
7094
  if (response.pagination?.has_more) {
6644
7095
  output += `
6645
- ${chalk15.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.")}`;
7096
+ ${chalk16.yellow("\u26A0\uFE0F More requirements exist. Use --limit to see more.")}`;
6646
7097
  }
6647
7098
  return {
6648
7099
  success: true,
@@ -6667,14 +7118,14 @@ async function handleRequirementShow(opts) {
6667
7118
  if (!isAuthenticated) {
6668
7119
  return {
6669
7120
  success: false,
6670
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7121
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
6671
7122
  };
6672
7123
  }
6673
7124
  const format = opts?.format || "table";
6674
7125
  if (!["table", "json", "xml", "markdown"].includes(format)) {
6675
7126
  return {
6676
7127
  success: false,
6677
- message: chalk15.red(
7128
+ message: chalk16.red(
6678
7129
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
6679
7130
  )
6680
7131
  };
@@ -6696,7 +7147,7 @@ async function handleRequirementShow(opts) {
6696
7147
  }
6697
7148
  const projectId = workspace.projectId;
6698
7149
  const normalizedId = normalizeRequirementId(requirementId);
6699
- stopSpinner = showSpinner("Loading requirement", chalk15.gray);
7150
+ stopSpinner = showSpinner("Loading requirement", chalk16.gray);
6700
7151
  const requirement2 = await requirementService.getProjectRequirement(projectId, normalizedId);
6701
7152
  stopSpinner();
6702
7153
  stopSpinner = null;
@@ -6752,7 +7203,7 @@ async function handleRequirementCreate(opts) {
6752
7203
  if (!isAuthenticated) {
6753
7204
  return {
6754
7205
  success: false,
6755
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7206
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
6756
7207
  };
6757
7208
  }
6758
7209
  const workspace = await workspaceManager.getProject(opts.project);
@@ -6769,7 +7220,7 @@ async function handleRequirementCreate(opts) {
6769
7220
  if (emailRegex.test(opts.assignedTo)) {
6770
7221
  return {
6771
7222
  success: false,
6772
- message: chalk15.red(
7223
+ message: chalk16.red(
6773
7224
  "\u274C Email addresses are not supported for --assigned-to yet.\nPlease use the user UUID instead.\nEmail lookup will be supported when the API provides a user lookup endpoint."
6774
7225
  )
6775
7226
  };
@@ -6777,7 +7228,7 @@ async function handleRequirementCreate(opts) {
6777
7228
  if (!uuidRegex.test(opts.assignedTo)) {
6778
7229
  return {
6779
7230
  success: false,
6780
- message: chalk15.red(
7231
+ message: chalk16.red(
6781
7232
  '\u274C Invalid UUID format for --assigned-to.\nPlease provide a valid user UUID (e.g., "550e8400-e29b-41d4-a716-446655440000")'
6782
7233
  )
6783
7234
  };
@@ -6789,12 +7240,12 @@ async function handleRequirementCreate(opts) {
6789
7240
  if (!tagResult.valid) {
6790
7241
  return {
6791
7242
  success: false,
6792
- message: chalk15.red(`\u274C ${tagResult.error}`)
7243
+ message: chalk16.red(`\u274C ${tagResult.error}`)
6793
7244
  };
6794
7245
  }
6795
7246
  validatedTags = tagResult.tags;
6796
7247
  }
6797
- stopSpinner = showSpinner("Creating requirement", chalk15.gray);
7248
+ stopSpinner = showSpinner("Creating requirement", chalk16.gray);
6798
7249
  const requirement2 = await requirementService.createProjectRequirement(projectId, {
6799
7250
  name: opts.name,
6800
7251
  content: opts.content || null,
@@ -6828,7 +7279,7 @@ async function handleRequirementCreate(opts) {
6828
7279
  const errorMessage = error instanceof Error ? error.message : String(error);
6829
7280
  return {
6830
7281
  success: false,
6831
- message: chalk15.red(`\u274C Error creating requirement: ${errorMessage}`)
7282
+ message: chalk16.red(`\u274C Error creating requirement: ${errorMessage}`)
6832
7283
  };
6833
7284
  }
6834
7285
  }
@@ -6840,14 +7291,14 @@ async function handleRequirementSpecify(opts) {
6840
7291
  if (!isAuthenticated) {
6841
7292
  return {
6842
7293
  success: false,
6843
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7294
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
6844
7295
  };
6845
7296
  }
6846
7297
  const format = opts.format || "table";
6847
7298
  if (!["table", "json", "xml", "markdown"].includes(format)) {
6848
7299
  return {
6849
7300
  success: false,
6850
- message: chalk15.red(
7301
+ message: chalk16.red(
6851
7302
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
6852
7303
  )
6853
7304
  };
@@ -6863,13 +7314,13 @@ async function handleRequirementSpecify(opts) {
6863
7314
  if (opts.prompt.length < 10) {
6864
7315
  return {
6865
7316
  success: false,
6866
- message: chalk15.red("\u274C Prompt must be at least 10 characters long")
7317
+ message: chalk16.red("\u274C Prompt must be at least 10 characters long")
6867
7318
  };
6868
7319
  }
6869
7320
  if (opts.prompt.length > 5e3) {
6870
7321
  return {
6871
7322
  success: false,
6872
- message: chalk15.red("\u274C Prompt must be no more than 5000 characters long")
7323
+ message: chalk16.red("\u274C Prompt must be no more than 5000 characters long")
6873
7324
  };
6874
7325
  }
6875
7326
  let validatedTags;
@@ -6878,7 +7329,7 @@ async function handleRequirementSpecify(opts) {
6878
7329
  if (!tagResult.valid) {
6879
7330
  return {
6880
7331
  success: false,
6881
- message: chalk15.red(`\u274C ${tagResult.error}`)
7332
+ message: chalk16.red(`\u274C ${tagResult.error}`)
6882
7333
  };
6883
7334
  }
6884
7335
  validatedTags = tagResult.tags;
@@ -6941,13 +7392,13 @@ async function handleRequirementUpdate(opts) {
6941
7392
  if (!isAuthenticated) {
6942
7393
  return {
6943
7394
  success: false,
6944
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7395
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
6945
7396
  };
6946
7397
  }
6947
7398
  if (!opts.status && !opts.name && !opts.content) {
6948
7399
  return {
6949
7400
  success: false,
6950
- message: chalk15.red(
7401
+ message: chalk16.red(
6951
7402
  "\u274C Please provide at least one field to update (--status, --name, or --content)"
6952
7403
  )
6953
7404
  };
@@ -6969,7 +7420,7 @@ async function handleRequirementUpdate(opts) {
6969
7420
  }
6970
7421
  const projectId = workspace.projectId;
6971
7422
  const normalizedId = normalizeRequirementId(requirementId);
6972
- stopSpinner = showSpinner("Updating requirement", chalk15.gray);
7423
+ stopSpinner = showSpinner("Updating requirement", chalk16.gray);
6973
7424
  const requirement2 = await requirementService.updateProjectRequirement(projectId, normalizedId, {
6974
7425
  status: opts.status,
6975
7426
  name: opts.name,
@@ -6979,7 +7430,7 @@ async function handleRequirementUpdate(opts) {
6979
7430
  stopSpinner = null;
6980
7431
  return {
6981
7432
  success: true,
6982
- message: chalk15.green(`\u2705 Updated requirement ${requirement2.short_id}: ${requirement2.name}`),
7433
+ message: chalk16.green(`\u2705 Updated requirement ${requirement2.short_id}: ${requirement2.name}`),
6983
7434
  data: requirement2
6984
7435
  };
6985
7436
  } catch (error) {
@@ -7000,13 +7451,13 @@ async function handleRequirementDelete(opts) {
7000
7451
  if (!isAuthenticated) {
7001
7452
  return {
7002
7453
  success: false,
7003
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7454
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7004
7455
  };
7005
7456
  }
7006
7457
  if (!opts.force) {
7007
7458
  return {
7008
7459
  success: false,
7009
- message: chalk15.yellow(
7460
+ message: chalk16.yellow(
7010
7461
  "\u26A0\uFE0F Deleting a requirement is permanent. Use --force to confirm deletion."
7011
7462
  )
7012
7463
  };
@@ -7028,13 +7479,13 @@ async function handleRequirementDelete(opts) {
7028
7479
  }
7029
7480
  const projectId = workspace.projectId;
7030
7481
  const normalizedId = normalizeRequirementId(requirementId);
7031
- stopSpinner = showSpinner("Deleting requirement", chalk15.gray);
7482
+ stopSpinner = showSpinner("Deleting requirement", chalk16.gray);
7032
7483
  await requirementService.deleteProjectRequirement(projectId, normalizedId);
7033
7484
  stopSpinner();
7034
7485
  stopSpinner = null;
7035
7486
  return {
7036
7487
  success: true,
7037
- message: chalk15.green(`\u2705 Deleted requirement ${requirementId}`)
7488
+ message: chalk16.green(`\u2705 Deleted requirement ${requirementId}`)
7038
7489
  };
7039
7490
  } catch (error) {
7040
7491
  if (stopSpinner) {
@@ -7054,14 +7505,14 @@ async function handleRequirementBreakdown(opts) {
7054
7505
  if (!isAuthenticated) {
7055
7506
  return {
7056
7507
  success: false,
7057
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7508
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7058
7509
  };
7059
7510
  }
7060
7511
  const format = opts.format || "table";
7061
7512
  if (!["table", "json", "xml", "markdown"].includes(format)) {
7062
7513
  return {
7063
7514
  success: false,
7064
- message: chalk15.red(
7515
+ message: chalk16.red(
7065
7516
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
7066
7517
  )
7067
7518
  };
@@ -7083,7 +7534,7 @@ async function handleRequirementBreakdown(opts) {
7083
7534
  }
7084
7535
  const projectId = workspace.projectId;
7085
7536
  const normalizedId = normalizeRequirementId(requirementId);
7086
- stop = showSpinner("Checking requirement...", chalk15.gray);
7537
+ stop = showSpinner("Checking requirement...", chalk16.gray);
7087
7538
  const requirement2 = await requirementService.getProjectRequirement(projectId, normalizedId);
7088
7539
  stop();
7089
7540
  const taskCount = requirement2.tasks?.length ?? requirement2.task_progress?.total ?? 0;
@@ -7091,13 +7542,13 @@ async function handleRequirementBreakdown(opts) {
7091
7542
  const shortId = requirement2.short_id || normalizedId;
7092
7543
  return {
7093
7544
  success: false,
7094
- message: chalk15.red(
7545
+ message: chalk16.red(
7095
7546
  `\u274C Cannot breakdown requirement ${shortId} - it already has ${taskCount} task(s)
7096
7547
 
7097
7548
  `
7098
- ) + "The breakdown command is only for initial task generation from requirements.\nOnce tasks exist, you should manage them individually.\n\n" + chalk15.bold("To add more tasks to this requirement:\n") + chalk15.cyan(` braingrid task create -r ${shortId} --title "Task title"
7549
+ ) + "The breakdown command is only for initial task generation from requirements.\nOnce tasks exist, you should manage them individually.\n\n" + chalk16.bold("To add more tasks to this requirement:\n") + chalk16.cyan(` braingrid task create -r ${shortId} --title "Task title"
7099
7550
 
7100
- `) + chalk15.bold("To view existing tasks:\n") + chalk15.cyan(` braingrid task list -r ${shortId}`)
7551
+ `) + chalk16.bold("To view existing tasks:\n") + chalk16.cyan(` braingrid task list -r ${shortId}`)
7101
7552
  };
7102
7553
  }
7103
7554
  stop = showSpinner("Breaking down requirement into tasks...");
@@ -7118,7 +7569,7 @@ async function handleRequirementBreakdown(opts) {
7118
7569
  break;
7119
7570
  }
7120
7571
  default: {
7121
- output = chalk15.green(
7572
+ output = chalk16.green(
7122
7573
  `\u2705 Generated ${response.tasks.length} tasks for ${response.requirement_short_id}
7123
7574
 
7124
7575
  `
@@ -7156,7 +7607,7 @@ async function handleRequirementBreakdown(opts) {
7156
7607
  const errorMessage = error instanceof Error ? error.message : String(error);
7157
7608
  return {
7158
7609
  success: false,
7159
- message: chalk15.red(`\u274C Error breaking down requirement: ${errorMessage}`)
7610
+ message: chalk16.red(`\u274C Error breaking down requirement: ${errorMessage}`)
7160
7611
  };
7161
7612
  }
7162
7613
  }
@@ -7168,14 +7619,14 @@ async function handleRequirementBuild(opts) {
7168
7619
  if (!isAuthenticated) {
7169
7620
  return {
7170
7621
  success: false,
7171
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7622
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7172
7623
  };
7173
7624
  }
7174
7625
  const format = opts.format || "markdown";
7175
7626
  if (!["markdown", "json", "xml"].includes(format)) {
7176
7627
  return {
7177
7628
  success: false,
7178
- message: chalk15.red("\u274C Invalid format. Must be one of: markdown, json, xml")
7629
+ message: chalk16.red("\u274C Invalid format. Must be one of: markdown, json, xml")
7179
7630
  };
7180
7631
  }
7181
7632
  const requirementResult = await workspaceManager.getRequirement(opts.id);
@@ -7195,7 +7646,7 @@ async function handleRequirementBuild(opts) {
7195
7646
  }
7196
7647
  const projectId = workspace.projectId;
7197
7648
  const normalizedId = normalizeRequirementId(requirementId);
7198
- stopSpinner = showSpinner("Building requirement with tasks", chalk15.gray);
7649
+ stopSpinner = showSpinner("Building requirement with tasks", chalk16.gray);
7199
7650
  const requirement2 = await requirementService.getProjectRequirement(projectId, normalizedId);
7200
7651
  stopSpinner();
7201
7652
  stopSpinner = null;
@@ -7243,14 +7694,14 @@ async function handleCreateGitBranch(opts) {
7243
7694
  if (!isAuthenticated) {
7244
7695
  return {
7245
7696
  success: false,
7246
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7697
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7247
7698
  };
7248
7699
  }
7249
7700
  const format = opts.format || "table";
7250
7701
  if (!["table", "json", "markdown"].includes(format)) {
7251
7702
  return {
7252
7703
  success: false,
7253
- message: chalk15.red(
7704
+ message: chalk16.red(
7254
7705
  `\u274C Invalid format: ${format}. Supported formats: table, json, markdown`
7255
7706
  )
7256
7707
  };
@@ -7278,7 +7729,7 @@ async function handleCreateGitBranch(opts) {
7278
7729
  if (!user) {
7279
7730
  return {
7280
7731
  success: false,
7281
- message: chalk15.red("\u274C Could not get current user for branch name generation")
7732
+ message: chalk16.red("\u274C Could not get current user for branch name generation")
7282
7733
  };
7283
7734
  }
7284
7735
  const requirement2 = await requirementService.getProjectRequirement(projectId, normalizedId);
@@ -7287,7 +7738,7 @@ async function handleCreateGitBranch(opts) {
7287
7738
  const sluggedName = slugify(requirement2.name);
7288
7739
  branchName = `${username}/${reqShortId}-${sluggedName}`;
7289
7740
  }
7290
- stopSpinner = showSpinner("Creating GitHub branch...", chalk15.gray);
7741
+ stopSpinner = showSpinner("Creating GitHub branch...", chalk16.gray);
7291
7742
  const response = await requirementService.createGitBranch(projectId, normalizedId, {
7292
7743
  branchName,
7293
7744
  baseBranch: opts.base
@@ -7319,13 +7770,13 @@ git fetch origin && git checkout ${response.branch.name}
7319
7770
  break;
7320
7771
  }
7321
7772
  default: {
7322
- output = chalk15.green(`\u2705 Created branch: ${response.branch.name}
7773
+ output = chalk16.green(`\u2705 Created branch: ${response.branch.name}
7323
7774
 
7324
7775
  `);
7325
- output += `${chalk15.bold("SHA:")} ${response.branch.sha.substring(0, 7)}
7776
+ output += `${chalk16.bold("SHA:")} ${response.branch.sha.substring(0, 7)}
7326
7777
  `;
7327
7778
  output += `
7328
- ${chalk15.dim("To checkout:")} git fetch origin && git checkout ${response.branch.name}`;
7779
+ ${chalk16.dim("To checkout:")} git fetch origin && git checkout ${response.branch.name}`;
7329
7780
  break;
7330
7781
  }
7331
7782
  }
@@ -7351,7 +7802,7 @@ async function handleReviewAcceptance(opts) {
7351
7802
  if (!isAuthenticated) {
7352
7803
  return {
7353
7804
  success: false,
7354
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7805
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7355
7806
  };
7356
7807
  }
7357
7808
  const requirementResult = await workspaceManager.getRequirement(opts.id);
@@ -7373,9 +7824,9 @@ async function handleReviewAcceptance(opts) {
7373
7824
  const normalizedId = normalizeRequirementId(requirementId);
7374
7825
  let prNumber = opts.pr;
7375
7826
  if (!prNumber) {
7376
- const { execAsync: execAsync5 } = await import("./command-execution-HEGDCOLO.js");
7827
+ const { execAsync: execAsync6 } = await import("./command-execution-HEGDCOLO.js");
7377
7828
  try {
7378
- const { stdout } = await execAsync5("gh pr view --json number -q .number");
7829
+ const { stdout } = await execAsync6("gh pr view --json number -q .number");
7379
7830
  const detectedPrNumber = stdout.trim();
7380
7831
  if (!detectedPrNumber) {
7381
7832
  throw new Error("No PR number returned from gh CLI");
@@ -7384,13 +7835,13 @@ async function handleReviewAcceptance(opts) {
7384
7835
  } catch {
7385
7836
  return {
7386
7837
  success: false,
7387
- message: chalk15.red(
7838
+ message: chalk16.red(
7388
7839
  "\u274C No PR specified and could not detect PR for current branch.\n Use --pr <number> or ensure you have an open PR for this branch."
7389
7840
  )
7390
7841
  };
7391
7842
  }
7392
7843
  }
7393
- console.log(chalk15.bold("\n\u{1F50D} AI Code Review\n"));
7844
+ console.log(chalk16.bold("\n\u{1F50D} AI Code Review\n"));
7394
7845
  let fullOutput = "";
7395
7846
  await requirementService.reviewAcceptance(
7396
7847
  projectId,
@@ -7423,14 +7874,14 @@ async function handleRequirementTagList(opts) {
7423
7874
  if (!isAuthenticated) {
7424
7875
  return {
7425
7876
  success: false,
7426
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7877
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7427
7878
  };
7428
7879
  }
7429
7880
  const format = opts.format || "table";
7430
7881
  if (!["table", "json", "xml", "markdown"].includes(format)) {
7431
7882
  return {
7432
7883
  success: false,
7433
- message: chalk15.red(
7884
+ message: chalk16.red(
7434
7885
  `\u274C Invalid format: ${format}. Supported formats: table, json, xml, markdown`
7435
7886
  )
7436
7887
  };
@@ -7452,7 +7903,7 @@ async function handleRequirementTagList(opts) {
7452
7903
  }
7453
7904
  const projectId = workspace.projectId;
7454
7905
  const normalizedId = normalizeRequirementId(requirementId);
7455
- stopSpinner = showSpinner("Loading tags", chalk15.gray);
7906
+ stopSpinner = showSpinner("Loading tags", chalk16.gray);
7456
7907
  const tags = await requirementService.listRequirementTags(projectId, normalizedId);
7457
7908
  stopSpinner();
7458
7909
  stopSpinner = null;
@@ -7499,11 +7950,11 @@ async function handleRequirementTagList(opts) {
7499
7950
  if (tags.length === 0) {
7500
7951
  return {
7501
7952
  success: true,
7502
- message: chalk15.yellow(`No tags found for ${normalizedId}.`),
7953
+ message: chalk16.yellow(`No tags found for ${normalizedId}.`),
7503
7954
  data: tags
7504
7955
  };
7505
7956
  }
7506
- output = chalk15.bold(`\u{1F3F7}\uFE0F Tags for ${normalizedId}
7957
+ output = chalk16.bold(`\u{1F3F7}\uFE0F Tags for ${normalizedId}
7507
7958
 
7508
7959
  `);
7509
7960
  output += "Name Color\n";
@@ -7544,20 +7995,20 @@ async function handleRequirementTagAdd(opts) {
7544
7995
  if (!isAuthenticated) {
7545
7996
  return {
7546
7997
  success: false,
7547
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
7998
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7548
7999
  };
7549
8000
  }
7550
8001
  if (!opts.name || opts.name.trim().length === 0) {
7551
8002
  return {
7552
8003
  success: false,
7553
- message: chalk15.red("\u274C Tag name is required")
8004
+ message: chalk16.red("\u274C Tag name is required")
7554
8005
  };
7555
8006
  }
7556
8007
  const colorResult = validateHexColor(opts.color);
7557
8008
  if (!colorResult.valid) {
7558
8009
  return {
7559
8010
  success: false,
7560
- message: chalk15.red(`\u274C ${colorResult.error}`)
8011
+ message: chalk16.red(`\u274C ${colorResult.error}`)
7561
8012
  };
7562
8013
  }
7563
8014
  const requirementResult = await workspaceManager.getRequirement(opts.requirementId);
@@ -7577,7 +8028,7 @@ async function handleRequirementTagAdd(opts) {
7577
8028
  }
7578
8029
  const projectId = workspace.projectId;
7579
8030
  const normalizedId = normalizeRequirementId(requirementId);
7580
- stopSpinner = showSpinner("Adding tag", chalk15.gray);
8031
+ stopSpinner = showSpinner("Adding tag", chalk16.gray);
7581
8032
  const response = await requirementService.addRequirementTag(projectId, normalizedId, {
7582
8033
  name: opts.name.trim(),
7583
8034
  color: opts.color
@@ -7586,7 +8037,7 @@ async function handleRequirementTagAdd(opts) {
7586
8037
  stopSpinner = null;
7587
8038
  return {
7588
8039
  success: true,
7589
- message: chalk15.green(
8040
+ message: chalk16.green(
7590
8041
  `\u2705 Added tag "${response.tag.name}" (${response.tag.color}) to ${normalizedId}`
7591
8042
  ),
7592
8043
  data: response
@@ -7602,13 +8053,13 @@ async function handleRequirementTagAdd(opts) {
7602
8053
  if (errorData?.code === "MAX_TAGS_EXCEEDED") {
7603
8054
  return {
7604
8055
  success: false,
7605
- message: chalk15.red("\u274C Maximum 5 tags allowed per requirement")
8056
+ message: chalk16.red("\u274C Maximum 5 tags allowed per requirement")
7606
8057
  };
7607
8058
  }
7608
8059
  if (errorData?.code === "TAG_ALREADY_ASSOCIATED") {
7609
8060
  return {
7610
8061
  success: false,
7611
- message: chalk15.red(`\u274C Tag "${opts.name}" is already associated with this requirement`)
8062
+ message: chalk16.red(`\u274C Tag "${opts.name}" is already associated with this requirement`)
7612
8063
  };
7613
8064
  }
7614
8065
  }
@@ -7630,13 +8081,13 @@ async function handleRequirementTagRemove(opts) {
7630
8081
  if (!isAuthenticated) {
7631
8082
  return {
7632
8083
  success: false,
7633
- message: chalk15.red("\u274C Not authenticated. Please run `braingrid login` first.")
8084
+ message: chalk16.red("\u274C Not authenticated. Please run `braingrid login` first.")
7634
8085
  };
7635
8086
  }
7636
8087
  if (!opts.name || opts.name.trim().length === 0) {
7637
8088
  return {
7638
8089
  success: false,
7639
- message: chalk15.red("\u274C Tag name is required")
8090
+ message: chalk16.red("\u274C Tag name is required")
7640
8091
  };
7641
8092
  }
7642
8093
  const requirementResult = await workspaceManager.getRequirement(opts.requirementId);
@@ -7656,13 +8107,13 @@ async function handleRequirementTagRemove(opts) {
7656
8107
  }
7657
8108
  const projectId = workspace.projectId;
7658
8109
  const normalizedId = normalizeRequirementId(requirementId);
7659
- stopSpinner = showSpinner("Removing tag", chalk15.gray);
8110
+ stopSpinner = showSpinner("Removing tag", chalk16.gray);
7660
8111
  await requirementService.removeRequirementTag(projectId, normalizedId, opts.name.trim());
7661
8112
  stopSpinner();
7662
8113
  stopSpinner = null;
7663
8114
  return {
7664
8115
  success: true,
7665
- message: chalk15.green(`\u2705 Removed tag "${opts.name}" from ${normalizedId}`)
8116
+ message: chalk16.green(`\u2705 Removed tag "${opts.name}" from ${normalizedId}`)
7666
8117
  };
7667
8118
  } catch (error) {
7668
8119
  if (stopSpinner) {
@@ -7675,13 +8126,13 @@ async function handleRequirementTagRemove(opts) {
7675
8126
  if (errorData?.code === "TAG_NOT_FOUND") {
7676
8127
  return {
7677
8128
  success: false,
7678
- message: chalk15.red(`\u274C Tag "${opts.name}" not found`)
8129
+ message: chalk16.red(`\u274C Tag "${opts.name}" not found`)
7679
8130
  };
7680
8131
  }
7681
8132
  if (errorData?.code === "ASSOCIATION_NOT_FOUND") {
7682
8133
  return {
7683
8134
  success: false,
7684
- message: chalk15.red(`\u274C Tag "${opts.name}" is not associated with this requirement`)
8135
+ message: chalk16.red(`\u274C Tag "${opts.name}" is not associated with this requirement`)
7685
8136
  };
7686
8137
  }
7687
8138
  }
@@ -7697,88 +8148,136 @@ async function handleRequirementTagRemove(opts) {
7697
8148
  }
7698
8149
 
7699
8150
  // src/handlers/status.handlers.ts
7700
- import chalk16 from "chalk";
8151
+ import fs6 from "fs";
8152
+ import path8 from "path";
8153
+ import chalk17 from "chalk";
7701
8154
  function getAuth2() {
7702
8155
  const config2 = getConfig();
7703
8156
  return new BraingridAuth(config2.apiUrl);
7704
8157
  }
8158
+ function formatFileSize(bytes) {
8159
+ if (bytes < 1024) return `${bytes} B`;
8160
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
8161
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
8162
+ }
8163
+ function getDebugLogsSection() {
8164
+ let section = chalk17.bold("Debug Logs\n");
8165
+ section += `${chalk17.dim("\u2500".repeat(50))}
8166
+ `;
8167
+ const logger4 = getLogger();
8168
+ const cliLogPath = logger4.getLogFilePath();
8169
+ const cliLogSize = logger4.getLogFileSize();
8170
+ if (cliLogSize > 0) {
8171
+ section += `${chalk17.bold("CLI Log:")} ${cliLogPath} (${formatFileSize(cliLogSize * 1024 * 1024)})
8172
+ `;
8173
+ } else {
8174
+ section += `${chalk17.bold("CLI Log:")} ${chalk17.dim("none")}
8175
+ `;
8176
+ }
8177
+ try {
8178
+ const tempDir = ".braingrid/temp";
8179
+ if (fs6.existsSync(tempDir)) {
8180
+ const hookLogFiles = fs6.readdirSync(tempDir).filter((f) => f.endsWith("-debug.log") || f === "build-debug.log");
8181
+ if (hookLogFiles.length > 0) {
8182
+ for (const file of hookLogFiles) {
8183
+ const filePath = path8.join(tempDir, file);
8184
+ const stats = fs6.statSync(filePath);
8185
+ section += `${chalk17.bold("Hook Log:")} ${filePath} (${formatFileSize(stats.size)})
8186
+ `;
8187
+ }
8188
+ } else {
8189
+ section += `${chalk17.bold("Hook Logs:")} ${chalk17.dim("none")}
8190
+ `;
8191
+ }
8192
+ } else {
8193
+ section += `${chalk17.bold("Hook Logs:")} ${chalk17.dim("none")}
8194
+ `;
8195
+ }
8196
+ } catch {
8197
+ section += `${chalk17.bold("Hook Logs:")} ${chalk17.dim("unable to check")}
8198
+ `;
8199
+ }
8200
+ section += "\n";
8201
+ return section;
8202
+ }
7705
8203
  async function handleStatus() {
7706
8204
  try {
7707
8205
  const config2 = getConfig();
7708
8206
  const auth = getAuth2();
7709
- const stop = showSpinner("Checking status", chalk16.gray);
8207
+ const stop = showSpinner("Checking status", chalk17.gray);
7710
8208
  const isAuthenticated = await auth.isAuthenticated(true);
7711
8209
  stop();
7712
- let output = chalk16.bold.cyan("\n\u{1F9E0} BrainGrid CLI Status\n\n");
7713
- output += chalk16.bold("Authentication\n");
7714
- output += `${chalk16.dim("\u2500".repeat(50))}
8210
+ let output = chalk17.bold.cyan("\n\u{1F9E0} BrainGrid CLI Status\n\n");
8211
+ output += chalk17.bold("Authentication\n");
8212
+ output += `${chalk17.dim("\u2500".repeat(50))}
7715
8213
  `;
7716
8214
  if (!isAuthenticated) {
7717
- output += chalk16.red("\u274C Not authenticated\n");
7718
- output += chalk16.dim(" Run ") + chalk16.cyan("braingrid login") + chalk16.dim(" to sign in\n\n");
7719
- output += chalk16.bold("Git Repository\n");
7720
- output += `${chalk16.dim("\u2500".repeat(50))}
8215
+ output += chalk17.red("\u274C Not authenticated\n");
8216
+ output += chalk17.dim(" Run ") + chalk17.cyan("braingrid login") + chalk17.dim(" to sign in\n\n");
8217
+ output += chalk17.bold("Git Repository\n");
8218
+ output += `${chalk17.dim("\u2500".repeat(50))}
7721
8219
  `;
7722
8220
  const gitInfo2 = await getGitRepositoryInfo();
7723
8221
  if (!gitInfo2 || !gitInfo2.isRepo) {
7724
- output += chalk16.yellow("\u26A0\uFE0F Not in a git repository\n\n");
8222
+ output += chalk17.yellow("\u26A0\uFE0F Not in a git repository\n\n");
7725
8223
  } else {
7726
- output += chalk16.green("\u2705 Repository detected!\n");
8224
+ output += chalk17.green("\u2705 Repository detected!\n");
7727
8225
  if (gitInfo2.owner && gitInfo2.name) {
7728
- output += `${chalk16.bold("Owner:")} ${gitInfo2.owner}
8226
+ output += `${chalk17.bold("Owner:")} ${gitInfo2.owner}
7729
8227
  `;
7730
- output += `${chalk16.bold("Name:")} ${gitInfo2.name}
8228
+ output += `${chalk17.bold("Name:")} ${gitInfo2.name}
7731
8229
  `;
7732
8230
  } else if (gitInfo2.remoteUrl) {
7733
- output += `${chalk16.bold("Remote:")} ${gitInfo2.remoteUrl}
8231
+ output += `${chalk17.bold("Remote:")} ${gitInfo2.remoteUrl}
7734
8232
  `;
7735
8233
  } else {
7736
- output += chalk16.yellow("\u26A0\uFE0F Local repository (no remote)\n");
8234
+ output += chalk17.yellow("\u26A0\uFE0F Local repository (no remote)\n");
7737
8235
  }
7738
8236
  if (gitInfo2.branch) {
7739
- output += `${chalk16.bold("Branch:")} ${gitInfo2.branch}
8237
+ output += `${chalk17.bold("Branch:")} ${gitInfo2.branch}
7740
8238
  `;
7741
8239
  }
7742
8240
  if (gitInfo2.userName || gitInfo2.userEmail) {
7743
8241
  const userDisplay = gitInfo2.userName && gitInfo2.userEmail ? `${gitInfo2.userName} <${gitInfo2.userEmail}>` : gitInfo2.userName || gitInfo2.userEmail;
7744
- output += `${chalk16.bold("Git User:")} ${userDisplay}
8242
+ output += `${chalk17.bold("Git User:")} ${userDisplay}
7745
8243
  `;
7746
8244
  } else {
7747
- output += `${chalk16.bold("Git User:")} ` + chalk16.yellow("\u26A0\uFE0F Not configured (run git config --global user.name/email)\n");
8245
+ output += `${chalk17.bold("Git User:")} ` + chalk17.yellow("\u26A0\uFE0F Not configured (run git config --global user.name/email)\n");
7748
8246
  }
7749
8247
  output += "\n";
7750
8248
  }
7751
- output += chalk16.bold("Installed Coding Tools\n");
7752
- output += `${chalk16.dim("\u2500".repeat(50))}
8249
+ output += chalk17.bold("Installed Coding Tools\n");
8250
+ output += `${chalk17.dim("\u2500".repeat(50))}
7753
8251
  `;
7754
8252
  const cliToolsUnauthenticated = await checkInstalledCliTools();
7755
8253
  const installedTools2 = cliToolsUnauthenticated.filter((tool) => tool.installed);
7756
8254
  if (installedTools2.length === 0) {
7757
- output += chalk16.yellow("\u26A0\uFE0F No coding tools detected\n\n");
8255
+ output += chalk17.yellow("\u26A0\uFE0F No coding tools detected\n\n");
7758
8256
  } else {
7759
8257
  installedTools2.forEach((tool) => {
7760
- const versionInfo = tool.version ? chalk16.dim(` (${tool.version})`) : "";
7761
- output += `${chalk16.green("\u2705")} ${tool.name}${versionInfo}
8258
+ const versionInfo = tool.version ? chalk17.dim(` (${tool.version})`) : "";
8259
+ output += `${chalk17.green("\u2705")} ${tool.name}${versionInfo}
7762
8260
  `;
7763
8261
  });
7764
8262
  output += "\n";
7765
8263
  }
7766
- output += chalk16.bold("Configuration\n");
7767
- output += `${chalk16.dim("\u2500".repeat(50))}
8264
+ output += chalk17.bold("Configuration\n");
8265
+ output += `${chalk17.dim("\u2500".repeat(50))}
7768
8266
  `;
7769
- output += `${chalk16.bold("API URL:")} ${config2.apiUrl}
8267
+ output += `${chalk17.bold("API URL:")} ${config2.apiUrl}
7770
8268
  `;
7771
- output += `${chalk16.bold("OAuth Client:")} ${config2.oauthClientId}
8269
+ output += `${chalk17.bold("OAuth Client:")} ${config2.oauthClientId}
7772
8270
  `;
7773
- output += `${chalk16.bold("Redirect URI:")} http://127.0.0.1:34536/callback
8271
+ output += `${chalk17.bold("Redirect URI:")} http://127.0.0.1:34536/callback
7774
8272
  `;
7775
- output += `${chalk16.bold("Config Path:")} ${credentialStore.getStoragePath()}
8273
+ output += `${chalk17.bold("Config Path:")} ${credentialStore.getStoragePath()}
7776
8274
 
7777
8275
  `;
7778
- output += chalk16.bold("Overall Status\n");
7779
- output += `${chalk16.dim("\u2500".repeat(50))}
8276
+ output += getDebugLogsSection();
8277
+ output += chalk17.bold("Overall Status\n");
8278
+ output += `${chalk17.dim("\u2500".repeat(50))}
7780
8279
  `;
7781
- output += chalk16.yellow("\u26A0\uFE0F Setup required - please authenticate\n");
8280
+ output += chalk17.yellow("\u26A0\uFE0F Setup required - please authenticate\n");
7782
8281
  return {
7783
8282
  success: true,
7784
8283
  message: output,
@@ -7787,94 +8286,95 @@ async function handleStatus() {
7787
8286
  }
7788
8287
  const session = await auth.getStoredSession();
7789
8288
  if (!session) {
7790
- output += chalk16.red("\u274C Session not found\n\n");
8289
+ output += chalk17.red("\u274C Session not found\n\n");
7791
8290
  return {
7792
8291
  success: true,
7793
8292
  message: output,
7794
8293
  data: { authenticated: false }
7795
8294
  };
7796
8295
  }
7797
- output += chalk16.green("\u2705 Authenticated\n");
8296
+ output += chalk17.green("\u2705 Authenticated\n");
7798
8297
  const userName = `${session.user.firstName || ""} ${session.user.lastName || ""}`.trim();
7799
8298
  if (userName) {
7800
- output += `${chalk16.bold("Name:")} ${userName}
8299
+ output += `${chalk17.bold("Name:")} ${userName}
7801
8300
  `;
7802
8301
  }
7803
- output += `${chalk16.bold("Email:")} ${session.user.email}
8302
+ output += `${chalk17.bold("Email:")} ${session.user.email}
7804
8303
  `;
7805
- output += `${chalk16.bold("User ID:")} ${session.user.id}
8304
+ output += `${chalk17.bold("User ID:")} ${session.user.id}
7806
8305
  `;
7807
- output += `${chalk16.bold("Organization:")} ${session.organization_id}
8306
+ output += `${chalk17.bold("Organization:")} ${session.organization_id}
7808
8307
  `;
7809
8308
  const sessionAge = Math.floor((Date.now() - session.created_at.getTime()) / 1e3 / 60);
7810
- output += `${chalk16.bold("Session Age:")} ${sessionAge} minutes
8309
+ output += `${chalk17.bold("Session Age:")} ${sessionAge} minutes
7811
8310
  `;
7812
- output += `${chalk16.bold("API URL:")} ${config2.apiUrl}
8311
+ output += `${chalk17.bold("API URL:")} ${config2.apiUrl}
7813
8312
  `;
7814
- output += `${chalk16.bold("Config Path:")} ${credentialStore.getStoragePath()}
8313
+ output += `${chalk17.bold("Config Path:")} ${credentialStore.getStoragePath()}
7815
8314
 
7816
8315
  `;
7817
- output += chalk16.bold("Git Repository\n");
7818
- output += `${chalk16.dim("\u2500".repeat(50))}
8316
+ output += chalk17.bold("Git Repository\n");
8317
+ output += `${chalk17.dim("\u2500".repeat(50))}
7819
8318
  `;
7820
8319
  const gitInfo = await getGitRepositoryInfo();
7821
8320
  if (!gitInfo || !gitInfo.isRepo) {
7822
- output += chalk16.yellow("\u26A0\uFE0F Not in a git repository\n\n");
8321
+ output += chalk17.yellow("\u26A0\uFE0F Not in a git repository\n\n");
7823
8322
  } else {
7824
- output += chalk16.green("\u2705 Repository detected!\n");
8323
+ output += chalk17.green("\u2705 Repository detected!\n");
7825
8324
  if (gitInfo.owner && gitInfo.name) {
7826
- output += `${chalk16.bold("Owner:")} ${gitInfo.owner}
8325
+ output += `${chalk17.bold("Owner:")} ${gitInfo.owner}
7827
8326
  `;
7828
- output += `${chalk16.bold("Name:")} ${gitInfo.name}
8327
+ output += `${chalk17.bold("Name:")} ${gitInfo.name}
7829
8328
  `;
7830
8329
  } else if (gitInfo.remoteUrl) {
7831
- output += `${chalk16.bold("Remote:")} ${gitInfo.remoteUrl}
8330
+ output += `${chalk17.bold("Remote:")} ${gitInfo.remoteUrl}
7832
8331
  `;
7833
8332
  } else {
7834
- output += chalk16.yellow("\u26A0\uFE0F Local repository (no remote)\n");
8333
+ output += chalk17.yellow("\u26A0\uFE0F Local repository (no remote)\n");
7835
8334
  }
7836
8335
  if (gitInfo.branch) {
7837
- output += `${chalk16.bold("Branch:")} ${gitInfo.branch}
8336
+ output += `${chalk17.bold("Branch:")} ${gitInfo.branch}
7838
8337
  `;
7839
8338
  }
7840
8339
  if (gitInfo.userName || gitInfo.userEmail) {
7841
8340
  const userDisplay = gitInfo.userName && gitInfo.userEmail ? `${gitInfo.userName} <${gitInfo.userEmail}>` : gitInfo.userName || gitInfo.userEmail;
7842
- output += `${chalk16.bold("Git User:")} ${userDisplay}
8341
+ output += `${chalk17.bold("Git User:")} ${userDisplay}
7843
8342
  `;
7844
8343
  } else {
7845
- output += `${chalk16.bold("Git User:")} ` + chalk16.yellow("\u26A0\uFE0F Not configured (run git config --global user.name/email)\n");
8344
+ output += `${chalk17.bold("Git User:")} ` + chalk17.yellow("\u26A0\uFE0F Not configured (run git config --global user.name/email)\n");
7846
8345
  }
7847
8346
  output += "\n";
7848
8347
  }
7849
- output += chalk16.bold("Installed Coding Tools\n");
7850
- output += `${chalk16.dim("\u2500".repeat(50))}
8348
+ output += chalk17.bold("Installed Coding Tools\n");
8349
+ output += `${chalk17.dim("\u2500".repeat(50))}
7851
8350
  `;
7852
8351
  const cliTools = await checkInstalledCliTools();
7853
8352
  const installedTools = cliTools.filter((tool) => tool.installed);
7854
8353
  if (installedTools.length === 0) {
7855
- output += chalk16.yellow("\u26A0\uFE0F No coding tools detected\n\n");
8354
+ output += chalk17.yellow("\u26A0\uFE0F No coding tools detected\n\n");
7856
8355
  } else {
7857
8356
  installedTools.forEach((tool) => {
7858
- const versionInfo = tool.version ? chalk16.dim(` (${tool.version})`) : "";
7859
- output += `${chalk16.green("\u2705")} ${tool.name}${versionInfo}
8357
+ const versionInfo = tool.version ? chalk17.dim(` (${tool.version})`) : "";
8358
+ output += `${chalk17.green("\u2705")} ${tool.name}${versionInfo}
7860
8359
  `;
7861
8360
  });
7862
8361
  output += "\n";
7863
8362
  }
7864
- output += chalk16.bold("Configuration\n");
7865
- output += `${chalk16.dim("\u2500".repeat(50))}
8363
+ output += chalk17.bold("Configuration\n");
8364
+ output += `${chalk17.dim("\u2500".repeat(50))}
7866
8365
  `;
7867
- output += `${chalk16.bold("OAuth Client:")} ${config2.oauthClientId}
8366
+ output += `${chalk17.bold("OAuth Client:")} ${config2.oauthClientId}
7868
8367
  `;
7869
- output += `${chalk16.bold("Redirect URI:")} http://127.0.0.1:34536/callback
8368
+ output += `${chalk17.bold("Redirect URI:")} http://127.0.0.1:34536/callback
7870
8369
  `;
7871
- output += `${chalk16.bold("Auth Server:")} ${config2.getWorkOSAuthUrl()}
8370
+ output += `${chalk17.bold("Auth Server:")} ${config2.getWorkOSAuthUrl()}
7872
8371
 
7873
8372
  `;
7874
- output += chalk16.bold("Overall Status\n");
7875
- output += `${chalk16.dim("\u2500".repeat(50))}
8373
+ output += getDebugLogsSection();
8374
+ output += chalk17.bold("Overall Status\n");
8375
+ output += `${chalk17.dim("\u2500".repeat(50))}
7876
8376
  `;
7877
- output += chalk16.green("\u2705 Ready to use BrainGrid CLI\n");
8377
+ output += chalk17.green("\u2705 Ready to use BrainGrid CLI\n");
7878
8378
  return {
7879
8379
  success: true,
7880
8380
  message: output,
@@ -7889,7 +8389,7 @@ async function handleStatus() {
7889
8389
  }
7890
8390
 
7891
8391
  // src/handlers/task.handlers.ts
7892
- import chalk17 from "chalk";
8392
+ import chalk18 from "chalk";
7893
8393
 
7894
8394
  // src/services/task-service.ts
7895
8395
  var TaskService = class {
@@ -7993,7 +8493,7 @@ async function handleTaskList(opts) {
7993
8493
  if (!isAuthenticated) {
7994
8494
  return {
7995
8495
  success: false,
7996
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8496
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
7997
8497
  };
7998
8498
  }
7999
8499
  const workspace = await workspaceManager.getProject(opts.project);
@@ -8013,7 +8513,7 @@ async function handleTaskList(opts) {
8013
8513
  }
8014
8514
  const requirementId = requirementResult.requirementId;
8015
8515
  if (opts.format !== "json" && opts.format !== "xml") {
8016
- stopSpinner = showSpinner("Loading tasks", chalk17.gray);
8516
+ stopSpinner = showSpinner("Loading tasks", chalk18.gray);
8017
8517
  }
8018
8518
  const response = await taskService.listTasks(projectId, requirementId, {
8019
8519
  page: opts.page ? parseInt(opts.page, 10) : 1,
@@ -8026,7 +8526,7 @@ async function handleTaskList(opts) {
8026
8526
  if (response.tasks.length === 0) {
8027
8527
  return {
8028
8528
  success: true,
8029
- message: chalk17.yellow("No tasks found."),
8529
+ message: chalk18.yellow("No tasks found."),
8030
8530
  data: response
8031
8531
  };
8032
8532
  }
@@ -8042,7 +8542,7 @@ async function handleTaskList(opts) {
8042
8542
  });
8043
8543
  if (response.pagination?.has_more) {
8044
8544
  output += `
8045
- ${chalk17.yellow("\u26A0\uFE0F More tasks exist. Use --limit to see more.")}`;
8545
+ ${chalk18.yellow("\u26A0\uFE0F More tasks exist. Use --limit to see more.")}`;
8046
8546
  }
8047
8547
  return {
8048
8548
  success: true,
@@ -8067,7 +8567,7 @@ async function handleTaskSummary(opts) {
8067
8567
  if (!isAuthenticated) {
8068
8568
  return {
8069
8569
  success: false,
8070
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8570
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8071
8571
  };
8072
8572
  }
8073
8573
  const workspace = await workspaceManager.getProject(opts.project);
@@ -8086,7 +8586,7 @@ async function handleTaskSummary(opts) {
8086
8586
  };
8087
8587
  }
8088
8588
  const requirementId = requirementResult.requirementId;
8089
- stopSpinner = showSpinner("Loading tasks", chalk17.gray);
8589
+ stopSpinner = showSpinner("Loading tasks", chalk18.gray);
8090
8590
  const response = await taskService.listTasks(projectId, requirementId, {
8091
8591
  page: opts.page ? parseInt(opts.page, 10) : 1,
8092
8592
  limit: opts.limit ? parseInt(opts.limit, 10) : 20
@@ -8096,7 +8596,7 @@ async function handleTaskSummary(opts) {
8096
8596
  if (response.tasks.length === 0) {
8097
8597
  return {
8098
8598
  success: true,
8099
- message: chalk17.yellow("No tasks found."),
8599
+ message: chalk18.yellow("No tasks found."),
8100
8600
  data: response
8101
8601
  };
8102
8602
  }
@@ -8111,7 +8611,7 @@ async function handleTaskSummary(opts) {
8111
8611
  });
8112
8612
  if (response.pagination?.has_more) {
8113
8613
  output += `
8114
- ${chalk17.yellow("\u26A0\uFE0F More tasks exist. Use --limit to see more.")}`;
8614
+ ${chalk18.yellow("\u26A0\uFE0F More tasks exist. Use --limit to see more.")}`;
8115
8615
  }
8116
8616
  return {
8117
8617
  success: true,
@@ -8136,14 +8636,14 @@ async function handleTaskShow(id, opts) {
8136
8636
  if (!isAuthenticated) {
8137
8637
  return {
8138
8638
  success: false,
8139
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8639
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8140
8640
  };
8141
8641
  }
8142
8642
  const format = opts?.format || "markdown";
8143
8643
  if (!["markdown", "json", "xml", "table"].includes(format)) {
8144
8644
  return {
8145
8645
  success: false,
8146
- message: chalk17.red(
8646
+ message: chalk18.red(
8147
8647
  `\u274C Invalid format: ${format}. Supported formats: markdown, json, xml, table`
8148
8648
  )
8149
8649
  };
@@ -8173,14 +8673,14 @@ async function handleTaskShow(id, opts) {
8173
8673
  if (!currentTask.success) {
8174
8674
  return {
8175
8675
  success: false,
8176
- message: chalk17.red(`\u274C ${currentTask.error}`)
8676
+ message: chalk18.red(`\u274C ${currentTask.error}`)
8177
8677
  };
8178
8678
  }
8179
8679
  taskId = currentTask.taskId;
8180
8680
  taskWarning = currentTask.warning;
8181
8681
  }
8182
8682
  const config2 = getConfig();
8183
- stopSpinner = showSpinner("Loading task", chalk17.gray);
8683
+ stopSpinner = showSpinner("Loading task", chalk18.gray);
8184
8684
  const task2 = await taskService.getTask(projectId, requirementId, taskId);
8185
8685
  stopSpinner();
8186
8686
  stopSpinner = null;
@@ -8213,7 +8713,7 @@ async function handleTaskShow(id, opts) {
8213
8713
  }
8214
8714
  if (taskWarning) {
8215
8715
  output += `
8216
- ${chalk17.yellow(`\u26A0\uFE0F ${taskWarning}`)}`;
8716
+ ${chalk18.yellow(`\u26A0\uFE0F ${taskWarning}`)}`;
8217
8717
  }
8218
8718
  return {
8219
8719
  success: true,
@@ -8238,7 +8738,7 @@ async function handleTaskCreate(opts) {
8238
8738
  if (!isAuthenticated) {
8239
8739
  return {
8240
8740
  success: false,
8241
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8741
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8242
8742
  };
8243
8743
  }
8244
8744
  const workspace = await workspaceManager.getProject(opts.project);
@@ -8260,7 +8760,7 @@ async function handleTaskCreate(opts) {
8260
8760
  const projectShortId = projectId;
8261
8761
  const requirementShortId = opts.requirement || requirementId;
8262
8762
  const config2 = getConfig();
8263
- stopSpinner = showSpinner("Creating task", chalk17.gray);
8763
+ stopSpinner = showSpinner("Creating task", chalk18.gray);
8264
8764
  const task2 = await taskService.createTask(projectId, requirementId, {
8265
8765
  title: opts.title,
8266
8766
  content: opts.content,
@@ -8299,13 +8799,13 @@ async function handleTaskUpdate(id, opts) {
8299
8799
  if (!isAuthenticated) {
8300
8800
  return {
8301
8801
  success: false,
8302
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8802
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8303
8803
  };
8304
8804
  }
8305
8805
  if (!opts?.status && !opts?.title && !opts?.externalId) {
8306
8806
  return {
8307
8807
  success: false,
8308
- message: chalk17.red(
8808
+ message: chalk18.red(
8309
8809
  "\u274C Please provide at least one field to update (--status, --title, or --external-id)"
8310
8810
  )
8311
8811
  };
@@ -8335,14 +8835,14 @@ async function handleTaskUpdate(id, opts) {
8335
8835
  if (!currentTask.success) {
8336
8836
  return {
8337
8837
  success: false,
8338
- message: chalk17.red(`\u274C ${currentTask.error}`)
8838
+ message: chalk18.red(`\u274C ${currentTask.error}`)
8339
8839
  };
8340
8840
  }
8341
8841
  taskId = currentTask.taskId;
8342
8842
  taskWarning = currentTask.warning;
8343
8843
  }
8344
8844
  const config2 = getConfig();
8345
- stopSpinner = showSpinner("Updating task", chalk17.gray);
8845
+ stopSpinner = showSpinner("Updating task", chalk18.gray);
8346
8846
  const task2 = await taskService.updateTask(projectId, requirementId, taskId, {
8347
8847
  status: opts?.status,
8348
8848
  title: opts?.title,
@@ -8360,7 +8860,7 @@ async function handleTaskUpdate(id, opts) {
8360
8860
  });
8361
8861
  if (taskWarning) {
8362
8862
  output += `
8363
- ${chalk17.yellow(`\u26A0\uFE0F ${taskWarning}`)}`;
8863
+ ${chalk18.yellow(`\u26A0\uFE0F ${taskWarning}`)}`;
8364
8864
  }
8365
8865
  return {
8366
8866
  success: true,
@@ -8385,13 +8885,13 @@ async function handleTaskDelete(id, opts) {
8385
8885
  if (!isAuthenticated) {
8386
8886
  return {
8387
8887
  success: false,
8388
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8888
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8389
8889
  };
8390
8890
  }
8391
8891
  if (!opts.force) {
8392
8892
  return {
8393
8893
  success: false,
8394
- message: chalk17.yellow("\u26A0\uFE0F Deleting a task is permanent. Use --force to confirm deletion.")
8894
+ message: chalk18.yellow("\u26A0\uFE0F Deleting a task is permanent. Use --force to confirm deletion.")
8395
8895
  };
8396
8896
  }
8397
8897
  const workspace = await workspaceManager.getProject(opts.project);
@@ -8411,13 +8911,13 @@ async function handleTaskDelete(id, opts) {
8411
8911
  }
8412
8912
  const requirementId = requirementResult.requirementId;
8413
8913
  const taskId = normalizeTaskId(id);
8414
- stopSpinner = showSpinner("Deleting task", chalk17.gray);
8914
+ stopSpinner = showSpinner("Deleting task", chalk18.gray);
8415
8915
  await taskService.deleteTask(projectId, requirementId, taskId);
8416
8916
  stopSpinner();
8417
8917
  stopSpinner = null;
8418
8918
  return {
8419
8919
  success: true,
8420
- message: chalk17.green(`\u2705 Deleted task ${id}`)
8920
+ message: chalk18.green(`\u2705 Deleted task ${id}`)
8421
8921
  };
8422
8922
  } catch (error) {
8423
8923
  if (stopSpinner) {
@@ -8437,14 +8937,14 @@ async function handleTaskSpecify(opts) {
8437
8937
  if (!isAuthenticated) {
8438
8938
  return {
8439
8939
  success: false,
8440
- message: chalk17.red("\u274C Not authenticated. Please run `braingrid login` first.")
8940
+ message: chalk18.red("\u274C Not authenticated. Please run `braingrid login` first.")
8441
8941
  };
8442
8942
  }
8443
8943
  const format = opts.format || "table";
8444
8944
  if (!["table", "json", "markdown"].includes(format)) {
8445
8945
  return {
8446
8946
  success: false,
8447
- message: chalk17.red(
8947
+ message: chalk18.red(
8448
8948
  `\u274C Invalid format: ${format}. Supported formats: table, json, markdown`
8449
8949
  )
8450
8950
  };
@@ -8468,16 +8968,16 @@ async function handleTaskSpecify(opts) {
8468
8968
  if (opts.prompt.length < 10) {
8469
8969
  return {
8470
8970
  success: false,
8471
- message: chalk17.red("\u274C Prompt must be at least 10 characters long")
8971
+ message: chalk18.red("\u274C Prompt must be at least 10 characters long")
8472
8972
  };
8473
8973
  }
8474
8974
  if (opts.prompt.length > 5e3) {
8475
8975
  return {
8476
8976
  success: false,
8477
- message: chalk17.red("\u274C Prompt must be no more than 5000 characters long")
8977
+ message: chalk18.red("\u274C Prompt must be no more than 5000 characters long")
8478
8978
  };
8479
8979
  }
8480
- stopSpinner = showSpinner("Creating task from prompt...", chalk17.gray);
8980
+ stopSpinner = showSpinner("Creating task from prompt...", chalk18.gray);
8481
8981
  const response = await taskService.specifyTask(projectId, requirementId, {
8482
8982
  prompt: opts.prompt
8483
8983
  });
@@ -8517,10 +9017,10 @@ async function handleTaskSpecify(opts) {
8517
9017
  function formatTaskSpecifyTable(response) {
8518
9018
  const task2 = response.task;
8519
9019
  const lines = [];
8520
- lines.push(chalk17.green(`\u2705 Created task ${response.requirement_short_id}/TASK-${task2.number}`));
9020
+ lines.push(chalk18.green(`\u2705 Created task ${response.requirement_short_id}/TASK-${task2.number}`));
8521
9021
  lines.push("");
8522
- lines.push(`${chalk17.bold("Title:")} ${task2.title}`);
8523
- lines.push(`${chalk17.bold("Status:")} ${task2.status}`);
9022
+ lines.push(`${chalk18.bold("Title:")} ${task2.title}`);
9023
+ lines.push(`${chalk18.bold("Status:")} ${task2.status}`);
8524
9024
  return lines.join("\n");
8525
9025
  }
8526
9026
  function formatTaskSpecifyMarkdown(response, _apiUrl) {