@braingrid/cli 0.2.57 → 0.2.59

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,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.2.59] - 2026-03-11
11
+
12
+ ### Fixed
13
+
14
+ - **`braingrid init` should continue after update** — init now continues the setup flow after updating instead of exiting early, and saves `project.json` after project creation
15
+ - **Skip deprecated files during setup** — setup no longer fails when encountering deprecated files that were already removed
16
+
17
+ ## [0.2.58] - 2026-03-06
18
+
19
+ ### Added
20
+
21
+ - **Frontmatter fields for build skill** — added frontmatter metadata to the `/build` skill for improved skill discovery and configuration
22
+
23
+ ### Fixed
24
+
25
+ - **Vercel protection bypass header missing from auth API calls** — added the `x-vercel-protection-bypass` header to authentication requests so the CLI can reach Vercel-protected dev/staging environments
26
+
10
27
  ## [0.2.57] - 2026-03-03
11
28
 
12
29
  ### Fixed
package/dist/cli.js CHANGED
@@ -226,7 +226,7 @@ async function axiosWithRetry(config2, options) {
226
226
 
227
227
  // src/build-config.ts
228
228
  var BUILD_ENV = true ? "production" : process.env.NODE_ENV === "test" ? "development" : "production";
229
- var CLI_VERSION = true ? "0.2.57" : "0.0.0-test";
229
+ var CLI_VERSION = true ? "0.2.59" : "0.0.0-test";
230
230
  var PRODUCTION_CONFIG = {
231
231
  apiUrl: "https://app.braingrid.ai",
232
232
  workosAuthUrl: "https://auth.braingrid.ai",
@@ -1020,13 +1020,17 @@ var BraingridAuth = class {
1020
1020
  }
1021
1021
  try {
1022
1022
  this.logger.debug("[AUTH] Fetching profile using BRAINGRID_API_TOKEN");
1023
+ const appConfig = getConfig();
1023
1024
  const response = await axiosWithRetry(
1024
1025
  {
1025
1026
  url: `${this.baseUrl}/api/v1/profile`,
1026
1027
  method: "POST",
1027
1028
  headers: {
1028
1029
  "Content-Type": "application/json",
1029
- Authorization: `Bearer ${BRAINGRID_API_TOKEN}`
1030
+ Authorization: `Bearer ${BRAINGRID_API_TOKEN}`,
1031
+ ...appConfig.vercelProtectionBypass && {
1032
+ "x-vercel-protection-bypass": appConfig.vercelProtectionBypass
1033
+ }
1030
1034
  },
1031
1035
  maxRedirects: 0,
1032
1036
  validateStatus: (status) => status < 500
@@ -1485,13 +1489,17 @@ var BraingridAuth = class {
1485
1489
  this.logger.debug(
1486
1490
  `[AUTH] Making API call to ${this.baseUrl}/api/v1/auth/validate for session validation`
1487
1491
  );
1492
+ const validationConfig = getConfig();
1488
1493
  const response = await axiosWithRetry(
1489
1494
  {
1490
1495
  url: `${this.baseUrl}/api/v1/auth/validate`,
1491
1496
  method: "POST",
1492
1497
  headers: {
1493
1498
  "Content-Type": "application/json",
1494
- Authorization: `Bearer ${session.sealed_session}`
1499
+ Authorization: `Bearer ${session.sealed_session}`,
1500
+ ...validationConfig.vercelProtectionBypass && {
1501
+ "x-vercel-protection-bypass": validationConfig.vercelProtectionBypass
1502
+ }
1495
1503
  },
1496
1504
  maxRedirects: 0,
1497
1505
  // Don't follow redirects
@@ -2372,6 +2380,7 @@ async function handleCompletion(shellArg, opts) {
2372
2380
  }
2373
2381
 
2374
2382
  // src/handlers/init.handlers.ts
2383
+ import { execSync as execSync4 } from "child_process";
2375
2384
  import { access as access3 } from "fs/promises";
2376
2385
  import { confirm as confirm2, input, select as select3 } from "@inquirer/prompts";
2377
2386
  import chalk12 from "chalk";
@@ -3926,7 +3935,10 @@ async function _handleSetup(config2, opts) {
3926
3935
  );
3927
3936
  console.log(chalk10.bold(`\u{1F680} Setting up ${config2.name} integration...
3928
3937
  `));
3929
- const operations = await getFileList(config2.sourceDirs, config2.targetDirs);
3938
+ const deprecatedSet = new Set((config2.deprecatedFiles ?? []).map((f) => path7.resolve(f)));
3939
+ const operations = (await getFileList(config2.sourceDirs, config2.targetDirs)).filter(
3940
+ (op) => !deprecatedSet.has(path7.resolve(op.targetPath))
3941
+ );
3930
3942
  const injectionFileExists = await fileExists(config2.injection.targetFile);
3931
3943
  operations.push({
3932
3944
  type: "inject",
@@ -4695,10 +4707,21 @@ async function handleInit(opts) {
4695
4707
  if (shouldUpdate) {
4696
4708
  const result = await handleUpdate({});
4697
4709
  console.log(result.message);
4698
- return {
4699
- success: true,
4700
- message: chalk12.dim("\nRun `braingrid init` again after the update completes.")
4701
- };
4710
+ try {
4711
+ const args = ["init"];
4712
+ if (opts.force) args.push("--force");
4713
+ if (opts.project) args.push("--project", opts.project);
4714
+ execSync4(`braingrid ${args.join(" ")}`, {
4715
+ stdio: "inherit",
4716
+ timeout: 12e4
4717
+ });
4718
+ return { success: true, message: "" };
4719
+ } catch {
4720
+ return {
4721
+ success: true,
4722
+ message: chalk12.dim("\nRun `braingrid init` again to complete setup.")
4723
+ };
4724
+ }
4702
4725
  }
4703
4726
  console.log();
4704
4727
  }
@@ -4868,7 +4891,7 @@ async function handleInit(opts) {
4868
4891
  console.log(chalk12.green("\u2705 Organization ID updated successfully\n"));
4869
4892
  }
4870
4893
  let gitInfo = await getGitRepositoryInfo();
4871
- let project2;
4894
+ let project2 = null;
4872
4895
  if (opts.project) {
4873
4896
  try {
4874
4897
  project2 = await projectService.getProject(opts.project);
@@ -4929,7 +4952,8 @@ async function handleInit(opts) {
4929
4952
  message: chalk12.red("\u274C Repository information is incomplete")
4930
4953
  };
4931
4954
  }
4932
- let response;
4955
+ let response = null;
4956
+ let handled404 = false;
4933
4957
  try {
4934
4958
  response = await projectService.listProjects({
4935
4959
  repository_owner: owner,
@@ -4939,7 +4963,8 @@ async function handleInit(opts) {
4939
4963
  if (error && typeof error === "object" && "response" in error) {
4940
4964
  const axiosError = error;
4941
4965
  if (axiosError.response?.status === 404) {
4942
- return await handleNoProjectForRepository(
4966
+ handled404 = true;
4967
+ const noProjectResult = await handleNoProjectForRepository(
4943
4968
  owner,
4944
4969
  name,
4945
4970
  gitInfo,
@@ -4948,22 +4973,42 @@ async function handleInit(opts) {
4948
4973
  projectService,
4949
4974
  config2
4950
4975
  );
4976
+ if (!noProjectResult.success || !noProjectResult.data) {
4977
+ return noProjectResult;
4978
+ }
4979
+ project2 = noProjectResult.data;
4980
+ } else {
4981
+ throw error;
4951
4982
  }
4983
+ } else {
4984
+ throw error;
4952
4985
  }
4953
- throw error;
4954
4986
  }
4955
- if (response.projects.length === 0) {
4956
- return await handleNoProjectForRepository(
4957
- owner,
4958
- name,
4959
- gitInfo,
4960
- githubService,
4961
- repositoryService,
4962
- projectService,
4963
- config2
4964
- );
4987
+ if (!handled404 && response) {
4988
+ if (response.projects.length === 0) {
4989
+ const noProjectResult = await handleNoProjectForRepository(
4990
+ owner,
4991
+ name,
4992
+ gitInfo,
4993
+ githubService,
4994
+ repositoryService,
4995
+ projectService,
4996
+ config2
4997
+ );
4998
+ if (!noProjectResult.success || !noProjectResult.data) {
4999
+ return noProjectResult;
5000
+ }
5001
+ project2 = noProjectResult.data;
5002
+ } else {
5003
+ project2 = response.projects[0];
5004
+ }
4965
5005
  }
4966
- project2 = response.projects[0];
5006
+ }
5007
+ if (!project2) {
5008
+ return {
5009
+ success: false,
5010
+ message: chalk12.red("\u274C Failed to determine project")
5011
+ };
4967
5012
  }
4968
5013
  log("INFO", "init", "project_found", `id=${project2.short_id} name=${project2.name}`);
4969
5014
  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)}