@braingrid/cli 0.2.19 → 0.2.21

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/CHANGELOG.md CHANGED
@@ -7,6 +7,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.21] - 2025-12-18
11
+
12
+ ### Fixed
13
+
14
+ - **Status line TASK null bug**
15
+ - Fixed jq query returning `TASK null` when no IN_PROGRESS tasks exist
16
+ - Added `select(. != null)` after `first` to properly trigger fallback to PLANNED tasks
17
+
18
+ ### Changed
19
+
20
+ - **Setup prompt default option**
21
+ - "Overwrite all" is now the first/default option in file conflict prompts
22
+ - Makes it easier to update all BrainGrid integration files at once
23
+
24
+ ## [0.2.20] - 2025-12-18
25
+
26
+ ### Added
27
+
28
+ - **IDE setup prompts after update**
29
+ - After running `braingrid update`, CLI detects installed Claude Code and Cursor
30
+ - Prompts user to update BrainGrid integration for each detected IDE
31
+ - Uses force mode to streamline the setup process
32
+
33
+ ### Changed
34
+
35
+ - **Enhanced status line display**
36
+ - Task display now shows status: `TASK 19 (In-Progress)` or `(Planned)`
37
+ - Added third line showing current git branch: `Branch: feature/REQ-12-something`
38
+
10
39
  ## [0.2.19] - 2025-12-17
11
40
 
12
41
  ### Added
package/dist/cli.js CHANGED
@@ -422,7 +422,7 @@ import axios3, { AxiosError as AxiosError2 } from "axios";
422
422
 
423
423
  // src/build-config.ts
424
424
  var BUILD_ENV = true ? "production" : process.env.NODE_ENV === "test" ? "development" : "production";
425
- var CLI_VERSION = true ? "0.2.19" : "0.0.0-test";
425
+ var CLI_VERSION = true ? "0.2.21" : "0.0.0-test";
426
426
  var PRODUCTION_CONFIG = {
427
427
  apiUrl: "https://app.braingrid.ai",
428
428
  workosAuthUrl: "https://auth.braingrid.ai",
@@ -5260,7 +5260,7 @@ async function handleStatus() {
5260
5260
 
5261
5261
  // src/handlers/init.handlers.ts
5262
5262
  import chalk15 from "chalk";
5263
- import { confirm, select as select3, input } from "@inquirer/prompts";
5263
+ import { confirm as confirm2, select as select3, input } from "@inquirer/prompts";
5264
5264
 
5265
5265
  // src/services/internal/github-service.ts
5266
5266
  var GitHubService = class {
@@ -5528,7 +5528,8 @@ function getManualInstallInstructions() {
5528
5528
  }
5529
5529
 
5530
5530
  // src/handlers/update.handlers.ts
5531
- import chalk12 from "chalk";
5531
+ import chalk13 from "chalk";
5532
+ import { confirm } from "@inquirer/prompts";
5532
5533
 
5533
5534
  // src/utils/package-manager.ts
5534
5535
  import { execSync } from "child_process";
@@ -5664,139 +5665,8 @@ function compareVersions(v1, v2) {
5664
5665
  return 0;
5665
5666
  }
5666
5667
 
5667
- // src/handlers/update.handlers.ts
5668
- async function handleUpdate(opts) {
5669
- try {
5670
- const currentVersion = getCurrentVersion();
5671
- let output = chalk12.bold.cyan("\n\u{1F504} BrainGrid CLI Update\n\n");
5672
- output += `${chalk12.bold("Current version:")} ${currentVersion}
5673
- `;
5674
- output += chalk12.dim("Checking for updates...\n");
5675
- const latestVersion = await getLatestVersion();
5676
- output += `${chalk12.bold("Latest version:")} ${latestVersion}
5677
-
5678
- `;
5679
- const comparison = compareVersions(currentVersion, latestVersion);
5680
- if (comparison === 0) {
5681
- output += chalk12.green("\u2705 You are already on the latest version!\n");
5682
- return {
5683
- success: true,
5684
- message: output,
5685
- data: { currentVersion, latestVersion, upToDate: true }
5686
- };
5687
- }
5688
- if (comparison > 0) {
5689
- output += chalk12.yellow("\u26A0\uFE0F You are on a newer version than what is published.\n");
5690
- output += chalk12.dim(" This is expected if you are developing locally.\n");
5691
- return {
5692
- success: true,
5693
- message: output,
5694
- data: { currentVersion, latestVersion, upToDate: false }
5695
- };
5696
- }
5697
- output += chalk12.yellow(`\u2B06\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}
5698
-
5699
- `);
5700
- if (opts.check) {
5701
- output += chalk12.dim("Run ") + chalk12.cyan("braingrid update") + chalk12.dim(" to update\n");
5702
- return {
5703
- success: true,
5704
- message: output,
5705
- data: { currentVersion, latestVersion, upToDate: false }
5706
- };
5707
- }
5708
- output += chalk12.dim("Detecting package manager...\n");
5709
- const packageManager = await detectPackageManager(PACKAGE_NAME);
5710
- output += `${chalk12.bold("Package manager:")} ${packageManager}
5711
-
5712
- `;
5713
- const updateCommand = getUpdateCommand(packageManager, PACKAGE_NAME);
5714
- output += chalk12.dim("Running: ") + chalk12.cyan(updateCommand) + "\n\n";
5715
- console.log(output);
5716
- executeUpdate(packageManager, PACKAGE_NAME);
5717
- return {
5718
- success: true,
5719
- message: chalk12.green("\n\u2705 Successfully updated BrainGrid CLI!\n"),
5720
- data: { currentVersion, latestVersion, packageManager }
5721
- };
5722
- } catch (error) {
5723
- return {
5724
- success: false,
5725
- message: formatError(error)
5726
- };
5727
- }
5728
- }
5729
-
5730
- // src/utils/update-checker.ts
5731
- import chalk13 from "chalk";
5732
- var CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
5733
- var CACHE_SERVICE = "braingrid-cli";
5734
- var CACHE_ACCOUNT = "update-cache";
5735
- async function getCache() {
5736
- try {
5737
- const cached = await credentialStore.getPassword(CACHE_SERVICE, CACHE_ACCOUNT);
5738
- if (!cached) return null;
5739
- return JSON.parse(cached);
5740
- } catch {
5741
- return null;
5742
- }
5743
- }
5744
- async function setCache(cache) {
5745
- try {
5746
- await credentialStore.setPassword(CACHE_SERVICE, CACHE_ACCOUNT, JSON.stringify(cache));
5747
- } catch {
5748
- }
5749
- }
5750
- function isCacheValid(cache) {
5751
- const now = Date.now();
5752
- return now - cache.checkedAt < CACHE_TTL_MS;
5753
- }
5754
- async function getLatestVersionCached() {
5755
- const cache = await getCache();
5756
- if (cache && isCacheValid(cache)) {
5757
- return cache.latestVersion;
5758
- }
5759
- try {
5760
- const latestVersion = await getLatestVersion(5e3);
5761
- await setCache({
5762
- latestVersion,
5763
- checkedAt: Date.now()
5764
- });
5765
- return latestVersion;
5766
- } catch {
5767
- return cache?.latestVersion ?? null;
5768
- }
5769
- }
5770
- async function isUpdateAvailable() {
5771
- const currentVersion = getCurrentVersion();
5772
- const latestVersion = await getLatestVersionCached();
5773
- if (!latestVersion) {
5774
- return { available: false, currentVersion, latestVersion: null };
5775
- }
5776
- const comparison = compareVersions(currentVersion, latestVersion);
5777
- return {
5778
- available: comparison < 0,
5779
- // Update available if current < latest
5780
- currentVersion,
5781
- latestVersion
5782
- };
5783
- }
5784
- function getUpdateCommand2() {
5785
- return `npm install -g ${PACKAGE_NAME}`;
5786
- }
5787
- async function checkAndShowUpdateWarning() {
5788
- try {
5789
- const { available, currentVersion, latestVersion } = await isUpdateAvailable();
5790
- if (available && latestVersion) {
5791
- const warning = "\n" + chalk13.yellow(`\u26A0\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}`) + "\n" + chalk13.dim(` Run \`${getUpdateCommand2()}\` to update`) + "\n";
5792
- console.log(warning);
5793
- }
5794
- } catch {
5795
- }
5796
- }
5797
-
5798
5668
  // src/handlers/setup.handlers.ts
5799
- import chalk14 from "chalk";
5669
+ import chalk12 from "chalk";
5800
5670
  import { select as select2 } from "@inquirer/prompts";
5801
5671
  import * as path4 from "path";
5802
5672
  import * as fs4 from "fs/promises";
@@ -6014,7 +5884,7 @@ async function checkPrerequisites() {
6014
5884
  } catch {
6015
5885
  return {
6016
5886
  success: false,
6017
- message: chalk14.red("\u274C GitHub CLI is not installed.\n\n") + chalk14.dim("Install instructions:\n") + chalk14.dim(" macOS: ") + chalk14.cyan("brew install gh") + chalk14.dim("\n") + chalk14.dim(" Windows: ") + chalk14.cyan("winget install GitHub.CLI") + chalk14.dim("\n") + chalk14.dim(" Linux: See ") + chalk14.cyan("https://cli.github.com/manual/installation") + chalk14.dim("\n\n") + chalk14.dim("After installing, run: ") + chalk14.cyan("gh auth login")
5887
+ message: chalk12.red("\u274C GitHub CLI is not installed.\n\n") + chalk12.dim("Install instructions:\n") + chalk12.dim(" macOS: ") + chalk12.cyan("brew install gh") + chalk12.dim("\n") + chalk12.dim(" Windows: ") + chalk12.cyan("winget install GitHub.CLI") + chalk12.dim("\n") + chalk12.dim(" Linux: See ") + chalk12.cyan("https://cli.github.com/manual/installation") + chalk12.dim("\n\n") + chalk12.dim("After installing, run: ") + chalk12.cyan("gh auth login")
6018
5888
  };
6019
5889
  }
6020
5890
  try {
@@ -6022,7 +5892,7 @@ async function checkPrerequisites() {
6022
5892
  } catch {
6023
5893
  return {
6024
5894
  success: false,
6025
- message: chalk14.red("\u274C Not authenticated with GitHub CLI.\n\n") + chalk14.dim("Please run: ") + chalk14.cyan("gh auth login")
5895
+ message: chalk12.red("\u274C Not authenticated with GitHub CLI.\n\n") + chalk12.dim("Please run: ") + chalk12.cyan("gh auth login")
6026
5896
  };
6027
5897
  }
6028
5898
  return null;
@@ -6049,7 +5919,7 @@ async function getFileList(sourcePaths, targetPaths) {
6049
5919
  }
6050
5920
  } catch (error) {
6051
5921
  console.warn(
6052
- chalk14.yellow(`\u26A0\uFE0F Could not list directory: ${sourceDir}`),
5922
+ chalk12.yellow(`\u26A0\uFE0F Could not list directory: ${sourceDir}`),
6053
5923
  error instanceof Error ? error.message : String(error)
6054
5924
  );
6055
5925
  }
@@ -6060,32 +5930,32 @@ async function getFileList(sourcePaths, targetPaths) {
6060
5930
  return operations;
6061
5931
  }
6062
5932
  function displayInstallationPlan(operations, injectionFile) {
6063
- console.log(chalk14.bold("\n\u{1F4CB} Installation Plan:\n"));
6064
- console.log(chalk14.cyan(" Content Injection:"));
6065
- console.log(chalk14.dim(` ${injectionFile}`));
5933
+ console.log(chalk12.bold("\n\u{1F4CB} Installation Plan:\n"));
5934
+ console.log(chalk12.cyan(" Content Injection:"));
5935
+ console.log(chalk12.dim(` ${injectionFile}`));
6066
5936
  const newFiles = operations.filter((op) => !op.exists);
6067
5937
  const existingFiles = operations.filter((op) => op.exists);
6068
5938
  if (newFiles.length > 0) {
6069
- console.log(chalk14.cyan("\n New Files:"));
5939
+ console.log(chalk12.cyan("\n New Files:"));
6070
5940
  for (const op of newFiles) {
6071
- console.log(chalk14.dim(` ${op.targetPath}`));
5941
+ console.log(chalk12.dim(` ${op.targetPath}`));
6072
5942
  }
6073
5943
  }
6074
5944
  if (existingFiles.length > 0) {
6075
- console.log(chalk14.yellow("\n Existing Files (will prompt):"));
5945
+ console.log(chalk12.yellow("\n Existing Files (will prompt):"));
6076
5946
  for (const op of existingFiles) {
6077
- console.log(chalk14.dim(` ${op.targetPath}`));
5947
+ console.log(chalk12.dim(` ${op.targetPath}`));
6078
5948
  }
6079
5949
  }
6080
5950
  console.log("");
6081
5951
  }
6082
5952
  async function promptForConflict(filePath) {
6083
5953
  const answer = await select2({
6084
- message: chalk14.yellow(`File exists: ${filePath}`),
5954
+ message: chalk12.yellow(`File exists: ${filePath}`),
6085
5955
  choices: [
5956
+ { name: "[A]ll - Overwrite all remaining", value: "all" },
6086
5957
  { name: "[O]verwrite - Replace this file", value: "overwrite" },
6087
5958
  { name: "[S]kip - Keep existing file", value: "skip" },
6088
- { name: "[A]ll - Overwrite all remaining", value: "all" },
6089
5959
  { name: "[Q]uit - Cancel installation", value: "quit" }
6090
5960
  ]
6091
5961
  });
@@ -6112,7 +5982,7 @@ async function installFiles(operations, force) {
6112
5982
  installed++;
6113
5983
  } catch (error) {
6114
5984
  console.error(
6115
- chalk14.red(`Failed to copy ${operation.targetPath}:`),
5985
+ chalk12.red(`Failed to copy ${operation.targetPath}:`),
6116
5986
  error instanceof Error ? error.message : String(error)
6117
5987
  );
6118
5988
  skipped++;
@@ -6126,7 +5996,7 @@ async function _handleSetup(config, opts) {
6126
5996
  if (prerequisiteError) {
6127
5997
  return prerequisiteError;
6128
5998
  }
6129
- console.log(chalk14.bold(`\u{1F680} Setting up ${config.name} integration...
5999
+ console.log(chalk12.bold(`\u{1F680} Setting up ${config.name} integration...
6130
6000
  `));
6131
6001
  const operations = await getFileList(config.sourceDirs, config.targetDirs);
6132
6002
  const injectionFileExists = await fileExists(config.injection.targetFile);
@@ -6143,7 +6013,7 @@ async function _handleSetup(config, opts) {
6143
6013
  if (opts.dryRun) {
6144
6014
  return {
6145
6015
  success: true,
6146
- message: chalk14.green("\u2705 Dry-run complete. No files were modified.\n\n") + chalk14.dim(`Would install ${operations.length} files.`)
6016
+ message: chalk12.green("\u2705 Dry-run complete. No files were modified.\n\n") + chalk12.dim(`Would install ${operations.length} files.`)
6147
6017
  };
6148
6018
  }
6149
6019
  const copyOps = operations.filter((op) => op.type === "copy");
@@ -6151,7 +6021,7 @@ async function _handleSetup(config, opts) {
6151
6021
  if (result.cancelled) {
6152
6022
  return {
6153
6023
  success: false,
6154
- message: chalk14.yellow("\u26A0\uFE0F Installation cancelled.\n\n") + chalk14.dim(`Installed: ${result.installed}, Skipped: ${result.skipped}`),
6024
+ message: chalk12.yellow("\u26A0\uFE0F Installation cancelled.\n\n") + chalk12.dim(`Installed: ${result.installed}, Skipped: ${result.skipped}`),
6155
6025
  code: "CANCELLED"
6156
6026
  };
6157
6027
  }
@@ -6160,7 +6030,7 @@ async function _handleSetup(config, opts) {
6160
6030
  await injectContentIntoFile(config.injection.targetFile, content);
6161
6031
  } catch (error) {
6162
6032
  console.error(
6163
- chalk14.red(`Failed to inject content into ${config.injection.targetFile}:`),
6033
+ chalk12.red(`Failed to inject content into ${config.injection.targetFile}:`),
6164
6034
  error instanceof Error ? error.message : String(error)
6165
6035
  );
6166
6036
  }
@@ -6173,27 +6043,27 @@ async function _handleSetup(config, opts) {
6173
6043
  statusLineInstalled = true;
6174
6044
  } catch (error) {
6175
6045
  console.error(
6176
- chalk14.yellow("\u26A0\uFE0F Failed to install status line script:"),
6046
+ chalk12.yellow("\u26A0\uFE0F Failed to install status line script:"),
6177
6047
  error instanceof Error ? error.message : String(error)
6178
6048
  );
6179
6049
  }
6180
6050
  }
6181
- const statusLineMessage = statusLineInstalled ? chalk14.dim(" Status line: .claude/statusline.sh\n") : "";
6051
+ const statusLineMessage = statusLineInstalled ? chalk12.dim(" Status line: .claude/statusline.sh\n") : "";
6182
6052
  return {
6183
6053
  success: true,
6184
- message: chalk14.green(`\u2705 ${config.name} integration installed successfully!
6054
+ message: chalk12.green(`\u2705 ${config.name} integration installed successfully!
6185
6055
 
6186
- `) + chalk14.dim("Files installed:\n") + chalk14.dim(` Commands: ${result.installed} files
6187
- `) + statusLineMessage + chalk14.dim(` Content injected into: ${config.injection.targetFile}
6056
+ `) + chalk12.dim("Files installed:\n") + chalk12.dim(` Commands: ${result.installed} files
6057
+ `) + statusLineMessage + chalk12.dim(` Content injected into: ${config.injection.targetFile}
6188
6058
 
6189
- `) + chalk14.dim("Next steps:\n") + chalk14.dim(" 1. Review the integration files\n") + chalk14.dim(` 2. Open ${config.name}
6190
- `) + chalk14.dim(" 3. Try the /specify or /breakdown commands\n") + chalk14.dim(" 4. Learn more: ") + chalk14.cyan(config.docsUrl)
6059
+ `) + chalk12.dim("Next steps:\n") + chalk12.dim(" 1. Review the integration files\n") + chalk12.dim(` 2. Open ${config.name}
6060
+ `) + chalk12.dim(" 3. Try the /specify or /breakdown commands\n") + chalk12.dim(" 4. Learn more: ") + chalk12.cyan(config.docsUrl)
6191
6061
  };
6192
6062
  } catch (error) {
6193
6063
  const errorMessage = error instanceof Error ? error.message : String(error);
6194
6064
  return {
6195
6065
  success: false,
6196
- message: chalk14.red(`\u274C Setup failed: ${errorMessage}`)
6066
+ message: chalk12.red(`\u274C Setup failed: ${errorMessage}`)
6197
6067
  };
6198
6068
  }
6199
6069
  }
@@ -6224,6 +6094,161 @@ async function handleSetupCursor(opts) {
6224
6094
  return _handleSetup(config, opts);
6225
6095
  }
6226
6096
 
6097
+ // src/handlers/update.handlers.ts
6098
+ async function handleUpdate(opts) {
6099
+ try {
6100
+ const currentVersion = getCurrentVersion();
6101
+ let output = chalk13.bold.cyan("\n\u{1F504} BrainGrid CLI Update\n\n");
6102
+ output += `${chalk13.bold("Current version:")} ${currentVersion}
6103
+ `;
6104
+ output += chalk13.dim("Checking for updates...\n");
6105
+ const latestVersion = await getLatestVersion();
6106
+ output += `${chalk13.bold("Latest version:")} ${latestVersion}
6107
+
6108
+ `;
6109
+ const comparison = compareVersions(currentVersion, latestVersion);
6110
+ if (comparison === 0) {
6111
+ output += chalk13.green("\u2705 You are already on the latest version!\n");
6112
+ return {
6113
+ success: true,
6114
+ message: output,
6115
+ data: { currentVersion, latestVersion, upToDate: true }
6116
+ };
6117
+ }
6118
+ if (comparison > 0) {
6119
+ output += chalk13.yellow("\u26A0\uFE0F You are on a newer version than what is published.\n");
6120
+ output += chalk13.dim(" This is expected if you are developing locally.\n");
6121
+ return {
6122
+ success: true,
6123
+ message: output,
6124
+ data: { currentVersion, latestVersion, upToDate: false }
6125
+ };
6126
+ }
6127
+ output += chalk13.yellow(`\u2B06\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}
6128
+
6129
+ `);
6130
+ if (opts.check) {
6131
+ output += chalk13.dim("Run ") + chalk13.cyan("braingrid update") + chalk13.dim(" to update\n");
6132
+ return {
6133
+ success: true,
6134
+ message: output,
6135
+ data: { currentVersion, latestVersion, upToDate: false }
6136
+ };
6137
+ }
6138
+ output += chalk13.dim("Detecting package manager...\n");
6139
+ const packageManager = await detectPackageManager(PACKAGE_NAME);
6140
+ output += `${chalk13.bold("Package manager:")} ${packageManager}
6141
+
6142
+ `;
6143
+ const updateCommand = getUpdateCommand(packageManager, PACKAGE_NAME);
6144
+ output += chalk13.dim("Running: ") + chalk13.cyan(updateCommand) + "\n\n";
6145
+ console.log(output);
6146
+ executeUpdate(packageManager, PACKAGE_NAME);
6147
+ const cliTools = await checkInstalledCliTools();
6148
+ const claudeInstalled = cliTools.find((t) => t.command === "claude")?.installed;
6149
+ const cursorInstalled = cliTools.find((t) => t.command === "cursor")?.installed;
6150
+ let setupOutput = "";
6151
+ if (claudeInstalled) {
6152
+ const shouldUpdate = await confirm({
6153
+ message: "Claude Code detected. Update BrainGrid integration?",
6154
+ default: true
6155
+ });
6156
+ if (shouldUpdate) {
6157
+ const result = await handleSetupClaudeCode({ force: true });
6158
+ setupOutput += "\n" + result.message;
6159
+ }
6160
+ }
6161
+ if (cursorInstalled) {
6162
+ const shouldUpdate = await confirm({
6163
+ message: "Cursor detected. Update BrainGrid integration?",
6164
+ default: true
6165
+ });
6166
+ if (shouldUpdate) {
6167
+ const result = await handleSetupCursor({ force: true });
6168
+ setupOutput += "\n" + result.message;
6169
+ }
6170
+ }
6171
+ return {
6172
+ success: true,
6173
+ message: chalk13.green("\n\u2705 Successfully updated BrainGrid CLI!\n") + setupOutput,
6174
+ data: { currentVersion, latestVersion, packageManager }
6175
+ };
6176
+ } catch (error) {
6177
+ return {
6178
+ success: false,
6179
+ message: formatError(error)
6180
+ };
6181
+ }
6182
+ }
6183
+
6184
+ // src/utils/update-checker.ts
6185
+ import chalk14 from "chalk";
6186
+ var CACHE_TTL_MS = 12 * 60 * 60 * 1e3;
6187
+ var CACHE_SERVICE = "braingrid-cli";
6188
+ var CACHE_ACCOUNT = "update-cache";
6189
+ async function getCache() {
6190
+ try {
6191
+ const cached = await credentialStore.getPassword(CACHE_SERVICE, CACHE_ACCOUNT);
6192
+ if (!cached) return null;
6193
+ return JSON.parse(cached);
6194
+ } catch {
6195
+ return null;
6196
+ }
6197
+ }
6198
+ async function setCache(cache) {
6199
+ try {
6200
+ await credentialStore.setPassword(CACHE_SERVICE, CACHE_ACCOUNT, JSON.stringify(cache));
6201
+ } catch {
6202
+ }
6203
+ }
6204
+ function isCacheValid(cache) {
6205
+ const now = Date.now();
6206
+ return now - cache.checkedAt < CACHE_TTL_MS;
6207
+ }
6208
+ async function getLatestVersionCached() {
6209
+ const cache = await getCache();
6210
+ if (cache && isCacheValid(cache)) {
6211
+ return cache.latestVersion;
6212
+ }
6213
+ try {
6214
+ const latestVersion = await getLatestVersion(5e3);
6215
+ await setCache({
6216
+ latestVersion,
6217
+ checkedAt: Date.now()
6218
+ });
6219
+ return latestVersion;
6220
+ } catch {
6221
+ return cache?.latestVersion ?? null;
6222
+ }
6223
+ }
6224
+ async function isUpdateAvailable() {
6225
+ const currentVersion = getCurrentVersion();
6226
+ const latestVersion = await getLatestVersionCached();
6227
+ if (!latestVersion) {
6228
+ return { available: false, currentVersion, latestVersion: null };
6229
+ }
6230
+ const comparison = compareVersions(currentVersion, latestVersion);
6231
+ return {
6232
+ available: comparison < 0,
6233
+ // Update available if current < latest
6234
+ currentVersion,
6235
+ latestVersion
6236
+ };
6237
+ }
6238
+ function getUpdateCommand2() {
6239
+ return `npm install -g ${PACKAGE_NAME}`;
6240
+ }
6241
+ async function checkAndShowUpdateWarning() {
6242
+ try {
6243
+ const { available, currentVersion, latestVersion } = await isUpdateAvailable();
6244
+ if (available && latestVersion) {
6245
+ const warning = "\n" + chalk14.yellow(`\u26A0\uFE0F Update available: ${currentVersion} \u2192 ${latestVersion}`) + "\n" + chalk14.dim(` Run \`${getUpdateCommand2()}\` to update`) + "\n";
6246
+ console.log(warning);
6247
+ }
6248
+ } catch {
6249
+ }
6250
+ }
6251
+
6227
6252
  // src/handlers/init.handlers.ts
6228
6253
  import { access as access3 } from "fs/promises";
6229
6254
 
@@ -6336,7 +6361,7 @@ async function promptToCreateProject(gitInfo, projectService, repositoryService)
6336
6361
  chalk15.yellow("\u26A0\uFE0F Repository accessible but no project exists.\n\n") + chalk15.dim(`Repository: ${gitInfo.owner}/${gitInfo.name}
6337
6362
  `)
6338
6363
  );
6339
- const shouldCreate = await confirm({
6364
+ const shouldCreate = await confirm2({
6340
6365
  message: `Would you like to create a project for ${gitInfo.name} now?`,
6341
6366
  default: true
6342
6367
  });
@@ -6457,7 +6482,7 @@ function showSetupInstructions(scenario) {
6457
6482
  async function handleNoGitRepository() {
6458
6483
  const canAutomate = await canUseGhAutomation();
6459
6484
  if (canAutomate) {
6460
- const shouldSetup = await confirm({
6485
+ const shouldSetup = await confirm2({
6461
6486
  message: "Would you like to initialize git and create a GitHub repository?",
6462
6487
  default: true
6463
6488
  });
@@ -6510,7 +6535,7 @@ async function handleNoGitRepository() {
6510
6535
  async function handleNoGitRemote() {
6511
6536
  const canAutomate = await canUseGhAutomation();
6512
6537
  if (canAutomate) {
6513
- const shouldCreate = await confirm({
6538
+ const shouldCreate = await confirm2({
6514
6539
  message: "Would you like to create a GitHub repository now?",
6515
6540
  default: true
6516
6541
  });
@@ -6559,7 +6584,7 @@ async function handleInit(opts) {
6559
6584
  chalk15.yellow(`
6560
6585
  \u26A0\uFE0F A new version of BrainGrid CLI is available: `) + chalk15.dim(`${updateInfo.currentVersion} \u2192 `) + chalk15.green(updateInfo.latestVersion) + "\n"
6561
6586
  );
6562
- const shouldUpdate = await confirm({
6587
+ const shouldUpdate = await confirm2({
6563
6588
  message: "Would you like to update now?",
6564
6589
  default: true
6565
6590
  });
@@ -6576,7 +6601,7 @@ async function handleInit(opts) {
6576
6601
  const config = getConfig();
6577
6602
  const { projectService, githubService, repositoryService, auth } = getServices4();
6578
6603
  if (!await isGitInstalled()) {
6579
- const shouldInstall = await confirm({
6604
+ const shouldInstall = await confirm2({
6580
6605
  message: "Git is required but not installed. Would you like to install it now?",
6581
6606
  default: true
6582
6607
  });
@@ -6608,7 +6633,7 @@ async function handleInit(opts) {
6608
6633
  console.log(
6609
6634
  chalk15.dim(" It enables seamless GitHub integration and repository management.\n")
6610
6635
  );
6611
- const shouldInstallGh = await confirm({
6636
+ const shouldInstallGh = await confirm2({
6612
6637
  message: "Would you like to install GitHub CLI now?",
6613
6638
  default: true
6614
6639
  });
@@ -6645,7 +6670,7 @@ async function handleInit(opts) {
6645
6670
  }
6646
6671
  const isAuthenticated = await auth.isAuthenticated();
6647
6672
  if (!isAuthenticated) {
6648
- const shouldLogin = await confirm({
6673
+ const shouldLogin = await confirm2({
6649
6674
  message: "You need to be authenticated. Would you like to log in / sign up now?",
6650
6675
  default: true
6651
6676
  });
@@ -6792,7 +6817,7 @@ async function handleInit(opts) {
6792
6817
  const projectInfo = chalk15.bold("\n\u{1F4E6} BrainGrid Project Found\n\n") + chalk15.dim("Project: ") + chalk15.cyan(project2.name) + "\n" + chalk15.dim("ID: ") + chalk15.gray(project2.short_id) + "\n" + (project2.description ? chalk15.dim("Description: ") + chalk15.gray(project2.description) + "\n" : "") + chalk15.dim("Repository: ") + chalk15.gray(project2.repository?.full_name || "N/A") + "\n\n";
6793
6818
  console.log(projectInfo);
6794
6819
  if (!opts.force) {
6795
- const shouldInit = await confirm({
6820
+ const shouldInit = await confirm2({
6796
6821
  message: "Initialize this repository with the above project?",
6797
6822
  default: true
6798
6823
  });
@@ -6829,7 +6854,7 @@ async function handleInit(opts) {
6829
6854
  const claudeSetupExists = await fileExists2(".claude/commands/specify.md");
6830
6855
  if (!claudeSetupExists) {
6831
6856
  console.log("");
6832
- const setupClaude = await confirm({
6857
+ const setupClaude = await confirm2({
6833
6858
  message: "Claude Code detected. Install BrainGrid integration? (slash commands, skills, status line)",
6834
6859
  default: true
6835
6860
  });
@@ -6859,7 +6884,7 @@ async function handleInit(opts) {
6859
6884
  const cursorSetupExists = await fileExists2(".cursor/commands/specify.md");
6860
6885
  if (!cursorSetupExists) {
6861
6886
  console.log("");
6862
- const setupCursor = await confirm({
6887
+ const setupCursor = await confirm2({
6863
6888
  message: "Cursor detected. Install BrainGrid integration? (slash commands, rules, context)",
6864
6889
  default: true
6865
6890
  });