@girardmedia/bootspring 2.7.0 → 3.1.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 +1009 -78
- package/dist/cli-launcher.js +2 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core.js +15 -9
- package/dist/mcp/index.d.ts +10 -1
- package/dist/mcp-server.js +327 -62
- package/package.json +1 -1
- package/scripts/postinstall.cjs +7 -1
package/dist/cli/index.js
CHANGED
|
@@ -31,10 +31,11 @@ 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
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.
|
|
36
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.14_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({
|
|
37
|
-
"../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.
|
|
38
|
+
"../../node_modules/.pnpm/tsup@8.5.1_jiti@1.21.7_postcss@8.5.14_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js"() {
|
|
38
39
|
"use strict";
|
|
39
40
|
}
|
|
40
41
|
});
|
|
@@ -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 = "
|
|
3389
|
+
BOOTSPRING_VERSION = "3.1.0";
|
|
3389
3390
|
BOOTSPRING_PACKAGE_NAME = "@girardmedia/bootspring";
|
|
3390
3391
|
}
|
|
3391
3392
|
});
|
|
@@ -32898,13 +32899,16 @@ var require_data = __commonJS({
|
|
|
32898
32899
|
}
|
|
32899
32900
|
});
|
|
32900
32901
|
|
|
32901
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
32902
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js
|
|
32902
32903
|
var require_utils = __commonJS({
|
|
32903
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
32904
|
+
"../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/utils.js"(exports2, module2) {
|
|
32904
32905
|
"use strict";
|
|
32905
32906
|
init_cjs_shims();
|
|
32906
32907
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
32907
32908
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
32909
|
+
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
32910
|
+
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
32911
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[\da-z\-._~!$&'()*+,;=:@/]$/iu);
|
|
32908
32912
|
function stringArrayToHexStripped(input) {
|
|
32909
32913
|
let acc = "";
|
|
32910
32914
|
let code = 0;
|
|
@@ -33097,27 +33101,77 @@ var require_utils = __commonJS({
|
|
|
33097
33101
|
}
|
|
33098
33102
|
return output.join("");
|
|
33099
33103
|
}
|
|
33100
|
-
|
|
33101
|
-
|
|
33102
|
-
|
|
33103
|
-
|
|
33104
|
-
|
|
33105
|
-
|
|
33106
|
-
|
|
33107
|
-
|
|
33108
|
-
|
|
33109
|
-
|
|
33104
|
+
var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
|
|
33105
|
+
var HOST_DELIM_RE = /[@/?#:]/g;
|
|
33106
|
+
var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
|
|
33107
|
+
function reescapeHostDelimiters(host, isIP) {
|
|
33108
|
+
const re = isIP ? HOST_DELIM_NO_COLON_RE : HOST_DELIM_RE;
|
|
33109
|
+
re.lastIndex = 0;
|
|
33110
|
+
return host.replace(re, (ch) => HOST_DELIMS[ch]);
|
|
33111
|
+
}
|
|
33112
|
+
function normalizePercentEncoding(input, decodeUnreserved = false) {
|
|
33113
|
+
if (input.indexOf("%") === -1) {
|
|
33114
|
+
return input;
|
|
33110
33115
|
}
|
|
33111
|
-
|
|
33112
|
-
|
|
33116
|
+
let output = "";
|
|
33117
|
+
for (let i = 0; i < input.length; i++) {
|
|
33118
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
33119
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
33120
|
+
if (isHexPair(hex3)) {
|
|
33121
|
+
const normalizedHex = hex3.toUpperCase();
|
|
33122
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
33123
|
+
if (decodeUnreserved && isUnreserved(decoded)) {
|
|
33124
|
+
output += decoded;
|
|
33125
|
+
} else {
|
|
33126
|
+
output += "%" + normalizedHex;
|
|
33127
|
+
}
|
|
33128
|
+
i += 2;
|
|
33129
|
+
continue;
|
|
33130
|
+
}
|
|
33131
|
+
}
|
|
33132
|
+
output += input[i];
|
|
33113
33133
|
}
|
|
33114
|
-
|
|
33115
|
-
|
|
33134
|
+
return output;
|
|
33135
|
+
}
|
|
33136
|
+
function normalizePathEncoding(input) {
|
|
33137
|
+
let output = "";
|
|
33138
|
+
for (let i = 0; i < input.length; i++) {
|
|
33139
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
33140
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
33141
|
+
if (isHexPair(hex3)) {
|
|
33142
|
+
const normalizedHex = hex3.toUpperCase();
|
|
33143
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
33144
|
+
if (decoded !== "." && isUnreserved(decoded)) {
|
|
33145
|
+
output += decoded;
|
|
33146
|
+
} else {
|
|
33147
|
+
output += "%" + normalizedHex;
|
|
33148
|
+
}
|
|
33149
|
+
i += 2;
|
|
33150
|
+
continue;
|
|
33151
|
+
}
|
|
33152
|
+
}
|
|
33153
|
+
if (isPathCharacter(input[i])) {
|
|
33154
|
+
output += input[i];
|
|
33155
|
+
} else {
|
|
33156
|
+
output += escape(input[i]);
|
|
33157
|
+
}
|
|
33116
33158
|
}
|
|
33117
|
-
|
|
33118
|
-
|
|
33159
|
+
return output;
|
|
33160
|
+
}
|
|
33161
|
+
function escapePreservingEscapes(input) {
|
|
33162
|
+
let output = "";
|
|
33163
|
+
for (let i = 0; i < input.length; i++) {
|
|
33164
|
+
if (input[i] === "%" && i + 2 < input.length) {
|
|
33165
|
+
const hex3 = input.slice(i + 1, i + 3);
|
|
33166
|
+
if (isHexPair(hex3)) {
|
|
33167
|
+
output += "%" + hex3.toUpperCase();
|
|
33168
|
+
i += 2;
|
|
33169
|
+
continue;
|
|
33170
|
+
}
|
|
33171
|
+
}
|
|
33172
|
+
output += escape(input[i]);
|
|
33119
33173
|
}
|
|
33120
|
-
return
|
|
33174
|
+
return output;
|
|
33121
33175
|
}
|
|
33122
33176
|
function recomposeAuthority(component) {
|
|
33123
33177
|
const uriTokens = [];
|
|
@@ -33132,7 +33186,7 @@ var require_utils = __commonJS({
|
|
|
33132
33186
|
if (ipV6res.isIPV6 === true) {
|
|
33133
33187
|
host = `[${ipV6res.escapedHost}]`;
|
|
33134
33188
|
} else {
|
|
33135
|
-
host =
|
|
33189
|
+
host = reescapeHostDelimiters(host, false);
|
|
33136
33190
|
}
|
|
33137
33191
|
}
|
|
33138
33192
|
uriTokens.push(host);
|
|
@@ -33146,7 +33200,10 @@ var require_utils = __commonJS({
|
|
|
33146
33200
|
module2.exports = {
|
|
33147
33201
|
nonSimpleDomain,
|
|
33148
33202
|
recomposeAuthority,
|
|
33149
|
-
|
|
33203
|
+
reescapeHostDelimiters,
|
|
33204
|
+
normalizePercentEncoding,
|
|
33205
|
+
normalizePathEncoding,
|
|
33206
|
+
escapePreservingEscapes,
|
|
33150
33207
|
removeDotSegments,
|
|
33151
33208
|
isIPv4,
|
|
33152
33209
|
isUUID,
|
|
@@ -33156,9 +33213,9 @@ var require_utils = __commonJS({
|
|
|
33156
33213
|
}
|
|
33157
33214
|
});
|
|
33158
33215
|
|
|
33159
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
33216
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js
|
|
33160
33217
|
var require_schemes = __commonJS({
|
|
33161
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
33218
|
+
"../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/lib/schemes.js"(exports2, module2) {
|
|
33162
33219
|
"use strict";
|
|
33163
33220
|
init_cjs_shims();
|
|
33164
33221
|
var { isUUID } = require_utils();
|
|
@@ -33367,17 +33424,17 @@ var require_schemes = __commonJS({
|
|
|
33367
33424
|
}
|
|
33368
33425
|
});
|
|
33369
33426
|
|
|
33370
|
-
// ../../node_modules/.pnpm/fast-uri@3.1.
|
|
33427
|
+
// ../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js
|
|
33371
33428
|
var require_fast_uri = __commonJS({
|
|
33372
|
-
"../../node_modules/.pnpm/fast-uri@3.1.
|
|
33429
|
+
"../../node_modules/.pnpm/fast-uri@3.1.2/node_modules/fast-uri/index.js"(exports2, module2) {
|
|
33373
33430
|
"use strict";
|
|
33374
33431
|
init_cjs_shims();
|
|
33375
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority,
|
|
33432
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, escapePreservingEscapes, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
|
|
33376
33433
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
33377
33434
|
function normalize2(uri, options) {
|
|
33378
33435
|
if (typeof uri === "string") {
|
|
33379
33436
|
uri = /** @type {T} */
|
|
33380
|
-
|
|
33437
|
+
normalizeString(uri, options);
|
|
33381
33438
|
} else if (typeof uri === "object") {
|
|
33382
33439
|
uri = /** @type {T} */
|
|
33383
33440
|
parse7(serialize(uri, options), options);
|
|
@@ -33444,19 +33501,9 @@ var require_fast_uri = __commonJS({
|
|
|
33444
33501
|
return target;
|
|
33445
33502
|
}
|
|
33446
33503
|
function equal(uriA, uriB, options) {
|
|
33447
|
-
|
|
33448
|
-
|
|
33449
|
-
|
|
33450
|
-
} else if (typeof uriA === "object") {
|
|
33451
|
-
uriA = serialize(normalizeComponentEncoding(uriA, true), { ...options, skipEscape: true });
|
|
33452
|
-
}
|
|
33453
|
-
if (typeof uriB === "string") {
|
|
33454
|
-
uriB = unescape(uriB);
|
|
33455
|
-
uriB = serialize(normalizeComponentEncoding(parse7(uriB, options), true), { ...options, skipEscape: true });
|
|
33456
|
-
} else if (typeof uriB === "object") {
|
|
33457
|
-
uriB = serialize(normalizeComponentEncoding(uriB, true), { ...options, skipEscape: true });
|
|
33458
|
-
}
|
|
33459
|
-
return uriA.toLowerCase() === uriB.toLowerCase();
|
|
33504
|
+
const normalizedA = normalizeComparableURI(uriA, options);
|
|
33505
|
+
const normalizedB = normalizeComparableURI(uriB, options);
|
|
33506
|
+
return normalizedA !== void 0 && normalizedB !== void 0 && normalizedA.toLowerCase() === normalizedB.toLowerCase();
|
|
33460
33507
|
}
|
|
33461
33508
|
function serialize(cmpts, opts) {
|
|
33462
33509
|
const component = {
|
|
@@ -33481,12 +33528,12 @@ var require_fast_uri = __commonJS({
|
|
|
33481
33528
|
if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
|
|
33482
33529
|
if (component.path !== void 0) {
|
|
33483
33530
|
if (!options.skipEscape) {
|
|
33484
|
-
component.path =
|
|
33531
|
+
component.path = escapePreservingEscapes(component.path);
|
|
33485
33532
|
if (component.scheme !== void 0) {
|
|
33486
33533
|
component.path = component.path.split("%3A").join(":");
|
|
33487
33534
|
}
|
|
33488
33535
|
} else {
|
|
33489
|
-
component.path =
|
|
33536
|
+
component.path = normalizePercentEncoding(component.path);
|
|
33490
33537
|
}
|
|
33491
33538
|
}
|
|
33492
33539
|
if (options.reference !== "suffix" && component.scheme) {
|
|
@@ -33521,7 +33568,16 @@ var require_fast_uri = __commonJS({
|
|
|
33521
33568
|
return uriTokens.join("");
|
|
33522
33569
|
}
|
|
33523
33570
|
var URI_PARSE = /^(?:([^#/:?]+):)?(?:\/\/((?:([^#/?@]*)@)?(\[[^#/?\]]+\]|[^#/:?]*)(?::(\d*))?))?([^#?]*)(?:\?([^#]*))?(?:#((?:.|[\n\r])*))?/u;
|
|
33524
|
-
function
|
|
33571
|
+
function getParseError(parsed, matches) {
|
|
33572
|
+
if (matches[2] !== void 0 && parsed.path && parsed.path[0] !== "/") {
|
|
33573
|
+
return 'URI path must start with "/" when authority is present.';
|
|
33574
|
+
}
|
|
33575
|
+
if (typeof parsed.port === "number" && (parsed.port < 0 || parsed.port > 65535)) {
|
|
33576
|
+
return "URI port is malformed.";
|
|
33577
|
+
}
|
|
33578
|
+
return void 0;
|
|
33579
|
+
}
|
|
33580
|
+
function parseWithStatus(uri, opts) {
|
|
33525
33581
|
const options = Object.assign({}, opts);
|
|
33526
33582
|
const parsed = {
|
|
33527
33583
|
scheme: void 0,
|
|
@@ -33532,6 +33588,7 @@ var require_fast_uri = __commonJS({
|
|
|
33532
33588
|
query: void 0,
|
|
33533
33589
|
fragment: void 0
|
|
33534
33590
|
};
|
|
33591
|
+
let malformedAuthorityOrPort = false;
|
|
33535
33592
|
let isIP = false;
|
|
33536
33593
|
if (options.reference === "suffix") {
|
|
33537
33594
|
if (options.scheme) {
|
|
@@ -33552,6 +33609,11 @@ var require_fast_uri = __commonJS({
|
|
|
33552
33609
|
if (isNaN(parsed.port)) {
|
|
33553
33610
|
parsed.port = matches[5];
|
|
33554
33611
|
}
|
|
33612
|
+
const parseError = getParseError(parsed, matches);
|
|
33613
|
+
if (parseError !== void 0) {
|
|
33614
|
+
parsed.error = parsed.error || parseError;
|
|
33615
|
+
malformedAuthorityOrPort = true;
|
|
33616
|
+
}
|
|
33555
33617
|
if (parsed.host) {
|
|
33556
33618
|
const ipv4result = isIPv4(parsed.host);
|
|
33557
33619
|
if (ipv4result === false) {
|
|
@@ -33590,14 +33652,18 @@ var require_fast_uri = __commonJS({
|
|
|
33590
33652
|
parsed.scheme = unescape(parsed.scheme);
|
|
33591
33653
|
}
|
|
33592
33654
|
if (parsed.host !== void 0) {
|
|
33593
|
-
parsed.host = unescape(parsed.host);
|
|
33655
|
+
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
33594
33656
|
}
|
|
33595
33657
|
}
|
|
33596
33658
|
if (parsed.path) {
|
|
33597
|
-
parsed.path =
|
|
33659
|
+
parsed.path = normalizePathEncoding(parsed.path);
|
|
33598
33660
|
}
|
|
33599
33661
|
if (parsed.fragment) {
|
|
33600
|
-
|
|
33662
|
+
try {
|
|
33663
|
+
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
33664
|
+
} catch {
|
|
33665
|
+
parsed.error = parsed.error || "URI malformed";
|
|
33666
|
+
}
|
|
33601
33667
|
}
|
|
33602
33668
|
}
|
|
33603
33669
|
if (schemeHandler && schemeHandler.parse) {
|
|
@@ -33606,7 +33672,29 @@ var require_fast_uri = __commonJS({
|
|
|
33606
33672
|
} else {
|
|
33607
33673
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
33608
33674
|
}
|
|
33609
|
-
return parsed;
|
|
33675
|
+
return { parsed, malformedAuthorityOrPort };
|
|
33676
|
+
}
|
|
33677
|
+
function parse7(uri, opts) {
|
|
33678
|
+
return parseWithStatus(uri, opts).parsed;
|
|
33679
|
+
}
|
|
33680
|
+
function normalizeString(uri, opts) {
|
|
33681
|
+
return normalizeStringWithStatus(uri, opts).normalized;
|
|
33682
|
+
}
|
|
33683
|
+
function normalizeStringWithStatus(uri, opts) {
|
|
33684
|
+
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
33685
|
+
return {
|
|
33686
|
+
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
33687
|
+
malformedAuthorityOrPort
|
|
33688
|
+
};
|
|
33689
|
+
}
|
|
33690
|
+
function normalizeComparableURI(uri, opts) {
|
|
33691
|
+
if (typeof uri === "string") {
|
|
33692
|
+
const { normalized, malformedAuthorityOrPort } = normalizeStringWithStatus(uri, opts);
|
|
33693
|
+
return malformedAuthorityOrPort ? void 0 : normalized;
|
|
33694
|
+
}
|
|
33695
|
+
if (typeof uri === "object") {
|
|
33696
|
+
return serialize(uri, opts);
|
|
33697
|
+
}
|
|
33610
33698
|
}
|
|
33611
33699
|
var fastUri = {
|
|
33612
33700
|
SCHEMES,
|
|
@@ -38412,7 +38500,7 @@ var require_main = __commonJS({
|
|
|
38412
38500
|
}
|
|
38413
38501
|
return to;
|
|
38414
38502
|
};
|
|
38415
|
-
var
|
|
38503
|
+
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
38416
38504
|
var node_exports = {};
|
|
38417
38505
|
__export2(node_exports, {
|
|
38418
38506
|
analyzeMetafile: () => analyzeMetafile,
|
|
@@ -38429,7 +38517,7 @@ var require_main = __commonJS({
|
|
|
38429
38517
|
transformSync: () => transformSync,
|
|
38430
38518
|
version: () => version3
|
|
38431
38519
|
});
|
|
38432
|
-
module2.exports =
|
|
38520
|
+
module2.exports = __toCommonJS2(node_exports);
|
|
38433
38521
|
function encodePacket(packet) {
|
|
38434
38522
|
let visit = (value) => {
|
|
38435
38523
|
if (value === null) {
|
|
@@ -39210,7 +39298,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
39210
39298
|
function buildOrContextImpl(callName, buildKey, sendRequest, sendResponse, refs, streamIn, requestCallbacks, options, isTTY2, defaultWD2, callback) {
|
|
39211
39299
|
const details = createObjectStash();
|
|
39212
39300
|
const isContext = callName === "context";
|
|
39213
|
-
const
|
|
39301
|
+
const handleError2 = (e, pluginName) => {
|
|
39214
39302
|
const flags = [];
|
|
39215
39303
|
try {
|
|
39216
39304
|
pushLogFlags(flags, options, {}, isTTY2, buildLogLevelDefault);
|
|
@@ -39226,12 +39314,12 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
39226
39314
|
if (typeof options === "object") {
|
|
39227
39315
|
const value = options.plugins;
|
|
39228
39316
|
if (value !== void 0) {
|
|
39229
|
-
if (!Array.isArray(value)) return
|
|
39317
|
+
if (!Array.isArray(value)) return handleError2(new Error(`"plugins" must be an array`), "");
|
|
39230
39318
|
plugins = value;
|
|
39231
39319
|
}
|
|
39232
39320
|
}
|
|
39233
39321
|
if (plugins && plugins.length > 0) {
|
|
39234
|
-
if (streamIn.isSync) return
|
|
39322
|
+
if (streamIn.isSync) return handleError2(new Error("Cannot use plugins in synchronous API calls"), "");
|
|
39235
39323
|
handlePlugins(
|
|
39236
39324
|
buildKey,
|
|
39237
39325
|
sendRequest,
|
|
@@ -39244,14 +39332,14 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
39244
39332
|
details
|
|
39245
39333
|
).then(
|
|
39246
39334
|
(result) => {
|
|
39247
|
-
if (!result.ok) return
|
|
39335
|
+
if (!result.ok) return handleError2(result.error, result.pluginName);
|
|
39248
39336
|
try {
|
|
39249
39337
|
buildOrContextContinue(result.requestPlugins, result.runOnEndCallbacks, result.scheduleOnDisposeCallbacks);
|
|
39250
39338
|
} catch (e) {
|
|
39251
|
-
|
|
39339
|
+
handleError2(e, "");
|
|
39252
39340
|
}
|
|
39253
39341
|
},
|
|
39254
|
-
(e) =>
|
|
39342
|
+
(e) => handleError2(e, "")
|
|
39255
39343
|
);
|
|
39256
39344
|
return;
|
|
39257
39345
|
}
|
|
@@ -39259,7 +39347,7 @@ is not a problem with esbuild. You need to fix your environment instead.
|
|
|
39259
39347
|
buildOrContextContinue(null, (result, done) => done([], []), () => {
|
|
39260
39348
|
});
|
|
39261
39349
|
} catch (e) {
|
|
39262
|
-
|
|
39350
|
+
handleError2(e, "");
|
|
39263
39351
|
}
|
|
39264
39352
|
function buildOrContextContinue(requestPlugins, runOnEndCallbacks, scheduleOnDisposeCallbacks) {
|
|
39265
39353
|
const writeDefault = streamIn.hasFS;
|
|
@@ -45895,6 +45983,317 @@ ${"=".repeat(50)}`);
|
|
|
45895
45983
|
}
|
|
45896
45984
|
});
|
|
45897
45985
|
|
|
45986
|
+
// ../../packages/mcp/src/swarm-tools.ts
|
|
45987
|
+
function errorResult(message) {
|
|
45988
|
+
return {
|
|
45989
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
45990
|
+
isError: true
|
|
45991
|
+
};
|
|
45992
|
+
}
|
|
45993
|
+
function registerSwarmTools() {
|
|
45994
|
+
registerTool(swarmDefinition, swarmHandler);
|
|
45995
|
+
registerTool(memoryDefinition, memoryHandler);
|
|
45996
|
+
registerTool(planDefinition, planHandler);
|
|
45997
|
+
}
|
|
45998
|
+
var swarmDefinition, swarmHandler, memoryDefinition, memoryHandler, planDefinition, planHandler, SWARM_TOOLS;
|
|
45999
|
+
var init_swarm_tools = __esm({
|
|
46000
|
+
"../../packages/mcp/src/swarm-tools.ts"() {
|
|
46001
|
+
"use strict";
|
|
46002
|
+
init_cjs_shims();
|
|
46003
|
+
init_registry();
|
|
46004
|
+
swarmDefinition = {
|
|
46005
|
+
name: "bootspring_swarm",
|
|
46006
|
+
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.",
|
|
46007
|
+
inputSchema: {
|
|
46008
|
+
type: "object",
|
|
46009
|
+
properties: {
|
|
46010
|
+
action: {
|
|
46011
|
+
type: "string",
|
|
46012
|
+
enum: ["start", "stop", "status", "spawn", "agents", "submit", "batch", "consensus", "topology"],
|
|
46013
|
+
description: "Swarm action to perform"
|
|
46014
|
+
},
|
|
46015
|
+
topology: {
|
|
46016
|
+
type: "string",
|
|
46017
|
+
enum: ["hierarchical", "mesh", "ring", "star", "adaptive"],
|
|
46018
|
+
description: "Swarm topology (for start/topology actions)"
|
|
46019
|
+
},
|
|
46020
|
+
role: {
|
|
46021
|
+
type: "string",
|
|
46022
|
+
enum: ["queen", "worker", "specialist", "reviewer", "monitor"],
|
|
46023
|
+
description: "Agent role (for spawn action)"
|
|
46024
|
+
},
|
|
46025
|
+
capabilities: {
|
|
46026
|
+
type: "array",
|
|
46027
|
+
items: { type: "string" },
|
|
46028
|
+
description: "Agent capabilities (for spawn action)"
|
|
46029
|
+
},
|
|
46030
|
+
taskType: {
|
|
46031
|
+
type: "string",
|
|
46032
|
+
description: "Task type (for submit action)"
|
|
46033
|
+
},
|
|
46034
|
+
taskDescription: {
|
|
46035
|
+
type: "string",
|
|
46036
|
+
description: "Task description (for submit action)"
|
|
46037
|
+
},
|
|
46038
|
+
priority: {
|
|
46039
|
+
type: "string",
|
|
46040
|
+
enum: ["critical", "high", "normal", "low"],
|
|
46041
|
+
description: "Task priority (for submit action)"
|
|
46042
|
+
},
|
|
46043
|
+
question: {
|
|
46044
|
+
type: "string",
|
|
46045
|
+
description: "Question for consensus vote"
|
|
46046
|
+
},
|
|
46047
|
+
options: {
|
|
46048
|
+
type: "array",
|
|
46049
|
+
items: { type: "string" },
|
|
46050
|
+
description: "Vote options for consensus"
|
|
46051
|
+
}
|
|
46052
|
+
},
|
|
46053
|
+
required: ["action"]
|
|
46054
|
+
}
|
|
46055
|
+
};
|
|
46056
|
+
swarmHandler = async (args) => {
|
|
46057
|
+
const action = String(args.action || "");
|
|
46058
|
+
try {
|
|
46059
|
+
const { api } = (init_src2(), __toCommonJS(src_exports2));
|
|
46060
|
+
let result;
|
|
46061
|
+
switch (action) {
|
|
46062
|
+
case "start":
|
|
46063
|
+
result = await api.request("POST", "/swarm/start", {
|
|
46064
|
+
topology: args.topology || "hierarchical"
|
|
46065
|
+
});
|
|
46066
|
+
break;
|
|
46067
|
+
case "stop":
|
|
46068
|
+
result = await api.request("POST", "/swarm/stop");
|
|
46069
|
+
break;
|
|
46070
|
+
case "status":
|
|
46071
|
+
result = await api.request("GET", "/swarm/status");
|
|
46072
|
+
break;
|
|
46073
|
+
case "spawn":
|
|
46074
|
+
if (!args.role) return errorResult("role is required for spawn");
|
|
46075
|
+
result = await api.request("POST", "/swarm/agents", {
|
|
46076
|
+
role: args.role,
|
|
46077
|
+
capabilities: args.capabilities || ["general"]
|
|
46078
|
+
});
|
|
46079
|
+
break;
|
|
46080
|
+
case "agents":
|
|
46081
|
+
result = await api.request("GET", "/swarm/agents");
|
|
46082
|
+
break;
|
|
46083
|
+
case "submit":
|
|
46084
|
+
if (!args.taskType || !args.taskDescription) {
|
|
46085
|
+
return errorResult("taskType and taskDescription are required for submit");
|
|
46086
|
+
}
|
|
46087
|
+
result = await api.request("POST", "/swarm/tasks", {
|
|
46088
|
+
type: args.taskType,
|
|
46089
|
+
description: args.taskDescription,
|
|
46090
|
+
input: {},
|
|
46091
|
+
priority: args.priority || "normal"
|
|
46092
|
+
});
|
|
46093
|
+
break;
|
|
46094
|
+
case "consensus":
|
|
46095
|
+
if (!args.question || !args.options) {
|
|
46096
|
+
return errorResult("question and options are required for consensus");
|
|
46097
|
+
}
|
|
46098
|
+
result = await api.request("POST", "/swarm/consensus", {
|
|
46099
|
+
question: args.question,
|
|
46100
|
+
options: args.options
|
|
46101
|
+
});
|
|
46102
|
+
break;
|
|
46103
|
+
case "topology":
|
|
46104
|
+
if (args.topology) {
|
|
46105
|
+
result = await api.request("POST", "/swarm/topology", { topology: args.topology });
|
|
46106
|
+
} else {
|
|
46107
|
+
result = await api.request("GET", "/swarm/topology");
|
|
46108
|
+
}
|
|
46109
|
+
break;
|
|
46110
|
+
default:
|
|
46111
|
+
return errorResult(`Unknown action: ${action}`);
|
|
46112
|
+
}
|
|
46113
|
+
return {
|
|
46114
|
+
content: [{
|
|
46115
|
+
type: "text",
|
|
46116
|
+
text: `Swarm ${action} result:
|
|
46117
|
+
${JSON.stringify(result, null, 2)}`
|
|
46118
|
+
}]
|
|
46119
|
+
};
|
|
46120
|
+
} catch (err) {
|
|
46121
|
+
return errorResult(err instanceof Error ? err.message : String(err));
|
|
46122
|
+
}
|
|
46123
|
+
};
|
|
46124
|
+
memoryDefinition = {
|
|
46125
|
+
name: "bootspring_memory",
|
|
46126
|
+
description: "Vector memory for AI agents \u2014 store decisions, patterns, and trajectories. Search by semantic similarity using HNSW index. Agents learn from past successes.",
|
|
46127
|
+
inputSchema: {
|
|
46128
|
+
type: "object",
|
|
46129
|
+
properties: {
|
|
46130
|
+
action: {
|
|
46131
|
+
type: "string",
|
|
46132
|
+
enum: ["search", "store", "trajectory", "stats", "forget"],
|
|
46133
|
+
description: "Memory action to perform"
|
|
46134
|
+
},
|
|
46135
|
+
query: {
|
|
46136
|
+
type: "string",
|
|
46137
|
+
description: "Search query (for search action)"
|
|
46138
|
+
},
|
|
46139
|
+
content: {
|
|
46140
|
+
type: "string",
|
|
46141
|
+
description: "Content to store (for store action)"
|
|
46142
|
+
},
|
|
46143
|
+
type: {
|
|
46144
|
+
type: "string",
|
|
46145
|
+
enum: ["decision", "pattern", "error", "solution", "context", "preference", "trajectory"],
|
|
46146
|
+
description: "Memory entry type"
|
|
46147
|
+
},
|
|
46148
|
+
goal: {
|
|
46149
|
+
type: "string",
|
|
46150
|
+
description: "Goal (for trajectory action)"
|
|
46151
|
+
},
|
|
46152
|
+
steps: {
|
|
46153
|
+
type: "array",
|
|
46154
|
+
items: { type: "string" },
|
|
46155
|
+
description: "Steps taken (for trajectory action)"
|
|
46156
|
+
},
|
|
46157
|
+
outcome: {
|
|
46158
|
+
type: "string",
|
|
46159
|
+
enum: ["success", "partial", "failure"],
|
|
46160
|
+
description: "Trajectory outcome"
|
|
46161
|
+
},
|
|
46162
|
+
id: {
|
|
46163
|
+
type: "string",
|
|
46164
|
+
description: "Entry ID (for forget action)"
|
|
46165
|
+
},
|
|
46166
|
+
limit: {
|
|
46167
|
+
type: "number",
|
|
46168
|
+
description: "Max results for search (default 10)"
|
|
46169
|
+
}
|
|
46170
|
+
},
|
|
46171
|
+
required: ["action"]
|
|
46172
|
+
}
|
|
46173
|
+
};
|
|
46174
|
+
memoryHandler = async (args) => {
|
|
46175
|
+
const action = String(args.action || "");
|
|
46176
|
+
try {
|
|
46177
|
+
const { api } = (init_src2(), __toCommonJS(src_exports2));
|
|
46178
|
+
let result;
|
|
46179
|
+
switch (action) {
|
|
46180
|
+
case "search":
|
|
46181
|
+
if (!args.query) return errorResult("query is required for search");
|
|
46182
|
+
result = await api.request("POST", "/swarm/memory/search", {
|
|
46183
|
+
query: args.query,
|
|
46184
|
+
limit: args.limit || 10,
|
|
46185
|
+
type: args.type
|
|
46186
|
+
});
|
|
46187
|
+
break;
|
|
46188
|
+
case "store":
|
|
46189
|
+
if (!args.content || !args.type) return errorResult("content and type are required for store");
|
|
46190
|
+
result = await api.request("POST", "/swarm/memory", {
|
|
46191
|
+
content: args.content,
|
|
46192
|
+
type: args.type,
|
|
46193
|
+
sessionId: `mcp-${Date.now()}`
|
|
46194
|
+
});
|
|
46195
|
+
break;
|
|
46196
|
+
case "trajectory":
|
|
46197
|
+
if (!args.goal || !args.steps || !args.outcome) {
|
|
46198
|
+
return errorResult("goal, steps, and outcome are required for trajectory");
|
|
46199
|
+
}
|
|
46200
|
+
result = await api.request("POST", "/swarm/memory/trajectory", {
|
|
46201
|
+
goal: args.goal,
|
|
46202
|
+
steps: args.steps,
|
|
46203
|
+
sessionId: `mcp-${Date.now()}`,
|
|
46204
|
+
outcome: args.outcome
|
|
46205
|
+
});
|
|
46206
|
+
break;
|
|
46207
|
+
case "stats":
|
|
46208
|
+
result = await api.request("GET", "/swarm/memory/stats");
|
|
46209
|
+
break;
|
|
46210
|
+
case "forget":
|
|
46211
|
+
if (!args.id) return errorResult("id is required for forget");
|
|
46212
|
+
result = await api.request("DELETE", `/swarm/memory/${args.id}`);
|
|
46213
|
+
break;
|
|
46214
|
+
default:
|
|
46215
|
+
return errorResult(`Unknown action: ${action}`);
|
|
46216
|
+
}
|
|
46217
|
+
return {
|
|
46218
|
+
content: [{
|
|
46219
|
+
type: "text",
|
|
46220
|
+
text: `Memory ${action} result:
|
|
46221
|
+
${JSON.stringify(result, null, 2)}`
|
|
46222
|
+
}]
|
|
46223
|
+
};
|
|
46224
|
+
} catch (err) {
|
|
46225
|
+
return errorResult(err instanceof Error ? err.message : String(err));
|
|
46226
|
+
}
|
|
46227
|
+
};
|
|
46228
|
+
planDefinition = {
|
|
46229
|
+
name: "bootspring_plan",
|
|
46230
|
+
description: "Goal-oriented action planning (GOAP) \u2014 decompose high-level goals into executable task DAGs with A* search. Finds optimal sequences and parallelizable groups.",
|
|
46231
|
+
inputSchema: {
|
|
46232
|
+
type: "object",
|
|
46233
|
+
properties: {
|
|
46234
|
+
action: {
|
|
46235
|
+
type: "string",
|
|
46236
|
+
enum: ["plan", "actions", "register"],
|
|
46237
|
+
description: "Planner action"
|
|
46238
|
+
},
|
|
46239
|
+
goal: {
|
|
46240
|
+
type: "string",
|
|
46241
|
+
description: "Goal to plan for (for plan action)"
|
|
46242
|
+
},
|
|
46243
|
+
parallel: {
|
|
46244
|
+
type: "boolean",
|
|
46245
|
+
description: "Enable parallel task groups"
|
|
46246
|
+
},
|
|
46247
|
+
currentState: {
|
|
46248
|
+
type: "object",
|
|
46249
|
+
description: "Current world state (key-value pairs)"
|
|
46250
|
+
},
|
|
46251
|
+
goalConditions: {
|
|
46252
|
+
type: "array",
|
|
46253
|
+
description: "Goal conditions [{key, operator, value}]"
|
|
46254
|
+
}
|
|
46255
|
+
},
|
|
46256
|
+
required: ["action"]
|
|
46257
|
+
}
|
|
46258
|
+
};
|
|
46259
|
+
planHandler = async (args) => {
|
|
46260
|
+
const action = String(args.action || "");
|
|
46261
|
+
try {
|
|
46262
|
+
const { api } = (init_src2(), __toCommonJS(src_exports2));
|
|
46263
|
+
let result;
|
|
46264
|
+
switch (action) {
|
|
46265
|
+
case "plan":
|
|
46266
|
+
if (!args.goal) return errorResult("goal is required for plan");
|
|
46267
|
+
result = await api.request("POST", "/swarm/plan", {
|
|
46268
|
+
goal: args.goal,
|
|
46269
|
+
currentState: args.currentState || {},
|
|
46270
|
+
goalConditions: args.goalConditions || [{ key: "deployed", operator: "==", value: true }],
|
|
46271
|
+
parallel: args.parallel ?? true
|
|
46272
|
+
});
|
|
46273
|
+
break;
|
|
46274
|
+
case "actions":
|
|
46275
|
+
result = await api.request("GET", "/swarm/plan/actions");
|
|
46276
|
+
break;
|
|
46277
|
+
case "register":
|
|
46278
|
+
return errorResult("Register custom actions via the API: POST /swarm/plan/actions");
|
|
46279
|
+
default:
|
|
46280
|
+
return errorResult(`Unknown action: ${action}`);
|
|
46281
|
+
}
|
|
46282
|
+
return {
|
|
46283
|
+
content: [{
|
|
46284
|
+
type: "text",
|
|
46285
|
+
text: `Plan ${action} result:
|
|
46286
|
+
${JSON.stringify(result, null, 2)}`
|
|
46287
|
+
}]
|
|
46288
|
+
};
|
|
46289
|
+
} catch (err) {
|
|
46290
|
+
return errorResult(err instanceof Error ? err.message : String(err));
|
|
46291
|
+
}
|
|
46292
|
+
};
|
|
46293
|
+
SWARM_TOOLS = [swarmDefinition, memoryDefinition, planDefinition];
|
|
46294
|
+
}
|
|
46295
|
+
});
|
|
46296
|
+
|
|
45898
46297
|
// ../../packages/mcp/src/index.ts
|
|
45899
46298
|
var src_exports3 = {};
|
|
45900
46299
|
__export(src_exports3, {
|
|
@@ -45912,6 +46311,7 @@ __export(src_exports3, {
|
|
|
45912
46311
|
QUALITY_INTELLIGENCE_TOOLS: () => QUALITY_INTELLIGENCE_TOOLS,
|
|
45913
46312
|
RBAC_TOOLS: () => RBAC_TOOLS,
|
|
45914
46313
|
RELEASE_TOOLS: () => RELEASE_TOOLS,
|
|
46314
|
+
SWARM_TOOLS: () => SWARM_TOOLS,
|
|
45915
46315
|
SYNC_TOOLS: () => SYNC_TOOLS,
|
|
45916
46316
|
agentDetails: () => agentDetails,
|
|
45917
46317
|
assistResponse: () => assistResponse,
|
|
@@ -45953,6 +46353,7 @@ __export(src_exports3, {
|
|
|
45953
46353
|
registerRbacTools: () => registerRbacTools,
|
|
45954
46354
|
registerReleaseTools: () => registerReleaseTools,
|
|
45955
46355
|
registerResource: () => registerResource,
|
|
46356
|
+
registerSwarmTools: () => registerSwarmTools,
|
|
45956
46357
|
registerSyncTools: () => registerSyncTools,
|
|
45957
46358
|
registerTool: () => registerTool,
|
|
45958
46359
|
resolveCompatibilityRegistry: () => resolveCompatibilityRegistry,
|
|
@@ -45988,6 +46389,7 @@ var init_src3 = __esm({
|
|
|
45988
46389
|
init_observer_tools();
|
|
45989
46390
|
init_autopilot_tools();
|
|
45990
46391
|
init_brain_tools();
|
|
46392
|
+
init_swarm_tools();
|
|
45991
46393
|
}
|
|
45992
46394
|
});
|
|
45993
46395
|
|
|
@@ -56629,7 +57031,7 @@ function registerBuildCommand(program3) {
|
|
|
56629
57031
|
print.info(`Complexity: ${next.complexity ?? "Unknown"}`);
|
|
56630
57032
|
if (current) print.info(`Status: ${next.status}`);
|
|
56631
57033
|
});
|
|
56632
|
-
build.command("done").alias("complete").description("Mark the current task as done
|
|
57034
|
+
build.command("done").alias("complete").description("Mark the current task as done, auto-commit, and show next task").option("--no-commit", "Skip auto-commit").action((opts) => {
|
|
56633
57035
|
const state = loadBuildStateWithAutoSync();
|
|
56634
57036
|
if (!state) {
|
|
56635
57037
|
print.error("No build state found");
|
|
@@ -56643,15 +57045,54 @@ function registerBuildCommand(program3) {
|
|
|
56643
57045
|
return;
|
|
56644
57046
|
}
|
|
56645
57047
|
const currentId = queue[idx].id;
|
|
57048
|
+
const currentTitle = queue[idx].title;
|
|
57049
|
+
if (opts.commit !== false) {
|
|
57050
|
+
try {
|
|
57051
|
+
const { execSync: execSync15 } = require("child_process");
|
|
57052
|
+
const cwd = process.cwd();
|
|
57053
|
+
const status = execSync15("git status --porcelain", { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
57054
|
+
if (status) {
|
|
57055
|
+
execSync15("git add -A", { cwd, stdio: ["ignore", "ignore", "ignore"] });
|
|
57056
|
+
const msg = `feat(${currentId}): ${currentTitle}`;
|
|
57057
|
+
execSync15(`git commit -m ${JSON.stringify(msg)}`, { cwd, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
57058
|
+
print.success(`Committed: ${msg}`);
|
|
57059
|
+
}
|
|
57060
|
+
} catch {
|
|
57061
|
+
}
|
|
57062
|
+
}
|
|
56646
57063
|
queue[idx].status = "completed";
|
|
56647
57064
|
if (state.loopSession) {
|
|
56648
57065
|
state.loopSession.currentIteration = (state.loopSession.currentIteration ?? 0) + 1;
|
|
56649
57066
|
}
|
|
56650
57067
|
saveBuildState(state);
|
|
56651
|
-
const nextTask =
|
|
57068
|
+
const nextTask = (() => {
|
|
57069
|
+
for (const task of queue) {
|
|
57070
|
+
if (task.status !== "pending") continue;
|
|
57071
|
+
if (task.dependencies?.length) {
|
|
57072
|
+
const allDone = task.dependencies.every((depId) => {
|
|
57073
|
+
const dep = queue.find((t) => t.id === depId);
|
|
57074
|
+
return dep && dep.status === "completed";
|
|
57075
|
+
});
|
|
57076
|
+
if (!allDone) continue;
|
|
57077
|
+
}
|
|
57078
|
+
return task;
|
|
57079
|
+
}
|
|
57080
|
+
return null;
|
|
57081
|
+
})();
|
|
56652
57082
|
print.success(`Task ${currentId} marked as done`);
|
|
56653
57083
|
if (nextTask) {
|
|
56654
|
-
|
|
57084
|
+
console.log("");
|
|
57085
|
+
print.header("Next Task");
|
|
57086
|
+
print.info(`ID: ${nextTask.id}`);
|
|
57087
|
+
print.info(`Title: ${nextTask.title}`);
|
|
57088
|
+
if (nextTask.phase) print.info(`Phase: ${nextTask.phase}`);
|
|
57089
|
+
if (nextTask.description) print.info(`Description: ${nextTask.description}`);
|
|
57090
|
+
if (nextTask.acceptanceCriteria && nextTask.acceptanceCriteria.length > 0) {
|
|
57091
|
+
print.info("Acceptance criteria:");
|
|
57092
|
+
for (const ac of nextTask.acceptanceCriteria) {
|
|
57093
|
+
console.log(` [ ] ${ac}`);
|
|
57094
|
+
}
|
|
57095
|
+
}
|
|
56655
57096
|
} else {
|
|
56656
57097
|
print.success("No more pending tasks!");
|
|
56657
57098
|
}
|
|
@@ -57537,6 +57978,71 @@ ${supplementaryContent}
|
|
|
57537
57978
|
print.dim(`${snapshot.completedCount} completed, ${snapshot.pendingCount} pending`);
|
|
57538
57979
|
}
|
|
57539
57980
|
});
|
|
57981
|
+
build.command("handoff").description("Save or load session handoff state for cross-session continuity").option("--save", "Save current session state").option("--notes <notes>", "Notes for the next session").option("--json", "Output as JSON").action((opts) => {
|
|
57982
|
+
const handoffPath = path52.join(process.cwd(), "planning", ".handoff.json");
|
|
57983
|
+
if (opts.save) {
|
|
57984
|
+
const state = loadBuildStateWithAutoSync(true);
|
|
57985
|
+
const queue = state?.implementationQueue ?? [];
|
|
57986
|
+
const inProgress = queue.find((t) => t.status === "in_progress");
|
|
57987
|
+
const lastCompleted = [...queue].reverse().find((t) => t.status === "completed");
|
|
57988
|
+
let filesModified = [];
|
|
57989
|
+
try {
|
|
57990
|
+
const { execSync: execSync15 } = require("child_process");
|
|
57991
|
+
const gitDiff = execSync15("git diff --name-only HEAD~1 2>/dev/null || true", { encoding: "utf8" }).trim();
|
|
57992
|
+
if (gitDiff) filesModified = gitDiff.split("\n").filter(Boolean);
|
|
57993
|
+
} catch {
|
|
57994
|
+
}
|
|
57995
|
+
const handoff = {
|
|
57996
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57997
|
+
lastTaskId: lastCompleted?.id ?? null,
|
|
57998
|
+
inProgressTask: inProgress?.id ?? null,
|
|
57999
|
+
inProgressTitle: inProgress?.title ?? null,
|
|
58000
|
+
filesModified,
|
|
58001
|
+
notes: opts.notes ?? "",
|
|
58002
|
+
blockers: [],
|
|
58003
|
+
progress: {
|
|
58004
|
+
completed: queue.filter((t) => t.status === "completed").length,
|
|
58005
|
+
pending: queue.filter((t) => t.status === "pending").length,
|
|
58006
|
+
total: queue.length
|
|
58007
|
+
}
|
|
58008
|
+
};
|
|
58009
|
+
const dir = path52.dirname(handoffPath);
|
|
58010
|
+
if (!fs51.existsSync(dir)) fs51.mkdirSync(dir, { recursive: true });
|
|
58011
|
+
fs51.writeFileSync(handoffPath, JSON.stringify(handoff, null, 2));
|
|
58012
|
+
if (opts.json) {
|
|
58013
|
+
console.log(JSON.stringify({ saved: true, handoff }));
|
|
58014
|
+
} else {
|
|
58015
|
+
print.success("Session handoff saved");
|
|
58016
|
+
if (inProgress) print.info(`In-progress: ${inProgress.id} \u2014 ${inProgress.title}`);
|
|
58017
|
+
if (opts.notes) print.info(`Notes: ${opts.notes}`);
|
|
58018
|
+
}
|
|
58019
|
+
return;
|
|
58020
|
+
}
|
|
58021
|
+
if (!fs51.existsSync(handoffPath)) {
|
|
58022
|
+
if (opts.json) {
|
|
58023
|
+
console.log(JSON.stringify({ hasHandoff: false }));
|
|
58024
|
+
} else {
|
|
58025
|
+
print.info("No previous session handoff found.");
|
|
58026
|
+
}
|
|
58027
|
+
return;
|
|
58028
|
+
}
|
|
58029
|
+
try {
|
|
58030
|
+
const handoff = JSON.parse(fs51.readFileSync(handoffPath, "utf-8"));
|
|
58031
|
+
if (opts.json) {
|
|
58032
|
+
console.log(JSON.stringify({ hasHandoff: true, handoff }));
|
|
58033
|
+
} else {
|
|
58034
|
+
print.header("Session Handoff");
|
|
58035
|
+
print.info(`Saved: ${handoff.timestamp}`);
|
|
58036
|
+
if (handoff.inProgressTask) print.info(`In-progress: ${handoff.inProgressTask} \u2014 ${handoff.inProgressTitle ?? ""}`);
|
|
58037
|
+
if (handoff.lastTaskId) print.info(`Last completed: ${handoff.lastTaskId}`);
|
|
58038
|
+
if (handoff.notes) print.info(`Notes: ${handoff.notes}`);
|
|
58039
|
+
if (handoff.progress) print.info(`Progress: ${handoff.progress.completed}/${handoff.progress.total}`);
|
|
58040
|
+
if (handoff.filesModified?.length) print.dim(`Files: ${handoff.filesModified.slice(0, 5).join(", ")}${handoff.filesModified.length > 5 ? ` +${handoff.filesModified.length - 5} more` : ""}`);
|
|
58041
|
+
}
|
|
58042
|
+
} catch {
|
|
58043
|
+
print.error("Failed to read handoff file");
|
|
58044
|
+
}
|
|
58045
|
+
});
|
|
57540
58046
|
build.action(() => {
|
|
57541
58047
|
build.outputHelp();
|
|
57542
58048
|
});
|
|
@@ -66356,7 +66862,7 @@ function drawProgressBar(progress, width = 20) {
|
|
|
66356
66862
|
}
|
|
66357
66863
|
function getWorkflowStates(projectRoot) {
|
|
66358
66864
|
const workflows = {};
|
|
66359
|
-
const names = ["onboard", "analyze", "audit", "seed", "context", "deploy", "loop"
|
|
66865
|
+
const names = ["onboard", "analyze", "audit", "seed", "context", "deploy", "loop"];
|
|
66360
66866
|
for (const name of names) {
|
|
66361
66867
|
const stateFile = path78.join(projectRoot, ".bootspring", name, "workflow-state.json");
|
|
66362
66868
|
if (fs77.existsSync(stateFile)) {
|
|
@@ -72858,10 +73364,434 @@ function registerHarnessCommand(program3) {
|
|
|
72858
73364
|
});
|
|
72859
73365
|
}
|
|
72860
73366
|
|
|
72861
|
-
// src/commands/
|
|
73367
|
+
// src/commands/swarm.ts
|
|
72862
73368
|
init_cjs_shims();
|
|
72863
73369
|
init_src2();
|
|
72864
73370
|
function requireAuth4() {
|
|
73371
|
+
if (auth_exports.isAuthenticated()) return true;
|
|
73372
|
+
print(`${COLORS.red}Not authenticated.${COLORS.reset} Run ${COLORS.bold}bootspring auth login${COLORS.reset} first.`);
|
|
73373
|
+
process.exitCode = 1;
|
|
73374
|
+
return false;
|
|
73375
|
+
}
|
|
73376
|
+
function handleError(error50) {
|
|
73377
|
+
if (error50 && typeof error50 === "object" && "response" in error50) {
|
|
73378
|
+
const resp = error50.response;
|
|
73379
|
+
if (resp?.status === 403) {
|
|
73380
|
+
print(`
|
|
73381
|
+
${COLORS.yellow}Swarm Intelligence requires Pro tier or higher.${COLORS.reset}`);
|
|
73382
|
+
print(`Upgrade at: ${COLORS.cyan}https://bootspring.com/pricing${COLORS.reset}
|
|
73383
|
+
`);
|
|
73384
|
+
return;
|
|
73385
|
+
}
|
|
73386
|
+
print(`${COLORS.red}Error:${COLORS.reset} ${resp?.data?.error || resp?.data?.message || "Unknown API error"}`);
|
|
73387
|
+
return;
|
|
73388
|
+
}
|
|
73389
|
+
print(`${COLORS.red}Error:${COLORS.reset} ${error50 instanceof Error ? error50.message : String(error50)}`);
|
|
73390
|
+
}
|
|
73391
|
+
var TOPOLOGY_SYMBOLS = {
|
|
73392
|
+
hierarchical: "\u25B3",
|
|
73393
|
+
// △
|
|
73394
|
+
mesh: "\u25C6",
|
|
73395
|
+
// ◆
|
|
73396
|
+
ring: "\u25CB",
|
|
73397
|
+
// ○
|
|
73398
|
+
star: "\u2605",
|
|
73399
|
+
// ★
|
|
73400
|
+
adaptive: "\u21C4"
|
|
73401
|
+
// ⇄
|
|
73402
|
+
};
|
|
73403
|
+
var STATUS_COLORS = {
|
|
73404
|
+
idle: COLORS.green,
|
|
73405
|
+
busy: COLORS.cyan,
|
|
73406
|
+
waiting: COLORS.yellow,
|
|
73407
|
+
failed: COLORS.red,
|
|
73408
|
+
offline: COLORS.dim
|
|
73409
|
+
};
|
|
73410
|
+
function registerSwarmCommand(program3) {
|
|
73411
|
+
const cmd = program3.command("swarm").description("Multi-agent swarm orchestration \u2014 topology, consensus, planning");
|
|
73412
|
+
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) => {
|
|
73413
|
+
if (!requireAuth4()) return;
|
|
73414
|
+
try {
|
|
73415
|
+
const res = await api_client_exports.request("POST", "/swarm/start", {
|
|
73416
|
+
topology: opts.topology,
|
|
73417
|
+
maxAgents: parseInt(opts.maxAgents, 10)
|
|
73418
|
+
});
|
|
73419
|
+
if (opts.json) {
|
|
73420
|
+
print(JSON.stringify(res, null, 2));
|
|
73421
|
+
return;
|
|
73422
|
+
}
|
|
73423
|
+
const topo = opts.topology;
|
|
73424
|
+
const sym = TOPOLOGY_SYMBOLS[topo] || "";
|
|
73425
|
+
print(`
|
|
73426
|
+
${COLORS.bold}${COLORS.cyan}${sym} Swarm Started${COLORS.reset}`);
|
|
73427
|
+
print(` Topology: ${COLORS.green}${topo}${COLORS.reset}`);
|
|
73428
|
+
print(` Max Agents: ${opts.maxAgents}`);
|
|
73429
|
+
print(` Phase: ${res.config?.phase || "running"}
|
|
73430
|
+
`);
|
|
73431
|
+
} catch (error50) {
|
|
73432
|
+
handleError(error50);
|
|
73433
|
+
}
|
|
73434
|
+
});
|
|
73435
|
+
cmd.command("stop").description("Stop the current swarm").option("--json", "Output as JSON").action(async (opts) => {
|
|
73436
|
+
if (!requireAuth4()) return;
|
|
73437
|
+
try {
|
|
73438
|
+
const res = await api_client_exports.request("POST", "/swarm/stop");
|
|
73439
|
+
if (opts.json) {
|
|
73440
|
+
print(JSON.stringify(res, null, 2));
|
|
73441
|
+
return;
|
|
73442
|
+
}
|
|
73443
|
+
print(`
|
|
73444
|
+
${COLORS.bold}Swarm Stopped${COLORS.reset}`);
|
|
73445
|
+
if (res.metrics) {
|
|
73446
|
+
print(` Tasks Completed: ${COLORS.green}${res.metrics.completedTasks}${COLORS.reset}`);
|
|
73447
|
+
print(` Tasks Failed: ${COLORS.red}${res.metrics.failedTasks}${COLORS.reset}`);
|
|
73448
|
+
print(` Total Agents: ${res.metrics.totalAgents}`);
|
|
73449
|
+
}
|
|
73450
|
+
print("");
|
|
73451
|
+
} catch (error50) {
|
|
73452
|
+
handleError(error50);
|
|
73453
|
+
}
|
|
73454
|
+
});
|
|
73455
|
+
cmd.command("status").description("Show swarm metrics and topology").option("--json", "Output as JSON").action(async (opts) => {
|
|
73456
|
+
if (!requireAuth4()) return;
|
|
73457
|
+
try {
|
|
73458
|
+
const res = await api_client_exports.request("GET", "/swarm/status");
|
|
73459
|
+
if (opts.json) {
|
|
73460
|
+
print(JSON.stringify(res, null, 2));
|
|
73461
|
+
return;
|
|
73462
|
+
}
|
|
73463
|
+
const m = res.metrics;
|
|
73464
|
+
const sym = TOPOLOGY_SYMBOLS[m.topology] || "";
|
|
73465
|
+
print(`
|
|
73466
|
+
${COLORS.bold}${COLORS.cyan}${sym} Swarm Status${COLORS.reset}`);
|
|
73467
|
+
print(`${"\u2500".repeat(50)}`);
|
|
73468
|
+
print(` Phase: ${m.phase}`);
|
|
73469
|
+
print(` Topology: ${COLORS.green}${m.topology}${COLORS.reset}`);
|
|
73470
|
+
print(` Uptime: ${Math.round(m.uptime / 1e3)}s`);
|
|
73471
|
+
print("");
|
|
73472
|
+
print(` ${COLORS.bold}Agents${COLORS.reset}`);
|
|
73473
|
+
print(` Total: ${m.totalAgents}`);
|
|
73474
|
+
print(` Active: ${COLORS.cyan}${m.activeAgents}${COLORS.reset}`);
|
|
73475
|
+
print(` Idle: ${COLORS.green}${m.idleAgents}${COLORS.reset}`);
|
|
73476
|
+
print(` Failed: ${COLORS.red}${m.failedAgents}${COLORS.reset}`);
|
|
73477
|
+
print("");
|
|
73478
|
+
print(` ${COLORS.bold}Tasks${COLORS.reset}`);
|
|
73479
|
+
print(` Total: ${m.totalTasks}`);
|
|
73480
|
+
print(` Running: ${COLORS.cyan}${m.runningTasks}${COLORS.reset}`);
|
|
73481
|
+
print(` Pending: ${COLORS.yellow}${m.pendingTasks}${COLORS.reset}`);
|
|
73482
|
+
print(` Completed: ${COLORS.green}${m.completedTasks}${COLORS.reset}`);
|
|
73483
|
+
print(` Failed: ${COLORS.red}${m.failedTasks}${COLORS.reset}`);
|
|
73484
|
+
print("");
|
|
73485
|
+
print(` Throughput: ${m.throughputTasksPerMin} tasks/min`);
|
|
73486
|
+
print(` Avg Time: ${m.avgTaskDurationMs}ms`);
|
|
73487
|
+
if (res.topology) {
|
|
73488
|
+
print(`
|
|
73489
|
+
${COLORS.bold}Topology Graph${COLORS.reset}`);
|
|
73490
|
+
print(` Nodes: ${res.topology.nodes.length} Edges: ${res.topology.edges.length}`);
|
|
73491
|
+
}
|
|
73492
|
+
print("");
|
|
73493
|
+
} catch (error50) {
|
|
73494
|
+
handleError(error50);
|
|
73495
|
+
}
|
|
73496
|
+
});
|
|
73497
|
+
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) => {
|
|
73498
|
+
if (!requireAuth4()) return;
|
|
73499
|
+
const validRoles = ["queen", "worker", "specialist", "reviewer", "monitor"];
|
|
73500
|
+
if (!validRoles.includes(role)) {
|
|
73501
|
+
print(`${COLORS.red}Invalid role:${COLORS.reset} ${role}. Must be one of: ${validRoles.join(", ")}`);
|
|
73502
|
+
return;
|
|
73503
|
+
}
|
|
73504
|
+
try {
|
|
73505
|
+
const capabilities = opts.capabilities.split(",").map((c) => c.trim());
|
|
73506
|
+
const res = await api_client_exports.request("POST", "/swarm/agents", { role, capabilities });
|
|
73507
|
+
if (opts.json) {
|
|
73508
|
+
print(JSON.stringify(res, null, 2));
|
|
73509
|
+
return;
|
|
73510
|
+
}
|
|
73511
|
+
print(`
|
|
73512
|
+
${COLORS.green}Agent spawned:${COLORS.reset} ${res.id}`);
|
|
73513
|
+
print(` Role: ${res.role}`);
|
|
73514
|
+
print(` Capabilities: ${res.capabilities.join(", ")}`);
|
|
73515
|
+
print(` Status: ${STATUS_COLORS[res.status] || ""}${res.status}${COLORS.reset}
|
|
73516
|
+
`);
|
|
73517
|
+
} catch (error50) {
|
|
73518
|
+
handleError(error50);
|
|
73519
|
+
}
|
|
73520
|
+
});
|
|
73521
|
+
cmd.command("agents").description("List swarm agents").option("--role <role>", "Filter by role").option("--json", "Output as JSON").action(async (opts) => {
|
|
73522
|
+
if (!requireAuth4()) return;
|
|
73523
|
+
try {
|
|
73524
|
+
const query = opts.role ? `?role=${opts.role}` : "";
|
|
73525
|
+
const res = await api_client_exports.request("GET", `/swarm/agents${query}`);
|
|
73526
|
+
if (opts.json) {
|
|
73527
|
+
print(JSON.stringify(res, null, 2));
|
|
73528
|
+
return;
|
|
73529
|
+
}
|
|
73530
|
+
print(`
|
|
73531
|
+
${COLORS.bold}${COLORS.cyan}Swarm Agents${COLORS.reset} (${res.count})
|
|
73532
|
+
`);
|
|
73533
|
+
print(`${"ID".padEnd(24)} ${"Role".padEnd(12)} ${"Status".padEnd(10)} ${"Done".padEnd(6)} ${"Fail".padEnd(6)} Capabilities`);
|
|
73534
|
+
print(`${"\u2500".repeat(24)} ${"\u2500".repeat(12)} ${"\u2500".repeat(10)} ${"\u2500".repeat(6)} ${"\u2500".repeat(6)} ${"\u2500".repeat(20)}`);
|
|
73535
|
+
for (const a of res.agents) {
|
|
73536
|
+
const color = STATUS_COLORS[a.status] || "";
|
|
73537
|
+
print(
|
|
73538
|
+
`${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(", ")}`
|
|
73539
|
+
);
|
|
73540
|
+
}
|
|
73541
|
+
print("");
|
|
73542
|
+
} catch (error50) {
|
|
73543
|
+
handleError(error50);
|
|
73544
|
+
}
|
|
73545
|
+
});
|
|
73546
|
+
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) => {
|
|
73547
|
+
if (!requireAuth4()) return;
|
|
73548
|
+
try {
|
|
73549
|
+
const res = await api_client_exports.request("POST", "/swarm/tasks", {
|
|
73550
|
+
type,
|
|
73551
|
+
description,
|
|
73552
|
+
input: {},
|
|
73553
|
+
priority: opts.priority
|
|
73554
|
+
});
|
|
73555
|
+
if (opts.json) {
|
|
73556
|
+
print(JSON.stringify(res, null, 2));
|
|
73557
|
+
return;
|
|
73558
|
+
}
|
|
73559
|
+
print(`
|
|
73560
|
+
${COLORS.green}Task submitted:${COLORS.reset} ${res.id}`);
|
|
73561
|
+
print(` Type: ${res.type}`);
|
|
73562
|
+
print(` Priority: ${res.priority}`);
|
|
73563
|
+
print(` Status: ${res.status}`);
|
|
73564
|
+
if (res.assignedAgentId) {
|
|
73565
|
+
print(` Assigned: ${res.assignedAgentId}`);
|
|
73566
|
+
}
|
|
73567
|
+
print("");
|
|
73568
|
+
} catch (error50) {
|
|
73569
|
+
handleError(error50);
|
|
73570
|
+
}
|
|
73571
|
+
});
|
|
73572
|
+
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) => {
|
|
73573
|
+
if (!requireAuth4()) return;
|
|
73574
|
+
try {
|
|
73575
|
+
const res = await api_client_exports.request("POST", "/swarm/plan", {
|
|
73576
|
+
goal,
|
|
73577
|
+
currentState: {},
|
|
73578
|
+
goalConditions: [{ key: "deployed", operator: "==", value: true }],
|
|
73579
|
+
parallel: !!opts.parallel
|
|
73580
|
+
});
|
|
73581
|
+
if (opts.json) {
|
|
73582
|
+
print(JSON.stringify(res, null, 2));
|
|
73583
|
+
return;
|
|
73584
|
+
}
|
|
73585
|
+
const feasibleStr = res.feasible ? `${COLORS.green}FEASIBLE${COLORS.reset}` : `${COLORS.red}INFEASIBLE${COLORS.reset}`;
|
|
73586
|
+
print(`
|
|
73587
|
+
${COLORS.bold}${COLORS.cyan}Goal Planner${COLORS.reset}
|
|
73588
|
+
`);
|
|
73589
|
+
print(` Goal: ${goal}`);
|
|
73590
|
+
print(` Feasible: ${feasibleStr}`);
|
|
73591
|
+
print(` Explanation: ${res.explanation}`);
|
|
73592
|
+
if (res.feasible && res.steps.length > 0) {
|
|
73593
|
+
print(` Total Cost: ${res.totalCost}`);
|
|
73594
|
+
print(` Est. Time: ${Math.round(res.estimatedDurationMs / 1e3)}s`);
|
|
73595
|
+
print(` Par. Groups: ${res.parallelGroups}`);
|
|
73596
|
+
print(`
|
|
73597
|
+
${COLORS.bold}Execution Steps:${COLORS.reset}
|
|
73598
|
+
`);
|
|
73599
|
+
print(` ${"#".padEnd(4)} ${"Action".padEnd(24)} ${"Agent".padEnd(14)} ${"Group".padEnd(8)} Duration`);
|
|
73600
|
+
print(` ${"\u2500".repeat(4)} ${"\u2500".repeat(24)} ${"\u2500".repeat(14)} ${"\u2500".repeat(8)} ${"\u2500".repeat(10)}`);
|
|
73601
|
+
for (const step of res.steps) {
|
|
73602
|
+
const group = `G${step.parallelGroup}`;
|
|
73603
|
+
const dur = `${Math.round(step.action.estimatedDurationMs / 1e3)}s`;
|
|
73604
|
+
print(
|
|
73605
|
+
` ${String(step.order + 1).padEnd(4)} ${step.action.name.padEnd(24)} ${step.action.agentCapability.padEnd(14)} ${group.padEnd(8)} ${dur}`
|
|
73606
|
+
);
|
|
73607
|
+
}
|
|
73608
|
+
if (res.steps.some((s) => s.dependencies.length > 0)) {
|
|
73609
|
+
print(`
|
|
73610
|
+
${COLORS.bold}Dependencies:${COLORS.reset}`);
|
|
73611
|
+
for (const step of res.steps) {
|
|
73612
|
+
if (step.dependencies.length > 0) {
|
|
73613
|
+
print(` ${step.action.name} ${COLORS.dim}<- ${step.dependencies.join(", ")}${COLORS.reset}`);
|
|
73614
|
+
}
|
|
73615
|
+
}
|
|
73616
|
+
}
|
|
73617
|
+
}
|
|
73618
|
+
print("");
|
|
73619
|
+
} catch (error50) {
|
|
73620
|
+
handleError(error50);
|
|
73621
|
+
}
|
|
73622
|
+
});
|
|
73623
|
+
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) => {
|
|
73624
|
+
if (!requireAuth4()) return;
|
|
73625
|
+
try {
|
|
73626
|
+
const options = opts.options.split(",").map((o) => o.trim());
|
|
73627
|
+
const res = await api_client_exports.request("POST", "/swarm/consensus", { question, options });
|
|
73628
|
+
if (opts.json) {
|
|
73629
|
+
print(JSON.stringify(res, null, 2));
|
|
73630
|
+
return;
|
|
73631
|
+
}
|
|
73632
|
+
const quorum = res.quorumReached ? `${COLORS.green}QUORUM REACHED${COLORS.reset}` : `${COLORS.yellow}NO QUORUM${COLORS.reset}`;
|
|
73633
|
+
print(`
|
|
73634
|
+
${COLORS.bold}${COLORS.cyan}Consensus Vote${COLORS.reset}
|
|
73635
|
+
`);
|
|
73636
|
+
print(` Question: ${question}`);
|
|
73637
|
+
print(` Decision: ${COLORS.bold}${res.decision}${COLORS.reset}`);
|
|
73638
|
+
print(` Agreement: ${Math.round(res.agreement * 100)}%`);
|
|
73639
|
+
print(` Status: ${quorum}`);
|
|
73640
|
+
print(` Votes: ${res.votes.length}
|
|
73641
|
+
`);
|
|
73642
|
+
} catch (error50) {
|
|
73643
|
+
handleError(error50);
|
|
73644
|
+
}
|
|
73645
|
+
});
|
|
73646
|
+
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) => {
|
|
73647
|
+
if (!requireAuth4()) return;
|
|
73648
|
+
try {
|
|
73649
|
+
if (action === "search" && query) {
|
|
73650
|
+
const res = await api_client_exports.request("POST", "/swarm/memory/search", {
|
|
73651
|
+
query,
|
|
73652
|
+
limit: parseInt(opts.limit, 10),
|
|
73653
|
+
type: opts.type
|
|
73654
|
+
});
|
|
73655
|
+
if (opts.json) {
|
|
73656
|
+
print(JSON.stringify(res, null, 2));
|
|
73657
|
+
return;
|
|
73658
|
+
}
|
|
73659
|
+
print(`
|
|
73660
|
+
${COLORS.bold}${COLORS.cyan}Memory Search${COLORS.reset} (${res.results.length} results, ${res.searchTimeMs}ms, ${res.method})
|
|
73661
|
+
`);
|
|
73662
|
+
for (const r of res.results) {
|
|
73663
|
+
const truncated = r.entry.content.length > 80 ? r.entry.content.slice(0, 80) + "..." : r.entry.content;
|
|
73664
|
+
print(` ${COLORS.green}#${r.rank}${COLORS.reset} [${r.score.toFixed(3)}] ${COLORS.dim}(${r.entry.type})${COLORS.reset} ${truncated}`);
|
|
73665
|
+
}
|
|
73666
|
+
print("");
|
|
73667
|
+
} else if (action === "stats") {
|
|
73668
|
+
const res = await api_client_exports.request("GET", "/swarm/memory/stats");
|
|
73669
|
+
if (opts.json) {
|
|
73670
|
+
print(JSON.stringify(res, null, 2));
|
|
73671
|
+
return;
|
|
73672
|
+
}
|
|
73673
|
+
print(`
|
|
73674
|
+
${COLORS.bold}${COLORS.cyan}Vector Memory Stats${COLORS.reset}
|
|
73675
|
+
`);
|
|
73676
|
+
print(` Entries: ${res.totalEntries}`);
|
|
73677
|
+
print(` Dimensions: ${res.dimensions}`);
|
|
73678
|
+
print(` Layers: ${res.layers}`);
|
|
73679
|
+
print(` Avg Import: ${res.avgImportance}`);
|
|
73680
|
+
print(` Memory: ${Math.round(res.memoryBytes / 1024)}KB`);
|
|
73681
|
+
if (res.byType && Object.keys(res.byType).length > 0) {
|
|
73682
|
+
print(`
|
|
73683
|
+
By Type:`);
|
|
73684
|
+
for (const [type, count] of Object.entries(res.byType)) {
|
|
73685
|
+
print(` ${type.padEnd(16)} ${count}`);
|
|
73686
|
+
}
|
|
73687
|
+
}
|
|
73688
|
+
print("");
|
|
73689
|
+
} else {
|
|
73690
|
+
print(`
|
|
73691
|
+
Usage: bootspring swarm memory <search|stats> [query]`);
|
|
73692
|
+
print(` ${COLORS.dim}bootspring swarm memory search "how to fix tests"${COLORS.reset}`);
|
|
73693
|
+
print(` ${COLORS.dim}bootspring swarm memory stats${COLORS.reset}
|
|
73694
|
+
`);
|
|
73695
|
+
}
|
|
73696
|
+
} catch (error50) {
|
|
73697
|
+
handleError(error50);
|
|
73698
|
+
}
|
|
73699
|
+
});
|
|
73700
|
+
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) => {
|
|
73701
|
+
if (!requireAuth4()) return;
|
|
73702
|
+
try {
|
|
73703
|
+
if (opts.set) {
|
|
73704
|
+
const res = await api_client_exports.request("POST", "/swarm/topology", { topology: opts.set });
|
|
73705
|
+
if (opts.json) {
|
|
73706
|
+
print(JSON.stringify(res, null, 2));
|
|
73707
|
+
return;
|
|
73708
|
+
}
|
|
73709
|
+
print(`
|
|
73710
|
+
${COLORS.green}Topology changed to:${COLORS.reset} ${opts.set}
|
|
73711
|
+
`);
|
|
73712
|
+
} else {
|
|
73713
|
+
const res = await api_client_exports.request("GET", "/swarm/topology");
|
|
73714
|
+
if (opts.json) {
|
|
73715
|
+
print(JSON.stringify(res, null, 2));
|
|
73716
|
+
return;
|
|
73717
|
+
}
|
|
73718
|
+
print(`
|
|
73719
|
+
${COLORS.bold}${COLORS.cyan}Topology Graph${COLORS.reset}
|
|
73720
|
+
`);
|
|
73721
|
+
print(` Nodes: ${res.nodes.length} Edges: ${res.edges.length}
|
|
73722
|
+
`);
|
|
73723
|
+
for (const node of res.nodes) {
|
|
73724
|
+
const color = STATUS_COLORS[node.status] || "";
|
|
73725
|
+
print(` ${color}\u25CF${COLORS.reset} ${node.id} (${node.role})`);
|
|
73726
|
+
}
|
|
73727
|
+
if (res.edges.length > 0) {
|
|
73728
|
+
print(`
|
|
73729
|
+
Edges:`);
|
|
73730
|
+
for (const edge of res.edges.slice(0, 20)) {
|
|
73731
|
+
const arrow = edge.type === "parent" ? "\u2192" : "\u2194";
|
|
73732
|
+
print(` ${edge.from} ${arrow} ${edge.to} ${COLORS.dim}(${edge.type})${COLORS.reset}`);
|
|
73733
|
+
}
|
|
73734
|
+
if (res.edges.length > 20) {
|
|
73735
|
+
print(` ${COLORS.dim}... and ${res.edges.length - 20} more edges${COLORS.reset}`);
|
|
73736
|
+
}
|
|
73737
|
+
}
|
|
73738
|
+
print("");
|
|
73739
|
+
}
|
|
73740
|
+
} catch (error50) {
|
|
73741
|
+
handleError(error50);
|
|
73742
|
+
}
|
|
73743
|
+
});
|
|
73744
|
+
cmd.command("visualize").description("Visualize swarm topology as ASCII art").option("--json", "Output as JSON").action(async (opts) => {
|
|
73745
|
+
if (!requireAuth4()) return;
|
|
73746
|
+
try {
|
|
73747
|
+
const res = await api_client_exports.request("GET", "/swarm/snapshot");
|
|
73748
|
+
if (opts.json) {
|
|
73749
|
+
print(JSON.stringify(res, null, 2));
|
|
73750
|
+
return;
|
|
73751
|
+
}
|
|
73752
|
+
const m = res.metrics;
|
|
73753
|
+
const sym = TOPOLOGY_SYMBOLS[m.topology] || "";
|
|
73754
|
+
print(`
|
|
73755
|
+
${COLORS.bold}${COLORS.cyan}${sym} Swarm Visualization \u2014 ${m.topology}${COLORS.reset}
|
|
73756
|
+
`);
|
|
73757
|
+
const agents = res.agents || [];
|
|
73758
|
+
const queen = agents.find((a) => a.role === "queen");
|
|
73759
|
+
if (m.topology === "hierarchical" || m.topology === "star") {
|
|
73760
|
+
if (queen) {
|
|
73761
|
+
print(` ${COLORS.yellow}\u265B ${queen.id}${COLORS.reset} (queen)`);
|
|
73762
|
+
const children = agents.filter((a) => a.parentId === queen.id);
|
|
73763
|
+
for (let i = 0; i < children.length; i++) {
|
|
73764
|
+
const isLast = i === children.length - 1;
|
|
73765
|
+
const prefix = isLast ? " \u2514\u2500\u2500 " : " \u251C\u2500\u2500 ";
|
|
73766
|
+
const color = STATUS_COLORS[children[i].status] || "";
|
|
73767
|
+
print(`${prefix}${color}\u25CF ${children[i].id}${COLORS.reset} (${children[i].role})`);
|
|
73768
|
+
}
|
|
73769
|
+
}
|
|
73770
|
+
} else if (m.topology === "ring") {
|
|
73771
|
+
for (let i = 0; i < agents.length; i++) {
|
|
73772
|
+
const color = STATUS_COLORS[agents[i].status] || "";
|
|
73773
|
+
const arrow = i < agents.length - 1 ? " \u2192" : ` \u2192 ${agents[0]?.id || ""}`;
|
|
73774
|
+
print(` ${color}\u25CF ${agents[i].id}${COLORS.reset}${arrow}`);
|
|
73775
|
+
}
|
|
73776
|
+
} else {
|
|
73777
|
+
for (const a of agents) {
|
|
73778
|
+
const color = STATUS_COLORS[a.status] || "";
|
|
73779
|
+
print(` ${color}\u25CF${COLORS.reset} ${a.id} (${a.role}) [${a.capabilities.join(", ")}]`);
|
|
73780
|
+
}
|
|
73781
|
+
}
|
|
73782
|
+
print(`
|
|
73783
|
+
${COLORS.dim}Agents: ${m.totalAgents} | Tasks: ${m.totalTasks} | Completed: ${m.completedTasks} | Phase: ${m.phase}${COLORS.reset}
|
|
73784
|
+
`);
|
|
73785
|
+
} catch (error50) {
|
|
73786
|
+
handleError(error50);
|
|
73787
|
+
}
|
|
73788
|
+
});
|
|
73789
|
+
}
|
|
73790
|
+
|
|
73791
|
+
// src/commands/geo.ts
|
|
73792
|
+
init_cjs_shims();
|
|
73793
|
+
init_src2();
|
|
73794
|
+
function requireAuth5() {
|
|
72865
73795
|
if (auth_exports.isAuthenticated()) {
|
|
72866
73796
|
return true;
|
|
72867
73797
|
}
|
|
@@ -72929,7 +73859,7 @@ function printGeoResult(result) {
|
|
|
72929
73859
|
function registerGeoCommand(program3) {
|
|
72930
73860
|
const geo = program3.command("geo").description("GEO-SEO analysis \u2014 optimize for AI search engines");
|
|
72931
73861
|
geo.command("audit <url>").description("Full GEO + SEO audit with parallel subagents").option("--format <format>", "Output format: markdown | json", "markdown").action(async (url2, opts) => {
|
|
72932
|
-
if (!
|
|
73862
|
+
if (!requireAuth5()) return;
|
|
72933
73863
|
const spinner = createSpinner("Running GEO audit...").start();
|
|
72934
73864
|
try {
|
|
72935
73865
|
const result = await api_client_exports.request("POST", "/geo/audit", { url: url2, options: opts });
|
|
@@ -72941,7 +73871,7 @@ function registerGeoCommand(program3) {
|
|
|
72941
73871
|
}
|
|
72942
73872
|
});
|
|
72943
73873
|
geo.command("quick <url>").description("60-second GEO visibility snapshot").action(async (url2) => {
|
|
72944
|
-
if (!
|
|
73874
|
+
if (!requireAuth5()) return;
|
|
72945
73875
|
const spinner = createSpinner("Quick GEO scan...").start();
|
|
72946
73876
|
try {
|
|
72947
73877
|
const result = await api_client_exports.request("POST", "/geo/quick", { url: url2 });
|
|
@@ -72968,7 +73898,7 @@ function registerGeoCommand(program3) {
|
|
|
72968
73898
|
];
|
|
72969
73899
|
for (const sub of subcommands) {
|
|
72970
73900
|
geo.command(`${sub.name} ${sub.arg}`).description(sub.desc).action(async (urlOrDomain) => {
|
|
72971
|
-
if (!
|
|
73901
|
+
if (!requireAuth5()) return;
|
|
72972
73902
|
const spinner = createSpinner(`Running ${sub.name}...`).start();
|
|
72973
73903
|
try {
|
|
72974
73904
|
const body = sub.arg === "<domain>" ? { domain: urlOrDomain } : { url: urlOrDomain };
|
|
@@ -72982,7 +73912,7 @@ function registerGeoCommand(program3) {
|
|
|
72982
73912
|
});
|
|
72983
73913
|
}
|
|
72984
73914
|
geo.command("prospect <action>").description("CRM: manage prospects (new, list, show, audit, note, status, pipeline)").argument("[args...]", "Action-specific arguments").action(async (action, args) => {
|
|
72985
|
-
if (!
|
|
73915
|
+
if (!requireAuth5()) return;
|
|
72986
73916
|
const spinner = createSpinner(`Prospect ${action}...`).start();
|
|
72987
73917
|
try {
|
|
72988
73918
|
const result = await api_client_exports.request("POST", "/geo/prospect", { action, data: args });
|
|
@@ -72994,7 +73924,7 @@ function registerGeoCommand(program3) {
|
|
|
72994
73924
|
}
|
|
72995
73925
|
});
|
|
72996
73926
|
geo.command("schemas [name]").description("List JSON-LD schema templates or view a specific one").action(async (name) => {
|
|
72997
|
-
if (!
|
|
73927
|
+
if (!requireAuth5()) return;
|
|
72998
73928
|
const spinner = createSpinner(name ? `Fetching ${name} schema...` : "Listing schemas...").start();
|
|
72999
73929
|
try {
|
|
73000
73930
|
if (name) {
|
|
@@ -73030,7 +73960,7 @@ function registerGeoCommand(program3) {
|
|
|
73030
73960
|
// src/commands/marketing.ts
|
|
73031
73961
|
init_cjs_shims();
|
|
73032
73962
|
init_src2();
|
|
73033
|
-
function
|
|
73963
|
+
function requireAuth6() {
|
|
73034
73964
|
if (auth_exports.isAuthenticated()) {
|
|
73035
73965
|
return true;
|
|
73036
73966
|
}
|
|
@@ -73176,7 +74106,7 @@ function registerMarketingCommand(program3) {
|
|
|
73176
74106
|
}
|
|
73177
74107
|
}
|
|
73178
74108
|
sub.action(async (...actionArgs) => {
|
|
73179
|
-
if (!
|
|
74109
|
+
if (!requireAuth6()) return;
|
|
73180
74110
|
const body = {};
|
|
73181
74111
|
for (let i = 0; i < cmd.args.length; i++) {
|
|
73182
74112
|
body[cmd.args[i].name] = actionArgs[i];
|
|
@@ -73219,7 +74149,7 @@ function registerMarketingCommand(program3) {
|
|
|
73219
74149
|
});
|
|
73220
74150
|
}
|
|
73221
74151
|
marketing.command("commands").description("List all available marketing commands").action(async () => {
|
|
73222
|
-
if (!
|
|
74152
|
+
if (!requireAuth6()) return;
|
|
73223
74153
|
const spinner = createSpinner("Fetching marketing commands...").start();
|
|
73224
74154
|
try {
|
|
73225
74155
|
const result = await api_client_exports.request("GET", "/marketing/commands");
|
|
@@ -73265,7 +74195,7 @@ function registerMarketingCommand(program3) {
|
|
|
73265
74195
|
// src/commands/sales.ts
|
|
73266
74196
|
init_cjs_shims();
|
|
73267
74197
|
init_src2();
|
|
73268
|
-
function
|
|
74198
|
+
function requireAuth7() {
|
|
73269
74199
|
if (auth_exports.isAuthenticated()) {
|
|
73270
74200
|
return true;
|
|
73271
74201
|
}
|
|
@@ -73386,7 +74316,7 @@ function registerSalesCommand(program3) {
|
|
|
73386
74316
|
}
|
|
73387
74317
|
}
|
|
73388
74318
|
sub.action(async (...actionArgs) => {
|
|
73389
|
-
if (!
|
|
74319
|
+
if (!requireAuth7()) return;
|
|
73390
74320
|
const body = {};
|
|
73391
74321
|
for (let i = 0; i < cmd.args.length; i++) {
|
|
73392
74322
|
body[cmd.args[i].name] = actionArgs[i];
|
|
@@ -73424,7 +74354,7 @@ function registerSalesCommand(program3) {
|
|
|
73424
74354
|
});
|
|
73425
74355
|
}
|
|
73426
74356
|
sales.command("commands").description("List all available sales commands").action(async () => {
|
|
73427
|
-
if (!
|
|
74357
|
+
if (!requireAuth7()) return;
|
|
73428
74358
|
const spinner = createSpinner("Fetching sales commands...").start();
|
|
73429
74359
|
try {
|
|
73430
74360
|
const result = await api_client_exports.request("GET", "/sales/commands");
|
|
@@ -73469,7 +74399,7 @@ function registerSalesCommand(program3) {
|
|
|
73469
74399
|
// src/commands/jobs.ts
|
|
73470
74400
|
init_cjs_shims();
|
|
73471
74401
|
init_src2();
|
|
73472
|
-
function
|
|
74402
|
+
function requireAuth8() {
|
|
73473
74403
|
if (auth_exports.isAuthenticated()) return true;
|
|
73474
74404
|
print.error('Not logged in. Run "bootspring auth login" first.');
|
|
73475
74405
|
process.exitCode = 1;
|
|
@@ -73478,7 +74408,7 @@ function requireAuth7() {
|
|
|
73478
74408
|
function registerJobsCommand(program3) {
|
|
73479
74409
|
const jobs = program3.command("jobs").description("List and poll async job results");
|
|
73480
74410
|
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) => {
|
|
73481
|
-
if (!
|
|
74411
|
+
if (!requireAuth8()) return;
|
|
73482
74412
|
try {
|
|
73483
74413
|
const params = new URLSearchParams();
|
|
73484
74414
|
if (opts.type) params.set("type", opts.type);
|
|
@@ -73505,7 +74435,7 @@ ${COLORS.bold}Recent Jobs${COLORS.reset}
|
|
|
73505
74435
|
}
|
|
73506
74436
|
});
|
|
73507
74437
|
jobs.command("status <jobId>").alias("get").description("Get job status and results").action(async (jobId) => {
|
|
73508
|
-
if (!
|
|
74438
|
+
if (!requireAuth8()) return;
|
|
73509
74439
|
try {
|
|
73510
74440
|
const response = await api_client_exports.request("GET", `/jobs/${encodeURIComponent(jobId)}`);
|
|
73511
74441
|
const job = response.job;
|
|
@@ -77931,6 +78861,7 @@ registerSetupCommand(program2);
|
|
|
77931
78861
|
registerPipelineCommand(program2);
|
|
77932
78862
|
registerWorkflowCommand(program2);
|
|
77933
78863
|
registerHarnessCommand(program2);
|
|
78864
|
+
registerSwarmCommand(program2);
|
|
77934
78865
|
registerGeoCommand(program2);
|
|
77935
78866
|
registerMarketingCommand(program2);
|
|
77936
78867
|
registerSalesCommand(program2);
|