@girardmedia/bootspring 2.6.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -31,6 +31,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
31
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
32
32
  mod
33
33
  ));
34
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
35
 
35
36
  // ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
36
37
  var init_cjs_shims = __esm({
@@ -3385,7 +3386,7 @@ var init_release = __esm({
3385
3386
  "../../packages/shared/src/release.ts"() {
3386
3387
  "use strict";
3387
3388
  init_cjs_shims();
3388
- BOOTSPRING_VERSION = "2.6.0";
3389
+ BOOTSPRING_VERSION = "3.0.0";
3389
3390
  BOOTSPRING_PACKAGE_NAME = "@girardmedia/bootspring";
3390
3391
  }
3391
3392
  });
@@ -38412,7 +38413,7 @@ var require_main = __commonJS({
38412
38413
  }
38413
38414
  return to;
38414
38415
  };
38415
- var __toCommonJS = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
38416
+ var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
38416
38417
  var node_exports = {};
38417
38418
  __export2(node_exports, {
38418
38419
  analyzeMetafile: () => analyzeMetafile,
@@ -38429,7 +38430,7 @@ var require_main = __commonJS({
38429
38430
  transformSync: () => transformSync,
38430
38431
  version: () => version3
38431
38432
  });
38432
- module2.exports = __toCommonJS(node_exports);
38433
+ module2.exports = __toCommonJS2(node_exports);
38433
38434
  function encodePacket(packet) {
38434
38435
  let visit = (value) => {
38435
38436
  if (value === null) {
@@ -39210,7 +39211,7 @@ is not a problem with esbuild. You need to fix your environment instead.
39210
39211
  function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY2, defaultWD2, callback) {
39211
39212
  const details = createObjectStash();
39212
39213
  const isContext = callName === "context";
39213
- const handleError = (e, pluginName) => {
39214
+ const handleError2 = (e, pluginName) => {
39214
39215
  const flags = [];
39215
39216
  try {
39216
39217
  pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault);
@@ -39226,12 +39227,12 @@ is not a problem with esbuild. You need to fix your environment instead.
39226
39227
  if (typeof options === "object") {
39227
39228
  const value = options.plugins;
39228
39229
  if (value !== void 0) {
39229
- if (!Array.isArray(value)) return handleError(new Error(`"plugins" must be an array`), "");
39230
+ if (!Array.isArray(value)) return handleError2(new Error(`"plugins" must be an array`), "");
39230
39231
  plugins = value;
39231
39232
  }
39232
39233
  }
39233
39234
  if (plugins && plugins.length > 0) {
39234
- if (streamIn.isSync) return handleError(new Error("Cannot use plugins in synchronous API calls"), "");
39235
+ if (streamIn.isSync) return handleError2(new Error("Cannot use plugins in synchronous API calls"), "");
39235
39236
  handlePlugins(
39236
39237
  buildKey,
39237
39238
  sendRequest,
@@ -39244,14 +39245,14 @@ is not a problem with esbuild. You need to fix your environment instead.
39244
39245
  details
39245
39246
  ).then(
39246
39247
  (result) => {
39247
- if (!result.ok) return handleError(result.error, result.pluginName);
39248
+ if (!result.ok) return handleError2(result.error, result.pluginName);
39248
39249
  try {
39249
39250
  buildOrContextContinue(result.requestPlugins, result.runOnEndCallbacks, result.scheduleOnDisposeCallbacks);
39250
39251
  } catch (e) {
39251
- handleError(e, "");
39252
+ handleError2(e, "");
39252
39253
  }
39253
39254
  },
39254
- (e) => handleError(e, "")
39255
+ (e) => handleError2(e, "")
39255
39256
  );
39256
39257
  return;
39257
39258
  }
@@ -39259,7 +39260,7 @@ is not a problem with esbuild. You need to fix your environment instead.
39259
39260
  buildOrContextContinue(null, (result, done) => done([], []), () => {
39260
39261
  });
39261
39262
  } catch (e) {
39262
- handleError(e, "");
39263
+ handleError2(e, "");
39263
39264
  }
39264
39265
  function buildOrContextContinue(requestPlugins, runOnEndCallbacks, scheduleOnDisposeCallbacks) {
39265
39266
  const writeDefault = streamIn.hasFS;
@@ -45805,12 +45806,414 @@ var init_autopilot_tools = __esm({
45805
45806
  }
45806
45807
  });
45807
45808
 
45809
+ // ../../packages/mcp/src/brain-tools.ts
45810
+ function getRouter() {
45811
+ if (!routerInstance) {
45812
+ try {
45813
+ const { brain } = require("@bootspring/session-intelligence");
45814
+ routerInstance = new brain.UnifiedBrainRouter();
45815
+ } catch {
45816
+ throw new Error("Brain router requires @bootspring/session-intelligence");
45817
+ }
45818
+ }
45819
+ return routerInstance;
45820
+ }
45821
+ function registerBrainTools() {
45822
+ registerTool(brainDefinition, brainHandler);
45823
+ }
45824
+ var routerInstance, brainDefinition, brainHandler, BRAIN_TOOLS;
45825
+ var init_brain_tools = __esm({
45826
+ "../../packages/mcp/src/brain-tools.ts"() {
45827
+ "use strict";
45828
+ init_cjs_shims();
45829
+ init_registry();
45830
+ routerInstance = null;
45831
+ brainDefinition = {
45832
+ name: "bootspring_brain",
45833
+ description: "Intelligent natural language router \u2014 analyzes input and dispatches to the right Bootspring skill, workflow, agent, or pipeline. Use this to find the best action for any request.",
45834
+ inputSchema: {
45835
+ type: "object",
45836
+ properties: {
45837
+ prompt: {
45838
+ type: "string",
45839
+ description: "Natural language input to route"
45840
+ },
45841
+ autoDispatch: {
45842
+ type: "boolean",
45843
+ description: "If true and confidence > 0.85, include a dispatch instruction"
45844
+ }
45845
+ },
45846
+ required: ["prompt"]
45847
+ }
45848
+ };
45849
+ brainHandler = async (args) => {
45850
+ const prompt2 = String(args.prompt || "");
45851
+ const autoDispatch = Boolean(args.autoDispatch);
45852
+ if (!prompt2.trim()) {
45853
+ return {
45854
+ content: [{ type: "text", text: "Error: prompt is required" }],
45855
+ isError: true
45856
+ };
45857
+ }
45858
+ const router = getRouter();
45859
+ const result = router.route(prompt2);
45860
+ const lines = [];
45861
+ lines.push(`Brain Router Result`);
45862
+ lines.push(`${"=".repeat(50)}`);
45863
+ lines.push(`Target: ${result.target.name}`);
45864
+ lines.push(`Type: ${result.target.type}`);
45865
+ lines.push(`Confidence: ${result.confidence}`);
45866
+ lines.push(`Method: ${result.method}`);
45867
+ if (result.target.command) {
45868
+ lines.push(`Command: ${result.target.command}`);
45869
+ }
45870
+ lines.push(`
45871
+ Description: ${result.target.description}`);
45872
+ lines.push(`
45873
+ Explanation: ${result.explanation}`);
45874
+ if (result.alternatives.length > 0) {
45875
+ lines.push(`
45876
+ Alternatives:`);
45877
+ for (const alt of result.alternatives) {
45878
+ const cmd = alt.target.command ? ` (${alt.target.command})` : "";
45879
+ lines.push(` - ${alt.target.name} [${alt.target.type}] confidence=${alt.confidence}${cmd}`);
45880
+ }
45881
+ }
45882
+ if (autoDispatch && result.confidence >= 0.85 && result.target.command) {
45883
+ lines.push(`
45884
+ ${"=".repeat(50)}`);
45885
+ lines.push(`AUTO-DISPATCH: Confidence ${result.confidence} >= 0.85`);
45886
+ lines.push(`Execute: ${result.target.command}`);
45887
+ lines.push(
45888
+ `Use the MCP tool or CLI command above to fulfill the user's request.`
45889
+ );
45890
+ }
45891
+ return {
45892
+ content: [{ type: "text", text: lines.join("\n") }]
45893
+ };
45894
+ };
45895
+ BRAIN_TOOLS = [brainDefinition];
45896
+ }
45897
+ });
45898
+
45899
+ // ../../packages/mcp/src/swarm-tools.ts
45900
+ function errorResult(message) {
45901
+ return {
45902
+ content: [{ type: "text", text: `Error: ${message}` }],
45903
+ isError: true
45904
+ };
45905
+ }
45906
+ function registerSwarmTools() {
45907
+ registerTool(swarmDefinition, swarmHandler);
45908
+ registerTool(memoryDefinition, memoryHandler);
45909
+ registerTool(planDefinition, planHandler);
45910
+ }
45911
+ var swarmDefinition, swarmHandler, memoryDefinition, memoryHandler, planDefinition, planHandler, SWARM_TOOLS;
45912
+ var init_swarm_tools = __esm({
45913
+ "../../packages/mcp/src/swarm-tools.ts"() {
45914
+ "use strict";
45915
+ init_cjs_shims();
45916
+ init_registry();
45917
+ swarmDefinition = {
45918
+ name: "bootspring_swarm",
45919
+ description: "Multi-agent swarm orchestration \u2014 start swarms, spawn agents, submit tasks, run consensus votes, and change topologies (hierarchical, mesh, ring, star, adaptive). Agents collaborate through shared state and self-organize based on workload.",
45920
+ inputSchema: {
45921
+ type: "object",
45922
+ properties: {
45923
+ action: {
45924
+ type: "string",
45925
+ enum: ["start", "stop", "status", "spawn", "agents", "submit", "batch", "consensus", "topology"],
45926
+ description: "Swarm action to perform"
45927
+ },
45928
+ topology: {
45929
+ type: "string",
45930
+ enum: ["hierarchical", "mesh", "ring", "star", "adaptive"],
45931
+ description: "Swarm topology (for start/topology actions)"
45932
+ },
45933
+ role: {
45934
+ type: "string",
45935
+ enum: ["queen", "worker", "specialist", "reviewer", "monitor"],
45936
+ description: "Agent role (for spawn action)"
45937
+ },
45938
+ capabilities: {
45939
+ type: "array",
45940
+ items: { type: "string" },
45941
+ description: "Agent capabilities (for spawn action)"
45942
+ },
45943
+ taskType: {
45944
+ type: "string",
45945
+ description: "Task type (for submit action)"
45946
+ },
45947
+ taskDescription: {
45948
+ type: "string",
45949
+ description: "Task description (for submit action)"
45950
+ },
45951
+ priority: {
45952
+ type: "string",
45953
+ enum: ["critical", "high", "normal", "low"],
45954
+ description: "Task priority (for submit action)"
45955
+ },
45956
+ question: {
45957
+ type: "string",
45958
+ description: "Question for consensus vote"
45959
+ },
45960
+ options: {
45961
+ type: "array",
45962
+ items: { type: "string" },
45963
+ description: "Vote options for consensus"
45964
+ }
45965
+ },
45966
+ required: ["action"]
45967
+ }
45968
+ };
45969
+ swarmHandler = async (args) => {
45970
+ const action = String(args.action || "");
45971
+ try {
45972
+ const { api } = (init_src2(), __toCommonJS(src_exports2));
45973
+ let result;
45974
+ switch (action) {
45975
+ case "start":
45976
+ result = await api.request("POST", "/swarm/start", {
45977
+ topology: args.topology || "hierarchical"
45978
+ });
45979
+ break;
45980
+ case "stop":
45981
+ result = await api.request("POST", "/swarm/stop");
45982
+ break;
45983
+ case "status":
45984
+ result = await api.request("GET", "/swarm/status");
45985
+ break;
45986
+ case "spawn":
45987
+ if (!args.role) return errorResult("role is required for spawn");
45988
+ result = await api.request("POST", "/swarm/agents", {
45989
+ role: args.role,
45990
+ capabilities: args.capabilities || ["general"]
45991
+ });
45992
+ break;
45993
+ case "agents":
45994
+ result = await api.request("GET", "/swarm/agents");
45995
+ break;
45996
+ case "submit":
45997
+ if (!args.taskType || !args.taskDescription) {
45998
+ return errorResult("taskType and taskDescription are required for submit");
45999
+ }
46000
+ result = await api.request("POST", "/swarm/tasks", {
46001
+ type: args.taskType,
46002
+ description: args.taskDescription,
46003
+ input: {},
46004
+ priority: args.priority || "normal"
46005
+ });
46006
+ break;
46007
+ case "consensus":
46008
+ if (!args.question || !args.options) {
46009
+ return errorResult("question and options are required for consensus");
46010
+ }
46011
+ result = await api.request("POST", "/swarm/consensus", {
46012
+ question: args.question,
46013
+ options: args.options
46014
+ });
46015
+ break;
46016
+ case "topology":
46017
+ if (args.topology) {
46018
+ result = await api.request("POST", "/swarm/topology", { topology: args.topology });
46019
+ } else {
46020
+ result = await api.request("GET", "/swarm/topology");
46021
+ }
46022
+ break;
46023
+ default:
46024
+ return errorResult(`Unknown action: ${action}`);
46025
+ }
46026
+ return {
46027
+ content: [{
46028
+ type: "text",
46029
+ text: `Swarm ${action} result:
46030
+ ${JSON.stringify(result, null, 2)}`
46031
+ }]
46032
+ };
46033
+ } catch (err) {
46034
+ return errorResult(err instanceof Error ? err.message : String(err));
46035
+ }
46036
+ };
46037
+ memoryDefinition = {
46038
+ name: "bootspring_memory",
46039
+ description: "Vector memory for AI agents \u2014 store decisions, patterns, and trajectories. Search by semantic similarity using HNSW index. Agents learn from past successes.",
46040
+ inputSchema: {
46041
+ type: "object",
46042
+ properties: {
46043
+ action: {
46044
+ type: "string",
46045
+ enum: ["search", "store", "trajectory", "stats", "forget"],
46046
+ description: "Memory action to perform"
46047
+ },
46048
+ query: {
46049
+ type: "string",
46050
+ description: "Search query (for search action)"
46051
+ },
46052
+ content: {
46053
+ type: "string",
46054
+ description: "Content to store (for store action)"
46055
+ },
46056
+ type: {
46057
+ type: "string",
46058
+ enum: ["decision", "pattern", "error", "solution", "context", "preference", "trajectory"],
46059
+ description: "Memory entry type"
46060
+ },
46061
+ goal: {
46062
+ type: "string",
46063
+ description: "Goal (for trajectory action)"
46064
+ },
46065
+ steps: {
46066
+ type: "array",
46067
+ items: { type: "string" },
46068
+ description: "Steps taken (for trajectory action)"
46069
+ },
46070
+ outcome: {
46071
+ type: "string",
46072
+ enum: ["success", "partial", "failure"],
46073
+ description: "Trajectory outcome"
46074
+ },
46075
+ id: {
46076
+ type: "string",
46077
+ description: "Entry ID (for forget action)"
46078
+ },
46079
+ limit: {
46080
+ type: "number",
46081
+ description: "Max results for search (default 10)"
46082
+ }
46083
+ },
46084
+ required: ["action"]
46085
+ }
46086
+ };
46087
+ memoryHandler = async (args) => {
46088
+ const action = String(args.action || "");
46089
+ try {
46090
+ const { api } = (init_src2(), __toCommonJS(src_exports2));
46091
+ let result;
46092
+ switch (action) {
46093
+ case "search":
46094
+ if (!args.query) return errorResult("query is required for search");
46095
+ result = await api.request("POST", "/swarm/memory/search", {
46096
+ query: args.query,
46097
+ limit: args.limit || 10,
46098
+ type: args.type
46099
+ });
46100
+ break;
46101
+ case "store":
46102
+ if (!args.content || !args.type) return errorResult("content and type are required for store");
46103
+ result = await api.request("POST", "/swarm/memory", {
46104
+ content: args.content,
46105
+ type: args.type,
46106
+ sessionId: `mcp-${Date.now()}`
46107
+ });
46108
+ break;
46109
+ case "trajectory":
46110
+ if (!args.goal || !args.steps || !args.outcome) {
46111
+ return errorResult("goal, steps, and outcome are required for trajectory");
46112
+ }
46113
+ result = await api.request("POST", "/swarm/memory/trajectory", {
46114
+ goal: args.goal,
46115
+ steps: args.steps,
46116
+ sessionId: `mcp-${Date.now()}`,
46117
+ outcome: args.outcome
46118
+ });
46119
+ break;
46120
+ case "stats":
46121
+ result = await api.request("GET", "/swarm/memory/stats");
46122
+ break;
46123
+ case "forget":
46124
+ if (!args.id) return errorResult("id is required for forget");
46125
+ result = await api.request("DELETE", `/swarm/memory/${args.id}`);
46126
+ break;
46127
+ default:
46128
+ return errorResult(`Unknown action: ${action}`);
46129
+ }
46130
+ return {
46131
+ content: [{
46132
+ type: "text",
46133
+ text: `Memory ${action} result:
46134
+ ${JSON.stringify(result, null, 2)}`
46135
+ }]
46136
+ };
46137
+ } catch (err) {
46138
+ return errorResult(err instanceof Error ? err.message : String(err));
46139
+ }
46140
+ };
46141
+ planDefinition = {
46142
+ name: "bootspring_plan",
46143
+ description: "Goal-oriented action planning (GOAP) \u2014 decompose high-level goals into executable task DAGs with A* search. Finds optimal sequences and parallelizable groups.",
46144
+ inputSchema: {
46145
+ type: "object",
46146
+ properties: {
46147
+ action: {
46148
+ type: "string",
46149
+ enum: ["plan", "actions", "register"],
46150
+ description: "Planner action"
46151
+ },
46152
+ goal: {
46153
+ type: "string",
46154
+ description: "Goal to plan for (for plan action)"
46155
+ },
46156
+ parallel: {
46157
+ type: "boolean",
46158
+ description: "Enable parallel task groups"
46159
+ },
46160
+ currentState: {
46161
+ type: "object",
46162
+ description: "Current world state (key-value pairs)"
46163
+ },
46164
+ goalConditions: {
46165
+ type: "array",
46166
+ description: "Goal conditions [{key, operator, value}]"
46167
+ }
46168
+ },
46169
+ required: ["action"]
46170
+ }
46171
+ };
46172
+ planHandler = async (args) => {
46173
+ const action = String(args.action || "");
46174
+ try {
46175
+ const { api } = (init_src2(), __toCommonJS(src_exports2));
46176
+ let result;
46177
+ switch (action) {
46178
+ case "plan":
46179
+ if (!args.goal) return errorResult("goal is required for plan");
46180
+ result = await api.request("POST", "/swarm/plan", {
46181
+ goal: args.goal,
46182
+ currentState: args.currentState || {},
46183
+ goalConditions: args.goalConditions || [{ key: "deployed", operator: "==", value: true }],
46184
+ parallel: args.parallel ?? true
46185
+ });
46186
+ break;
46187
+ case "actions":
46188
+ result = await api.request("GET", "/swarm/plan/actions");
46189
+ break;
46190
+ case "register":
46191
+ return errorResult("Register custom actions via the API: POST /swarm/plan/actions");
46192
+ default:
46193
+ return errorResult(`Unknown action: ${action}`);
46194
+ }
46195
+ return {
46196
+ content: [{
46197
+ type: "text",
46198
+ text: `Plan ${action} result:
46199
+ ${JSON.stringify(result, null, 2)}`
46200
+ }]
46201
+ };
46202
+ } catch (err) {
46203
+ return errorResult(err instanceof Error ? err.message : String(err));
46204
+ }
46205
+ };
46206
+ SWARM_TOOLS = [swarmDefinition, memoryDefinition, planDefinition];
46207
+ }
46208
+ });
46209
+
45808
46210
  // ../../packages/mcp/src/index.ts
45809
46211
  var src_exports3 = {};
45810
46212
  __export(src_exports3, {
45811
46213
  ASSISTANT_PARITY_TOOLS: () => ASSISTANT_PARITY_TOOLS,
45812
46214
  AUDIT_TOOLS: () => AUDIT_TOOLS,
45813
46215
  AUTOPILOT_TOOLS: () => AUTOPILOT_TOOLS,
46216
+ BRAIN_TOOLS: () => BRAIN_TOOLS,
45814
46217
  COMPLIANCE_TOOLS: () => COMPLIANCE_TOOLS,
45815
46218
  DOCS_INTELLIGENCE_TOOLS: () => DOCS_INTELLIGENCE_TOOLS,
45816
46219
  MARKETPLACE_TOOLS: () => MARKETPLACE_TOOLS,
@@ -45821,6 +46224,7 @@ __export(src_exports3, {
45821
46224
  QUALITY_INTELLIGENCE_TOOLS: () => QUALITY_INTELLIGENCE_TOOLS,
45822
46225
  RBAC_TOOLS: () => RBAC_TOOLS,
45823
46226
  RELEASE_TOOLS: () => RELEASE_TOOLS,
46227
+ SWARM_TOOLS: () => SWARM_TOOLS,
45824
46228
  SYNC_TOOLS: () => SYNC_TOOLS,
45825
46229
  agentDetails: () => agentDetails,
45826
46230
  assistResponse: () => assistResponse,
@@ -45850,6 +46254,7 @@ __export(src_exports3, {
45850
46254
  registerAssistantParityTools: () => registerAssistantParityTools,
45851
46255
  registerAuditTools: () => registerAuditTools,
45852
46256
  registerAutopilotTools: () => registerAutopilotTools,
46257
+ registerBrainTools: () => registerBrainTools,
45853
46258
  registerComplianceTools: () => registerComplianceTools,
45854
46259
  registerDocsIntelligenceTools: () => registerDocsIntelligenceTools,
45855
46260
  registerMarketplaceTools: () => registerMarketplaceTools,
@@ -45861,6 +46266,7 @@ __export(src_exports3, {
45861
46266
  registerRbacTools: () => registerRbacTools,
45862
46267
  registerReleaseTools: () => registerReleaseTools,
45863
46268
  registerResource: () => registerResource,
46269
+ registerSwarmTools: () => registerSwarmTools,
45864
46270
  registerSyncTools: () => registerSyncTools,
45865
46271
  registerTool: () => registerTool,
45866
46272
  resolveCompatibilityRegistry: () => resolveCompatibilityRegistry,
@@ -45895,6 +46301,8 @@ var init_src3 = __esm({
45895
46301
  init_notification_tools();
45896
46302
  init_observer_tools();
45897
46303
  init_autopilot_tools();
46304
+ init_brain_tools();
46305
+ init_swarm_tools();
45898
46306
  }
45899
46307
  });
45900
46308
 
@@ -66263,7 +66671,7 @@ function drawProgressBar(progress, width = 20) {
66263
66671
  }
66264
66672
  function getWorkflowStates(projectRoot) {
66265
66673
  const workflows = {};
66266
- const names = ["onboard", "analyze", "audit", "seed", "context", "deploy", "loop", "preseed"];
66674
+ const names = ["onboard", "analyze", "audit", "seed", "context", "deploy", "loop"];
66267
66675
  for (const name of names) {
66268
66676
  const stateFile = path78.join(projectRoot, ".bootspring", name, "workflow-state.json");
66269
66677
  if (fs77.existsSync(stateFile)) {
@@ -72765,10 +73173,434 @@ function registerHarnessCommand(program3) {
72765
73173
  });
72766
73174
  }
72767
73175
 
72768
- // src/commands/geo.ts
73176
+ // src/commands/swarm.ts
72769
73177
  init_cjs_shims();
72770
73178
  init_src2();
72771
73179
  function requireAuth4() {
73180
+ if (auth_exports.isAuthenticated()) return true;
73181
+ print(`${COLORS.red}Not authenticated.${COLORS.reset} Run ${COLORS.bold}bootspring auth login${COLORS.reset} first.`);
73182
+ process.exitCode = 1;
73183
+ return false;
73184
+ }
73185
+ function handleError(error50) {
73186
+ if (error50 && typeof error50 === "object" && "response" in error50) {
73187
+ const resp = error50.response;
73188
+ if (resp?.status === 403) {
73189
+ print(`
73190
+ ${COLORS.yellow}Swarm Intelligence requires Pro tier or higher.${COLORS.reset}`);
73191
+ print(`Upgrade at: ${COLORS.cyan}https://bootspring.com/pricing${COLORS.reset}
73192
+ `);
73193
+ return;
73194
+ }
73195
+ print(`${COLORS.red}Error:${COLORS.reset} ${resp?.data?.error || resp?.data?.message || "Unknown API error"}`);
73196
+ return;
73197
+ }
73198
+ print(`${COLORS.red}Error:${COLORS.reset} ${error50 instanceof Error ? error50.message : String(error50)}`);
73199
+ }
73200
+ var TOPOLOGY_SYMBOLS = {
73201
+ hierarchical: "\u25B3",
73202
+ // △
73203
+ mesh: "\u25C6",
73204
+ // ◆
73205
+ ring: "\u25CB",
73206
+ // ○
73207
+ star: "\u2605",
73208
+ // ★
73209
+ adaptive: "\u21C4"
73210
+ // ⇄
73211
+ };
73212
+ var STATUS_COLORS = {
73213
+ idle: COLORS.green,
73214
+ busy: COLORS.cyan,
73215
+ waiting: COLORS.yellow,
73216
+ failed: COLORS.red,
73217
+ offline: COLORS.dim
73218
+ };
73219
+ function registerSwarmCommand(program3) {
73220
+ const cmd = program3.command("swarm").description("Multi-agent swarm orchestration \u2014 topology, consensus, planning");
73221
+ cmd.command("start").description("Start a new swarm").option("-t, --topology <type>", "Topology: hierarchical, mesh, ring, star, adaptive", "hierarchical").option("--max-agents <n>", "Maximum agents", "50").option("--json", "Output as JSON").action(async (opts) => {
73222
+ if (!requireAuth4()) return;
73223
+ try {
73224
+ const res = await api_client_exports.request("POST", "/swarm/start", {
73225
+ topology: opts.topology,
73226
+ maxAgents: parseInt(opts.maxAgents, 10)
73227
+ });
73228
+ if (opts.json) {
73229
+ print(JSON.stringify(res, null, 2));
73230
+ return;
73231
+ }
73232
+ const topo = opts.topology;
73233
+ const sym = TOPOLOGY_SYMBOLS[topo] || "";
73234
+ print(`
73235
+ ${COLORS.bold}${COLORS.cyan}${sym} Swarm Started${COLORS.reset}`);
73236
+ print(` Topology: ${COLORS.green}${topo}${COLORS.reset}`);
73237
+ print(` Max Agents: ${opts.maxAgents}`);
73238
+ print(` Phase: ${res.config?.phase || "running"}
73239
+ `);
73240
+ } catch (error50) {
73241
+ handleError(error50);
73242
+ }
73243
+ });
73244
+ cmd.command("stop").description("Stop the current swarm").option("--json", "Output as JSON").action(async (opts) => {
73245
+ if (!requireAuth4()) return;
73246
+ try {
73247
+ const res = await api_client_exports.request("POST", "/swarm/stop");
73248
+ if (opts.json) {
73249
+ print(JSON.stringify(res, null, 2));
73250
+ return;
73251
+ }
73252
+ print(`
73253
+ ${COLORS.bold}Swarm Stopped${COLORS.reset}`);
73254
+ if (res.metrics) {
73255
+ print(` Tasks Completed: ${COLORS.green}${res.metrics.completedTasks}${COLORS.reset}`);
73256
+ print(` Tasks Failed: ${COLORS.red}${res.metrics.failedTasks}${COLORS.reset}`);
73257
+ print(` Total Agents: ${res.metrics.totalAgents}`);
73258
+ }
73259
+ print("");
73260
+ } catch (error50) {
73261
+ handleError(error50);
73262
+ }
73263
+ });
73264
+ cmd.command("status").description("Show swarm metrics and topology").option("--json", "Output as JSON").action(async (opts) => {
73265
+ if (!requireAuth4()) return;
73266
+ try {
73267
+ const res = await api_client_exports.request("GET", "/swarm/status");
73268
+ if (opts.json) {
73269
+ print(JSON.stringify(res, null, 2));
73270
+ return;
73271
+ }
73272
+ const m = res.metrics;
73273
+ const sym = TOPOLOGY_SYMBOLS[m.topology] || "";
73274
+ print(`
73275
+ ${COLORS.bold}${COLORS.cyan}${sym} Swarm Status${COLORS.reset}`);
73276
+ print(`${"\u2500".repeat(50)}`);
73277
+ print(` Phase: ${m.phase}`);
73278
+ print(` Topology: ${COLORS.green}${m.topology}${COLORS.reset}`);
73279
+ print(` Uptime: ${Math.round(m.uptime / 1e3)}s`);
73280
+ print("");
73281
+ print(` ${COLORS.bold}Agents${COLORS.reset}`);
73282
+ print(` Total: ${m.totalAgents}`);
73283
+ print(` Active: ${COLORS.cyan}${m.activeAgents}${COLORS.reset}`);
73284
+ print(` Idle: ${COLORS.green}${m.idleAgents}${COLORS.reset}`);
73285
+ print(` Failed: ${COLORS.red}${m.failedAgents}${COLORS.reset}`);
73286
+ print("");
73287
+ print(` ${COLORS.bold}Tasks${COLORS.reset}`);
73288
+ print(` Total: ${m.totalTasks}`);
73289
+ print(` Running: ${COLORS.cyan}${m.runningTasks}${COLORS.reset}`);
73290
+ print(` Pending: ${COLORS.yellow}${m.pendingTasks}${COLORS.reset}`);
73291
+ print(` Completed: ${COLORS.green}${m.completedTasks}${COLORS.reset}`);
73292
+ print(` Failed: ${COLORS.red}${m.failedTasks}${COLORS.reset}`);
73293
+ print("");
73294
+ print(` Throughput: ${m.throughputTasksPerMin} tasks/min`);
73295
+ print(` Avg Time: ${m.avgTaskDurationMs}ms`);
73296
+ if (res.topology) {
73297
+ print(`
73298
+ ${COLORS.bold}Topology Graph${COLORS.reset}`);
73299
+ print(` Nodes: ${res.topology.nodes.length} Edges: ${res.topology.edges.length}`);
73300
+ }
73301
+ print("");
73302
+ } catch (error50) {
73303
+ handleError(error50);
73304
+ }
73305
+ });
73306
+ cmd.command("spawn <role>").description("Spawn a new agent (queen, worker, specialist, reviewer, monitor)").option("-c, --capabilities <caps>", "Comma-separated capabilities", "general").option("--json", "Output as JSON").action(async (role, opts) => {
73307
+ if (!requireAuth4()) return;
73308
+ const validRoles = ["queen", "worker", "specialist", "reviewer", "monitor"];
73309
+ if (!validRoles.includes(role)) {
73310
+ print(`${COLORS.red}Invalid role:${COLORS.reset} ${role}. Must be one of: ${validRoles.join(", ")}`);
73311
+ return;
73312
+ }
73313
+ try {
73314
+ const capabilities = opts.capabilities.split(",").map((c) => c.trim());
73315
+ const res = await api_client_exports.request("POST", "/swarm/agents", { role, capabilities });
73316
+ if (opts.json) {
73317
+ print(JSON.stringify(res, null, 2));
73318
+ return;
73319
+ }
73320
+ print(`
73321
+ ${COLORS.green}Agent spawned:${COLORS.reset} ${res.id}`);
73322
+ print(` Role: ${res.role}`);
73323
+ print(` Capabilities: ${res.capabilities.join(", ")}`);
73324
+ print(` Status: ${STATUS_COLORS[res.status] || ""}${res.status}${COLORS.reset}
73325
+ `);
73326
+ } catch (error50) {
73327
+ handleError(error50);
73328
+ }
73329
+ });
73330
+ cmd.command("agents").description("List swarm agents").option("--role <role>", "Filter by role").option("--json", "Output as JSON").action(async (opts) => {
73331
+ if (!requireAuth4()) return;
73332
+ try {
73333
+ const query = opts.role ? `?role=${opts.role}` : "";
73334
+ const res = await api_client_exports.request("GET", `/swarm/agents${query}`);
73335
+ if (opts.json) {
73336
+ print(JSON.stringify(res, null, 2));
73337
+ return;
73338
+ }
73339
+ print(`
73340
+ ${COLORS.bold}${COLORS.cyan}Swarm Agents${COLORS.reset} (${res.count})
73341
+ `);
73342
+ print(`${"ID".padEnd(24)} ${"Role".padEnd(12)} ${"Status".padEnd(10)} ${"Done".padEnd(6)} ${"Fail".padEnd(6)} Capabilities`);
73343
+ print(`${"\u2500".repeat(24)} ${"\u2500".repeat(12)} ${"\u2500".repeat(10)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(20)}`);
73344
+ for (const a of res.agents) {
73345
+ const color = STATUS_COLORS[a.status] || "";
73346
+ print(
73347
+ `${a.id.padEnd(24)} ${a.role.padEnd(12)} ${color}${a.status.padEnd(10)}${COLORS.reset} ${String(a.completedTasks).padEnd(6)} ${String(a.failedTasks).padEnd(6)} ${a.capabilities.join(", ")}`
73348
+ );
73349
+ }
73350
+ print("");
73351
+ } catch (error50) {
73352
+ handleError(error50);
73353
+ }
73354
+ });
73355
+ cmd.command("submit <type>").description("Submit a task to the swarm").argument("<description>", "Task description").option("-p, --priority <level>", "Priority: critical, high, normal, low", "normal").option("--json", "Output as JSON").action(async (type, description, opts) => {
73356
+ if (!requireAuth4()) return;
73357
+ try {
73358
+ const res = await api_client_exports.request("POST", "/swarm/tasks", {
73359
+ type,
73360
+ description,
73361
+ input: {},
73362
+ priority: opts.priority
73363
+ });
73364
+ if (opts.json) {
73365
+ print(JSON.stringify(res, null, 2));
73366
+ return;
73367
+ }
73368
+ print(`
73369
+ ${COLORS.green}Task submitted:${COLORS.reset} ${res.id}`);
73370
+ print(` Type: ${res.type}`);
73371
+ print(` Priority: ${res.priority}`);
73372
+ print(` Status: ${res.status}`);
73373
+ if (res.assignedAgentId) {
73374
+ print(` Assigned: ${res.assignedAgentId}`);
73375
+ }
73376
+ print("");
73377
+ } catch (error50) {
73378
+ handleError(error50);
73379
+ }
73380
+ });
73381
+ cmd.command("plan <goal>").description("Generate a GOAP execution plan from a goal").option("--parallel", "Enable parallel task groups").option("--json", "Output as JSON").action(async (goal, opts) => {
73382
+ if (!requireAuth4()) return;
73383
+ try {
73384
+ const res = await api_client_exports.request("POST", "/swarm/plan", {
73385
+ goal,
73386
+ currentState: {},
73387
+ goalConditions: [{ key: "deployed", operator: "==", value: true }],
73388
+ parallel: !!opts.parallel
73389
+ });
73390
+ if (opts.json) {
73391
+ print(JSON.stringify(res, null, 2));
73392
+ return;
73393
+ }
73394
+ const feasibleStr = res.feasible ? `${COLORS.green}FEASIBLE${COLORS.reset}` : `${COLORS.red}INFEASIBLE${COLORS.reset}`;
73395
+ print(`
73396
+ ${COLORS.bold}${COLORS.cyan}Goal Planner${COLORS.reset}
73397
+ `);
73398
+ print(` Goal: ${goal}`);
73399
+ print(` Feasible: ${feasibleStr}`);
73400
+ print(` Explanation: ${res.explanation}`);
73401
+ if (res.feasible && res.steps.length > 0) {
73402
+ print(` Total Cost: ${res.totalCost}`);
73403
+ print(` Est. Time: ${Math.round(res.estimatedDurationMs / 1e3)}s`);
73404
+ print(` Par. Groups: ${res.parallelGroups}`);
73405
+ print(`
73406
+ ${COLORS.bold}Execution Steps:${COLORS.reset}
73407
+ `);
73408
+ print(` ${"#".padEnd(4)} ${"Action".padEnd(24)} ${"Agent".padEnd(14)} ${"Group".padEnd(8)} Duration`);
73409
+ print(` ${"\u2500".repeat(4)} ${"\u2500".repeat(24)} ${"\u2500".repeat(14)} ${"\u2500".repeat(8)} ${"\u2500".repeat(10)}`);
73410
+ for (const step of res.steps) {
73411
+ const group = `G${step.parallelGroup}`;
73412
+ const dur = `${Math.round(step.action.estimatedDurationMs / 1e3)}s`;
73413
+ print(
73414
+ ` ${String(step.order + 1).padEnd(4)} ${step.action.name.padEnd(24)} ${step.action.agentCapability.padEnd(14)} ${group.padEnd(8)} ${dur}`
73415
+ );
73416
+ }
73417
+ if (res.steps.some((s) => s.dependencies.length > 0)) {
73418
+ print(`
73419
+ ${COLORS.bold}Dependencies:${COLORS.reset}`);
73420
+ for (const step of res.steps) {
73421
+ if (step.dependencies.length > 0) {
73422
+ print(` ${step.action.name} ${COLORS.dim}<- ${step.dependencies.join(", ")}${COLORS.reset}`);
73423
+ }
73424
+ }
73425
+ }
73426
+ }
73427
+ print("");
73428
+ } catch (error50) {
73429
+ handleError(error50);
73430
+ }
73431
+ });
73432
+ cmd.command("consensus <question>").description("Run a consensus vote across agents").requiredOption("-o, --options <opts>", "Comma-separated vote options").option("--json", "Output as JSON").action(async (question, opts) => {
73433
+ if (!requireAuth4()) return;
73434
+ try {
73435
+ const options = opts.options.split(",").map((o) => o.trim());
73436
+ const res = await api_client_exports.request("POST", "/swarm/consensus", { question, options });
73437
+ if (opts.json) {
73438
+ print(JSON.stringify(res, null, 2));
73439
+ return;
73440
+ }
73441
+ const quorum = res.quorumReached ? `${COLORS.green}QUORUM REACHED${COLORS.reset}` : `${COLORS.yellow}NO QUORUM${COLORS.reset}`;
73442
+ print(`
73443
+ ${COLORS.bold}${COLORS.cyan}Consensus Vote${COLORS.reset}
73444
+ `);
73445
+ print(` Question: ${question}`);
73446
+ print(` Decision: ${COLORS.bold}${res.decision}${COLORS.reset}`);
73447
+ print(` Agreement: ${Math.round(res.agreement * 100)}%`);
73448
+ print(` Status: ${quorum}`);
73449
+ print(` Votes: ${res.votes.length}
73450
+ `);
73451
+ } catch (error50) {
73452
+ handleError(error50);
73453
+ }
73454
+ });
73455
+ cmd.command("memory <action>").description("Vector memory: search, store, stats").argument("[query]", "Search query or content to store").option("--type <type>", "Memory type filter").option("--limit <n>", "Max results", "10").option("--json", "Output as JSON").action(async (action, query, opts) => {
73456
+ if (!requireAuth4()) return;
73457
+ try {
73458
+ if (action === "search" && query) {
73459
+ const res = await api_client_exports.request("POST", "/swarm/memory/search", {
73460
+ query,
73461
+ limit: parseInt(opts.limit, 10),
73462
+ type: opts.type
73463
+ });
73464
+ if (opts.json) {
73465
+ print(JSON.stringify(res, null, 2));
73466
+ return;
73467
+ }
73468
+ print(`
73469
+ ${COLORS.bold}${COLORS.cyan}Memory Search${COLORS.reset} (${res.results.length} results, ${res.searchTimeMs}ms, ${res.method})
73470
+ `);
73471
+ for (const r of res.results) {
73472
+ const truncated = r.entry.content.length > 80 ? r.entry.content.slice(0, 80) + "..." : r.entry.content;
73473
+ print(` ${COLORS.green}#${r.rank}${COLORS.reset} [${r.score.toFixed(3)}] ${COLORS.dim}(${r.entry.type})${COLORS.reset} ${truncated}`);
73474
+ }
73475
+ print("");
73476
+ } else if (action === "stats") {
73477
+ const res = await api_client_exports.request("GET", "/swarm/memory/stats");
73478
+ if (opts.json) {
73479
+ print(JSON.stringify(res, null, 2));
73480
+ return;
73481
+ }
73482
+ print(`
73483
+ ${COLORS.bold}${COLORS.cyan}Vector Memory Stats${COLORS.reset}
73484
+ `);
73485
+ print(` Entries: ${res.totalEntries}`);
73486
+ print(` Dimensions: ${res.dimensions}`);
73487
+ print(` Layers: ${res.layers}`);
73488
+ print(` Avg Import: ${res.avgImportance}`);
73489
+ print(` Memory: ${Math.round(res.memoryBytes / 1024)}KB`);
73490
+ if (res.byType && Object.keys(res.byType).length > 0) {
73491
+ print(`
73492
+ By Type:`);
73493
+ for (const [type, count] of Object.entries(res.byType)) {
73494
+ print(` ${type.padEnd(16)} ${count}`);
73495
+ }
73496
+ }
73497
+ print("");
73498
+ } else {
73499
+ print(`
73500
+ Usage: bootspring swarm memory <search|stats> [query]`);
73501
+ print(` ${COLORS.dim}bootspring swarm memory search "how to fix tests"${COLORS.reset}`);
73502
+ print(` ${COLORS.dim}bootspring swarm memory stats${COLORS.reset}
73503
+ `);
73504
+ }
73505
+ } catch (error50) {
73506
+ handleError(error50);
73507
+ }
73508
+ });
73509
+ cmd.command("topology").description("Show or change swarm topology").option("-s, --set <type>", "Change topology: hierarchical, mesh, ring, star, adaptive").option("--json", "Output as JSON").action(async (opts) => {
73510
+ if (!requireAuth4()) return;
73511
+ try {
73512
+ if (opts.set) {
73513
+ const res = await api_client_exports.request("POST", "/swarm/topology", { topology: opts.set });
73514
+ if (opts.json) {
73515
+ print(JSON.stringify(res, null, 2));
73516
+ return;
73517
+ }
73518
+ print(`
73519
+ ${COLORS.green}Topology changed to:${COLORS.reset} ${opts.set}
73520
+ `);
73521
+ } else {
73522
+ const res = await api_client_exports.request("GET", "/swarm/topology");
73523
+ if (opts.json) {
73524
+ print(JSON.stringify(res, null, 2));
73525
+ return;
73526
+ }
73527
+ print(`
73528
+ ${COLORS.bold}${COLORS.cyan}Topology Graph${COLORS.reset}
73529
+ `);
73530
+ print(` Nodes: ${res.nodes.length} Edges: ${res.edges.length}
73531
+ `);
73532
+ for (const node of res.nodes) {
73533
+ const color = STATUS_COLORS[node.status] || "";
73534
+ print(` ${color}\u25CF${COLORS.reset} ${node.id} (${node.role})`);
73535
+ }
73536
+ if (res.edges.length > 0) {
73537
+ print(`
73538
+ Edges:`);
73539
+ for (const edge of res.edges.slice(0, 20)) {
73540
+ const arrow = edge.type === "parent" ? "\u2192" : "\u2194";
73541
+ print(` ${edge.from} ${arrow} ${edge.to} ${COLORS.dim}(${edge.type})${COLORS.reset}`);
73542
+ }
73543
+ if (res.edges.length > 20) {
73544
+ print(` ${COLORS.dim}... and ${res.edges.length - 20} more edges${COLORS.reset}`);
73545
+ }
73546
+ }
73547
+ print("");
73548
+ }
73549
+ } catch (error50) {
73550
+ handleError(error50);
73551
+ }
73552
+ });
73553
+ cmd.command("visualize").description("Visualize swarm topology as ASCII art").option("--json", "Output as JSON").action(async (opts) => {
73554
+ if (!requireAuth4()) return;
73555
+ try {
73556
+ const res = await api_client_exports.request("GET", "/swarm/snapshot");
73557
+ if (opts.json) {
73558
+ print(JSON.stringify(res, null, 2));
73559
+ return;
73560
+ }
73561
+ const m = res.metrics;
73562
+ const sym = TOPOLOGY_SYMBOLS[m.topology] || "";
73563
+ print(`
73564
+ ${COLORS.bold}${COLORS.cyan}${sym} Swarm Visualization \u2014 ${m.topology}${COLORS.reset}
73565
+ `);
73566
+ const agents = res.agents || [];
73567
+ const queen = agents.find((a) => a.role === "queen");
73568
+ if (m.topology === "hierarchical" || m.topology === "star") {
73569
+ if (queen) {
73570
+ print(` ${COLORS.yellow}\u265B ${queen.id}${COLORS.reset} (queen)`);
73571
+ const children = agents.filter((a) => a.parentId === queen.id);
73572
+ for (let i = 0; i < children.length; i++) {
73573
+ const isLast = i === children.length - 1;
73574
+ const prefix = isLast ? " \u2514\u2500\u2500 " : " \u251C\u2500\u2500 ";
73575
+ const color = STATUS_COLORS[children[i].status] || "";
73576
+ print(`${prefix}${color}\u25CF ${children[i].id}${COLORS.reset} (${children[i].role})`);
73577
+ }
73578
+ }
73579
+ } else if (m.topology === "ring") {
73580
+ for (let i = 0; i < agents.length; i++) {
73581
+ const color = STATUS_COLORS[agents[i].status] || "";
73582
+ const arrow = i < agents.length - 1 ? " \u2192" : ` \u2192 ${agents[0]?.id || ""}`;
73583
+ print(` ${color}\u25CF ${agents[i].id}${COLORS.reset}${arrow}`);
73584
+ }
73585
+ } else {
73586
+ for (const a of agents) {
73587
+ const color = STATUS_COLORS[a.status] || "";
73588
+ print(` ${color}\u25CF${COLORS.reset} ${a.id} (${a.role}) [${a.capabilities.join(", ")}]`);
73589
+ }
73590
+ }
73591
+ print(`
73592
+ ${COLORS.dim}Agents: ${m.totalAgents} | Tasks: ${m.totalTasks} | Completed: ${m.completedTasks} | Phase: ${m.phase}${COLORS.reset}
73593
+ `);
73594
+ } catch (error50) {
73595
+ handleError(error50);
73596
+ }
73597
+ });
73598
+ }
73599
+
73600
+ // src/commands/geo.ts
73601
+ init_cjs_shims();
73602
+ init_src2();
73603
+ function requireAuth5() {
72772
73604
  if (auth_exports.isAuthenticated()) {
72773
73605
  return true;
72774
73606
  }
@@ -72836,7 +73668,7 @@ function printGeoResult(result) {
72836
73668
  function registerGeoCommand(program3) {
72837
73669
  const geo = program3.command("geo").description("GEO-SEO analysis \u2014 optimize for AI search engines");
72838
73670
  geo.command("audit <url>").description("Full GEO + SEO audit with parallel subagents").option("--format <format>", "Output format: markdown | json", "markdown").action(async (url2, opts) => {
72839
- if (!requireAuth4()) return;
73671
+ if (!requireAuth5()) return;
72840
73672
  const spinner = createSpinner("Running GEO audit...").start();
72841
73673
  try {
72842
73674
  const result = await api_client_exports.request("POST", "/geo/audit", { url: url2, options: opts });
@@ -72848,7 +73680,7 @@ function registerGeoCommand(program3) {
72848
73680
  }
72849
73681
  });
72850
73682
  geo.command("quick <url>").description("60-second GEO visibility snapshot").action(async (url2) => {
72851
- if (!requireAuth4()) return;
73683
+ if (!requireAuth5()) return;
72852
73684
  const spinner = createSpinner("Quick GEO scan...").start();
72853
73685
  try {
72854
73686
  const result = await api_client_exports.request("POST", "/geo/quick", { url: url2 });
@@ -72875,7 +73707,7 @@ function registerGeoCommand(program3) {
72875
73707
  ];
72876
73708
  for (const sub of subcommands) {
72877
73709
  geo.command(`${sub.name} ${sub.arg}`).description(sub.desc).action(async (urlOrDomain) => {
72878
- if (!requireAuth4()) return;
73710
+ if (!requireAuth5()) return;
72879
73711
  const spinner = createSpinner(`Running ${sub.name}...`).start();
72880
73712
  try {
72881
73713
  const body = sub.arg === "<domain>" ? { domain: urlOrDomain } : { url: urlOrDomain };
@@ -72889,7 +73721,7 @@ function registerGeoCommand(program3) {
72889
73721
  });
72890
73722
  }
72891
73723
  geo.command("prospect <action>").description("CRM: manage prospects (new, list, show, audit, note, status, pipeline)").argument("[args...]", "Action-specific arguments").action(async (action, args) => {
72892
- if (!requireAuth4()) return;
73724
+ if (!requireAuth5()) return;
72893
73725
  const spinner = createSpinner(`Prospect ${action}...`).start();
72894
73726
  try {
72895
73727
  const result = await api_client_exports.request("POST", "/geo/prospect", { action, data: args });
@@ -72901,7 +73733,7 @@ function registerGeoCommand(program3) {
72901
73733
  }
72902
73734
  });
72903
73735
  geo.command("schemas [name]").description("List JSON-LD schema templates or view a specific one").action(async (name) => {
72904
- if (!requireAuth4()) return;
73736
+ if (!requireAuth5()) return;
72905
73737
  const spinner = createSpinner(name ? `Fetching ${name} schema...` : "Listing schemas...").start();
72906
73738
  try {
72907
73739
  if (name) {
@@ -72937,7 +73769,7 @@ function registerGeoCommand(program3) {
72937
73769
  // src/commands/marketing.ts
72938
73770
  init_cjs_shims();
72939
73771
  init_src2();
72940
- function requireAuth5() {
73772
+ function requireAuth6() {
72941
73773
  if (auth_exports.isAuthenticated()) {
72942
73774
  return true;
72943
73775
  }
@@ -73083,7 +73915,7 @@ function registerMarketingCommand(program3) {
73083
73915
  }
73084
73916
  }
73085
73917
  sub.action(async (...actionArgs) => {
73086
- if (!requireAuth5()) return;
73918
+ if (!requireAuth6()) return;
73087
73919
  const body = {};
73088
73920
  for (let i = 0; i < cmd.args.length; i++) {
73089
73921
  body[cmd.args[i].name] = actionArgs[i];
@@ -73126,7 +73958,7 @@ function registerMarketingCommand(program3) {
73126
73958
  });
73127
73959
  }
73128
73960
  marketing.command("commands").description("List all available marketing commands").action(async () => {
73129
- if (!requireAuth5()) return;
73961
+ if (!requireAuth6()) return;
73130
73962
  const spinner = createSpinner("Fetching marketing commands...").start();
73131
73963
  try {
73132
73964
  const result = await api_client_exports.request("GET", "/marketing/commands");
@@ -73172,7 +74004,7 @@ function registerMarketingCommand(program3) {
73172
74004
  // src/commands/sales.ts
73173
74005
  init_cjs_shims();
73174
74006
  init_src2();
73175
- function requireAuth6() {
74007
+ function requireAuth7() {
73176
74008
  if (auth_exports.isAuthenticated()) {
73177
74009
  return true;
73178
74010
  }
@@ -73293,7 +74125,7 @@ function registerSalesCommand(program3) {
73293
74125
  }
73294
74126
  }
73295
74127
  sub.action(async (...actionArgs) => {
73296
- if (!requireAuth6()) return;
74128
+ if (!requireAuth7()) return;
73297
74129
  const body = {};
73298
74130
  for (let i = 0; i < cmd.args.length; i++) {
73299
74131
  body[cmd.args[i].name] = actionArgs[i];
@@ -73331,7 +74163,7 @@ function registerSalesCommand(program3) {
73331
74163
  });
73332
74164
  }
73333
74165
  sales.command("commands").description("List all available sales commands").action(async () => {
73334
- if (!requireAuth6()) return;
74166
+ if (!requireAuth7()) return;
73335
74167
  const spinner = createSpinner("Fetching sales commands...").start();
73336
74168
  try {
73337
74169
  const result = await api_client_exports.request("GET", "/sales/commands");
@@ -73376,7 +74208,7 @@ function registerSalesCommand(program3) {
73376
74208
  // src/commands/jobs.ts
73377
74209
  init_cjs_shims();
73378
74210
  init_src2();
73379
- function requireAuth7() {
74211
+ function requireAuth8() {
73380
74212
  if (auth_exports.isAuthenticated()) return true;
73381
74213
  print.error('Not logged in. Run "bootspring auth login" first.');
73382
74214
  process.exitCode = 1;
@@ -73385,7 +74217,7 @@ function requireAuth7() {
73385
74217
  function registerJobsCommand(program3) {
73386
74218
  const jobs = program3.command("jobs").description("List and poll async job results");
73387
74219
  jobs.command("list").alias("ls").description("List recent jobs").option("--type <type>", "Filter by type (geo, marketing, sales)").option("--limit <n>", "Number of jobs to show", "20").action(async (opts) => {
73388
- if (!requireAuth7()) return;
74220
+ if (!requireAuth8()) return;
73389
74221
  try {
73390
74222
  const params = new URLSearchParams();
73391
74223
  if (opts.type) params.set("type", opts.type);
@@ -73412,7 +74244,7 @@ ${COLORS.bold}Recent Jobs${COLORS.reset}
73412
74244
  }
73413
74245
  });
73414
74246
  jobs.command("status <jobId>").alias("get").description("Get job status and results").action(async (jobId) => {
73415
- if (!requireAuth7()) return;
74247
+ if (!requireAuth8()) return;
73416
74248
  try {
73417
74249
  const response = await api_client_exports.request("GET", `/jobs/${encodeURIComponent(jobId)}`);
73418
74250
  const job = response.job;
@@ -77615,6 +78447,164 @@ ${COLORS.bold}Shell Completion${COLORS.reset}
77615
78447
  });
77616
78448
  }
77617
78449
 
78450
+ // src/commands/brain.ts
78451
+ init_cjs_shims();
78452
+ var _router = null;
78453
+ function getRouter2() {
78454
+ if (!_router) {
78455
+ try {
78456
+ const { brain } = require("@bootspring/session-intelligence");
78457
+ _router = new brain.UnifiedBrainRouter();
78458
+ } catch {
78459
+ return null;
78460
+ }
78461
+ }
78462
+ return _router;
78463
+ }
78464
+ function registerBrainCommand(program3) {
78465
+ const brain = program3.command("brain").description("NLU brain \u2014 natural language routing to skills, workflows, agents, and pipelines");
78466
+ brain.command("route <prompt...>").description("Route a natural language query and show the result").option("--json", "Output as JSON").option("--auto-dispatch", "Include dispatch instruction if confidence > 0.85").action(async (promptParts, opts) => {
78467
+ const router = getRouter2();
78468
+ if (!router) {
78469
+ console.error("Brain router not available. Ensure @bootspring/session-intelligence is installed.");
78470
+ process.exitCode = 1;
78471
+ return;
78472
+ }
78473
+ const prompt2 = promptParts.join(" ");
78474
+ const result = router.route(prompt2);
78475
+ if (opts.json) {
78476
+ console.log(JSON.stringify(result, null, 2));
78477
+ return;
78478
+ }
78479
+ console.log(`
78480
+ \x1B[1mBrain Router Result\x1B[0m`);
78481
+ console.log(` ${"\u2500".repeat(46)}`);
78482
+ console.log(` Target: ${result.target.name}`);
78483
+ console.log(` Type: ${result.target.type}`);
78484
+ console.log(` Confidence: ${result.confidence}`);
78485
+ console.log(` Method: ${result.method}`);
78486
+ if (result.target.command) {
78487
+ console.log(` Command: \x1B[36m${result.target.command}\x1B[0m`);
78488
+ }
78489
+ console.log(` Description: ${result.target.description}`);
78490
+ console.log(` Explanation: ${result.explanation}`);
78491
+ if (result.alternatives.length > 0) {
78492
+ console.log(`
78493
+ Alternatives:`);
78494
+ for (const alt of result.alternatives) {
78495
+ const cmd = alt.target.command ? ` \u2192 ${alt.target.command}` : "";
78496
+ console.log(` - ${alt.target.name} [${alt.target.type}] (${alt.confidence})${cmd}`);
78497
+ }
78498
+ }
78499
+ if (opts.autoDispatch && result.confidence >= 0.85 && result.target.command) {
78500
+ console.log(`
78501
+ \x1B[32mAUTO-DISPATCH\x1B[0m: Run \x1B[36m${result.target.command}\x1B[0m`);
78502
+ }
78503
+ console.log();
78504
+ });
78505
+ brain.command("status", { isDefault: true }).description("Show brain status \u2014 loaded targets, corpus size, config").option("--json", "Output as JSON").action(async (opts) => {
78506
+ const router = getRouter2();
78507
+ if (!router) {
78508
+ console.error("Brain router not available.");
78509
+ process.exitCode = 1;
78510
+ return;
78511
+ }
78512
+ let corpusSize = 0;
78513
+ let targetTypes = {};
78514
+ try {
78515
+ const { brain: brainMod } = require("@bootspring/session-intelligence");
78516
+ const corpus = brainMod.BRAIN_CORPUS;
78517
+ corpusSize = corpus.length;
78518
+ for (const t of corpus) {
78519
+ targetTypes[t.type] = (targetTypes[t.type] || 0) + 1;
78520
+ }
78521
+ } catch {
78522
+ }
78523
+ const analytics = router.getAnalytics();
78524
+ const status = {
78525
+ active: true,
78526
+ corpusSize,
78527
+ targetTypes,
78528
+ totalInvocations: analytics.totalInvocations,
78529
+ accuracyRate: analytics.accuracyRate,
78530
+ methodBreakdown: analytics.methodBreakdown
78531
+ };
78532
+ if (opts.json) {
78533
+ console.log(JSON.stringify(status, null, 2));
78534
+ return;
78535
+ }
78536
+ console.log(`
78537
+ \x1B[1mBrain Status\x1B[0m`);
78538
+ console.log(` ${"\u2500".repeat(46)}`);
78539
+ console.log(` Active: \x1B[32myes\x1B[0m`);
78540
+ console.log(` Corpus size: ${corpusSize} targets`);
78541
+ if (Object.keys(targetTypes).length > 0) {
78542
+ console.log(` Target types:`);
78543
+ for (const [type, count] of Object.entries(targetTypes)) {
78544
+ console.log(` ${type}: ${count}`);
78545
+ }
78546
+ }
78547
+ console.log(` Invocations: ${analytics.totalInvocations}`);
78548
+ console.log(` Accuracy: ${(analytics.accuracyRate * 100).toFixed(1)}%`);
78549
+ if (Object.keys(analytics.methodBreakdown).length > 0) {
78550
+ console.log(` Methods:`);
78551
+ for (const [method, count] of Object.entries(analytics.methodBreakdown)) {
78552
+ console.log(` ${method}: ${count}`);
78553
+ }
78554
+ }
78555
+ console.log();
78556
+ });
78557
+ brain.command("analytics").description("Show routing analytics \u2014 invocations, accuracy, top targets").option("--json", "Output as JSON").action(async (opts) => {
78558
+ const router = getRouter2();
78559
+ if (!router) {
78560
+ console.error("Brain router not available.");
78561
+ process.exitCode = 1;
78562
+ return;
78563
+ }
78564
+ const analytics = router.getAnalytics();
78565
+ if (opts.json) {
78566
+ console.log(JSON.stringify(analytics, null, 2));
78567
+ return;
78568
+ }
78569
+ console.log(`
78570
+ \x1B[1mBrain Analytics\x1B[0m`);
78571
+ console.log(` ${"\u2500".repeat(46)}`);
78572
+ console.log(` Total invocations: ${analytics.totalInvocations}`);
78573
+ console.log(` Correct routes: ${analytics.correctRoutes}`);
78574
+ console.log(` User overrides: ${analytics.userOverrides}`);
78575
+ console.log(` Accuracy rate: ${(analytics.accuracyRate * 100).toFixed(1)}%`);
78576
+ if (Object.keys(analytics.methodBreakdown).length > 0) {
78577
+ console.log(`
78578
+ Method breakdown:`);
78579
+ for (const [method, count] of Object.entries(analytics.methodBreakdown)) {
78580
+ console.log(` ${method}: ${count}`);
78581
+ }
78582
+ }
78583
+ if (analytics.topTargets.length > 0) {
78584
+ console.log(`
78585
+ Top targets:`);
78586
+ for (const t of analytics.topTargets) {
78587
+ console.log(` ${t.name}: ${t.count} hits`);
78588
+ }
78589
+ }
78590
+ console.log();
78591
+ });
78592
+ brain.command("reset").description("Reset brain analytics").option("--json", "Output as JSON").action(async (opts) => {
78593
+ const router = getRouter2();
78594
+ if (!router) {
78595
+ console.error("Brain router not available.");
78596
+ process.exitCode = 1;
78597
+ return;
78598
+ }
78599
+ router.resetAnalytics();
78600
+ if (opts.json) {
78601
+ console.log(JSON.stringify({ reset: true }));
78602
+ return;
78603
+ }
78604
+ console.log("Brain analytics reset.");
78605
+ });
78606
+ }
78607
+
77618
78608
  // src/index.ts
77619
78609
  var program2 = new Command();
77620
78610
  program2.name("bootspring").description("Thin CLI for Bootspring cloud MCP, hosted agents, and AI-assisted workflows").version(BOOTSPRING_VERSION);
@@ -77680,6 +78670,7 @@ registerSetupCommand(program2);
77680
78670
  registerPipelineCommand(program2);
77681
78671
  registerWorkflowCommand(program2);
77682
78672
  registerHarnessCommand(program2);
78673
+ registerSwarmCommand(program2);
77683
78674
  registerGeoCommand(program2);
77684
78675
  registerMarketingCommand(program2);
77685
78676
  registerSalesCommand(program2);
@@ -77702,6 +78693,7 @@ registerExperimental(registerSpecCommand);
77702
78693
  registerSyncCommand(program2);
77703
78694
  registerHookCommand(program2);
77704
78695
  registerCompletionCommand(program2);
78696
+ registerBrainCommand(program2);
77705
78697
  var HERO_COMMANDS = /* @__PURE__ */ new Set([
77706
78698
  "auth",
77707
78699
  "build",
@@ -77721,7 +78713,7 @@ var COMMAND_GROUPS = {
77721
78713
  "Project": ["project", "workspace", "org", "switch", "checkpoint"],
77722
78714
  "Dev Tools": ["doctor", "health", "setup", "validate", "watch", "dashboard", "update", "hook", "completion"],
77723
78715
  "Analysis": ["analyze", "audit", "quality", "security", "diff", "report"],
77724
- "AI & Agents": ["agent", "skill", "context", "prompt", "flow"],
78716
+ "AI & Agents": ["agent", "skill", "brain", "context", "prompt", "flow"],
77725
78717
  "Observe": ["observe", "autopilot", "monitor", "session", "metrics", "telemetry"],
77726
78718
  "Docs": ["docs", "generate", "prd", "content", "plan", "suggest"],
77727
78719
  "Deploy & Ops": ["deploy", "sync", "cloud-sync", "github", "undo", "history", "changes", "log"],