@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 +29 -0
- package/dist/cli.js +195 -170
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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
|
|
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
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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(
|
|
6064
|
-
console.log(
|
|
6065
|
-
console.log(
|
|
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(
|
|
5939
|
+
console.log(chalk12.cyan("\n New Files:"));
|
|
6070
5940
|
for (const op of newFiles) {
|
|
6071
|
-
console.log(
|
|
5941
|
+
console.log(chalk12.dim(` ${op.targetPath}`));
|
|
6072
5942
|
}
|
|
6073
5943
|
}
|
|
6074
5944
|
if (existingFiles.length > 0) {
|
|
6075
|
-
console.log(
|
|
5945
|
+
console.log(chalk12.yellow("\n Existing Files (will prompt):"));
|
|
6076
5946
|
for (const op of existingFiles) {
|
|
6077
|
-
console.log(
|
|
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:
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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 ?
|
|
6051
|
+
const statusLineMessage = statusLineInstalled ? chalk12.dim(" Status line: .claude/statusline.sh\n") : "";
|
|
6182
6052
|
return {
|
|
6183
6053
|
success: true,
|
|
6184
|
-
message:
|
|
6054
|
+
message: chalk12.green(`\u2705 ${config.name} integration installed successfully!
|
|
6185
6055
|
|
|
6186
|
-
`) +
|
|
6187
|
-
`) + statusLineMessage +
|
|
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
|
-
`) +
|
|
6190
|
-
`) +
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
6887
|
+
const setupCursor = await confirm2({
|
|
6863
6888
|
message: "Cursor detected. Install BrainGrid integration? (slash commands, rules, context)",
|
|
6864
6889
|
default: true
|
|
6865
6890
|
});
|