@girardmedia/bootspring 2.5.10 → 2.5.11

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.
@@ -25,20 +25,31 @@ var C = {
25
25
  yellow: "\x1B[33m",
26
26
  red: "\x1B[31m"
27
27
  };
28
+ var PRIMARY_COMMANDS = ["auth", "build", "seed", "init", "go", "mcp", "doctor", "deploy", "agent", "observe", "commands"];
28
29
  var HELP_GROUPS = {
29
- "Core": ["auth", "init", "project", "switch", "health", "doctor", "mcp", "dashboard", "context", "setup", "go"],
30
- "Build & Deploy": ["build", "deploy", "loop", "quality", "security", "update", "undo", "scaffold", "guardian"],
31
- "Planning": ["plan", "prd", "seed", "manager", "spec"],
32
- "Pipeline & Workflows": ["pipeline", "workflow", "harness", "flow", "autonomous", "pair"],
33
- "Agents & Skills": ["agent", "skill", "todo", "billing", "plugin", "studio", "prompt"],
34
- "Analysis & Quality": ["analyze", "audit", "monitor", "metrics", "validate", "visualize", "graph", "diff", "review-code", "arch", "predict", "profile", "runtime", "testgen"],
35
- "AI & Models": ["model", "local", "learn", "memory", "suggest", "orchestrator"],
36
- "Intelligence": ["observe", "autopilot", "watch", "timemachine", "team", "network", "report"],
37
- "Pro Tools": ["geo", "marketing", "sales", "jobs"],
38
- "Docs & Content": ["generate", "content", "docs"],
39
- "Business": ["business", "fundraise", "legal", "org"],
40
- "Infrastructure": ["workspace", "cloud-sync", "github", "onboard", "checkpoint", "sync", "issue"],
41
- "Tools": ["log", "mvp", "task", "telemetry", "visual"]
30
+ "Core": ["auth", "build", "seed", "init", "go", "mcp"],
31
+ "Project": ["project", "workspace", "org", "switch", "checkpoint"],
32
+ "Dev Tools": ["doctor", "health", "setup", "validate", "watch", "dashboard", "update", "hook"],
33
+ "Analysis": ["analyze", "audit", "quality", "security", "diff", "report"],
34
+ "AI & Agents": ["agent", "skill", "context", "prompt", "flow"],
35
+ "Observe": ["observe", "autopilot", "monitor", "session", "metrics", "telemetry"],
36
+ "Docs": ["docs", "generate", "prd", "content", "plan", "suggest"],
37
+ "Deploy & Ops": ["deploy", "sync", "cloud-sync", "github", "undo", "history", "changes", "log"],
38
+ "Business": ["business", "marketing", "sales", "geo", "fundraise", "legal", "jobs"],
39
+ "Tasks": ["todo", "task", "memory", "learn", "issue", "loop"],
40
+ "Other": [
41
+ "billing",
42
+ "onboard",
43
+ "visualize",
44
+ "mvp",
45
+ "plugin",
46
+ "manager",
47
+ "harness",
48
+ "pipeline",
49
+ "workflow",
50
+ "orchestrator",
51
+ "marketplace"
52
+ ]
42
53
  };
43
54
  function showHelp() {
44
55
  console.log(`${C.cyan}${C.bold}\u26A1 Bootspring${C.reset} ${C.dim}v${VERSION}${C.reset}`);
@@ -46,29 +57,20 @@ function showHelp() {
46
57
  `);
47
58
  console.log(`${C.bold}Usage:${C.reset} bootspring <command> [options]
48
59
  `);
49
- console.log(`${C.cyan}${C.bold}QUICK START${C.reset}`);
50
- console.log(` ${C.green}bootspring go${C.reset} ${C.dim}One command to set up everything${C.reset}`);
51
- console.log(` ${C.green}bootspring auth login${C.reset} ${C.dim}Authenticate (required first time)${C.reset}`);
52
- console.log(` ${C.green}bootspring setup${C.reset} ${C.dim}Configure MCP for Claude/Codex/Gemini${C.reset}`);
60
+ console.log(`${C.cyan}${C.bold}COMMANDS${C.reset}`);
61
+ console.log(` ${C.green}go${C.reset} ${C.dim}One command to set up everything${C.reset}`);
62
+ console.log(` ${C.green}auth${C.reset} ${C.dim}Login, logout, status${C.reset}`);
63
+ console.log(` ${C.green}init${C.reset} ${C.dim}Initialize a new project${C.reset}`);
64
+ console.log(` ${C.green}seed${C.reset} ${C.dim}Create and refine context documents${C.reset}`);
65
+ console.log(` ${C.green}build${C.reset} ${C.dim}Build loop \u2014 next, done, status, auto${C.reset}`);
66
+ console.log(` ${C.green}deploy${C.reset} ${C.dim}Validate and deploy${C.reset}`);
67
+ console.log(` ${C.green}mcp${C.reset} ${C.dim}MCP server management${C.reset}`);
68
+ console.log(` ${C.green}agent${C.reset} ${C.dim}AI agent proxy${C.reset}`);
69
+ console.log(` ${C.green}observe${C.reset} ${C.dim}Session intelligence and analytics${C.reset}`);
70
+ console.log(` ${C.green}doctor${C.reset} ${C.dim}Diagnose project issues${C.reset}`);
53
71
  console.log("");
54
- console.log(`${C.cyan}${C.bold}NEW PROJECT${C.reset}`);
55
- console.log(` ${C.green}bootspring seed init${C.reset} ${C.dim}Create context document templates${C.reset}`);
56
- console.log(` ${C.green}bootspring seed go${C.reset} ${C.dim}Full workflow: detect + seed + generate + build${C.reset}`);
57
- console.log(` ${C.green}bootspring generate${C.reset} ${C.dim}Generate AI context files${C.reset}`);
58
- console.log("");
59
- console.log(`${C.cyan}${C.bold}EXISTING PROJECT${C.reset}`);
60
- console.log(` ${C.green}bootspring seed from-codebase${C.reset} ${C.dim}Detect stack and generate context${C.reset}`);
61
- console.log(` ${C.green}bootspring onboard start${C.reset} ${C.dim}Full analysis of existing codebase${C.reset}`);
62
- console.log("");
63
- console.log(`${C.cyan}${C.bold}BUILD LOOP${C.reset}`);
64
- console.log(` ${C.green}bootspring build next${C.reset} ${C.dim}Start the next task${C.reset}`);
65
- console.log(` ${C.green}bootspring build done${C.reset} ${C.dim}Mark current task complete${C.reset}`);
66
- console.log(` ${C.green}bootspring build status${C.reset} ${C.dim}Check build progress${C.reset}`);
67
- console.log("");
68
- console.log(`${C.cyan}${C.bold}MORE${C.reset}`);
69
- console.log(` ${C.green}bootspring doctor${C.reset} ${C.dim}Diagnose project issues${C.reset}`);
70
- console.log(` ${C.green}bootspring observe${C.reset} ${C.dim}Session intelligence and analytics${C.reset}`);
71
- console.log(` ${C.green}bootspring commands${C.reset} ${C.dim}Show all ${Object.values(HELP_GROUPS).flat().length} commands${C.reset}`);
72
+ const total = Object.values(HELP_GROUPS).flat().length;
73
+ console.log(` ${C.green}commands${C.reset} ${C.dim}Show all ${total} commands${C.reset}`);
72
74
  console.log(`
73
75
  ${C.dim}Run "bootspring <command> --help" for details${C.reset}`);
74
76
  console.log(`${C.dim}Docs: https://bootspring.com/docs${C.reset}
@@ -76,13 +78,18 @@ ${C.dim}Run "bootspring <command> --help" for details${C.reset}`);
76
78
  }
77
79
  function showFullCommands() {
78
80
  const total = Object.values(HELP_GROUPS).flat().length;
79
- console.log(`${C.cyan}${C.bold}\u26A1 Bootspring${C.reset} ${C.dim}v${VERSION} \u2014 ${total} commands${C.reset}
81
+ const primarySet = new Set(PRIMARY_COMMANDS);
82
+ console.log(`${C.cyan}${C.bold}\u26A1 Bootspring${C.reset} ${C.dim}v${VERSION} \u2014 ${total} commands (${PRIMARY_COMMANDS.length - 1} primary)${C.reset}
80
83
  `);
81
84
  for (const [group, cmds] of Object.entries(HELP_GROUPS)) {
82
- console.log(`${C.bold}${group}:${C.reset} ${cmds.map((command) => `${C.green}${command}${C.reset}`).join(", ")}`);
85
+ const formatted = cmds.map(
86
+ (command) => primarySet.has(command) ? `${C.green}${C.bold}${command}${C.reset}` : `${C.dim}${command}${C.reset}`
87
+ ).join(", ");
88
+ console.log(`${C.bold}${group}:${C.reset} ${formatted}`);
83
89
  }
84
90
  console.log(`
85
- ${C.dim}Run "bootspring <command> --help" for command details${C.reset}`);
91
+ ${C.dim}Bold = primary commands shown in help${C.reset}`);
92
+ console.log(`${C.dim}Run "bootspring <command> --help" for command details${C.reset}`);
86
93
  console.log(`${C.dim}Docs: https://bootspring.com/docs${C.reset}
87
94
  `);
88
95
  }
@@ -414,15 +414,22 @@ interface DiagnosticResult {
414
414
  fix?: string;
415
415
  }
416
416
  declare function runDiagnostics(autoFix?: boolean): DiagnosticResult[];
417
+ type AssistantTarget = 'claude' | 'cursor' | 'codex' | 'gemini';
418
+ declare function registerMcpForAssistant(target: AssistantTarget): {
419
+ success: boolean;
420
+ path: string;
421
+ };
417
422
 
423
+ type selfHeal_AssistantTarget = AssistantTarget;
418
424
  type selfHeal_DiagnosticResult = DiagnosticResult;
419
425
  type selfHeal_HealResult = HealResult;
420
426
  type selfHeal_Issue = Issue;
421
427
  declare const selfHeal_classifyError: typeof classifyError;
428
+ declare const selfHeal_registerMcpForAssistant: typeof registerMcpForAssistant;
422
429
  declare const selfHeal_runDiagnostics: typeof runDiagnostics;
423
430
  declare const selfHeal_tryHeal: typeof tryHeal;
424
431
  declare namespace selfHeal {
425
- export { type selfHeal_DiagnosticResult as DiagnosticResult, type selfHeal_HealResult as HealResult, type selfHeal_Issue as Issue, selfHeal_classifyError as classifyError, selfHeal_runDiagnostics as runDiagnostics, selfHeal_tryHeal as tryHeal };
432
+ export { type selfHeal_AssistantTarget as AssistantTarget, type selfHeal_DiagnosticResult as DiagnosticResult, type selfHeal_HealResult as HealResult, type selfHeal_Issue as Issue, selfHeal_classifyError as classifyError, selfHeal_registerMcpForAssistant as registerMcpForAssistant, selfHeal_runDiagnostics as runDiagnostics, selfHeal_tryHeal as tryHeal };
426
433
  }
427
434
 
428
435
  /**
@@ -470,7 +477,7 @@ interface InstallContext {
470
477
  scriptPath: string;
471
478
  }
472
479
  declare const PACKAGE_NAME = "@girardmedia/bootspring";
473
- declare const CURRENT_VERSION = "2.5.10";
480
+ declare const CURRENT_VERSION = "2.5.11";
474
481
  declare const DEFAULT_INTERVAL_MS: number;
475
482
  declare const STATE_PATH: string;
476
483
  declare function compareVersions(a: string, b: string): number;
@@ -2403,4 +2410,4 @@ declare namespace telemetry {
2403
2410
  export { telemetry_ASSISTANTS as ASSISTANTS, telemetry_ASSISTANT_FIRST_SUCCESS_EVENT as ASSISTANT_FIRST_SUCCESS_EVENT, telemetry_ASSISTANT_RETURN_EVENT as ASSISTANT_RETURN_EVENT, telemetry_ASSISTANT_SETUP_EVENT as ASSISTANT_SETUP_EVENT, type telemetry_AssistantFunnelEntry as AssistantFunnelEntry, type telemetry_AssistantFunnelSummary as AssistantFunnelSummary, type telemetry_AssistantId as AssistantId, type telemetry_AssistantTrackOptions as AssistantTrackOptions, type telemetry_AssistantUsageTrackResult as AssistantUsageTrackResult, telemetry_BILLING_UPGRADE_STARTED_EVENT as BILLING_UPGRADE_STARTED_EVENT, type telemetry_ClearResult as ClearResult, type telemetry_EmitOptions as EmitOptions, type telemetry_FailedBatch as FailedBatch, type telemetry_ListEventsOptions as ListEventsOptions, telemetry_MAX_EVENTS_LIMIT as MAX_EVENTS_LIMIT, type telemetry_TelemetryRecord as TelemetryRecord, type telemetry_TelemetryStatus as TelemetryStatus, telemetry_UPGRADE_COMPLETED_EVENT as UPGRADE_COMPLETED_EVENT, telemetry_UPGRADE_PROMPT_EVENT as UPGRADE_PROMPT_EVENT, type telemetry_UpgradeFunnelEntry as UpgradeFunnelEntry, type telemetry_UpgradeFunnelSummary as UpgradeFunnelSummary, type telemetry_UploadOptions as UploadOptions, type telemetry_UploadResult as UploadResult, telemetry_clearEvents as clearEvents, telemetry_emitEvent as emitEvent, telemetry_ensureTelemetryDir as ensureTelemetryDir, telemetry_getAssistantActivationFunnel as getAssistantActivationFunnel, telemetry_getStatus as getStatus, telemetry_getTelemetryDir as getTelemetryDir, telemetry_getTelemetryFile as getTelemetryFile, telemetry_getUpgradeConversionFunnel as getUpgradeConversionFunnel, telemetry_inferAssistantFromEnvironment as inferAssistantFromEnvironment, telemetry_listEvents as listEvents, telemetry_track as track, telemetry_trackAssistantSetup as trackAssistantSetup, telemetry_trackAssistantUsageSuccess as trackAssistantUsageSuccess, telemetry_uploadEvents as uploadEvents };
2404
2411
  }
2405
2412
 
2406
- export { API_BASE, API_VERSION, BOOTSPRING_DIR, type BootspringConfig, COMMANDS_SOURCE, CONFIG_FILE, CREDENTIALS_FILE, CURRENT_VERSION, type Credentials, DEFAULT_INTERVAL_MS, DEFAULT_POLICY_PROFILE, DEVICE_FILE, type DeviceContext, type DeviceInfo, type DiagnosticResult, type ExpiryStatus, type HealResult, type Issue, LIMITS, LOCAL_CONFIG_NAME, type LoginResponse, PACKAGE_NAME, PATTERNS, POLICY_PROFILES, type PolicyOptions, type PolicyProfile, type ProjectAuth, type ProjectConfig, type ProjectContext$1 as ProjectContext, SESSION_FILE, SHELL_DANGEROUS_CHARS, STATE_PATH, type SessionData, type SessionOptions, TARGET_DIRS, type UserProfile, type ValidationResult$1 as ValidationResult, type Workflow, addRecentProject, apiClient as api, apiLogin, applyUpdate, auth, callMcpTool, checkForUpdates, checkInstallation, classifyError, clearCredentials, clearDeviceInfo, clearProjectApiKey, clearProjectScopedSession, clearSession, compareVersions, config, context, createLocalConfig, decrypt, encrypt, ensureBootspringDir, ensureLatestVersion, entitlements, findLocalConfig, findNearestProjectConfigPath, generateDeviceFingerprint, getApiKey, getCommandFiles, getConfig, getCredentials, getCredentialsPath, getCurrentProject, getDeviceContext, getDeviceId, getDeviceInfo, getEffectiveProject, getInstallContext, getLatestVersion, getLegacyProjectApiKey, getMcpResource, getPolicyProfile, getProjectScopedSessionState, getProjectScopedToken, getRecentProjects, getRefreshToken, getSession, getSessionState, getStoredApiKey, getTier$1 as getTier, getToken, getTokenExpiryStatus, getUser, healthCheck, installAll, installToTarget, isApiKeyAuth, isAuthenticated, isWorkflowBlocked, listMcpResources, listMcpTools, login, loginWithApiKey, logout, maybeAutoUploadTelemetry, normalizeProfile, policies, pollDeviceToken, presence, readNearestProjectConfig, refreshSession, remoteLogout, request, resolvePolicyProfile, runDiagnostics, saveApiKeyToProject, saveConfig, saveCredentials, saveProjectScopedSession, saveSession, selfHeal, selfUpdate, sendHealthReport, sendHeartbeat, session, setAuthFailureHandler, setCurrentProject, setupCommands, startDeviceFlow, stripUnsafeControlChars, telemetry, tierEnforcement, tryHeal, uninstallAll, updateTokens, validateNumericId, validateSlug, validateStringLength, validateTodoText, writeNearestProjectConfig };
2413
+ export { API_BASE, API_VERSION, type AssistantTarget, BOOTSPRING_DIR, type BootspringConfig, COMMANDS_SOURCE, CONFIG_FILE, CREDENTIALS_FILE, CURRENT_VERSION, type Credentials, DEFAULT_INTERVAL_MS, DEFAULT_POLICY_PROFILE, DEVICE_FILE, type DeviceContext, type DeviceInfo, type DiagnosticResult, type ExpiryStatus, type HealResult, type Issue, LIMITS, LOCAL_CONFIG_NAME, type LoginResponse, PACKAGE_NAME, PATTERNS, POLICY_PROFILES, type PolicyOptions, type PolicyProfile, type ProjectAuth, type ProjectConfig, type ProjectContext$1 as ProjectContext, SESSION_FILE, SHELL_DANGEROUS_CHARS, STATE_PATH, type SessionData, type SessionOptions, TARGET_DIRS, type UserProfile, type ValidationResult$1 as ValidationResult, type Workflow, addRecentProject, apiClient as api, apiLogin, applyUpdate, auth, callMcpTool, checkForUpdates, checkInstallation, classifyError, clearCredentials, clearDeviceInfo, clearProjectApiKey, clearProjectScopedSession, clearSession, compareVersions, config, context, createLocalConfig, decrypt, encrypt, ensureBootspringDir, ensureLatestVersion, entitlements, findLocalConfig, findNearestProjectConfigPath, generateDeviceFingerprint, getApiKey, getCommandFiles, getConfig, getCredentials, getCredentialsPath, getCurrentProject, getDeviceContext, getDeviceId, getDeviceInfo, getEffectiveProject, getInstallContext, getLatestVersion, getLegacyProjectApiKey, getMcpResource, getPolicyProfile, getProjectScopedSessionState, getProjectScopedToken, getRecentProjects, getRefreshToken, getSession, getSessionState, getStoredApiKey, getTier$1 as getTier, getToken, getTokenExpiryStatus, getUser, healthCheck, installAll, installToTarget, isApiKeyAuth, isAuthenticated, isWorkflowBlocked, listMcpResources, listMcpTools, login, loginWithApiKey, logout, maybeAutoUploadTelemetry, normalizeProfile, policies, pollDeviceToken, presence, readNearestProjectConfig, refreshSession, registerMcpForAssistant, remoteLogout, request, resolvePolicyProfile, runDiagnostics, saveApiKeyToProject, saveConfig, saveCredentials, saveProjectScopedSession, saveSession, selfHeal, selfUpdate, sendHealthReport, sendHeartbeat, session, setAuthFailureHandler, setCurrentProject, setupCommands, startDeviceFlow, stripUnsafeControlChars, telemetry, tierEnforcement, tryHeal, uninstallAll, updateTokens, validateNumericId, validateSlug, validateStringLength, validateTodoText, writeNearestProjectConfig };
package/dist/core.js CHANGED
@@ -158,6 +158,13 @@ ${COLORS.bold}${msg}${COLORS.reset}`);
158
158
  console.log(`${indent}- ${formatListItem(item)}`);
159
159
  }
160
160
  };
161
+ printImpl.apiError = (prefix, err) => {
162
+ if (err && typeof err === "object" && err.authHandled) {
163
+ return;
164
+ }
165
+ const message = err instanceof Error ? err.message : String(err);
166
+ console.log(`${COLORS.red}\u2717${COLORS.reset} ${prefix}: ${message}`);
167
+ };
161
168
  print = printImpl;
162
169
  }
163
170
  });
@@ -372,7 +379,7 @@ var init_release = __esm({
372
379
  "../../packages/shared/src/release.ts"() {
373
380
  "use strict";
374
381
  init_cjs_shims();
375
- BOOTSPRING_VERSION = "2.5.10";
382
+ BOOTSPRING_VERSION = "2.5.11";
376
383
  BOOTSPRING_PACKAGE_NAME = "@girardmedia/bootspring";
377
384
  }
378
385
  });
@@ -17934,6 +17941,7 @@ var require_dist = __commonJS({
17934
17941
  presence: () => presence_exports,
17935
17942
  readNearestProjectConfig: () => readNearestProjectConfig,
17936
17943
  refreshSession: () => refreshSession,
17944
+ registerMcpForAssistant: () => registerMcpForAssistant,
17937
17945
  remoteLogout: () => remoteLogout,
17938
17946
  request: () => request,
17939
17947
  resolvePolicyProfile: () => resolvePolicyProfile,
@@ -18153,6 +18161,7 @@ var require_dist = __commonJS({
18153
18161
  if (reauthOk) {
18154
18162
  return rawRequest(method, path10, data, { ...options, _authRetried: true, noCache: true });
18155
18163
  }
18164
+ err.authHandled = true;
18156
18165
  }
18157
18166
  throw err;
18158
18167
  }
@@ -18382,6 +18391,7 @@ var require_dist = __commonJS({
18382
18391
  var self_heal_exports = {};
18383
18392
  __export2(self_heal_exports, {
18384
18393
  classifyError: () => classifyError,
18394
+ registerMcpForAssistant: () => registerMcpForAssistant,
18385
18395
  runDiagnostics: () => runDiagnostics,
18386
18396
  tryHeal: () => tryHeal
18387
18397
  });
@@ -18629,6 +18639,30 @@ var require_dist = __commonJS({
18629
18639
  } else {
18630
18640
  results.push({ id: "deps", status: "ok", message: "Dependencies installed." });
18631
18641
  }
18642
+ const lockPath = import_path3.default.join(cwd, "package-lock.json");
18643
+ const pnpmLock = import_path3.default.join(cwd, "pnpm-lock.yaml");
18644
+ const nmPath = import_path3.default.join(cwd, "node_modules");
18645
+ const lockFile = import_fs3.default.existsSync(pnpmLock) ? pnpmLock : import_fs3.default.existsSync(lockPath) ? lockPath : null;
18646
+ if (lockFile && import_fs3.default.existsSync(nmPath)) {
18647
+ try {
18648
+ const lockMtime = import_fs3.default.statSync(lockFile).mtimeMs;
18649
+ const nmMtime = import_fs3.default.statSync(nmPath).mtimeMs;
18650
+ if (lockMtime > nmMtime) {
18651
+ const installCmd = lockFile.endsWith(".yaml") ? "pnpm install" : "npm install";
18652
+ if (autoFix) {
18653
+ try {
18654
+ (0, import_child_process.execSync)(installCmd, { cwd, timeout: 12e4, stdio: "pipe" });
18655
+ results.push({ id: "deps-stale", status: "healed", message: `Lockfile newer than node_modules \u2014 ran ${installCmd}.` });
18656
+ } catch {
18657
+ results.push({ id: "deps-stale", status: "action-needed", message: "Lockfile newer than node_modules.", fix: installCmd });
18658
+ }
18659
+ } else {
18660
+ results.push({ id: "deps-stale", status: "action-needed", message: "Lockfile newer than node_modules \u2014 dependencies may be stale.", fix: `${installCmd}` });
18661
+ }
18662
+ }
18663
+ } catch {
18664
+ }
18665
+ }
18632
18666
  const mcpTargets = {
18633
18667
  claude: import_path3.default.join(homeDir, ".claude.json"),
18634
18668
  codex: import_path3.default.join(homeDir, ".codex", "config.toml"),
@@ -18679,7 +18713,9 @@ var require_dist = __commonJS({
18679
18713
  if (autoFix) {
18680
18714
  const backup = buildStatePath + ".bak";
18681
18715
  import_fs3.default.copyFileSync(buildStatePath, backup);
18682
- results.push({ id: "build-state", status: "action-needed", message: "BUILD_STATE.json has invalid structure.", fix: "bootspring build start" });
18716
+ state.implementationQueue = state.implementationQueue || [];
18717
+ import_fs3.default.writeFileSync(buildStatePath, JSON.stringify(state, null, 2));
18718
+ results.push({ id: "build-state", status: "healed", message: `BUILD_STATE.json repaired (backed up to ${import_path3.default.basename(backup)}).` });
18683
18719
  } else {
18684
18720
  results.push({ id: "build-state", status: "action-needed", message: "BUILD_STATE.json has invalid structure.", fix: "bootspring doctor --fix" });
18685
18721
  }
@@ -18775,6 +18811,29 @@ ${block}` : block;
18775
18811
  return false;
18776
18812
  }
18777
18813
  }
18814
+ var MCP_PATHS = {
18815
+ claude: () => import_path3.default.join(import_os2.default.homedir(), ".claude.json"),
18816
+ cursor: () => import_path3.default.join(import_os2.default.homedir(), ".cursor", "mcp.json"),
18817
+ codex: () => import_path3.default.join(import_os2.default.homedir(), ".codex", "config.toml"),
18818
+ gemini: () => import_path3.default.join(import_os2.default.homedir(), ".gemini", "settings.json")
18819
+ };
18820
+ function registerMcpForAssistant(target) {
18821
+ const configPath = MCP_PATHS[target]();
18822
+ let success = false;
18823
+ switch (target) {
18824
+ case "claude":
18825
+ case "cursor":
18826
+ success = writeClaudeMcp(configPath);
18827
+ break;
18828
+ case "codex":
18829
+ success = writeCodexMcp(configPath);
18830
+ break;
18831
+ case "gemini":
18832
+ success = writeGeminiMcp(configPath);
18833
+ break;
18834
+ }
18835
+ return { success, path: configPath };
18836
+ }
18778
18837
  var presence_exports = {};
18779
18838
  __export2(presence_exports, {
18780
18839
  maybeAutoUploadTelemetry: () => maybeAutoUploadTelemetry,
@@ -21339,6 +21398,13 @@ ${COLORS2.bold}${msg}${COLORS2.reset}`);
21339
21398
  console.log(`${indent}- ${formatListItem2(item)}`);
21340
21399
  }
21341
21400
  };
21401
+ printImpl2.apiError = (prefix, err) => {
21402
+ if (err && typeof err === "object" && err.authHandled) {
21403
+ return;
21404
+ }
21405
+ const message = err instanceof Error ? err.message : String(err);
21406
+ console.log(`${COLORS2.red}\u2717${COLORS2.reset} ${prefix}: ${message}`);
21407
+ };
21342
21408
  var print2 = printImpl2;
21343
21409
  function createSpinner2(message) {
21344
21410
  const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
@@ -21577,7 +21643,7 @@ ${COLORS2.dim}Run "bootspring mcp" for server options${COLORS2.reset}
21577
21643
  console.log(`${COLORS2.dim}Run "bootspring mcp" for setup instructions.${COLORS2.reset}
21578
21644
  `);
21579
21645
  }
21580
- var BOOTSPRING_VERSION2 = "2.5.10";
21646
+ var BOOTSPRING_VERSION2 = "2.5.11";
21581
21647
  var BOOTSPRING_PACKAGE_NAME2 = "@girardmedia/bootspring";
21582
21648
  var REDACTED2 = "[REDACTED]";
21583
21649
  var SENSITIVE_KEY_PATTERN2 = /(?:^|[_-])(api[_-]?key|token|refresh[_-]?token|authorization|x[_-]?api[_-]?key|project[_-]?id)$/i;
@@ -21625,7 +21691,7 @@ var require_package = __commonJS({
21625
21691
  "../../../package.json"(exports2, module2) {
21626
21692
  module2.exports = {
21627
21693
  name: "bootspring-workspace",
21628
- version: "2.5.10",
21694
+ version: "2.5.11",
21629
21695
  private: true,
21630
21696
  description: "Workspace tooling for the Bootspring monorepo",
21631
21697
  keywords: [
@@ -21655,7 +21721,9 @@ var require_package = __commonJS({
21655
21721
  mcp: "node monorepo/apps/cli/dist/mcp-server.js",
21656
21722
  "version:sync": "node scripts/sync-version-metadata.js",
21657
21723
  "verify:version-sync": "node scripts/sync-version-metadata.js --check",
21658
- "release:prepare": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates",
21724
+ "release:prepare": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates && npm run smoke:publish",
21725
+ "release:dry-run": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates && npm run smoke:publish && echo '\\n--- DRY RUN COMPLETE (no publish) ---'",
21726
+ "smoke:publish": "node scripts/smoke-publish.js",
21659
21727
  pretest: "npm run build",
21660
21728
  test: "vitest run",
21661
21729
  "test:launch-smoke": "vitest run __tests__/unit/cli-first-run-smoke.test.js __tests__/unit/health-fresh-start.test.ts __tests__/unit/session-project-scope.test.ts __tests__/unit/auth-cli-mixed-states.test.ts __tests__/unit/api-client-project-auth-fallback.test.js __tests__/unit/cli-help-surface.test.js __tests__/unit/cli-command-manifest.test.js",
@@ -21682,7 +21750,10 @@ var require_package = __commonJS({
21682
21750
  "server:bundle:configure-shared-billing-gh": "bash monorepo/apps/server/compat-runtime/scripts/configure-shared-billing-smoke-gh.sh",
21683
21751
  "build:cli": "npm --prefix monorepo/apps/cli run build",
21684
21752
  "build:watch": "npm --prefix monorepo/apps/cli run dev",
21685
- dev: "npm --prefix monorepo/apps/cli run dev",
21753
+ dev: "cd monorepo && pnpm turbo dev --filter=@girardmedia/bootspring --filter=@bootspring/server --concurrency=10",
21754
+ "dev:cli": "npm --prefix monorepo/apps/cli run dev",
21755
+ "dev:server": "npm --prefix monorepo/apps/server run dev",
21756
+ "dev:test": "vitest",
21686
21757
  "verify:lint-budget": "node scripts/check-lint-budgets.js",
21687
21758
  "verify:release-gates": "node scripts/release-gate-check.js",
21688
21759
  "verify:shared-contracts": "node scripts/verify-shared-contracts.js",
@@ -31156,6 +31156,13 @@ ${COLORS.bold}${msg}${COLORS.reset}`);
31156
31156
  console.log(`${indent}- ${formatListItem(item)}`);
31157
31157
  }
31158
31158
  };
31159
+ printImpl.apiError = (prefix, err) => {
31160
+ if (err && typeof err === "object" && err.authHandled) {
31161
+ return;
31162
+ }
31163
+ const message = err instanceof Error ? err.message : String(err);
31164
+ console.log(`${COLORS.red}\u2717${COLORS.reset} ${prefix}: ${message}`);
31165
+ };
31159
31166
  print = printImpl;
31160
31167
  }
31161
31168
  });
@@ -31370,7 +31377,7 @@ var init_release = __esm({
31370
31377
  "../../packages/shared/src/release.ts"() {
31371
31378
  "use strict";
31372
31379
  init_cjs_shims();
31373
- BOOTSPRING_VERSION = "2.5.10";
31380
+ BOOTSPRING_VERSION = "2.5.11";
31374
31381
  BOOTSPRING_PACKAGE_NAME = "@girardmedia/bootspring";
31375
31382
  }
31376
31383
  });
@@ -48932,6 +48939,7 @@ var require_dist2 = __commonJS({
48932
48939
  presence: () => presence_exports,
48933
48940
  readNearestProjectConfig: () => readNearestProjectConfig,
48934
48941
  refreshSession: () => refreshSession,
48942
+ registerMcpForAssistant: () => registerMcpForAssistant,
48935
48943
  remoteLogout: () => remoteLogout,
48936
48944
  request: () => request,
48937
48945
  resolvePolicyProfile: () => resolvePolicyProfile,
@@ -49151,6 +49159,7 @@ var require_dist2 = __commonJS({
49151
49159
  if (reauthOk) {
49152
49160
  return rawRequest(method, path10, data, { ...options, _authRetried: true, noCache: true });
49153
49161
  }
49162
+ err.authHandled = true;
49154
49163
  }
49155
49164
  throw err;
49156
49165
  }
@@ -49380,6 +49389,7 @@ var require_dist2 = __commonJS({
49380
49389
  var self_heal_exports = {};
49381
49390
  __export2(self_heal_exports, {
49382
49391
  classifyError: () => classifyError,
49392
+ registerMcpForAssistant: () => registerMcpForAssistant,
49383
49393
  runDiagnostics: () => runDiagnostics,
49384
49394
  tryHeal: () => tryHeal
49385
49395
  });
@@ -49627,6 +49637,30 @@ var require_dist2 = __commonJS({
49627
49637
  } else {
49628
49638
  results.push({ id: "deps", status: "ok", message: "Dependencies installed." });
49629
49639
  }
49640
+ const lockPath = import_path3.default.join(cwd, "package-lock.json");
49641
+ const pnpmLock = import_path3.default.join(cwd, "pnpm-lock.yaml");
49642
+ const nmPath = import_path3.default.join(cwd, "node_modules");
49643
+ const lockFile = import_fs3.default.existsSync(pnpmLock) ? pnpmLock : import_fs3.default.existsSync(lockPath) ? lockPath : null;
49644
+ if (lockFile && import_fs3.default.existsSync(nmPath)) {
49645
+ try {
49646
+ const lockMtime = import_fs3.default.statSync(lockFile).mtimeMs;
49647
+ const nmMtime = import_fs3.default.statSync(nmPath).mtimeMs;
49648
+ if (lockMtime > nmMtime) {
49649
+ const installCmd = lockFile.endsWith(".yaml") ? "pnpm install" : "npm install";
49650
+ if (autoFix) {
49651
+ try {
49652
+ (0, import_child_process.execSync)(installCmd, { cwd, timeout: 12e4, stdio: "pipe" });
49653
+ results.push({ id: "deps-stale", status: "healed", message: `Lockfile newer than node_modules \u2014 ran ${installCmd}.` });
49654
+ } catch {
49655
+ results.push({ id: "deps-stale", status: "action-needed", message: "Lockfile newer than node_modules.", fix: installCmd });
49656
+ }
49657
+ } else {
49658
+ results.push({ id: "deps-stale", status: "action-needed", message: "Lockfile newer than node_modules \u2014 dependencies may be stale.", fix: `${installCmd}` });
49659
+ }
49660
+ }
49661
+ } catch {
49662
+ }
49663
+ }
49630
49664
  const mcpTargets = {
49631
49665
  claude: import_path3.default.join(homeDir, ".claude.json"),
49632
49666
  codex: import_path3.default.join(homeDir, ".codex", "config.toml"),
@@ -49677,7 +49711,9 @@ var require_dist2 = __commonJS({
49677
49711
  if (autoFix) {
49678
49712
  const backup = buildStatePath + ".bak";
49679
49713
  import_fs3.default.copyFileSync(buildStatePath, backup);
49680
- results.push({ id: "build-state", status: "action-needed", message: "BUILD_STATE.json has invalid structure.", fix: "bootspring build start" });
49714
+ state.implementationQueue = state.implementationQueue || [];
49715
+ import_fs3.default.writeFileSync(buildStatePath, JSON.stringify(state, null, 2));
49716
+ results.push({ id: "build-state", status: "healed", message: `BUILD_STATE.json repaired (backed up to ${import_path3.default.basename(backup)}).` });
49681
49717
  } else {
49682
49718
  results.push({ id: "build-state", status: "action-needed", message: "BUILD_STATE.json has invalid structure.", fix: "bootspring doctor --fix" });
49683
49719
  }
@@ -49773,6 +49809,29 @@ ${block}` : block;
49773
49809
  return false;
49774
49810
  }
49775
49811
  }
49812
+ var MCP_PATHS = {
49813
+ claude: () => import_path3.default.join(import_os2.default.homedir(), ".claude.json"),
49814
+ cursor: () => import_path3.default.join(import_os2.default.homedir(), ".cursor", "mcp.json"),
49815
+ codex: () => import_path3.default.join(import_os2.default.homedir(), ".codex", "config.toml"),
49816
+ gemini: () => import_path3.default.join(import_os2.default.homedir(), ".gemini", "settings.json")
49817
+ };
49818
+ function registerMcpForAssistant(target) {
49819
+ const configPath = MCP_PATHS[target]();
49820
+ let success = false;
49821
+ switch (target) {
49822
+ case "claude":
49823
+ case "cursor":
49824
+ success = writeClaudeMcp(configPath);
49825
+ break;
49826
+ case "codex":
49827
+ success = writeCodexMcp(configPath);
49828
+ break;
49829
+ case "gemini":
49830
+ success = writeGeminiMcp(configPath);
49831
+ break;
49832
+ }
49833
+ return { success, path: configPath };
49834
+ }
49776
49835
  var presence_exports = {};
49777
49836
  __export2(presence_exports, {
49778
49837
  maybeAutoUploadTelemetry: () => maybeAutoUploadTelemetry,
@@ -52219,7 +52278,7 @@ var require_package = __commonJS({
52219
52278
  "../../../package.json"(exports2, module2) {
52220
52279
  module2.exports = {
52221
52280
  name: "bootspring-workspace",
52222
- version: "2.5.10",
52281
+ version: "2.5.11",
52223
52282
  private: true,
52224
52283
  description: "Workspace tooling for the Bootspring monorepo",
52225
52284
  keywords: [
@@ -52249,7 +52308,9 @@ var require_package = __commonJS({
52249
52308
  mcp: "node monorepo/apps/cli/dist/mcp-server.js",
52250
52309
  "version:sync": "node scripts/sync-version-metadata.js",
52251
52310
  "verify:version-sync": "node scripts/sync-version-metadata.js --check",
52252
- "release:prepare": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates",
52311
+ "release:prepare": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates && npm run smoke:publish",
52312
+ "release:dry-run": "npm run version:sync && npm run build && npm test && npm run lint --if-present && npm run verify:package && npm run verify:thin-client-contract && npm run verify:mcp-contract && npm run verify:monorepo-assets && npm run verify:release-gates && npm run smoke:publish && echo '\\n--- DRY RUN COMPLETE (no publish) ---'",
52313
+ "smoke:publish": "node scripts/smoke-publish.js",
52253
52314
  pretest: "npm run build",
52254
52315
  test: "vitest run",
52255
52316
  "test:launch-smoke": "vitest run __tests__/unit/cli-first-run-smoke.test.js __tests__/unit/health-fresh-start.test.ts __tests__/unit/session-project-scope.test.ts __tests__/unit/auth-cli-mixed-states.test.ts __tests__/unit/api-client-project-auth-fallback.test.js __tests__/unit/cli-help-surface.test.js __tests__/unit/cli-command-manifest.test.js",
@@ -52276,7 +52337,10 @@ var require_package = __commonJS({
52276
52337
  "server:bundle:configure-shared-billing-gh": "bash monorepo/apps/server/compat-runtime/scripts/configure-shared-billing-smoke-gh.sh",
52277
52338
  "build:cli": "npm --prefix monorepo/apps/cli run build",
52278
52339
  "build:watch": "npm --prefix monorepo/apps/cli run dev",
52279
- dev: "npm --prefix monorepo/apps/cli run dev",
52340
+ dev: "cd monorepo && pnpm turbo dev --filter=@girardmedia/bootspring --filter=@bootspring/server --concurrency=10",
52341
+ "dev:cli": "npm --prefix monorepo/apps/cli run dev",
52342
+ "dev:server": "npm --prefix monorepo/apps/server run dev",
52343
+ "dev:test": "vitest",
52280
52344
  "verify:lint-budget": "node scripts/check-lint-budgets.js",
52281
52345
  "verify:release-gates": "node scripts/release-gate-check.js",
52282
52346
  "verify:shared-contracts": "node scripts/verify-shared-contracts.js",
@@ -52680,8 +52744,58 @@ async function executeLocalBuild(args) {
52680
52744
  hint: "Create planning/TODO.md with tasks, then use action=sync to load them"
52681
52745
  }, null, 2) }] };
52682
52746
  }
52747
+ case "scan": {
52748
+ if (!state) {
52749
+ return { content: [{ type: "text", text: JSON.stringify({ error: "No build state found", hint: "Use action=init or action=sync first" }, null, 2) }] };
52750
+ }
52751
+ const { execSync } = require("child_process");
52752
+ const projectRoot = getProjectRoot();
52753
+ let gitLog;
52754
+ try {
52755
+ const since = state.loopSession?.startedAt;
52756
+ const sinceArg = since ? ` --since="${since}"` : " -100";
52757
+ gitLog = execSync(`git log --oneline${sinceArg}`, { cwd: projectRoot, encoding: "utf-8", timeout: 1e4 }).trim();
52758
+ } catch {
52759
+ return { content: [{ type: "text", text: JSON.stringify({ error: "Failed to read git log \u2014 not a git repo or git not available" }, null, 2) }] };
52760
+ }
52761
+ if (!gitLog) {
52762
+ return { content: [{ type: "text", text: JSON.stringify({ scanned: 0, marked: 0, message: "No commits found to scan" }, null, 2) }] };
52763
+ }
52764
+ const lines = gitLog.split("\n").filter(Boolean);
52765
+ const bsIdPattern = /\bbs-(\d+)\b/gi;
52766
+ const foundIds = /* @__PURE__ */ new Set();
52767
+ for (const line of lines) {
52768
+ for (const match of line.matchAll(bsIdPattern)) {
52769
+ foundIds.add(`bs-${match[1]}`);
52770
+ }
52771
+ }
52772
+ const queue = state.implementationQueue || [];
52773
+ const marked = [];
52774
+ for (const id of foundIds) {
52775
+ const task = queue.find((t) => t.id === id && (t.status === "pending" || t.status === "in_progress"));
52776
+ if (task) {
52777
+ task.status = "completed";
52778
+ task.completedAt = (/* @__PURE__ */ new Date()).toISOString();
52779
+ task.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
52780
+ task.completedBy = "commit-back-scan";
52781
+ marked.push(id);
52782
+ }
52783
+ }
52784
+ if (marked.length > 0) {
52785
+ saveBuildState(state);
52786
+ }
52787
+ const stats = buildGetStats(state);
52788
+ return { content: [{ type: "text", text: JSON.stringify({
52789
+ scanned: lines.length,
52790
+ bsIdsFound: foundIds.size,
52791
+ marked: marked.length,
52792
+ markedIds: marked,
52793
+ progress: stats,
52794
+ message: marked.length > 0 ? `Marked ${marked.length} task${marked.length === 1 ? "" : "s"} as completed from git history` : `Scanned ${lines.length} commits, found ${foundIds.size} bs-IDs, but none matched pending/in-progress tasks`
52795
+ }, null, 2) }] };
52796
+ }
52683
52797
  default:
52684
- return { content: [{ type: "text", text: JSON.stringify({ error: `Unknown action: ${action}`, validActions: ["next", "current", "done", "skip", "status", "list", "init", "sync", "advance"] }, null, 2) }] };
52798
+ return { content: [{ type: "text", text: JSON.stringify({ error: `Unknown action: ${action}`, validActions: ["next", "current", "done", "skip", "status", "list", "init", "sync", "advance", "scan"] }, null, 2) }] };
52685
52799
  }
52686
52800
  }
52687
52801
  async function executeLocalSeed(args) {
@@ -52943,7 +53057,7 @@ var FALLBACK_TOOLS = [
52943
53057
  inputSchema: {
52944
53058
  type: "object",
52945
53059
  properties: {
52946
- action: { type: "string", enum: ["next", "current", "done", "skip", "status", "list", "init", "sync", "advance"] },
53060
+ action: { type: "string", enum: ["next", "current", "done", "skip", "status", "list", "init", "sync", "advance", "scan"] },
52947
53061
  reason: { type: "string" },
52948
53062
  autoDone: { type: "boolean" }
52949
53063
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@girardmedia/bootspring",
3
- "version": "2.5.10",
3
+ "version": "2.5.11",
4
4
  "description": "Thin client for Bootspring cloud MCP, hosted agents, and paywalled workflow intelligence",
5
5
  "keywords": [
6
6
  "ai",