@girardmedia/bootspring 2.5.6 → 2.5.8
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 +17688 -5524
- package/dist/cli-launcher.js +51 -17
- package/dist/core/index.d.ts +153 -172
- package/dist/core.js +3735 -3463
- package/dist/mcp/index.d.ts +168 -1
- package/dist/mcp-server.js +1933 -1541
- package/package.json +1 -1
- package/scripts/postinstall.cjs +159 -2
package/dist/mcp-server.js
CHANGED
|
@@ -33,9 +33,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
33
33
|
));
|
|
34
34
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
35
35
|
|
|
36
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.
|
|
36
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js
|
|
37
37
|
var init_cjs_shims = __esm({
|
|
38
|
-
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.
|
|
38
|
+
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js"() {
|
|
39
39
|
"use strict";
|
|
40
40
|
}
|
|
41
41
|
});
|
|
@@ -17063,9 +17063,9 @@ var require_v4_mini = __commonJS({
|
|
|
17063
17063
|
}
|
|
17064
17064
|
});
|
|
17065
17065
|
|
|
17066
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
17066
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js
|
|
17067
17067
|
var require_zod_compat = __commonJS({
|
|
17068
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
17068
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-compat.js"(exports2) {
|
|
17069
17069
|
"use strict";
|
|
17070
17070
|
init_cjs_shims();
|
|
17071
17071
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -18911,9 +18911,9 @@ var require_v4 = __commonJS({
|
|
|
18911
18911
|
}
|
|
18912
18912
|
});
|
|
18913
18913
|
|
|
18914
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
18914
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/types.js
|
|
18915
18915
|
var require_types2 = __commonJS({
|
|
18916
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
18916
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/types.js"(exports2) {
|
|
18917
18917
|
"use strict";
|
|
18918
18918
|
init_cjs_shims();
|
|
18919
18919
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -18961,10 +18961,9 @@ var require_types2 = __commonJS({
|
|
|
18961
18961
|
exports2.CursorSchema = z.string();
|
|
18962
18962
|
exports2.TaskCreationParamsSchema = z.looseObject({
|
|
18963
18963
|
/**
|
|
18964
|
-
*
|
|
18965
|
-
* If null, the task has unlimited lifetime until manually cleaned up.
|
|
18964
|
+
* Requested duration in milliseconds to retain task from creation.
|
|
18966
18965
|
*/
|
|
18967
|
-
ttl: z.
|
|
18966
|
+
ttl: z.number().optional(),
|
|
18968
18967
|
/**
|
|
18969
18968
|
* Time in milliseconds to wait between task status requests.
|
|
18970
18969
|
*/
|
|
@@ -19272,7 +19271,11 @@ var require_types2 = __commonJS({
|
|
|
19272
19271
|
/**
|
|
19273
19272
|
* Present if the client supports task creation.
|
|
19274
19273
|
*/
|
|
19275
|
-
tasks: exports2.ClientTasksCapabilitySchema.optional()
|
|
19274
|
+
tasks: exports2.ClientTasksCapabilitySchema.optional(),
|
|
19275
|
+
/**
|
|
19276
|
+
* Extensions that the client supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
19277
|
+
*/
|
|
19278
|
+
extensions: z.record(z.string(), AssertObjectSchema).optional()
|
|
19276
19279
|
});
|
|
19277
19280
|
exports2.InitializeRequestParamsSchema = BaseRequestParamsSchema.extend({
|
|
19278
19281
|
/**
|
|
@@ -19335,7 +19338,11 @@ var require_types2 = __commonJS({
|
|
|
19335
19338
|
/**
|
|
19336
19339
|
* Present if the server supports task creation.
|
|
19337
19340
|
*/
|
|
19338
|
-
tasks: exports2.ServerTasksCapabilitySchema.optional()
|
|
19341
|
+
tasks: exports2.ServerTasksCapabilitySchema.optional(),
|
|
19342
|
+
/**
|
|
19343
|
+
* Extensions that the server supports. Keys are extension identifiers (vendor-prefix/extension-name).
|
|
19344
|
+
*/
|
|
19345
|
+
extensions: z.record(z.string(), AssertObjectSchema).optional()
|
|
19339
19346
|
});
|
|
19340
19347
|
exports2.InitializeResultSchema = exports2.ResultSchema.extend({
|
|
19341
19348
|
/**
|
|
@@ -19529,6 +19536,12 @@ var require_types2 = __commonJS({
|
|
|
19529
19536
|
* The MIME type of this resource, if known.
|
|
19530
19537
|
*/
|
|
19531
19538
|
mimeType: z.optional(z.string()),
|
|
19539
|
+
/**
|
|
19540
|
+
* The size of the raw resource content, in bytes (i.e., before base64 encoding or any tokenization), if known.
|
|
19541
|
+
*
|
|
19542
|
+
* This can be used by Hosts to display file sizes and estimate context window usage.
|
|
19543
|
+
*/
|
|
19544
|
+
size: z.optional(z.number()),
|
|
19532
19545
|
/**
|
|
19533
19546
|
* Optional annotations for the client.
|
|
19534
19547
|
*/
|
|
@@ -20486,9 +20499,9 @@ var require_types2 = __commonJS({
|
|
|
20486
20499
|
}
|
|
20487
20500
|
});
|
|
20488
20501
|
|
|
20489
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
20502
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.js
|
|
20490
20503
|
var require_interfaces = __commonJS({
|
|
20491
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
20504
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/interfaces.js"(exports2) {
|
|
20492
20505
|
"use strict";
|
|
20493
20506
|
init_cjs_shims();
|
|
20494
20507
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20499,9 +20512,9 @@ var require_interfaces = __commonJS({
|
|
|
20499
20512
|
}
|
|
20500
20513
|
});
|
|
20501
20514
|
|
|
20502
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20515
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/Options.js
|
|
20503
20516
|
var require_Options = __commonJS({
|
|
20504
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20517
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/Options.js"(exports2) {
|
|
20505
20518
|
"use strict";
|
|
20506
20519
|
init_cjs_shims();
|
|
20507
20520
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20555,9 +20568,9 @@ var require_Options = __commonJS({
|
|
|
20555
20568
|
}
|
|
20556
20569
|
});
|
|
20557
20570
|
|
|
20558
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20571
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/Refs.js
|
|
20559
20572
|
var require_Refs = __commonJS({
|
|
20560
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20573
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/Refs.js"(exports2) {
|
|
20561
20574
|
"use strict";
|
|
20562
20575
|
init_cjs_shims();
|
|
20563
20576
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20586,9 +20599,9 @@ var require_Refs = __commonJS({
|
|
|
20586
20599
|
}
|
|
20587
20600
|
});
|
|
20588
20601
|
|
|
20589
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20602
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/errorMessages.js
|
|
20590
20603
|
var require_errorMessages = __commonJS({
|
|
20591
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20604
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/errorMessages.js"(exports2) {
|
|
20592
20605
|
"use strict";
|
|
20593
20606
|
init_cjs_shims();
|
|
20594
20607
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20612,9 +20625,9 @@ var require_errorMessages = __commonJS({
|
|
|
20612
20625
|
}
|
|
20613
20626
|
});
|
|
20614
20627
|
|
|
20615
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20628
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/getRelativePath.js
|
|
20616
20629
|
var require_getRelativePath = __commonJS({
|
|
20617
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20630
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/getRelativePath.js"(exports2) {
|
|
20618
20631
|
"use strict";
|
|
20619
20632
|
init_cjs_shims();
|
|
20620
20633
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20631,9 +20644,9 @@ var require_getRelativePath = __commonJS({
|
|
|
20631
20644
|
}
|
|
20632
20645
|
});
|
|
20633
20646
|
|
|
20634
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20647
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/any.js
|
|
20635
20648
|
var require_any = __commonJS({
|
|
20636
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20649
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/any.js"(exports2) {
|
|
20637
20650
|
"use strict";
|
|
20638
20651
|
init_cjs_shims();
|
|
20639
20652
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20657,9 +20670,9 @@ var require_any = __commonJS({
|
|
|
20657
20670
|
}
|
|
20658
20671
|
});
|
|
20659
20672
|
|
|
20660
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20673
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/array.js
|
|
20661
20674
|
var require_array = __commonJS({
|
|
20662
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20675
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/array.js"(exports2) {
|
|
20663
20676
|
"use strict";
|
|
20664
20677
|
init_cjs_shims();
|
|
20665
20678
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20693,9 +20706,9 @@ var require_array = __commonJS({
|
|
|
20693
20706
|
}
|
|
20694
20707
|
});
|
|
20695
20708
|
|
|
20696
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20709
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/bigint.js
|
|
20697
20710
|
var require_bigint = __commonJS({
|
|
20698
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20711
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/bigint.js"(exports2) {
|
|
20699
20712
|
"use strict";
|
|
20700
20713
|
init_cjs_shims();
|
|
20701
20714
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20749,9 +20762,9 @@ var require_bigint = __commonJS({
|
|
|
20749
20762
|
}
|
|
20750
20763
|
});
|
|
20751
20764
|
|
|
20752
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20765
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/boolean.js
|
|
20753
20766
|
var require_boolean = __commonJS({
|
|
20754
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20767
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/boolean.js"(exports2) {
|
|
20755
20768
|
"use strict";
|
|
20756
20769
|
init_cjs_shims();
|
|
20757
20770
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20765,9 +20778,9 @@ var require_boolean = __commonJS({
|
|
|
20765
20778
|
}
|
|
20766
20779
|
});
|
|
20767
20780
|
|
|
20768
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20781
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/branded.js
|
|
20769
20782
|
var require_branded = __commonJS({
|
|
20770
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20783
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/branded.js"(exports2) {
|
|
20771
20784
|
"use strict";
|
|
20772
20785
|
init_cjs_shims();
|
|
20773
20786
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20780,9 +20793,9 @@ var require_branded = __commonJS({
|
|
|
20780
20793
|
}
|
|
20781
20794
|
});
|
|
20782
20795
|
|
|
20783
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20796
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/catch.js
|
|
20784
20797
|
var require_catch = __commonJS({
|
|
20785
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20798
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/catch.js"(exports2) {
|
|
20786
20799
|
"use strict";
|
|
20787
20800
|
init_cjs_shims();
|
|
20788
20801
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20795,9 +20808,9 @@ var require_catch = __commonJS({
|
|
|
20795
20808
|
}
|
|
20796
20809
|
});
|
|
20797
20810
|
|
|
20798
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20811
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/date.js
|
|
20799
20812
|
var require_date = __commonJS({
|
|
20800
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20813
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/date.js"(exports2) {
|
|
20801
20814
|
"use strict";
|
|
20802
20815
|
init_cjs_shims();
|
|
20803
20816
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20864,9 +20877,9 @@ var require_date = __commonJS({
|
|
|
20864
20877
|
}
|
|
20865
20878
|
});
|
|
20866
20879
|
|
|
20867
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20880
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/default.js
|
|
20868
20881
|
var require_default = __commonJS({
|
|
20869
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20882
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/default.js"(exports2) {
|
|
20870
20883
|
"use strict";
|
|
20871
20884
|
init_cjs_shims();
|
|
20872
20885
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20882,9 +20895,9 @@ var require_default = __commonJS({
|
|
|
20882
20895
|
}
|
|
20883
20896
|
});
|
|
20884
20897
|
|
|
20885
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20898
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/effects.js
|
|
20886
20899
|
var require_effects = __commonJS({
|
|
20887
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20900
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/effects.js"(exports2) {
|
|
20888
20901
|
"use strict";
|
|
20889
20902
|
init_cjs_shims();
|
|
20890
20903
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20898,9 +20911,9 @@ var require_effects = __commonJS({
|
|
|
20898
20911
|
}
|
|
20899
20912
|
});
|
|
20900
20913
|
|
|
20901
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20914
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/enum.js
|
|
20902
20915
|
var require_enum = __commonJS({
|
|
20903
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20916
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/enum.js"(exports2) {
|
|
20904
20917
|
"use strict";
|
|
20905
20918
|
init_cjs_shims();
|
|
20906
20919
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20915,9 +20928,9 @@ var require_enum = __commonJS({
|
|
|
20915
20928
|
}
|
|
20916
20929
|
});
|
|
20917
20930
|
|
|
20918
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20931
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/intersection.js
|
|
20919
20932
|
var require_intersection = __commonJS({
|
|
20920
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20933
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/intersection.js"(exports2) {
|
|
20921
20934
|
"use strict";
|
|
20922
20935
|
init_cjs_shims();
|
|
20923
20936
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20967,9 +20980,9 @@ var require_intersection = __commonJS({
|
|
|
20967
20980
|
}
|
|
20968
20981
|
});
|
|
20969
20982
|
|
|
20970
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20983
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/literal.js
|
|
20971
20984
|
var require_literal = __commonJS({
|
|
20972
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
20985
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/literal.js"(exports2) {
|
|
20973
20986
|
"use strict";
|
|
20974
20987
|
init_cjs_shims();
|
|
20975
20988
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -20996,9 +21009,9 @@ var require_literal = __commonJS({
|
|
|
20996
21009
|
}
|
|
20997
21010
|
});
|
|
20998
21011
|
|
|
20999
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21012
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/string.js
|
|
21000
21013
|
var require_string = __commonJS({
|
|
21001
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21014
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/string.js"(exports2) {
|
|
21002
21015
|
"use strict";
|
|
21003
21016
|
init_cjs_shims();
|
|
21004
21017
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21331,9 +21344,9 @@ var require_string = __commonJS({
|
|
|
21331
21344
|
}
|
|
21332
21345
|
});
|
|
21333
21346
|
|
|
21334
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21347
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/record.js
|
|
21335
21348
|
var require_record = __commonJS({
|
|
21336
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21349
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/record.js"(exports2) {
|
|
21337
21350
|
"use strict";
|
|
21338
21351
|
init_cjs_shims();
|
|
21339
21352
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21397,9 +21410,9 @@ var require_record = __commonJS({
|
|
|
21397
21410
|
}
|
|
21398
21411
|
});
|
|
21399
21412
|
|
|
21400
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21413
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/map.js
|
|
21401
21414
|
var require_map = __commonJS({
|
|
21402
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21415
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/map.js"(exports2) {
|
|
21403
21416
|
"use strict";
|
|
21404
21417
|
init_cjs_shims();
|
|
21405
21418
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21434,9 +21447,9 @@ var require_map = __commonJS({
|
|
|
21434
21447
|
}
|
|
21435
21448
|
});
|
|
21436
21449
|
|
|
21437
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21450
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/nativeEnum.js
|
|
21438
21451
|
var require_nativeEnum = __commonJS({
|
|
21439
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21452
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/nativeEnum.js"(exports2) {
|
|
21440
21453
|
"use strict";
|
|
21441
21454
|
init_cjs_shims();
|
|
21442
21455
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21457,9 +21470,9 @@ var require_nativeEnum = __commonJS({
|
|
|
21457
21470
|
}
|
|
21458
21471
|
});
|
|
21459
21472
|
|
|
21460
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21473
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/never.js
|
|
21461
21474
|
var require_never = __commonJS({
|
|
21462
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21475
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/never.js"(exports2) {
|
|
21463
21476
|
"use strict";
|
|
21464
21477
|
init_cjs_shims();
|
|
21465
21478
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21477,9 +21490,9 @@ var require_never = __commonJS({
|
|
|
21477
21490
|
}
|
|
21478
21491
|
});
|
|
21479
21492
|
|
|
21480
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21493
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/null.js
|
|
21481
21494
|
var require_null = __commonJS({
|
|
21482
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21495
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/null.js"(exports2) {
|
|
21483
21496
|
"use strict";
|
|
21484
21497
|
init_cjs_shims();
|
|
21485
21498
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21496,9 +21509,9 @@ var require_null = __commonJS({
|
|
|
21496
21509
|
}
|
|
21497
21510
|
});
|
|
21498
21511
|
|
|
21499
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21512
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/union.js
|
|
21500
21513
|
var require_union = __commonJS({
|
|
21501
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21514
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/union.js"(exports2) {
|
|
21502
21515
|
"use strict";
|
|
21503
21516
|
init_cjs_shims();
|
|
21504
21517
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21574,9 +21587,9 @@ var require_union = __commonJS({
|
|
|
21574
21587
|
}
|
|
21575
21588
|
});
|
|
21576
21589
|
|
|
21577
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21590
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/nullable.js
|
|
21578
21591
|
var require_nullable = __commonJS({
|
|
21579
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21592
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/nullable.js"(exports2) {
|
|
21580
21593
|
"use strict";
|
|
21581
21594
|
init_cjs_shims();
|
|
21582
21595
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21617,9 +21630,9 @@ var require_nullable = __commonJS({
|
|
|
21617
21630
|
}
|
|
21618
21631
|
});
|
|
21619
21632
|
|
|
21620
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21633
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/number.js
|
|
21621
21634
|
var require_number = __commonJS({
|
|
21622
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21635
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/number.js"(exports2) {
|
|
21623
21636
|
"use strict";
|
|
21624
21637
|
init_cjs_shims();
|
|
21625
21638
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21676,9 +21689,9 @@ var require_number = __commonJS({
|
|
|
21676
21689
|
}
|
|
21677
21690
|
});
|
|
21678
21691
|
|
|
21679
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21692
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/object.js
|
|
21680
21693
|
var require_object = __commonJS({
|
|
21681
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21694
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/object.js"(exports2) {
|
|
21682
21695
|
"use strict";
|
|
21683
21696
|
init_cjs_shims();
|
|
21684
21697
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21756,9 +21769,9 @@ var require_object = __commonJS({
|
|
|
21756
21769
|
}
|
|
21757
21770
|
});
|
|
21758
21771
|
|
|
21759
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21772
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/optional.js
|
|
21760
21773
|
var require_optional = __commonJS({
|
|
21761
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21774
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/optional.js"(exports2) {
|
|
21762
21775
|
"use strict";
|
|
21763
21776
|
init_cjs_shims();
|
|
21764
21777
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21786,9 +21799,9 @@ var require_optional = __commonJS({
|
|
|
21786
21799
|
}
|
|
21787
21800
|
});
|
|
21788
21801
|
|
|
21789
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21802
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/pipeline.js
|
|
21790
21803
|
var require_pipeline = __commonJS({
|
|
21791
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21804
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/pipeline.js"(exports2) {
|
|
21792
21805
|
"use strict";
|
|
21793
21806
|
init_cjs_shims();
|
|
21794
21807
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21816,9 +21829,9 @@ var require_pipeline = __commonJS({
|
|
|
21816
21829
|
}
|
|
21817
21830
|
});
|
|
21818
21831
|
|
|
21819
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21832
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/promise.js
|
|
21820
21833
|
var require_promise = __commonJS({
|
|
21821
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21834
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/promise.js"(exports2) {
|
|
21822
21835
|
"use strict";
|
|
21823
21836
|
init_cjs_shims();
|
|
21824
21837
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21831,9 +21844,9 @@ var require_promise = __commonJS({
|
|
|
21831
21844
|
}
|
|
21832
21845
|
});
|
|
21833
21846
|
|
|
21834
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21847
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/set.js
|
|
21835
21848
|
var require_set = __commonJS({
|
|
21836
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21849
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/set.js"(exports2) {
|
|
21837
21850
|
"use strict";
|
|
21838
21851
|
init_cjs_shims();
|
|
21839
21852
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21862,9 +21875,9 @@ var require_set = __commonJS({
|
|
|
21862
21875
|
}
|
|
21863
21876
|
});
|
|
21864
21877
|
|
|
21865
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21878
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/tuple.js
|
|
21866
21879
|
var require_tuple = __commonJS({
|
|
21867
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21880
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/tuple.js"(exports2) {
|
|
21868
21881
|
"use strict";
|
|
21869
21882
|
init_cjs_shims();
|
|
21870
21883
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21900,9 +21913,9 @@ var require_tuple = __commonJS({
|
|
|
21900
21913
|
}
|
|
21901
21914
|
});
|
|
21902
21915
|
|
|
21903
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21916
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/undefined.js
|
|
21904
21917
|
var require_undefined = __commonJS({
|
|
21905
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21918
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/undefined.js"(exports2) {
|
|
21906
21919
|
"use strict";
|
|
21907
21920
|
init_cjs_shims();
|
|
21908
21921
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21917,9 +21930,9 @@ var require_undefined = __commonJS({
|
|
|
21917
21930
|
}
|
|
21918
21931
|
});
|
|
21919
21932
|
|
|
21920
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21933
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/unknown.js
|
|
21921
21934
|
var require_unknown = __commonJS({
|
|
21922
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21935
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/unknown.js"(exports2) {
|
|
21923
21936
|
"use strict";
|
|
21924
21937
|
init_cjs_shims();
|
|
21925
21938
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21932,9 +21945,9 @@ var require_unknown = __commonJS({
|
|
|
21932
21945
|
}
|
|
21933
21946
|
});
|
|
21934
21947
|
|
|
21935
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21948
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/readonly.js
|
|
21936
21949
|
var require_readonly = __commonJS({
|
|
21937
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21950
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parsers/readonly.js"(exports2) {
|
|
21938
21951
|
"use strict";
|
|
21939
21952
|
init_cjs_shims();
|
|
21940
21953
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -21947,9 +21960,9 @@ var require_readonly = __commonJS({
|
|
|
21947
21960
|
}
|
|
21948
21961
|
});
|
|
21949
21962
|
|
|
21950
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21963
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/selectParser.js
|
|
21951
21964
|
var require_selectParser = __commonJS({
|
|
21952
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
21965
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/selectParser.js"(exports2) {
|
|
21953
21966
|
"use strict";
|
|
21954
21967
|
init_cjs_shims();
|
|
21955
21968
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -22063,9 +22076,9 @@ var require_selectParser = __commonJS({
|
|
|
22063
22076
|
}
|
|
22064
22077
|
});
|
|
22065
22078
|
|
|
22066
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22079
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parseDef.js
|
|
22067
22080
|
var require_parseDef = __commonJS({
|
|
22068
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22081
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parseDef.js"(exports2) {
|
|
22069
22082
|
"use strict";
|
|
22070
22083
|
init_cjs_shims();
|
|
22071
22084
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -22132,18 +22145,18 @@ var require_parseDef = __commonJS({
|
|
|
22132
22145
|
}
|
|
22133
22146
|
});
|
|
22134
22147
|
|
|
22135
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22148
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parseTypes.js
|
|
22136
22149
|
var require_parseTypes = __commonJS({
|
|
22137
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22150
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/parseTypes.js"(exports2) {
|
|
22138
22151
|
"use strict";
|
|
22139
22152
|
init_cjs_shims();
|
|
22140
22153
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
22141
22154
|
}
|
|
22142
22155
|
});
|
|
22143
22156
|
|
|
22144
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22157
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/zodToJsonSchema.js
|
|
22145
22158
|
var require_zodToJsonSchema = __commonJS({
|
|
22146
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22159
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/zodToJsonSchema.js"(exports2) {
|
|
22147
22160
|
"use strict";
|
|
22148
22161
|
init_cjs_shims();
|
|
22149
22162
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -22215,9 +22228,9 @@ var require_zodToJsonSchema = __commonJS({
|
|
|
22215
22228
|
}
|
|
22216
22229
|
});
|
|
22217
22230
|
|
|
22218
|
-
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22231
|
+
// ../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/index.js
|
|
22219
22232
|
var require_cjs = __commonJS({
|
|
22220
|
-
"../../node_modules/.pnpm/zod-to-json-schema@3.25.
|
|
22233
|
+
"../../node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/cjs/index.js"(exports2) {
|
|
22221
22234
|
"use strict";
|
|
22222
22235
|
init_cjs_shims();
|
|
22223
22236
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -22280,9 +22293,9 @@ var require_cjs = __commonJS({
|
|
|
22280
22293
|
}
|
|
22281
22294
|
});
|
|
22282
22295
|
|
|
22283
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22296
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-json-schema-compat.js
|
|
22284
22297
|
var require_zod_json_schema_compat = __commonJS({
|
|
22285
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22298
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/zod-json-schema-compat.js"(exports2) {
|
|
22286
22299
|
"use strict";
|
|
22287
22300
|
init_cjs_shims();
|
|
22288
22301
|
var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
|
|
@@ -22362,9 +22375,9 @@ var require_zod_json_schema_compat = __commonJS({
|
|
|
22362
22375
|
}
|
|
22363
22376
|
});
|
|
22364
22377
|
|
|
22365
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22378
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js
|
|
22366
22379
|
var require_protocol = __commonJS({
|
|
22367
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
22380
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/protocol.js"(exports2) {
|
|
22368
22381
|
"use strict";
|
|
22369
22382
|
init_cjs_shims();
|
|
22370
22383
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -22585,6 +22598,10 @@ var require_protocol = __commonJS({
|
|
|
22585
22598
|
this._progressHandlers.clear();
|
|
22586
22599
|
this._taskProgressTokens.clear();
|
|
22587
22600
|
this._pendingDebouncedNotifications.clear();
|
|
22601
|
+
for (const info of this._timeoutInfo.values()) {
|
|
22602
|
+
clearTimeout(info.timeoutId);
|
|
22603
|
+
}
|
|
22604
|
+
this._timeoutInfo.clear();
|
|
22588
22605
|
for (const controller of this._requestHandlerAbortControllers.values()) {
|
|
22589
22606
|
controller.abort();
|
|
22590
22607
|
}
|
|
@@ -22715,7 +22732,9 @@ var require_protocol = __commonJS({
|
|
|
22715
22732
|
await capturedTransport?.send(errorResponse);
|
|
22716
22733
|
}
|
|
22717
22734
|
}).catch((error) => this._onerror(new Error(`Failed to send response: ${error}`))).finally(() => {
|
|
22718
|
-
this._requestHandlerAbortControllers.
|
|
22735
|
+
if (this._requestHandlerAbortControllers.get(request.id) === abortController) {
|
|
22736
|
+
this._requestHandlerAbortControllers.delete(request.id);
|
|
22737
|
+
}
|
|
22719
22738
|
});
|
|
22720
22739
|
}
|
|
22721
22740
|
_onprogress(notification) {
|
|
@@ -30162,9 +30181,9 @@ var require_dist = __commonJS({
|
|
|
30162
30181
|
}
|
|
30163
30182
|
});
|
|
30164
30183
|
|
|
30165
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30184
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/validation/ajv-provider.js
|
|
30166
30185
|
var require_ajv_provider = __commonJS({
|
|
30167
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30186
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/validation/ajv-provider.js"(exports2) {
|
|
30168
30187
|
"use strict";
|
|
30169
30188
|
init_cjs_shims();
|
|
30170
30189
|
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
@@ -30242,9 +30261,9 @@ var require_ajv_provider = __commonJS({
|
|
|
30242
30261
|
}
|
|
30243
30262
|
});
|
|
30244
30263
|
|
|
30245
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30264
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/server.js
|
|
30246
30265
|
var require_server = __commonJS({
|
|
30247
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30266
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/server.js"(exports2) {
|
|
30248
30267
|
"use strict";
|
|
30249
30268
|
init_cjs_shims();
|
|
30250
30269
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -30465,9 +30484,9 @@ var require_server = __commonJS({
|
|
|
30465
30484
|
}
|
|
30466
30485
|
});
|
|
30467
30486
|
|
|
30468
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30487
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/helpers.js
|
|
30469
30488
|
var require_helpers = __commonJS({
|
|
30470
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30489
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/experimental/tasks/helpers.js"(exports2) {
|
|
30471
30490
|
"use strict";
|
|
30472
30491
|
init_cjs_shims();
|
|
30473
30492
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -30509,9 +30528,9 @@ var require_helpers = __commonJS({
|
|
|
30509
30528
|
}
|
|
30510
30529
|
});
|
|
30511
30530
|
|
|
30512
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30531
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js
|
|
30513
30532
|
var require_server2 = __commonJS({
|
|
30514
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30533
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/index.js"(exports2) {
|
|
30515
30534
|
"use strict";
|
|
30516
30535
|
init_cjs_shims();
|
|
30517
30536
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -30904,9 +30923,9 @@ var require_server2 = __commonJS({
|
|
|
30904
30923
|
}
|
|
30905
30924
|
});
|
|
30906
30925
|
|
|
30907
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30926
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js
|
|
30908
30927
|
var require_stdio = __commonJS({
|
|
30909
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30928
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/shared/stdio.js"(exports2) {
|
|
30910
30929
|
"use strict";
|
|
30911
30930
|
init_cjs_shims();
|
|
30912
30931
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
@@ -30944,9 +30963,9 @@ var require_stdio = __commonJS({
|
|
|
30944
30963
|
}
|
|
30945
30964
|
});
|
|
30946
30965
|
|
|
30947
|
-
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30966
|
+
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js
|
|
30948
30967
|
var require_stdio2 = __commonJS({
|
|
30949
|
-
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.
|
|
30968
|
+
"../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/cjs/server/stdio.js"(exports2) {
|
|
30950
30969
|
"use strict";
|
|
30951
30970
|
init_cjs_shims();
|
|
30952
30971
|
var __importDefault = exports2 && exports2.__importDefault || function(mod) {
|
|
@@ -31351,7 +31370,7 @@ var init_release = __esm({
|
|
|
31351
31370
|
"../../packages/shared/src/release.ts"() {
|
|
31352
31371
|
"use strict";
|
|
31353
31372
|
init_cjs_shims();
|
|
31354
|
-
BOOTSPRING_VERSION = "2.5.
|
|
31373
|
+
BOOTSPRING_VERSION = "2.5.7";
|
|
31355
31374
|
BOOTSPRING_PACKAGE_NAME = "@girardmedia/bootspring";
|
|
31356
31375
|
}
|
|
31357
31376
|
});
|
|
@@ -47575,7 +47594,7 @@ var require_dist2 = __commonJS({
|
|
|
47575
47594
|
));
|
|
47576
47595
|
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
47577
47596
|
var init_cjs_shims2 = __esm2({
|
|
47578
|
-
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.
|
|
47597
|
+
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.3/node_modules/tsup/assets/cjs_shims.js"() {
|
|
47579
47598
|
"use strict";
|
|
47580
47599
|
}
|
|
47581
47600
|
});
|
|
@@ -47623,33 +47642,69 @@ var require_dist2 = __commonJS({
|
|
|
47623
47642
|
updateTokens: () => updateTokens,
|
|
47624
47643
|
writeNearestProjectConfig: () => writeNearestProjectConfig
|
|
47625
47644
|
});
|
|
47645
|
+
function getOrCreateSalt() {
|
|
47646
|
+
try {
|
|
47647
|
+
if (import_fs2.default.existsSync(SALT_FILE)) {
|
|
47648
|
+
return Buffer.from(import_fs2.default.readFileSync(SALT_FILE, "utf-8").trim(), "hex");
|
|
47649
|
+
}
|
|
47650
|
+
} catch (e) {
|
|
47651
|
+
debug("salt file read failed, regenerating", e);
|
|
47652
|
+
}
|
|
47653
|
+
ensureBootspringDir();
|
|
47654
|
+
const salt = import_crypto.default.randomBytes(32);
|
|
47655
|
+
import_fs2.default.writeFileSync(SALT_FILE, salt.toString("hex"), { mode: 384 });
|
|
47656
|
+
return salt;
|
|
47657
|
+
}
|
|
47658
|
+
function getEncryptionKeyV2() {
|
|
47659
|
+
const salt = getOrCreateSalt();
|
|
47660
|
+
const machineId = generateDeviceFingerprint();
|
|
47661
|
+
return import_crypto.default.scryptSync(machineId, salt, 32);
|
|
47662
|
+
}
|
|
47663
|
+
function getEncryptionKeyV1() {
|
|
47664
|
+
const machineId = import_os.default.hostname() + import_os.default.userInfo().username;
|
|
47665
|
+
return import_crypto.default.createHash("sha256").update(machineId).digest();
|
|
47666
|
+
}
|
|
47626
47667
|
function ensureBootspringDir() {
|
|
47627
47668
|
if (!import_fs2.default.existsSync(BOOTSPRING_DIR)) {
|
|
47628
47669
|
import_fs2.default.mkdirSync(BOOTSPRING_DIR, { recursive: true, mode: 448 });
|
|
47629
47670
|
}
|
|
47630
47671
|
}
|
|
47631
47672
|
function encrypt(data) {
|
|
47632
|
-
const key =
|
|
47673
|
+
const key = getEncryptionKeyV2();
|
|
47633
47674
|
const iv = import_crypto.default.randomBytes(16);
|
|
47634
47675
|
const cipher = import_crypto.default.createCipheriv("aes-256-cbc", key, iv);
|
|
47635
47676
|
let encrypted = cipher.update(JSON.stringify(data), "utf8", "hex");
|
|
47636
47677
|
encrypted += cipher.final("hex");
|
|
47637
|
-
return { iv: iv.toString("hex"), data: encrypted, v:
|
|
47678
|
+
return { iv: iv.toString("hex"), data: encrypted, v: 2 };
|
|
47679
|
+
}
|
|
47680
|
+
function decryptWithKey(blob, key) {
|
|
47681
|
+
const iv = Buffer.from(blob.iv, "hex");
|
|
47682
|
+
const decipher = import_crypto.default.createDecipheriv("aes-256-cbc", key, iv);
|
|
47683
|
+
let decrypted = decipher.update(blob.data, "hex", "utf8");
|
|
47684
|
+
decrypted += decipher.final("utf8");
|
|
47685
|
+
return JSON.parse(decrypted);
|
|
47638
47686
|
}
|
|
47639
47687
|
function decrypt(encrypted) {
|
|
47640
|
-
if (!encrypted || typeof encrypted !== "object"
|
|
47641
|
-
|
|
47688
|
+
if (!encrypted || typeof encrypted !== "object") {
|
|
47689
|
+
throw new Error("Invalid credential format");
|
|
47690
|
+
}
|
|
47691
|
+
const blob = encrypted;
|
|
47692
|
+
if (!blob.iv || !blob.data) {
|
|
47693
|
+
if (blob.token || blob.apiKey) {
|
|
47642
47694
|
console.error("[bootspring] Migrating legacy unencrypted credentials to encrypted storage");
|
|
47643
47695
|
return encrypted;
|
|
47644
47696
|
}
|
|
47645
47697
|
throw new Error("Invalid credential format");
|
|
47646
47698
|
}
|
|
47647
|
-
const
|
|
47648
|
-
|
|
47649
|
-
|
|
47650
|
-
|
|
47651
|
-
|
|
47652
|
-
|
|
47699
|
+
const encBlob = encrypted;
|
|
47700
|
+
if (encBlob.v === 2) {
|
|
47701
|
+
return decryptWithKey(encBlob, getEncryptionKeyV2());
|
|
47702
|
+
}
|
|
47703
|
+
try {
|
|
47704
|
+
return decryptWithKey(encBlob, getEncryptionKeyV2());
|
|
47705
|
+
} catch {
|
|
47706
|
+
return decryptWithKey(encBlob, getEncryptionKeyV1());
|
|
47707
|
+
}
|
|
47653
47708
|
}
|
|
47654
47709
|
function getCredentials() {
|
|
47655
47710
|
if (_credentialCache) return _credentialCache.value;
|
|
@@ -47657,7 +47712,8 @@ var require_dist2 = __commonJS({
|
|
|
47657
47712
|
if (import_fs2.default.existsSync(CREDENTIALS_FILE)) {
|
|
47658
47713
|
const raw = JSON.parse(import_fs2.default.readFileSync(CREDENTIALS_FILE, "utf-8"));
|
|
47659
47714
|
const decrypted = decrypt(raw);
|
|
47660
|
-
|
|
47715
|
+
const needsMigration = raw && typeof raw === "object" && !raw.iv && !raw.data || raw && typeof raw === "object" && raw.iv && raw.v !== 2;
|
|
47716
|
+
if (needsMigration) {
|
|
47661
47717
|
saveCredentials(decrypted);
|
|
47662
47718
|
}
|
|
47663
47719
|
_credentialCache = { resolved: true, value: decrypted };
|
|
@@ -47667,7 +47723,8 @@ var require_dist2 = __commonJS({
|
|
|
47667
47723
|
_credentialDecryptFailed = true;
|
|
47668
47724
|
try {
|
|
47669
47725
|
import_fs2.default.unlinkSync(CREDENTIALS_FILE);
|
|
47670
|
-
} catch {
|
|
47726
|
+
} catch (e) {
|
|
47727
|
+
debug("failed to delete corrupt credentials file", e);
|
|
47671
47728
|
}
|
|
47672
47729
|
}
|
|
47673
47730
|
_credentialCache = { resolved: true, value: null };
|
|
@@ -47699,7 +47756,7 @@ var require_dist2 = __commonJS({
|
|
|
47699
47756
|
if (creds.expiresAt && new Date(creds.expiresAt) < /* @__PURE__ */ new Date()) {
|
|
47700
47757
|
return null;
|
|
47701
47758
|
}
|
|
47702
|
-
return creds.token;
|
|
47759
|
+
return creds.token ?? null;
|
|
47703
47760
|
}
|
|
47704
47761
|
function getTokenExpiryStatus(thresholdMs = 5 * 60 * 1e3) {
|
|
47705
47762
|
const creds = getCredentials();
|
|
@@ -47758,7 +47815,7 @@ var require_dist2 = __commonJS({
|
|
|
47758
47815
|
token: projectAuth.token,
|
|
47759
47816
|
expiresAt: projectAuth.expiresAt,
|
|
47760
47817
|
issuedAt: typeof projectAuth.issuedAt === "string" ? projectAuth.issuedAt : (/* @__PURE__ */ new Date()).toISOString(),
|
|
47761
|
-
source: typeof projectAuth.source === "string" ? projectAuth.source :
|
|
47818
|
+
source: typeof projectAuth.source === "string" ? projectAuth.source : "unknown",
|
|
47762
47819
|
migratedFromLegacyApiKey: Boolean(projectAuth.migratedFromLegacyApiKey)
|
|
47763
47820
|
};
|
|
47764
47821
|
}
|
|
@@ -47791,14 +47848,6 @@ var require_dist2 = __commonJS({
|
|
|
47791
47848
|
if (storedApiKey) return storedApiKey;
|
|
47792
47849
|
const legacyApiKey = getLegacyProjectApiKey();
|
|
47793
47850
|
if (legacyApiKey) {
|
|
47794
|
-
if (_credentialDecryptFailed) {
|
|
47795
|
-
try {
|
|
47796
|
-
saveCredentials({ apiKey: legacyApiKey });
|
|
47797
|
-
_credentialCache = null;
|
|
47798
|
-
_credentialDecryptFailed = false;
|
|
47799
|
-
} catch {
|
|
47800
|
-
}
|
|
47801
|
-
}
|
|
47802
47851
|
return legacyApiKey;
|
|
47803
47852
|
}
|
|
47804
47853
|
return null;
|
|
@@ -47813,7 +47862,9 @@ var require_dist2 = __commonJS({
|
|
|
47813
47862
|
return creds?.refreshToken || null;
|
|
47814
47863
|
}
|
|
47815
47864
|
function isAuthenticated() {
|
|
47816
|
-
|
|
47865
|
+
if (getToken() || getApiKey()) return true;
|
|
47866
|
+
if (getRefreshToken()) return true;
|
|
47867
|
+
return false;
|
|
47817
47868
|
}
|
|
47818
47869
|
function getUser() {
|
|
47819
47870
|
const creds = getCredentials();
|
|
@@ -47944,7 +47995,8 @@ var require_dist2 = __commonJS({
|
|
|
47944
47995
|
if (import_fs2.default.existsSync(CONFIG_FILE)) {
|
|
47945
47996
|
return JSON.parse(import_fs2.default.readFileSync(CONFIG_FILE, "utf-8"));
|
|
47946
47997
|
}
|
|
47947
|
-
} catch {
|
|
47998
|
+
} catch (e) {
|
|
47999
|
+
debug("failed to read config file", e);
|
|
47948
48000
|
}
|
|
47949
48001
|
return {};
|
|
47950
48002
|
}
|
|
@@ -47974,7 +48026,8 @@ var require_dist2 = __commonJS({
|
|
|
47974
48026
|
const stored = JSON.parse(import_fs2.default.readFileSync(DEVICE_FILE, "utf-8"));
|
|
47975
48027
|
if (stored.fingerprint === generateDeviceFingerprint()) return stored;
|
|
47976
48028
|
}
|
|
47977
|
-
} catch {
|
|
48029
|
+
} catch (e) {
|
|
48030
|
+
debug("failed to read device file, regenerating", e);
|
|
47978
48031
|
}
|
|
47979
48032
|
const deviceInfo = {
|
|
47980
48033
|
deviceId: import_crypto.default.randomUUID(),
|
|
@@ -47992,6 +48045,7 @@ var require_dist2 = __commonJS({
|
|
|
47992
48045
|
}
|
|
47993
48046
|
function getDeviceContext(cliVersion = "0.0.0") {
|
|
47994
48047
|
const info = getDeviceInfo();
|
|
48048
|
+
const cwd = process.cwd();
|
|
47995
48049
|
return {
|
|
47996
48050
|
deviceId: info.deviceId,
|
|
47997
48051
|
platform: info.platform,
|
|
@@ -47999,26 +48053,30 @@ var require_dist2 = __commonJS({
|
|
|
47999
48053
|
hostname: info.hostname,
|
|
48000
48054
|
cliVersion,
|
|
48001
48055
|
nodeVersion: process.version,
|
|
48002
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
48056
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
48057
|
+
cwd: import_path2.default.basename(cwd),
|
|
48058
|
+
cwdFull: cwd
|
|
48003
48059
|
};
|
|
48004
48060
|
}
|
|
48005
48061
|
function clearDeviceInfo() {
|
|
48006
48062
|
try {
|
|
48007
48063
|
if (import_fs2.default.existsSync(DEVICE_FILE)) import_fs2.default.unlinkSync(DEVICE_FILE);
|
|
48008
|
-
} catch {
|
|
48064
|
+
} catch (e) {
|
|
48065
|
+
debug("failed to delete device file", e);
|
|
48009
48066
|
}
|
|
48010
48067
|
}
|
|
48011
48068
|
var import_fs2;
|
|
48012
48069
|
var import_path2;
|
|
48013
48070
|
var import_os;
|
|
48014
48071
|
var import_crypto;
|
|
48072
|
+
var debug;
|
|
48015
48073
|
var BOOTSPRING_DIR;
|
|
48016
48074
|
var CREDENTIALS_FILE;
|
|
48017
48075
|
var CONFIG_FILE;
|
|
48018
48076
|
var DEVICE_FILE;
|
|
48077
|
+
var SALT_FILE;
|
|
48019
48078
|
var _credentialCache;
|
|
48020
48079
|
var _credentialDecryptFailed;
|
|
48021
|
-
var getEncryptionKey;
|
|
48022
48080
|
var init_auth = __esm2({
|
|
48023
48081
|
"src/auth.ts"() {
|
|
48024
48082
|
"use strict";
|
|
@@ -48027,16 +48085,15 @@ var require_dist2 = __commonJS({
|
|
|
48027
48085
|
import_path2 = __toESM2(require("path"));
|
|
48028
48086
|
import_os = __toESM2(require("os"));
|
|
48029
48087
|
import_crypto = __toESM2(require("crypto"));
|
|
48088
|
+
debug = process.env.BOOTSPRING_DEBUG ? (...args) => console.debug("[bootspring:auth]", ...args) : () => {
|
|
48089
|
+
};
|
|
48030
48090
|
BOOTSPRING_DIR = import_path2.default.join(import_os.default.homedir(), ".bootspring");
|
|
48031
48091
|
CREDENTIALS_FILE = import_path2.default.join(BOOTSPRING_DIR, "credentials.json");
|
|
48032
48092
|
CONFIG_FILE = import_path2.default.join(BOOTSPRING_DIR, "config.json");
|
|
48033
48093
|
DEVICE_FILE = import_path2.default.join(BOOTSPRING_DIR, "device.json");
|
|
48094
|
+
SALT_FILE = import_path2.default.join(BOOTSPRING_DIR, ".encryption-salt");
|
|
48034
48095
|
_credentialCache = null;
|
|
48035
48096
|
_credentialDecryptFailed = false;
|
|
48036
|
-
getEncryptionKey = () => {
|
|
48037
|
-
const machineId = import_os.default.hostname() + import_os.default.userInfo().username;
|
|
48038
|
-
return import_crypto.default.createHash("sha256").update(machineId).digest();
|
|
48039
|
-
};
|
|
48040
48097
|
}
|
|
48041
48098
|
});
|
|
48042
48099
|
var session_exports = {};
|
|
@@ -48060,7 +48117,8 @@ var require_dist2 = __commonJS({
|
|
|
48060
48117
|
if (import_fs22.default.existsSync(SESSION_FILE)) {
|
|
48061
48118
|
return JSON.parse(import_fs22.default.readFileSync(SESSION_FILE, "utf-8"));
|
|
48062
48119
|
}
|
|
48063
|
-
} catch {
|
|
48120
|
+
} catch (e) {
|
|
48121
|
+
debug2("failed to read session file", e);
|
|
48064
48122
|
}
|
|
48065
48123
|
return null;
|
|
48066
48124
|
}
|
|
@@ -48077,7 +48135,8 @@ var require_dist2 = __commonJS({
|
|
|
48077
48135
|
if (import_fs22.default.existsSync(SESSION_FILE)) {
|
|
48078
48136
|
import_fs22.default.unlinkSync(SESSION_FILE);
|
|
48079
48137
|
}
|
|
48080
|
-
} catch {
|
|
48138
|
+
} catch (e) {
|
|
48139
|
+
debug2("failed to delete session file", e);
|
|
48081
48140
|
}
|
|
48082
48141
|
}
|
|
48083
48142
|
function getCurrentProject() {
|
|
@@ -48156,7 +48215,8 @@ var require_dist2 = __commonJS({
|
|
|
48156
48215
|
try {
|
|
48157
48216
|
const config2 = JSON.parse(import_fs22.default.readFileSync(jsonConfigPath, "utf-8"));
|
|
48158
48217
|
return { ...config2, _path: jsonConfigPath, _dir: dir };
|
|
48159
|
-
} catch {
|
|
48218
|
+
} catch (e) {
|
|
48219
|
+
debug2("failed to parse local config at", jsonConfigPath, e);
|
|
48160
48220
|
}
|
|
48161
48221
|
}
|
|
48162
48222
|
const parent = import_path22.default.dirname(dir);
|
|
@@ -48219,6 +48279,7 @@ var require_dist2 = __commonJS({
|
|
|
48219
48279
|
}
|
|
48220
48280
|
var import_fs22;
|
|
48221
48281
|
var import_path22;
|
|
48282
|
+
var debug2;
|
|
48222
48283
|
var SESSION_FILE;
|
|
48223
48284
|
var LOCAL_CONFIG_NAME;
|
|
48224
48285
|
var PROJECT_SCOPE_MARKERS;
|
|
@@ -48229,6 +48290,8 @@ var require_dist2 = __commonJS({
|
|
|
48229
48290
|
import_fs22 = __toESM2(require("fs"));
|
|
48230
48291
|
import_path22 = __toESM2(require("path"));
|
|
48231
48292
|
init_auth();
|
|
48293
|
+
debug2 = process.env.BOOTSPRING_DEBUG ? (...args) => console.debug("[bootspring:session]", ...args) : () => {
|
|
48294
|
+
};
|
|
48232
48295
|
SESSION_FILE = import_path22.default.join(BOOTSPRING_DIR, "session.json");
|
|
48233
48296
|
LOCAL_CONFIG_NAME = ".bootspring.json";
|
|
48234
48297
|
PROJECT_SCOPE_MARKERS = [
|
|
@@ -48238,292 +48301,927 @@ var require_dist2 = __commonJS({
|
|
|
48238
48301
|
];
|
|
48239
48302
|
}
|
|
48240
48303
|
});
|
|
48241
|
-
var
|
|
48242
|
-
__export2(
|
|
48243
|
-
|
|
48244
|
-
|
|
48245
|
-
|
|
48246
|
-
|
|
48247
|
-
|
|
48248
|
-
|
|
48249
|
-
|
|
48250
|
-
|
|
48251
|
-
|
|
48252
|
-
|
|
48253
|
-
|
|
48254
|
-
|
|
48255
|
-
|
|
48256
|
-
|
|
48257
|
-
|
|
48258
|
-
|
|
48259
|
-
|
|
48260
|
-
|
|
48261
|
-
|
|
48262
|
-
|
|
48263
|
-
|
|
48264
|
-
|
|
48265
|
-
applyUpdate: () => applyUpdate,
|
|
48266
|
-
auth: () => auth_exports,
|
|
48267
|
-
checkForUpdates: () => checkForUpdates,
|
|
48268
|
-
checkInstallation: () => checkInstallation,
|
|
48269
|
-
classifyError: () => classifyError,
|
|
48270
|
-
clearCredentials: () => clearCredentials,
|
|
48271
|
-
clearDeviceInfo: () => clearDeviceInfo,
|
|
48272
|
-
clearProjectApiKey: () => clearProjectApiKey,
|
|
48273
|
-
clearProjectScopedSession: () => clearProjectScopedSession,
|
|
48274
|
-
clearSession: () => clearSession,
|
|
48275
|
-
compareVersions: () => compareVersions,
|
|
48276
|
-
config: () => config_exports,
|
|
48277
|
-
context: () => context_exports,
|
|
48278
|
-
createLocalConfig: () => createLocalConfig,
|
|
48279
|
-
decrypt: () => decrypt,
|
|
48280
|
-
encrypt: () => encrypt,
|
|
48281
|
-
ensureBootspringDir: () => ensureBootspringDir,
|
|
48282
|
-
ensureLatestVersion: () => ensureLatestVersion,
|
|
48283
|
-
entitlements: () => entitlements_exports,
|
|
48284
|
-
findLocalConfig: () => findLocalConfig,
|
|
48285
|
-
findNearestProjectConfigPath: () => findNearestProjectConfigPath,
|
|
48286
|
-
generateDeviceFingerprint: () => generateDeviceFingerprint,
|
|
48287
|
-
getApiKey: () => getApiKey,
|
|
48288
|
-
getCommandFiles: () => getCommandFiles,
|
|
48289
|
-
getConfig: () => getConfig,
|
|
48290
|
-
getCredentials: () => getCredentials,
|
|
48291
|
-
getCredentialsPath: () => getCredentialsPath,
|
|
48292
|
-
getCurrentProject: () => getCurrentProject,
|
|
48293
|
-
getDeviceContext: () => getDeviceContext,
|
|
48294
|
-
getDeviceId: () => getDeviceId,
|
|
48295
|
-
getDeviceInfo: () => getDeviceInfo,
|
|
48296
|
-
getEffectiveProject: () => getEffectiveProject,
|
|
48297
|
-
getInstallContext: () => getInstallContext,
|
|
48298
|
-
getLatestVersion: () => getLatestVersion,
|
|
48299
|
-
getLegacyProjectApiKey: () => getLegacyProjectApiKey,
|
|
48300
|
-
getPolicyProfile: () => getPolicyProfile,
|
|
48301
|
-
getProjectScopedSessionState: () => getProjectScopedSessionState,
|
|
48302
|
-
getProjectScopedToken: () => getProjectScopedToken,
|
|
48303
|
-
getRecentProjects: () => getRecentProjects,
|
|
48304
|
-
getRefreshToken: () => getRefreshToken,
|
|
48305
|
-
getSession: () => getSession,
|
|
48306
|
-
getSessionState: () => getSessionState,
|
|
48307
|
-
getStoredApiKey: () => getStoredApiKey,
|
|
48308
|
-
getTier: () => getTier,
|
|
48309
|
-
getToken: () => getToken,
|
|
48310
|
-
getTokenExpiryStatus: () => getTokenExpiryStatus,
|
|
48311
|
-
getUser: () => getUser,
|
|
48312
|
-
healthCheck: () => healthCheck,
|
|
48313
|
-
installAll: () => installAll,
|
|
48314
|
-
installToTarget: () => installToTarget,
|
|
48315
|
-
isApiKeyAuth: () => isApiKeyAuth,
|
|
48316
|
-
isAuthenticated: () => isAuthenticated,
|
|
48317
|
-
isWorkflowBlocked: () => isWorkflowBlocked,
|
|
48318
|
-
login: () => login,
|
|
48319
|
-
loginWithApiKey: () => loginWithApiKey,
|
|
48320
|
-
logout: () => logout,
|
|
48321
|
-
maybeAutoUploadTelemetry: () => maybeAutoUploadTelemetry,
|
|
48322
|
-
normalizeProfile: () => normalizeProfile,
|
|
48323
|
-
policies: () => policies_exports,
|
|
48324
|
-
pollDeviceToken: () => pollDeviceToken,
|
|
48325
|
-
presence: () => presence_exports,
|
|
48326
|
-
readNearestProjectConfig: () => readNearestProjectConfig,
|
|
48327
|
-
request: () => request,
|
|
48328
|
-
resolvePolicyProfile: () => resolvePolicyProfile,
|
|
48329
|
-
runDiagnostics: () => runDiagnostics,
|
|
48330
|
-
saveApiKeyToProject: () => saveApiKeyToProject,
|
|
48331
|
-
saveConfig: () => saveConfig,
|
|
48332
|
-
saveCredentials: () => saveCredentials,
|
|
48333
|
-
saveProjectScopedSession: () => saveProjectScopedSession,
|
|
48334
|
-
saveSession: () => saveSession,
|
|
48335
|
-
selfHeal: () => self_heal_exports,
|
|
48336
|
-
selfUpdate: () => self_update_exports,
|
|
48337
|
-
sendHealthReport: () => sendHealthReport,
|
|
48338
|
-
sendHeartbeat: () => sendHeartbeat,
|
|
48339
|
-
session: () => session_exports,
|
|
48340
|
-
setAuthFailureHandler: () => setAuthFailureHandler,
|
|
48341
|
-
setCurrentProject: () => setCurrentProject,
|
|
48342
|
-
setupCommands: () => setup_commands_exports,
|
|
48343
|
-
startDeviceFlow: () => startDeviceFlow,
|
|
48344
|
-
stripUnsafeControlChars: () => stripUnsafeControlChars,
|
|
48345
|
-
telemetry: () => telemetry_exports,
|
|
48346
|
-
tierEnforcement: () => tier_enforcement_exports,
|
|
48347
|
-
tryHeal: () => tryHeal,
|
|
48348
|
-
uninstallAll: () => uninstallAll,
|
|
48349
|
-
updateTokens: () => updateTokens,
|
|
48350
|
-
validateNumericId: () => validateNumericId,
|
|
48351
|
-
validateSlug: () => validateSlug,
|
|
48352
|
-
validateStringLength: () => validateStringLength,
|
|
48353
|
-
validateTodoText: () => validateTodoText,
|
|
48354
|
-
writeNearestProjectConfig: () => writeNearestProjectConfig
|
|
48355
|
-
});
|
|
48356
|
-
module2.exports = __toCommonJS2(index_exports);
|
|
48357
|
-
init_cjs_shims2();
|
|
48358
|
-
__reExport(index_exports, (init_src(), __toCommonJS(src_exports)), module2.exports);
|
|
48359
|
-
init_auth();
|
|
48360
|
-
var api_client_exports = {};
|
|
48361
|
-
__export2(api_client_exports, {
|
|
48362
|
-
API_BASE: () => API_BASE,
|
|
48363
|
-
API_VERSION: () => API_VERSION,
|
|
48364
|
-
apiLogin: () => apiLogin,
|
|
48365
|
-
healthCheck: () => healthCheck,
|
|
48366
|
-
pollDeviceToken: () => pollDeviceToken,
|
|
48367
|
-
request: () => request,
|
|
48368
|
-
setAuthFailureHandler: () => setAuthFailureHandler,
|
|
48369
|
-
startDeviceFlow: () => startDeviceFlow
|
|
48304
|
+
var telemetry_exports = {};
|
|
48305
|
+
__export2(telemetry_exports, {
|
|
48306
|
+
ASSISTANTS: () => ASSISTANTS,
|
|
48307
|
+
ASSISTANT_FIRST_SUCCESS_EVENT: () => ASSISTANT_FIRST_SUCCESS_EVENT,
|
|
48308
|
+
ASSISTANT_RETURN_EVENT: () => ASSISTANT_RETURN_EVENT,
|
|
48309
|
+
ASSISTANT_SETUP_EVENT: () => ASSISTANT_SETUP_EVENT,
|
|
48310
|
+
BILLING_UPGRADE_STARTED_EVENT: () => BILLING_UPGRADE_STARTED_EVENT,
|
|
48311
|
+
MAX_EVENTS_LIMIT: () => MAX_EVENTS_LIMIT,
|
|
48312
|
+
UPGRADE_COMPLETED_EVENT: () => UPGRADE_COMPLETED_EVENT,
|
|
48313
|
+
UPGRADE_PROMPT_EVENT: () => UPGRADE_PROMPT_EVENT,
|
|
48314
|
+
clearEvents: () => clearEvents,
|
|
48315
|
+
emitEvent: () => emitEvent,
|
|
48316
|
+
ensureTelemetryDir: () => ensureTelemetryDir,
|
|
48317
|
+
getAssistantActivationFunnel: () => getAssistantActivationFunnel,
|
|
48318
|
+
getStatus: () => getStatus,
|
|
48319
|
+
getTelemetryDir: () => getTelemetryDir,
|
|
48320
|
+
getTelemetryFile: () => getTelemetryFile,
|
|
48321
|
+
getUpgradeConversionFunnel: () => getUpgradeConversionFunnel,
|
|
48322
|
+
inferAssistantFromEnvironment: () => inferAssistantFromEnvironment,
|
|
48323
|
+
listEvents: () => listEvents,
|
|
48324
|
+
track: () => track,
|
|
48325
|
+
trackAssistantSetup: () => trackAssistantSetup,
|
|
48326
|
+
trackAssistantUsageSuccess: () => trackAssistantUsageSuccess,
|
|
48327
|
+
uploadEvents: () => uploadEvents
|
|
48370
48328
|
});
|
|
48371
|
-
|
|
48372
|
-
|
|
48373
|
-
|
|
48374
|
-
|
|
48375
|
-
|
|
48376
|
-
|
|
48377
|
-
|
|
48378
|
-
|
|
48379
|
-
function setAuthFailureHandler(handler) {
|
|
48380
|
-
_onAuthFailure = handler;
|
|
48329
|
+
function normalizeAssistantId(value) {
|
|
48330
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
48331
|
+
if (!normalized) return null;
|
|
48332
|
+
const compact = normalized.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
48333
|
+
if (compact === "claude" || compact === "claude-code") return "claude";
|
|
48334
|
+
if (compact === "codex" || compact === "openai-codex") return "codex";
|
|
48335
|
+
if (compact === "gemini" || compact === "gemini-cli") return "gemini";
|
|
48336
|
+
return null;
|
|
48381
48337
|
}
|
|
48382
|
-
|
|
48383
|
-
|
|
48384
|
-
|
|
48385
|
-
|
|
48386
|
-
if (
|
|
48387
|
-
if (
|
|
48388
|
-
|
|
48389
|
-
const title = titleMatch && titleMatch[1] ? `: ${titleMatch[1].trim()}` : "";
|
|
48390
|
-
return `Bootspring API returned an HTML error page (HTTP ${statusCode || "unknown"}${title})`;
|
|
48391
|
-
}
|
|
48392
|
-
return (0, import_shared.redactSensitiveString)(raw);
|
|
48338
|
+
function inferAssistantFromEnvironment(env = process.env) {
|
|
48339
|
+
const explicit = normalizeAssistantId(env.BOOTSPRING_ASSISTANT);
|
|
48340
|
+
if (explicit) return explicit;
|
|
48341
|
+
if (env.CLAUDE_CODE || env.CLAUDECODE) return "claude";
|
|
48342
|
+
if (env.CODEX_SANDBOX || env.CODEX_ENV || env.OPENAI_CODEX) return "codex";
|
|
48343
|
+
if (env.GEMINI_CLI || env.GOOGLE_GEMINI_CLI) return "gemini";
|
|
48344
|
+
return null;
|
|
48393
48345
|
}
|
|
48394
|
-
|
|
48395
|
-
const
|
|
48396
|
-
|
|
48397
|
-
const apiKey = getApiKey();
|
|
48398
|
-
if (apiKey) return { "X-API-Key": apiKey };
|
|
48399
|
-
return {};
|
|
48346
|
+
function normalizeCardinalityValue(value, fallback = "unknown") {
|
|
48347
|
+
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
48348
|
+
return normalized || fallback;
|
|
48400
48349
|
}
|
|
48401
|
-
function
|
|
48402
|
-
|
|
48403
|
-
|
|
48404
|
-
}
|
|
48405
|
-
for (const [key, value] of Object.entries(data)) {
|
|
48406
|
-
if (value == null) continue;
|
|
48407
|
-
if (Array.isArray(value)) {
|
|
48408
|
-
value.forEach((item) => url.searchParams.append(key, String(item)));
|
|
48409
|
-
continue;
|
|
48410
|
-
}
|
|
48411
|
-
url.searchParams.set(key, String(value));
|
|
48412
|
-
}
|
|
48413
|
-
return url;
|
|
48350
|
+
function normalizeAssistantStatus(value) {
|
|
48351
|
+
const normalized = normalizeCardinalityValue(value, "updated");
|
|
48352
|
+
return ASSISTANT_STATUS_ALLOWLIST.has(normalized) ? normalized : "other";
|
|
48414
48353
|
}
|
|
48415
|
-
|
|
48416
|
-
const
|
|
48417
|
-
|
|
48418
|
-
|
|
48419
|
-
|
|
48420
|
-
|
|
48421
|
-
|
|
48422
|
-
|
|
48423
|
-
|
|
48424
|
-
|
|
48425
|
-
|
|
48354
|
+
function normalizeAssistantSource(value) {
|
|
48355
|
+
const normalized = normalizeCardinalityValue(value, "unknown");
|
|
48356
|
+
return ASSISTANT_SOURCE_ALLOWLIST.has(normalized) ? normalized : "other";
|
|
48357
|
+
}
|
|
48358
|
+
function getTelemetryDir(projectRoot = process.cwd()) {
|
|
48359
|
+
return path4.join(projectRoot, ".bootspring", "telemetry");
|
|
48360
|
+
}
|
|
48361
|
+
function getTelemetryFile(projectRoot = process.cwd()) {
|
|
48362
|
+
return path4.join(getTelemetryDir(projectRoot), "events.jsonl");
|
|
48363
|
+
}
|
|
48364
|
+
function ensureTelemetryDir(projectRoot = process.cwd()) {
|
|
48365
|
+
const dir = getTelemetryDir(projectRoot);
|
|
48366
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
48367
|
+
return dir;
|
|
48368
|
+
}
|
|
48369
|
+
function emitEvent(event, payload = {}, options = {}) {
|
|
48370
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48371
|
+
ensureTelemetryDir(projectRoot);
|
|
48372
|
+
const file = getTelemetryFile(projectRoot);
|
|
48373
|
+
const eventTime = options.now ? new Date(options.now) : /* @__PURE__ */ new Date();
|
|
48374
|
+
const record = {
|
|
48375
|
+
timestamp: eventTime.toISOString(),
|
|
48376
|
+
event: String(event || "").trim(),
|
|
48377
|
+
payload: (0, import_shared2.redactSensitiveData)(payload || {})
|
|
48426
48378
|
};
|
|
48427
|
-
|
|
48428
|
-
|
|
48429
|
-
|
|
48430
|
-
|
|
48379
|
+
fs4.appendFileSync(file, `${JSON.stringify(record)}
|
|
48380
|
+
`, "utf-8");
|
|
48381
|
+
return record;
|
|
48382
|
+
}
|
|
48383
|
+
function getAssistantRecords(assistant, options = {}) {
|
|
48384
|
+
return listEvents({
|
|
48385
|
+
projectRoot: options.projectRoot
|
|
48386
|
+
}).filter((record) => normalizeAssistantId(record?.payload?.assistant) === assistant);
|
|
48387
|
+
}
|
|
48388
|
+
function returnWindow(daysSinceFirst) {
|
|
48389
|
+
if (daysSinceFirst >= 7) return "d7_plus";
|
|
48390
|
+
if (daysSinceFirst >= 2) return "d2_6";
|
|
48391
|
+
if (daysSinceFirst >= 1) return "d1";
|
|
48392
|
+
return "d0";
|
|
48393
|
+
}
|
|
48394
|
+
function eventTimeMs(record) {
|
|
48395
|
+
const occurredAt = String(record?.payload?.occurredAt || "").trim();
|
|
48396
|
+
const source = occurredAt || String(record?.timestamp || "").trim();
|
|
48397
|
+
const ts = new Date(source).getTime();
|
|
48398
|
+
return Number.isFinite(ts) ? ts : null;
|
|
48399
|
+
}
|
|
48400
|
+
function eventTimeIso(record) {
|
|
48401
|
+
const occurredAt = String(record?.payload?.occurredAt || "").trim();
|
|
48402
|
+
if (occurredAt) return occurredAt;
|
|
48403
|
+
const fallback = String(record?.timestamp || "").trim();
|
|
48404
|
+
return fallback || null;
|
|
48405
|
+
}
|
|
48406
|
+
function trackAssistantSetup(assistant, payload = {}, options = {}) {
|
|
48407
|
+
const normalized = normalizeAssistantId(assistant);
|
|
48408
|
+
if (!normalized) {
|
|
48409
|
+
return null;
|
|
48431
48410
|
}
|
|
48432
|
-
return
|
|
48433
|
-
|
|
48434
|
-
|
|
48435
|
-
|
|
48436
|
-
timeout: options.timeout || 3e4
|
|
48437
|
-
}, (res) => {
|
|
48438
|
-
let body = "";
|
|
48439
|
-
res.on("data", (chunk) => body += chunk);
|
|
48440
|
-
res.on("end", () => {
|
|
48441
|
-
try {
|
|
48442
|
-
const json = JSON.parse(body);
|
|
48443
|
-
if (res.statusCode >= 400) {
|
|
48444
|
-
const error = new Error((0, import_shared.redactSensitiveString)(String(json.message || json.error || "API Error")));
|
|
48445
|
-
error.status = res.statusCode;
|
|
48446
|
-
error.code = json.error || json.code;
|
|
48447
|
-
error.details = (0, import_shared.redactSensitiveData)(json.details);
|
|
48448
|
-
reject(error);
|
|
48449
|
-
} else {
|
|
48450
|
-
if (method === "GET" && !options.noCache) {
|
|
48451
|
-
cache.set(`${method}:${url.pathname}${url.search}`, { data: json, time: Date.now() });
|
|
48452
|
-
}
|
|
48453
|
-
resolve3(json);
|
|
48454
|
-
}
|
|
48455
|
-
} catch {
|
|
48456
|
-
if (res.statusCode >= 400) {
|
|
48457
|
-
const error = new Error(formatHttpErrorBody(body, res.statusCode));
|
|
48458
|
-
error.status = res.statusCode;
|
|
48459
|
-
reject(error);
|
|
48460
|
-
} else {
|
|
48461
|
-
resolve3(body);
|
|
48462
|
-
}
|
|
48463
|
-
}
|
|
48464
|
-
});
|
|
48465
|
-
});
|
|
48466
|
-
req.on("error", (err) => {
|
|
48467
|
-
const wrapped = new Error(
|
|
48468
|
-
err.code === "ECONNREFUSED" ? "Cannot connect to Bootspring API." : err.code === "ENOTFOUND" ? "Cannot resolve api.bootspring.com \u2014 check your internet connection." : err.code === "ETIMEDOUT" ? "API request timed out." : err.code === "EHOSTUNREACH" ? "API host unreachable \u2014 check your network." : (0, import_shared.redactSensitiveString)(err.message || String(err))
|
|
48469
|
-
);
|
|
48470
|
-
wrapped.code = err.code;
|
|
48471
|
-
reject(wrapped);
|
|
48472
|
-
});
|
|
48473
|
-
if (data && method !== "GET") req.write(JSON.stringify(data));
|
|
48474
|
-
req.end();
|
|
48475
|
-
});
|
|
48411
|
+
return emitEvent(ASSISTANT_SETUP_EVENT, {
|
|
48412
|
+
assistant: normalized,
|
|
48413
|
+
status: normalizeAssistantStatus(payload.status)
|
|
48414
|
+
}, options);
|
|
48476
48415
|
}
|
|
48477
|
-
|
|
48478
|
-
|
|
48479
|
-
|
|
48480
|
-
|
|
48481
|
-
|
|
48482
|
-
|
|
48483
|
-
|
|
48484
|
-
|
|
48485
|
-
|
|
48416
|
+
function trackAssistantUsageSuccess(assistant, payload = {}, options = {}) {
|
|
48417
|
+
const normalized = normalizeAssistantId(assistant);
|
|
48418
|
+
if (!normalized) {
|
|
48419
|
+
return {
|
|
48420
|
+
assistant: null,
|
|
48421
|
+
firstSuccessTracked: false,
|
|
48422
|
+
returnTracked: false,
|
|
48423
|
+
daysSinceFirst: null
|
|
48424
|
+
};
|
|
48425
|
+
}
|
|
48426
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48427
|
+
const now = options.now ? new Date(options.now) : /* @__PURE__ */ new Date();
|
|
48428
|
+
const records = getAssistantRecords(normalized, { projectRoot });
|
|
48429
|
+
const firstSuccess = records.find((record) => record.event === ASSISTANT_FIRST_SUCCESS_EVENT);
|
|
48430
|
+
if (!firstSuccess) {
|
|
48431
|
+
emitEvent(ASSISTANT_FIRST_SUCCESS_EVENT, {
|
|
48432
|
+
assistant: normalized,
|
|
48433
|
+
source: normalizeAssistantSource(payload.source || "mcp")
|
|
48434
|
+
}, { projectRoot, now });
|
|
48435
|
+
return {
|
|
48436
|
+
assistant: normalized,
|
|
48437
|
+
firstSuccessTracked: true,
|
|
48438
|
+
returnTracked: false,
|
|
48439
|
+
daysSinceFirst: 0
|
|
48440
|
+
};
|
|
48441
|
+
}
|
|
48442
|
+
const firstSuccessAt = eventTimeMs(firstSuccess);
|
|
48443
|
+
const daysSinceFirst = firstSuccessAt !== null ? Math.floor((now.getTime() - firstSuccessAt) / (24 * 60 * 60 * 1e3)) : 0;
|
|
48444
|
+
if (daysSinceFirst >= 1) {
|
|
48445
|
+
const window = returnWindow(daysSinceFirst);
|
|
48446
|
+
const alreadyTrackedWindow = records.some((record) => {
|
|
48447
|
+
if (record.event !== ASSISTANT_RETURN_EVENT) return false;
|
|
48448
|
+
return String(record?.payload?.window || "") === window;
|
|
48449
|
+
});
|
|
48450
|
+
if (!alreadyTrackedWindow) {
|
|
48451
|
+
emitEvent(ASSISTANT_RETURN_EVENT, {
|
|
48452
|
+
assistant: normalized,
|
|
48453
|
+
source: normalizeAssistantSource(payload.source || "mcp"),
|
|
48454
|
+
window
|
|
48455
|
+
}, { projectRoot, now });
|
|
48456
|
+
return {
|
|
48457
|
+
assistant: normalized,
|
|
48458
|
+
firstSuccessTracked: false,
|
|
48459
|
+
returnTracked: true,
|
|
48460
|
+
daysSinceFirst
|
|
48461
|
+
};
|
|
48486
48462
|
}
|
|
48487
|
-
throw err;
|
|
48488
48463
|
}
|
|
48464
|
+
return {
|
|
48465
|
+
assistant: normalized,
|
|
48466
|
+
firstSuccessTracked: false,
|
|
48467
|
+
returnTracked: false,
|
|
48468
|
+
daysSinceFirst
|
|
48469
|
+
};
|
|
48489
48470
|
}
|
|
48490
|
-
|
|
48471
|
+
function parseEventLine(line) {
|
|
48491
48472
|
try {
|
|
48492
|
-
|
|
48493
|
-
return new Promise((resolve3) => {
|
|
48494
|
-
const httpModule = url.protocol === "https:" ? import_https.default : import_http.default;
|
|
48495
|
-
httpModule.get(url, (res) => {
|
|
48496
|
-
let body = "";
|
|
48497
|
-
res.on("data", (chunk) => body += chunk);
|
|
48498
|
-
res.on("end", () => {
|
|
48499
|
-
try {
|
|
48500
|
-
resolve3({ connected: true, ...JSON.parse(body) });
|
|
48501
|
-
} catch {
|
|
48502
|
-
resolve3({ connected: false });
|
|
48503
|
-
}
|
|
48504
|
-
});
|
|
48505
|
-
}).on("error", () => resolve3({ connected: false }));
|
|
48506
|
-
});
|
|
48473
|
+
return JSON.parse(line);
|
|
48507
48474
|
} catch {
|
|
48508
|
-
return
|
|
48475
|
+
return null;
|
|
48509
48476
|
}
|
|
48510
48477
|
}
|
|
48511
|
-
|
|
48512
|
-
const
|
|
48513
|
-
|
|
48514
|
-
return
|
|
48478
|
+
function listEvents(options = {}) {
|
|
48479
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48480
|
+
const file = getTelemetryFile(projectRoot);
|
|
48481
|
+
if (!fs4.existsSync(file)) return [];
|
|
48482
|
+
const eventFilter = String(options.event || "").trim();
|
|
48483
|
+
const from = options.from ? new Date(options.from).getTime() : null;
|
|
48484
|
+
const to = options.to ? new Date(options.to).getTime() : null;
|
|
48485
|
+
const limit = Number(options.limit);
|
|
48486
|
+
const lines = fs4.readFileSync(file, "utf-8").split("\n").filter(Boolean);
|
|
48487
|
+
let records = lines.map(parseEventLine).filter((record) => record !== null).filter((record) => {
|
|
48488
|
+
if (eventFilter && record.event !== eventFilter) return false;
|
|
48489
|
+
const ts = new Date(record.timestamp).getTime();
|
|
48490
|
+
if (Number.isFinite(from) && from !== null && ts < from) return false;
|
|
48491
|
+
if (Number.isFinite(to) && to !== null && ts > to) return false;
|
|
48492
|
+
return true;
|
|
48493
|
+
});
|
|
48494
|
+
const effectiveLimit = Number.isFinite(limit) && limit > 0 ? Math.min(limit, MAX_EVENTS_LIMIT) : MAX_EVENTS_LIMIT;
|
|
48495
|
+
records = records.slice(-effectiveLimit);
|
|
48496
|
+
return records;
|
|
48515
48497
|
}
|
|
48516
|
-
|
|
48517
|
-
|
|
48498
|
+
function clearEvents(options = {}) {
|
|
48499
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48500
|
+
const file = getTelemetryFile(projectRoot);
|
|
48501
|
+
const records = listEvents({ projectRoot });
|
|
48502
|
+
if (fs4.existsSync(file)) {
|
|
48503
|
+
fs4.writeFileSync(file, "", "utf-8");
|
|
48504
|
+
}
|
|
48505
|
+
return {
|
|
48506
|
+
cleared: records.length,
|
|
48507
|
+
file
|
|
48508
|
+
};
|
|
48518
48509
|
}
|
|
48519
|
-
|
|
48520
|
-
|
|
48510
|
+
function getStatus(options = {}) {
|
|
48511
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48512
|
+
const file = getTelemetryFile(projectRoot);
|
|
48513
|
+
const records = listEvents({ projectRoot });
|
|
48514
|
+
const lastRecord = records.length > 0 ? records[records.length - 1] : null;
|
|
48515
|
+
return {
|
|
48516
|
+
file,
|
|
48517
|
+
exists: fs4.existsSync(file),
|
|
48518
|
+
count: records.length,
|
|
48519
|
+
lastEventAt: lastRecord?.timestamp ?? null
|
|
48520
|
+
};
|
|
48521
48521
|
}
|
|
48522
|
-
|
|
48523
|
-
|
|
48524
|
-
|
|
48525
|
-
|
|
48526
|
-
|
|
48522
|
+
function dayDelta(fromIso, toIso) {
|
|
48523
|
+
const from = new Date(String(fromIso || "")).getTime();
|
|
48524
|
+
const to = new Date(String(toIso || "")).getTime();
|
|
48525
|
+
if (!Number.isFinite(from) || !Number.isFinite(to)) {
|
|
48526
|
+
return null;
|
|
48527
|
+
}
|
|
48528
|
+
return Math.floor((to - from) / (24 * 60 * 60 * 1e3));
|
|
48529
|
+
}
|
|
48530
|
+
function summarizeAssistantFunnel(records, assistant) {
|
|
48531
|
+
const filtered = records.filter((record) => normalizeAssistantId(record?.payload?.assistant) === assistant);
|
|
48532
|
+
const setupEvent = filtered.find((record) => record.event === ASSISTANT_SETUP_EVENT) || null;
|
|
48533
|
+
const firstSuccessEvent = filtered.find((record) => record.event === ASSISTANT_FIRST_SUCCESS_EVENT) || null;
|
|
48534
|
+
const returns = filtered.filter((record) => record.event === ASSISTANT_RETURN_EVENT);
|
|
48535
|
+
const d1 = firstSuccessEvent ? returns.some((record) => {
|
|
48536
|
+
const delta = dayDelta(eventTimeIso(firstSuccessEvent), eventTimeIso(record));
|
|
48537
|
+
return delta !== null && delta >= 1;
|
|
48538
|
+
}) : false;
|
|
48539
|
+
const d7 = firstSuccessEvent ? returns.some((record) => {
|
|
48540
|
+
const delta = dayDelta(eventTimeIso(firstSuccessEvent), eventTimeIso(record));
|
|
48541
|
+
return delta !== null && delta >= 7;
|
|
48542
|
+
}) : false;
|
|
48543
|
+
const lastReturn = returns.length > 0 ? returns[returns.length - 1] : null;
|
|
48544
|
+
return {
|
|
48545
|
+
setup: Boolean(setupEvent),
|
|
48546
|
+
firstSuccess: Boolean(firstSuccessEvent),
|
|
48547
|
+
returned: returns.length > 0,
|
|
48548
|
+
d1,
|
|
48549
|
+
d7,
|
|
48550
|
+
setupAt: eventTimeIso(setupEvent),
|
|
48551
|
+
firstSuccessAt: eventTimeIso(firstSuccessEvent),
|
|
48552
|
+
lastReturnAt: eventTimeIso(lastReturn)
|
|
48553
|
+
};
|
|
48554
|
+
}
|
|
48555
|
+
function getAssistantActivationFunnel(options = {}) {
|
|
48556
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48557
|
+
const assistantFilter = normalizeAssistantId(options.assistant);
|
|
48558
|
+
const records = listEvents({
|
|
48559
|
+
projectRoot,
|
|
48560
|
+
from: options.from,
|
|
48561
|
+
to: options.to
|
|
48562
|
+
});
|
|
48563
|
+
const allAssistants = {
|
|
48564
|
+
claude: summarizeAssistantFunnel(records, "claude"),
|
|
48565
|
+
codex: summarizeAssistantFunnel(records, "codex"),
|
|
48566
|
+
gemini: summarizeAssistantFunnel(records, "gemini")
|
|
48567
|
+
};
|
|
48568
|
+
const assistants = assistantFilter ? { [assistantFilter]: allAssistants[assistantFilter] } : allAssistants;
|
|
48569
|
+
const assistantEntries = Object.values(assistants);
|
|
48570
|
+
const totals = assistantEntries.reduce((acc, entry) => {
|
|
48571
|
+
if (entry.setup) acc.setup += 1;
|
|
48572
|
+
if (entry.firstSuccess) acc.firstSuccess += 1;
|
|
48573
|
+
if (entry.returned) acc.return += 1;
|
|
48574
|
+
if (entry.d1) acc.d1 += 1;
|
|
48575
|
+
if (entry.d7) acc.d7 += 1;
|
|
48576
|
+
return acc;
|
|
48577
|
+
}, { setup: 0, firstSuccess: 0, return: 0, d1: 0, d7: 0 });
|
|
48578
|
+
return {
|
|
48579
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48580
|
+
query: {
|
|
48581
|
+
assistant: assistantFilter,
|
|
48582
|
+
from: options.from || null,
|
|
48583
|
+
to: options.to || null
|
|
48584
|
+
},
|
|
48585
|
+
totals,
|
|
48586
|
+
assistants
|
|
48587
|
+
};
|
|
48588
|
+
}
|
|
48589
|
+
function safeRate(numerator, denominator) {
|
|
48590
|
+
if (!denominator) return 0;
|
|
48591
|
+
return Number((numerator / denominator).toFixed(4));
|
|
48592
|
+
}
|
|
48593
|
+
function normalizeDimension(value, fallback) {
|
|
48594
|
+
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
48595
|
+
return normalized || fallback;
|
|
48596
|
+
}
|
|
48597
|
+
function getUpgradeEventContext(payload = {}) {
|
|
48598
|
+
const feature = payload.feature || payload.skillId || payload.workflow || payload.agent || "unknown";
|
|
48599
|
+
return {
|
|
48600
|
+
capability: normalizeDimension(payload.capability, "unknown"),
|
|
48601
|
+
featureType: normalizeDimension(payload.featureType, "general"),
|
|
48602
|
+
feature: normalizeDimension(feature, "unknown"),
|
|
48603
|
+
placement: normalizeDimension(payload.placement, "inline"),
|
|
48604
|
+
variant: normalizeDimension(payload.variant, "control")
|
|
48605
|
+
};
|
|
48606
|
+
}
|
|
48607
|
+
function getUpgradeConversionFunnel(options = {}) {
|
|
48608
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48609
|
+
const records = listEvents({ projectRoot });
|
|
48610
|
+
const capabilities = {};
|
|
48611
|
+
for (const record of records) {
|
|
48612
|
+
if (record.event !== UPGRADE_PROMPT_EVENT && record.event !== BILLING_UPGRADE_STARTED_EVENT && record.event !== UPGRADE_COMPLETED_EVENT) {
|
|
48613
|
+
continue;
|
|
48614
|
+
}
|
|
48615
|
+
const context2 = getUpgradeEventContext(record.payload);
|
|
48616
|
+
const key = `${context2.capability}:${context2.featureType}:${context2.feature}`;
|
|
48617
|
+
if (!capabilities[key]) {
|
|
48618
|
+
capabilities[key] = {
|
|
48619
|
+
capability: context2.capability,
|
|
48620
|
+
featureType: context2.featureType,
|
|
48621
|
+
feature: context2.feature,
|
|
48622
|
+
prompted: 0,
|
|
48623
|
+
started: 0,
|
|
48624
|
+
completed: 0,
|
|
48625
|
+
converted: 0,
|
|
48626
|
+
conversionRate: 0,
|
|
48627
|
+
placements: {},
|
|
48628
|
+
variants: {}
|
|
48629
|
+
};
|
|
48630
|
+
}
|
|
48631
|
+
const bucket = capabilities[key];
|
|
48632
|
+
if (!bucket) continue;
|
|
48633
|
+
if (record.event === UPGRADE_PROMPT_EVENT) {
|
|
48634
|
+
bucket.prompted += 1;
|
|
48635
|
+
bucket.placements[context2.placement] = (bucket.placements[context2.placement] || 0) + 1;
|
|
48636
|
+
bucket.variants[context2.variant] = (bucket.variants[context2.variant] || 0) + 1;
|
|
48637
|
+
continue;
|
|
48638
|
+
}
|
|
48639
|
+
if (record.event === BILLING_UPGRADE_STARTED_EVENT) {
|
|
48640
|
+
bucket.started += 1;
|
|
48641
|
+
continue;
|
|
48642
|
+
}
|
|
48643
|
+
bucket.completed += 1;
|
|
48644
|
+
}
|
|
48645
|
+
const totals = Object.values(capabilities).reduce((acc, bucket) => {
|
|
48646
|
+
bucket.converted = Math.min(bucket.prompted, bucket.completed);
|
|
48647
|
+
bucket.conversionRate = safeRate(bucket.converted, bucket.prompted);
|
|
48648
|
+
acc.prompted += bucket.prompted;
|
|
48649
|
+
acc.started += bucket.started;
|
|
48650
|
+
acc.completed += bucket.completed;
|
|
48651
|
+
acc.converted += bucket.converted;
|
|
48652
|
+
return acc;
|
|
48653
|
+
}, {
|
|
48654
|
+
prompted: 0,
|
|
48655
|
+
started: 0,
|
|
48656
|
+
completed: 0,
|
|
48657
|
+
converted: 0
|
|
48658
|
+
});
|
|
48659
|
+
return {
|
|
48660
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48661
|
+
totals: {
|
|
48662
|
+
...totals,
|
|
48663
|
+
startRate: safeRate(totals.started, totals.prompted),
|
|
48664
|
+
conversionRate: safeRate(totals.converted, totals.prompted)
|
|
48665
|
+
},
|
|
48666
|
+
capabilities
|
|
48667
|
+
};
|
|
48668
|
+
}
|
|
48669
|
+
function sleep(ms) {
|
|
48670
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
48671
|
+
}
|
|
48672
|
+
function chunkArray(items, size) {
|
|
48673
|
+
const chunks = [];
|
|
48674
|
+
for (let i = 0; i < items.length; i += size) {
|
|
48675
|
+
chunks.push(items.slice(i, i + size));
|
|
48676
|
+
}
|
|
48677
|
+
return chunks;
|
|
48678
|
+
}
|
|
48679
|
+
async function postBatchWithRetry(endpoint, body, headers, options = {}) {
|
|
48680
|
+
const maxRetries = Number(options.maxRetries);
|
|
48681
|
+
const retryDelayMs = Number(options.retryDelayMs);
|
|
48682
|
+
const retries = Number.isFinite(maxRetries) && maxRetries >= 0 ? maxRetries : 2;
|
|
48683
|
+
const delayBase = Number.isFinite(retryDelayMs) && retryDelayMs > 0 ? retryDelayMs : 300;
|
|
48684
|
+
let attempt = 0;
|
|
48685
|
+
while (true) {
|
|
48686
|
+
try {
|
|
48687
|
+
const response = await fetch(endpoint, {
|
|
48688
|
+
method: "POST",
|
|
48689
|
+
headers,
|
|
48690
|
+
body: JSON.stringify(body)
|
|
48691
|
+
});
|
|
48692
|
+
if (!response.ok) {
|
|
48693
|
+
throw new Error(`HTTP ${response.status}`);
|
|
48694
|
+
}
|
|
48695
|
+
return { success: true, attempts: attempt + 1 };
|
|
48696
|
+
} catch (error) {
|
|
48697
|
+
if (attempt >= retries) {
|
|
48698
|
+
return {
|
|
48699
|
+
success: false,
|
|
48700
|
+
attempts: attempt + 1,
|
|
48701
|
+
error: (0, import_shared2.redactErrorMessage)(error)
|
|
48702
|
+
};
|
|
48703
|
+
}
|
|
48704
|
+
attempt += 1;
|
|
48705
|
+
const delay = delayBase * 2 ** (attempt - 1);
|
|
48706
|
+
await sleep(delay);
|
|
48707
|
+
}
|
|
48708
|
+
}
|
|
48709
|
+
}
|
|
48710
|
+
async function uploadEvents(options = {}) {
|
|
48711
|
+
const projectRoot = options.projectRoot || process.cwd();
|
|
48712
|
+
const API_BASE2 = process.env.BOOTSPRING_API_URL || "https://api.bootspring.com";
|
|
48713
|
+
const defaultEndpoint = `${API_BASE2}/api/v1/events/batch`;
|
|
48714
|
+
const endpoint = options.endpoint || process.env.BOOTSPRING_TELEMETRY_ENDPOINT || defaultEndpoint;
|
|
48715
|
+
const token = options.token || process.env.BOOTSPRING_TELEMETRY_TOKEN;
|
|
48716
|
+
const event = options.event;
|
|
48717
|
+
const limit = Number(options.limit) || void 0;
|
|
48718
|
+
const batchSizeOption = Number(options.batchSize || process.env.BOOTSPRING_TELEMETRY_BATCH_SIZE);
|
|
48719
|
+
const batchSize = Number.isFinite(batchSizeOption) && batchSizeOption > 0 ? batchSizeOption : 100;
|
|
48720
|
+
const clearOnSuccess = options.clearOnSuccess === true;
|
|
48721
|
+
const records = listEvents({ projectRoot, event, limit });
|
|
48722
|
+
if (records.length === 0) {
|
|
48723
|
+
return {
|
|
48724
|
+
uploaded: 0,
|
|
48725
|
+
remaining: 0,
|
|
48726
|
+
endpoint
|
|
48727
|
+
};
|
|
48728
|
+
}
|
|
48729
|
+
let apiKey = options.apiKey ?? null;
|
|
48730
|
+
let projectId = options.projectId ?? null;
|
|
48731
|
+
if (!apiKey) {
|
|
48732
|
+
try {
|
|
48733
|
+
const auth3 = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
48734
|
+
const session2 = await Promise.resolve().then(() => (init_session(), session_exports));
|
|
48735
|
+
apiKey = auth3.getApiKey();
|
|
48736
|
+
const project = session2.getEffectiveProject();
|
|
48737
|
+
projectId = projectId ?? project?.id ?? null;
|
|
48738
|
+
} catch {
|
|
48739
|
+
}
|
|
48740
|
+
}
|
|
48741
|
+
const version = import_shared2.BOOTSPRING_VERSION || "unknown";
|
|
48742
|
+
const headers = {
|
|
48743
|
+
"content-type": "application/json",
|
|
48744
|
+
accept: "application/json",
|
|
48745
|
+
"user-agent": `bootspring-cli/${version}`
|
|
48746
|
+
};
|
|
48747
|
+
if (apiKey) {
|
|
48748
|
+
headers["x-api-key"] = apiKey;
|
|
48749
|
+
} else if (token) {
|
|
48750
|
+
headers.authorization = `Bearer ${token}`;
|
|
48751
|
+
}
|
|
48752
|
+
if (projectId) {
|
|
48753
|
+
headers["x-project-id"] = projectId;
|
|
48754
|
+
}
|
|
48755
|
+
const batches = chunkArray(records, batchSize);
|
|
48756
|
+
let uploaded = 0;
|
|
48757
|
+
let totalAttempts = 0;
|
|
48758
|
+
const failedBatches = [];
|
|
48759
|
+
for (let i = 0; i < batches.length; i++) {
|
|
48760
|
+
const events = batches[i];
|
|
48761
|
+
if (!events) continue;
|
|
48762
|
+
const batchId = crypto2.createHash("sha1").update(JSON.stringify(events)).digest("hex");
|
|
48763
|
+
const result = await postBatchWithRetry(
|
|
48764
|
+
endpoint,
|
|
48765
|
+
{
|
|
48766
|
+
source: "bootspring",
|
|
48767
|
+
batch: {
|
|
48768
|
+
index: i,
|
|
48769
|
+
total: batches.length,
|
|
48770
|
+
id: batchId
|
|
48771
|
+
},
|
|
48772
|
+
events
|
|
48773
|
+
},
|
|
48774
|
+
{
|
|
48775
|
+
...headers,
|
|
48776
|
+
"x-bootspring-batch-id": batchId
|
|
48777
|
+
},
|
|
48778
|
+
options
|
|
48779
|
+
);
|
|
48780
|
+
totalAttempts += result.attempts ?? 1;
|
|
48781
|
+
if (!result.success) {
|
|
48782
|
+
failedBatches.push({
|
|
48783
|
+
index: i,
|
|
48784
|
+
count: events.length,
|
|
48785
|
+
error: (0, import_shared2.redactErrorMessage)(result.error ?? "upload_failed")
|
|
48786
|
+
});
|
|
48787
|
+
continue;
|
|
48788
|
+
}
|
|
48789
|
+
uploaded += events.length;
|
|
48790
|
+
}
|
|
48791
|
+
if (failedBatches.length > 0) {
|
|
48792
|
+
throw new Error(`Telemetry upload failed for ${failedBatches.length}/${batches.length} batches`);
|
|
48793
|
+
}
|
|
48794
|
+
if (clearOnSuccess) {
|
|
48795
|
+
clearEvents({ projectRoot });
|
|
48796
|
+
}
|
|
48797
|
+
const remaining = clearOnSuccess ? 0 : listEvents({ projectRoot }).length;
|
|
48798
|
+
return {
|
|
48799
|
+
uploaded,
|
|
48800
|
+
attempted: records.length,
|
|
48801
|
+
batches: batches.length,
|
|
48802
|
+
attempts: totalAttempts,
|
|
48803
|
+
remaining,
|
|
48804
|
+
endpoint,
|
|
48805
|
+
failedBatches
|
|
48806
|
+
};
|
|
48807
|
+
}
|
|
48808
|
+
var fs4;
|
|
48809
|
+
var path4;
|
|
48810
|
+
var crypto2;
|
|
48811
|
+
var import_shared2;
|
|
48812
|
+
var MAX_EVENTS_LIMIT;
|
|
48813
|
+
var ASSISTANTS;
|
|
48814
|
+
var ASSISTANT_SETUP_EVENT;
|
|
48815
|
+
var ASSISTANT_FIRST_SUCCESS_EVENT;
|
|
48816
|
+
var ASSISTANT_RETURN_EVENT;
|
|
48817
|
+
var BILLING_UPGRADE_STARTED_EVENT;
|
|
48818
|
+
var UPGRADE_PROMPT_EVENT;
|
|
48819
|
+
var UPGRADE_COMPLETED_EVENT;
|
|
48820
|
+
var ASSISTANT_STATUS_ALLOWLIST;
|
|
48821
|
+
var ASSISTANT_SOURCE_ALLOWLIST;
|
|
48822
|
+
var track;
|
|
48823
|
+
var init_telemetry = __esm2({
|
|
48824
|
+
"src/telemetry.ts"() {
|
|
48825
|
+
"use strict";
|
|
48826
|
+
init_cjs_shims2();
|
|
48827
|
+
fs4 = __toESM2(require("fs"));
|
|
48828
|
+
path4 = __toESM2(require("path"));
|
|
48829
|
+
crypto2 = __toESM2(require("crypto"));
|
|
48830
|
+
import_shared2 = (init_src(), __toCommonJS(src_exports));
|
|
48831
|
+
MAX_EVENTS_LIMIT = 1e4;
|
|
48832
|
+
ASSISTANTS = ["claude", "codex", "gemini"];
|
|
48833
|
+
ASSISTANT_SETUP_EVENT = "assistant_setup";
|
|
48834
|
+
ASSISTANT_FIRST_SUCCESS_EVENT = "assistant_first_success";
|
|
48835
|
+
ASSISTANT_RETURN_EVENT = "assistant_return";
|
|
48836
|
+
BILLING_UPGRADE_STARTED_EVENT = "billing_upgrade_started";
|
|
48837
|
+
UPGRADE_PROMPT_EVENT = "premium_prompted";
|
|
48838
|
+
UPGRADE_COMPLETED_EVENT = "premium_unlocked";
|
|
48839
|
+
ASSISTANT_STATUS_ALLOWLIST = /* @__PURE__ */ new Set(["installed", "updated", "skipped", "failed", "created", "unchanged"]);
|
|
48840
|
+
ASSISTANT_SOURCE_ALLOWLIST = /* @__PURE__ */ new Set(["mcp", "cli", "setup", "dashboard", "api", "unknown"]);
|
|
48841
|
+
track = emitEvent;
|
|
48842
|
+
}
|
|
48843
|
+
});
|
|
48844
|
+
var index_exports = {};
|
|
48845
|
+
__export2(index_exports, {
|
|
48846
|
+
API_BASE: () => API_BASE,
|
|
48847
|
+
API_VERSION: () => API_VERSION,
|
|
48848
|
+
BOOTSPRING_DIR: () => BOOTSPRING_DIR,
|
|
48849
|
+
COMMANDS_SOURCE: () => COMMANDS_SOURCE,
|
|
48850
|
+
CONFIG_FILE: () => CONFIG_FILE,
|
|
48851
|
+
CREDENTIALS_FILE: () => CREDENTIALS_FILE,
|
|
48852
|
+
CURRENT_VERSION: () => CURRENT_VERSION,
|
|
48853
|
+
DEFAULT_INTERVAL_MS: () => DEFAULT_INTERVAL_MS,
|
|
48854
|
+
DEFAULT_POLICY_PROFILE: () => DEFAULT_POLICY_PROFILE,
|
|
48855
|
+
DEVICE_FILE: () => DEVICE_FILE,
|
|
48856
|
+
LIMITS: () => LIMITS,
|
|
48857
|
+
LOCAL_CONFIG_NAME: () => LOCAL_CONFIG_NAME,
|
|
48858
|
+
PACKAGE_NAME: () => PACKAGE_NAME,
|
|
48859
|
+
PATTERNS: () => PATTERNS,
|
|
48860
|
+
POLICY_PROFILES: () => POLICY_PROFILES,
|
|
48861
|
+
SESSION_FILE: () => SESSION_FILE,
|
|
48862
|
+
SHELL_DANGEROUS_CHARS: () => SHELL_DANGEROUS_CHARS,
|
|
48863
|
+
STATE_PATH: () => STATE_PATH,
|
|
48864
|
+
TARGET_DIRS: () => TARGET_DIRS,
|
|
48865
|
+
addRecentProject: () => addRecentProject,
|
|
48866
|
+
api: () => api_client_exports,
|
|
48867
|
+
apiLogin: () => apiLogin,
|
|
48868
|
+
applyUpdate: () => applyUpdate,
|
|
48869
|
+
auth: () => auth_exports,
|
|
48870
|
+
callMcpTool: () => callMcpTool,
|
|
48871
|
+
checkForUpdates: () => checkForUpdates,
|
|
48872
|
+
checkInstallation: () => checkInstallation,
|
|
48873
|
+
classifyError: () => classifyError,
|
|
48874
|
+
clearCredentials: () => clearCredentials,
|
|
48875
|
+
clearDeviceInfo: () => clearDeviceInfo,
|
|
48876
|
+
clearProjectApiKey: () => clearProjectApiKey,
|
|
48877
|
+
clearProjectScopedSession: () => clearProjectScopedSession,
|
|
48878
|
+
clearSession: () => clearSession,
|
|
48879
|
+
compareVersions: () => compareVersions,
|
|
48880
|
+
config: () => config_exports,
|
|
48881
|
+
context: () => context_exports,
|
|
48882
|
+
createLocalConfig: () => createLocalConfig,
|
|
48883
|
+
decrypt: () => decrypt,
|
|
48884
|
+
encrypt: () => encrypt,
|
|
48885
|
+
ensureBootspringDir: () => ensureBootspringDir,
|
|
48886
|
+
ensureLatestVersion: () => ensureLatestVersion,
|
|
48887
|
+
entitlements: () => entitlements_exports,
|
|
48888
|
+
findLocalConfig: () => findLocalConfig,
|
|
48889
|
+
findNearestProjectConfigPath: () => findNearestProjectConfigPath,
|
|
48890
|
+
generateDeviceFingerprint: () => generateDeviceFingerprint,
|
|
48891
|
+
getApiKey: () => getApiKey,
|
|
48892
|
+
getCommandFiles: () => getCommandFiles,
|
|
48893
|
+
getConfig: () => getConfig,
|
|
48894
|
+
getCredentials: () => getCredentials,
|
|
48895
|
+
getCredentialsPath: () => getCredentialsPath,
|
|
48896
|
+
getCurrentProject: () => getCurrentProject,
|
|
48897
|
+
getDeviceContext: () => getDeviceContext,
|
|
48898
|
+
getDeviceId: () => getDeviceId,
|
|
48899
|
+
getDeviceInfo: () => getDeviceInfo,
|
|
48900
|
+
getEffectiveProject: () => getEffectiveProject,
|
|
48901
|
+
getInstallContext: () => getInstallContext,
|
|
48902
|
+
getLatestVersion: () => getLatestVersion,
|
|
48903
|
+
getLegacyProjectApiKey: () => getLegacyProjectApiKey,
|
|
48904
|
+
getMcpResource: () => getMcpResource,
|
|
48905
|
+
getPolicyProfile: () => getPolicyProfile,
|
|
48906
|
+
getProjectScopedSessionState: () => getProjectScopedSessionState,
|
|
48907
|
+
getProjectScopedToken: () => getProjectScopedToken,
|
|
48908
|
+
getRecentProjects: () => getRecentProjects,
|
|
48909
|
+
getRefreshToken: () => getRefreshToken,
|
|
48910
|
+
getSession: () => getSession,
|
|
48911
|
+
getSessionState: () => getSessionState,
|
|
48912
|
+
getStoredApiKey: () => getStoredApiKey,
|
|
48913
|
+
getTier: () => getTier,
|
|
48914
|
+
getToken: () => getToken,
|
|
48915
|
+
getTokenExpiryStatus: () => getTokenExpiryStatus,
|
|
48916
|
+
getUser: () => getUser,
|
|
48917
|
+
healthCheck: () => healthCheck,
|
|
48918
|
+
installAll: () => installAll,
|
|
48919
|
+
installToTarget: () => installToTarget,
|
|
48920
|
+
isApiKeyAuth: () => isApiKeyAuth,
|
|
48921
|
+
isAuthenticated: () => isAuthenticated,
|
|
48922
|
+
isWorkflowBlocked: () => isWorkflowBlocked,
|
|
48923
|
+
listMcpResources: () => listMcpResources,
|
|
48924
|
+
listMcpTools: () => listMcpTools,
|
|
48925
|
+
login: () => login,
|
|
48926
|
+
loginWithApiKey: () => loginWithApiKey,
|
|
48927
|
+
logout: () => logout,
|
|
48928
|
+
maybeAutoUploadTelemetry: () => maybeAutoUploadTelemetry,
|
|
48929
|
+
normalizeProfile: () => normalizeProfile,
|
|
48930
|
+
policies: () => policies_exports,
|
|
48931
|
+
pollDeviceToken: () => pollDeviceToken,
|
|
48932
|
+
presence: () => presence_exports,
|
|
48933
|
+
readNearestProjectConfig: () => readNearestProjectConfig,
|
|
48934
|
+
refreshSession: () => refreshSession,
|
|
48935
|
+
remoteLogout: () => remoteLogout,
|
|
48936
|
+
request: () => request,
|
|
48937
|
+
resolvePolicyProfile: () => resolvePolicyProfile,
|
|
48938
|
+
runDiagnostics: () => runDiagnostics,
|
|
48939
|
+
saveApiKeyToProject: () => saveApiKeyToProject,
|
|
48940
|
+
saveConfig: () => saveConfig,
|
|
48941
|
+
saveCredentials: () => saveCredentials,
|
|
48942
|
+
saveProjectScopedSession: () => saveProjectScopedSession,
|
|
48943
|
+
saveSession: () => saveSession,
|
|
48944
|
+
selfHeal: () => self_heal_exports,
|
|
48945
|
+
selfUpdate: () => self_update_exports,
|
|
48946
|
+
sendHealthReport: () => sendHealthReport,
|
|
48947
|
+
sendHeartbeat: () => sendHeartbeat,
|
|
48948
|
+
session: () => session_exports,
|
|
48949
|
+
setAuthFailureHandler: () => setAuthFailureHandler,
|
|
48950
|
+
setCurrentProject: () => setCurrentProject,
|
|
48951
|
+
setupCommands: () => setup_commands_exports,
|
|
48952
|
+
startDeviceFlow: () => startDeviceFlow,
|
|
48953
|
+
stripUnsafeControlChars: () => stripUnsafeControlChars,
|
|
48954
|
+
telemetry: () => telemetry_exports,
|
|
48955
|
+
tierEnforcement: () => tier_enforcement_exports,
|
|
48956
|
+
tryHeal: () => tryHeal,
|
|
48957
|
+
uninstallAll: () => uninstallAll,
|
|
48958
|
+
updateTokens: () => updateTokens,
|
|
48959
|
+
validateNumericId: () => validateNumericId,
|
|
48960
|
+
validateSlug: () => validateSlug,
|
|
48961
|
+
validateStringLength: () => validateStringLength,
|
|
48962
|
+
validateTodoText: () => validateTodoText,
|
|
48963
|
+
writeNearestProjectConfig: () => writeNearestProjectConfig
|
|
48964
|
+
});
|
|
48965
|
+
module2.exports = __toCommonJS2(index_exports);
|
|
48966
|
+
init_cjs_shims2();
|
|
48967
|
+
__reExport(index_exports, (init_src(), __toCommonJS(src_exports)), module2.exports);
|
|
48968
|
+
init_auth();
|
|
48969
|
+
var api_client_exports = {};
|
|
48970
|
+
__export2(api_client_exports, {
|
|
48971
|
+
API_BASE: () => API_BASE,
|
|
48972
|
+
API_VERSION: () => API_VERSION,
|
|
48973
|
+
apiLogin: () => apiLogin,
|
|
48974
|
+
callMcpTool: () => callMcpTool,
|
|
48975
|
+
getMcpResource: () => getMcpResource,
|
|
48976
|
+
healthCheck: () => healthCheck,
|
|
48977
|
+
listMcpResources: () => listMcpResources,
|
|
48978
|
+
listMcpTools: () => listMcpTools,
|
|
48979
|
+
pollDeviceToken: () => pollDeviceToken,
|
|
48980
|
+
refreshSession: () => refreshSession,
|
|
48981
|
+
remoteLogout: () => remoteLogout,
|
|
48982
|
+
request: () => request,
|
|
48983
|
+
setAuthFailureHandler: () => setAuthFailureHandler,
|
|
48984
|
+
startDeviceFlow: () => startDeviceFlow
|
|
48985
|
+
});
|
|
48986
|
+
init_cjs_shims2();
|
|
48987
|
+
var import_https = __toESM2(require("https"));
|
|
48988
|
+
var import_http = __toESM2(require("http"));
|
|
48989
|
+
init_auth();
|
|
48990
|
+
var import_shared = (init_src(), __toCommonJS(src_exports));
|
|
48991
|
+
var API_BASE = process.env["BOOTSPRING_API_URL"] || "https://api.bootspring.com";
|
|
48992
|
+
var API_VERSION = "v1";
|
|
48993
|
+
var _onAuthFailure = null;
|
|
48994
|
+
function setAuthFailureHandler(handler) {
|
|
48995
|
+
_onAuthFailure = handler;
|
|
48996
|
+
}
|
|
48997
|
+
var cache = /* @__PURE__ */ new Map();
|
|
48998
|
+
var CACHE_TTL = 6e4;
|
|
48999
|
+
function formatHttpErrorBody(body, statusCode) {
|
|
49000
|
+
const raw = String(body || "").trim();
|
|
49001
|
+
if (!raw) return `API Error (${statusCode || "unknown"})`;
|
|
49002
|
+
if (/^\s*<!doctype html/i.test(raw) || /^\s*<html/i.test(raw)) {
|
|
49003
|
+
const titleMatch = raw.match(/<title[^>]*>([^<]+)<\/title>/i);
|
|
49004
|
+
const title = titleMatch && titleMatch[1] ? `: ${titleMatch[1].trim()}` : "";
|
|
49005
|
+
return `Bootspring API returned an HTML error page (HTTP ${statusCode || "unknown"}${title})`;
|
|
49006
|
+
}
|
|
49007
|
+
return (0, import_shared.redactSensitiveString)(raw);
|
|
49008
|
+
}
|
|
49009
|
+
var _refreshPromise = null;
|
|
49010
|
+
async function tryAutoRefresh() {
|
|
49011
|
+
const refreshToken = getRefreshToken();
|
|
49012
|
+
if (!refreshToken) return null;
|
|
49013
|
+
if (_refreshPromise) return _refreshPromise;
|
|
49014
|
+
_refreshPromise = (async () => {
|
|
49015
|
+
try {
|
|
49016
|
+
const url = new URL(`/api/${API_VERSION}/auth/refresh`, API_BASE);
|
|
49017
|
+
const isHttps = url.protocol === "https:";
|
|
49018
|
+
const httpModule = isHttps ? import_https.default : import_http.default;
|
|
49019
|
+
const body = JSON.stringify({ refreshToken, device: getDeviceContext() });
|
|
49020
|
+
const response = await new Promise((resolve3, reject) => {
|
|
49021
|
+
const req = httpModule.request(url, {
|
|
49022
|
+
method: "POST",
|
|
49023
|
+
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) },
|
|
49024
|
+
timeout: 1e4
|
|
49025
|
+
}, (res) => {
|
|
49026
|
+
let data = "";
|
|
49027
|
+
res.on("data", (chunk) => data += chunk);
|
|
49028
|
+
res.on("end", () => {
|
|
49029
|
+
try {
|
|
49030
|
+
const json = JSON.parse(data);
|
|
49031
|
+
if ((res.statusCode || 500) >= 400) {
|
|
49032
|
+
reject(new Error(json.error || "refresh failed"));
|
|
49033
|
+
return;
|
|
49034
|
+
}
|
|
49035
|
+
resolve3(json);
|
|
49036
|
+
} catch (e) {
|
|
49037
|
+
reject(e);
|
|
49038
|
+
}
|
|
49039
|
+
});
|
|
49040
|
+
});
|
|
49041
|
+
req.on("error", reject);
|
|
49042
|
+
req.on("timeout", () => req.destroy(new Error("refresh timeout")));
|
|
49043
|
+
req.write(body);
|
|
49044
|
+
req.end();
|
|
49045
|
+
});
|
|
49046
|
+
login(response);
|
|
49047
|
+
return response.token || null;
|
|
49048
|
+
} catch {
|
|
49049
|
+
return null;
|
|
49050
|
+
} finally {
|
|
49051
|
+
_refreshPromise = null;
|
|
49052
|
+
}
|
|
49053
|
+
})();
|
|
49054
|
+
return _refreshPromise;
|
|
49055
|
+
}
|
|
49056
|
+
async function resolveAuthHeaders() {
|
|
49057
|
+
let token = getToken();
|
|
49058
|
+
if (!token) {
|
|
49059
|
+
const creds = getCredentials();
|
|
49060
|
+
if (creds?.refreshToken && creds?.expiresAt) {
|
|
49061
|
+
token = await tryAutoRefresh();
|
|
49062
|
+
}
|
|
49063
|
+
}
|
|
49064
|
+
if (token) return { "Authorization": `Bearer ${token}` };
|
|
49065
|
+
const apiKey = getApiKey();
|
|
49066
|
+
if (apiKey) return { "X-API-Key": apiKey };
|
|
49067
|
+
return {};
|
|
49068
|
+
}
|
|
49069
|
+
function appendQueryParams(url, data) {
|
|
49070
|
+
if (!data || typeof data !== "object") {
|
|
49071
|
+
return url;
|
|
49072
|
+
}
|
|
49073
|
+
for (const [key, value] of Object.entries(data)) {
|
|
49074
|
+
if (value == null) continue;
|
|
49075
|
+
if (Array.isArray(value)) {
|
|
49076
|
+
value.forEach((item) => url.searchParams.append(key, String(item)));
|
|
49077
|
+
continue;
|
|
49078
|
+
}
|
|
49079
|
+
url.searchParams.set(key, String(value));
|
|
49080
|
+
}
|
|
49081
|
+
return url;
|
|
49082
|
+
}
|
|
49083
|
+
async function rawRequest(method, path10, data, options) {
|
|
49084
|
+
const authHeaders = await resolveAuthHeaders();
|
|
49085
|
+
const url = appendQueryParams(new URL(`/api/${API_VERSION}${path10}`, API_BASE), method === "GET" ? data : null);
|
|
49086
|
+
const isHttps = url.protocol === "https:";
|
|
49087
|
+
const httpModule = isHttps ? import_https.default : import_http.default;
|
|
49088
|
+
const headers = {
|
|
49089
|
+
"Content-Type": "application/json",
|
|
49090
|
+
"User-Agent": "bootspring-core",
|
|
49091
|
+
"X-Device-Id": getDeviceId(),
|
|
49092
|
+
...authHeaders,
|
|
49093
|
+
...options.headers
|
|
49094
|
+
};
|
|
49095
|
+
if (method === "GET" && !options.noCache) {
|
|
49096
|
+
const cacheKey = `${method}:${url.pathname}${url.search}`;
|
|
49097
|
+
const cached = cache.get(cacheKey);
|
|
49098
|
+
if (cached && Date.now() - cached.time < CACHE_TTL) return cached.data;
|
|
49099
|
+
}
|
|
49100
|
+
return new Promise((resolve3, reject) => {
|
|
49101
|
+
const req = httpModule.request(url, {
|
|
49102
|
+
method,
|
|
49103
|
+
headers,
|
|
49104
|
+
timeout: options.timeout || 3e4
|
|
49105
|
+
}, (res) => {
|
|
49106
|
+
let body = "";
|
|
49107
|
+
res.on("data", (chunk) => body += chunk);
|
|
49108
|
+
res.on("end", () => {
|
|
49109
|
+
try {
|
|
49110
|
+
const json = JSON.parse(body);
|
|
49111
|
+
if (res.statusCode >= 400) {
|
|
49112
|
+
const error = new Error((0, import_shared.redactSensitiveString)(String(json.message || json.error || "API Error")));
|
|
49113
|
+
error.status = res.statusCode;
|
|
49114
|
+
error.code = json.error || json.code;
|
|
49115
|
+
error.details = (0, import_shared.redactSensitiveData)(json.details);
|
|
49116
|
+
reject(error);
|
|
49117
|
+
} else {
|
|
49118
|
+
if (method === "GET" && !options.noCache) {
|
|
49119
|
+
cache.set(`${method}:${url.pathname}${url.search}`, { data: json, time: Date.now() });
|
|
49120
|
+
}
|
|
49121
|
+
resolve3(json);
|
|
49122
|
+
}
|
|
49123
|
+
} catch {
|
|
49124
|
+
if (res.statusCode >= 400) {
|
|
49125
|
+
const error = new Error(formatHttpErrorBody(body, res.statusCode));
|
|
49126
|
+
error.status = res.statusCode;
|
|
49127
|
+
reject(error);
|
|
49128
|
+
} else {
|
|
49129
|
+
resolve3(body);
|
|
49130
|
+
}
|
|
49131
|
+
}
|
|
49132
|
+
});
|
|
49133
|
+
});
|
|
49134
|
+
req.on("error", (err) => {
|
|
49135
|
+
const wrapped = new Error(
|
|
49136
|
+
err.code === "ECONNREFUSED" ? "Cannot connect to Bootspring API." : err.code === "ENOTFOUND" ? "Cannot resolve api.bootspring.com \u2014 check your internet connection." : err.code === "ETIMEDOUT" ? "API request timed out." : err.code === "EHOSTUNREACH" ? "API host unreachable \u2014 check your network." : (0, import_shared.redactSensitiveString)(err.message || String(err))
|
|
49137
|
+
);
|
|
49138
|
+
wrapped.code = err.code;
|
|
49139
|
+
reject(wrapped);
|
|
49140
|
+
});
|
|
49141
|
+
if (data && method !== "GET") req.write(JSON.stringify(data));
|
|
49142
|
+
req.end();
|
|
49143
|
+
});
|
|
49144
|
+
}
|
|
49145
|
+
async function request(method, path10, data = null, options = {}) {
|
|
49146
|
+
try {
|
|
49147
|
+
return await rawRequest(method, path10, data, options);
|
|
49148
|
+
} catch (err) {
|
|
49149
|
+
if (err.status === 401 && _onAuthFailure && !options._authRetried) {
|
|
49150
|
+
const reauthOk = await _onAuthFailure();
|
|
49151
|
+
if (reauthOk) {
|
|
49152
|
+
return rawRequest(method, path10, data, { ...options, _authRetried: true, noCache: true });
|
|
49153
|
+
}
|
|
49154
|
+
}
|
|
49155
|
+
throw err;
|
|
49156
|
+
}
|
|
49157
|
+
}
|
|
49158
|
+
async function healthCheck() {
|
|
49159
|
+
try {
|
|
49160
|
+
const url = new URL("/health", API_BASE);
|
|
49161
|
+
return new Promise((resolve3) => {
|
|
49162
|
+
const httpModule = url.protocol === "https:" ? import_https.default : import_http.default;
|
|
49163
|
+
httpModule.get(url, (res) => {
|
|
49164
|
+
let body = "";
|
|
49165
|
+
res.on("data", (chunk) => body += chunk);
|
|
49166
|
+
res.on("end", () => {
|
|
49167
|
+
try {
|
|
49168
|
+
resolve3({ connected: true, ...JSON.parse(body) });
|
|
49169
|
+
} catch {
|
|
49170
|
+
resolve3({ connected: false });
|
|
49171
|
+
}
|
|
49172
|
+
});
|
|
49173
|
+
}).on("error", () => resolve3({ connected: false }));
|
|
49174
|
+
});
|
|
49175
|
+
} catch {
|
|
49176
|
+
return { connected: false };
|
|
49177
|
+
}
|
|
49178
|
+
}
|
|
49179
|
+
async function apiLogin(email, password) {
|
|
49180
|
+
const response = await request("POST", "/auth/login", { email, password, device: getDeviceContext() });
|
|
49181
|
+
login(response);
|
|
49182
|
+
return response;
|
|
49183
|
+
}
|
|
49184
|
+
async function startDeviceFlow() {
|
|
49185
|
+
return request("POST", "/auth/device", { device: getDeviceContext() }, { noCache: true });
|
|
49186
|
+
}
|
|
49187
|
+
async function pollDeviceToken(deviceCode) {
|
|
49188
|
+
return request("POST", "/auth/device/token", { device_code: deviceCode }, { noCache: true });
|
|
49189
|
+
}
|
|
49190
|
+
async function refreshSession() {
|
|
49191
|
+
const refreshToken = getRefreshToken();
|
|
49192
|
+
if (!refreshToken) {
|
|
49193
|
+
throw Object.assign(new Error("No refresh token available"), { code: "NO_REFRESH_TOKEN" });
|
|
49194
|
+
}
|
|
49195
|
+
const response = await request("POST", "/auth/refresh", { refreshToken, device: getDeviceContext() }, { noCache: true });
|
|
49196
|
+
login(response);
|
|
49197
|
+
return response;
|
|
49198
|
+
}
|
|
49199
|
+
async function remoteLogout() {
|
|
49200
|
+
const refreshToken = getRefreshToken();
|
|
49201
|
+
try {
|
|
49202
|
+
const response = await request("POST", "/auth/logout", { refreshToken }, { noCache: true });
|
|
49203
|
+
return response;
|
|
49204
|
+
} finally {
|
|
49205
|
+
logout();
|
|
49206
|
+
}
|
|
49207
|
+
}
|
|
49208
|
+
async function listMcpTools() {
|
|
49209
|
+
return request("GET", "/mcp/tools");
|
|
49210
|
+
}
|
|
49211
|
+
async function callMcpTool(tool, args) {
|
|
49212
|
+
return request("POST", "/mcp/tool", { tool, arguments: args });
|
|
49213
|
+
}
|
|
49214
|
+
async function listMcpResources() {
|
|
49215
|
+
return request("GET", "/mcp/resources");
|
|
49216
|
+
}
|
|
49217
|
+
async function getMcpResource(uri) {
|
|
49218
|
+
return request("GET", `/mcp/resources/${encodeURIComponent(uri)}`);
|
|
49219
|
+
}
|
|
49220
|
+
var policies_exports = {};
|
|
49221
|
+
__export2(policies_exports, {
|
|
49222
|
+
DEFAULT_POLICY_PROFILE: () => DEFAULT_POLICY_PROFILE,
|
|
49223
|
+
POLICY_PROFILES: () => POLICY_PROFILES,
|
|
49224
|
+
getPolicyProfile: () => getPolicyProfile,
|
|
48527
49225
|
isWorkflowBlocked: () => isWorkflowBlocked,
|
|
48528
49226
|
normalizeProfile: () => normalizeProfile,
|
|
48529
49227
|
resolvePolicyProfile: () => resolvePolicyProfile
|
|
@@ -48691,6 +49389,8 @@ var require_dist2 = __commonJS({
|
|
|
48691
49389
|
var import_os2 = __toESM2(require("os"));
|
|
48692
49390
|
var import_child_process = require("child_process");
|
|
48693
49391
|
init_auth();
|
|
49392
|
+
var debug3 = process.env.BOOTSPRING_DEBUG ? (...args) => console.debug("[bootspring:self-heal]", ...args) : () => {
|
|
49393
|
+
};
|
|
48694
49394
|
function classifyError(err) {
|
|
48695
49395
|
const msg = String(err?.message || err || "").toLowerCase();
|
|
48696
49396
|
const status = err?.status;
|
|
@@ -48805,7 +49505,8 @@ var require_dist2 = __commonJS({
|
|
|
48805
49505
|
saveCredentials({ apiKey: legacyKey });
|
|
48806
49506
|
return { issue: classifyError({ message: "bad decrypt" }), healed: true, detail: "Re-encrypted credentials from project API key." };
|
|
48807
49507
|
}
|
|
48808
|
-
} catch {
|
|
49508
|
+
} catch (e) {
|
|
49509
|
+
debug3("credential recovery failed", e);
|
|
48809
49510
|
}
|
|
48810
49511
|
return { issue: classifyError({ message: "bad decrypt" }), healed: false, detail: "No fallback API key available." };
|
|
48811
49512
|
},
|
|
@@ -48926,24 +49627,42 @@ var require_dist2 = __commonJS({
|
|
|
48926
49627
|
} else {
|
|
48927
49628
|
results.push({ id: "deps", status: "ok", message: "Dependencies installed." });
|
|
48928
49629
|
}
|
|
48929
|
-
const
|
|
49630
|
+
const mcpTargets = {
|
|
49631
|
+
claude: import_path3.default.join(homeDir, ".claude.json"),
|
|
49632
|
+
codex: import_path3.default.join(homeDir, ".codex", "config.toml"),
|
|
49633
|
+
gemini: import_path3.default.join(homeDir, ".gemini", "settings.json")
|
|
49634
|
+
};
|
|
48930
49635
|
const projectMcp = import_path3.default.join(cwd, ".mcp.json");
|
|
48931
|
-
const
|
|
48932
|
-
|
|
48933
|
-
|
|
48934
|
-
|
|
48935
|
-
|
|
48936
|
-
|
|
48937
|
-
|
|
48938
|
-
|
|
48939
|
-
|
|
49636
|
+
const mcpStatus = {
|
|
49637
|
+
claude: hasBootspringInJson(mcpTargets.claude),
|
|
49638
|
+
codex: hasBootspringInToml(mcpTargets.codex),
|
|
49639
|
+
gemini: hasBootspringInJson(mcpTargets.gemini),
|
|
49640
|
+
project: hasBootspringInJson(projectMcp)
|
|
49641
|
+
};
|
|
49642
|
+
const anyConfigured = mcpStatus.claude || mcpStatus.codex || mcpStatus.gemini || mcpStatus.project;
|
|
49643
|
+
if (anyConfigured) {
|
|
49644
|
+
const configured = Object.entries(mcpStatus).filter(([, v]) => v).map(([k]) => k);
|
|
49645
|
+
results.push({ id: "mcp", status: "ok", message: `MCP configured for: ${configured.join(", ")}.` });
|
|
49646
|
+
} else if (autoFix) {
|
|
49647
|
+
const healed = [];
|
|
49648
|
+
const failed = [];
|
|
49649
|
+
if (writeClaudeMcp(mcpTargets.claude)) healed.push("Claude Code");
|
|
49650
|
+
else failed.push("Claude Code");
|
|
49651
|
+
if (import_fs3.default.existsSync(import_path3.default.dirname(mcpTargets.codex))) {
|
|
49652
|
+
if (writeCodexMcp(mcpTargets.codex)) healed.push("Codex");
|
|
49653
|
+
else failed.push("Codex");
|
|
49654
|
+
}
|
|
49655
|
+
if (import_fs3.default.existsSync(import_path3.default.dirname(mcpTargets.gemini))) {
|
|
49656
|
+
if (writeGeminiMcp(mcpTargets.gemini)) healed.push("Gemini CLI");
|
|
49657
|
+
else failed.push("Gemini CLI");
|
|
49658
|
+
}
|
|
49659
|
+
if (healed.length > 0) {
|
|
49660
|
+
results.push({ id: "mcp", status: "healed", message: `Registered bootspring MCP for: ${healed.join(", ")}.` });
|
|
49661
|
+
} else {
|
|
49662
|
+
results.push({ id: "mcp", status: "action-needed", message: "Bootspring MCP not configured.", fix: "bootspring setup assistants" });
|
|
48940
49663
|
}
|
|
48941
|
-
return false;
|
|
48942
|
-
})();
|
|
48943
|
-
if (hasMcp) {
|
|
48944
|
-
results.push({ id: "mcp", status: "ok", message: "MCP server configured." });
|
|
48945
49664
|
} else {
|
|
48946
|
-
results.push({ id: "mcp", status: "action-needed", message: "Bootspring MCP not configured.", fix: "bootspring
|
|
49665
|
+
results.push({ id: "mcp", status: "action-needed", message: "Bootspring MCP not configured.", fix: "bootspring doctor --fix" });
|
|
48947
49666
|
}
|
|
48948
49667
|
if (import_fs3.default.existsSync(import_path3.default.join(cwd, "CLAUDE.md"))) {
|
|
48949
49668
|
results.push({ id: "claude-md", status: "ok", message: "CLAUDE.md present." });
|
|
@@ -48971,6 +49690,89 @@ var require_dist2 = __commonJS({
|
|
|
48971
49690
|
}
|
|
48972
49691
|
return results;
|
|
48973
49692
|
}
|
|
49693
|
+
function hasBootspringInJson(filePath) {
|
|
49694
|
+
try {
|
|
49695
|
+
if (!import_fs3.default.existsSync(filePath)) return false;
|
|
49696
|
+
const raw = import_fs3.default.readFileSync(filePath, "utf-8");
|
|
49697
|
+
if (!raw.trim()) return false;
|
|
49698
|
+
const data = JSON.parse(raw);
|
|
49699
|
+
return Boolean(data?.mcpServers?.bootspring);
|
|
49700
|
+
} catch {
|
|
49701
|
+
return false;
|
|
49702
|
+
}
|
|
49703
|
+
}
|
|
49704
|
+
function hasBootspringInToml(filePath) {
|
|
49705
|
+
try {
|
|
49706
|
+
if (!import_fs3.default.existsSync(filePath)) return false;
|
|
49707
|
+
const raw = import_fs3.default.readFileSync(filePath, "utf-8");
|
|
49708
|
+
return raw.includes("[mcp_servers.bootspring]");
|
|
49709
|
+
} catch {
|
|
49710
|
+
return false;
|
|
49711
|
+
}
|
|
49712
|
+
}
|
|
49713
|
+
function writeClaudeMcp(configPath) {
|
|
49714
|
+
try {
|
|
49715
|
+
let config2 = {};
|
|
49716
|
+
if (import_fs3.default.existsSync(configPath)) {
|
|
49717
|
+
const raw = import_fs3.default.readFileSync(configPath, "utf-8");
|
|
49718
|
+
config2 = raw.trim() ? JSON.parse(raw) : {};
|
|
49719
|
+
}
|
|
49720
|
+
if (!config2.mcpServers || typeof config2.mcpServers !== "object") {
|
|
49721
|
+
config2.mcpServers = {};
|
|
49722
|
+
}
|
|
49723
|
+
config2.mcpServers.bootspring = {
|
|
49724
|
+
type: "stdio",
|
|
49725
|
+
command: "bootspring",
|
|
49726
|
+
args: ["mcp"],
|
|
49727
|
+
env: { BOOTSPRING_ASSISTANT: "claude" }
|
|
49728
|
+
};
|
|
49729
|
+
import_fs3.default.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
|
|
49730
|
+
`, "utf-8");
|
|
49731
|
+
return true;
|
|
49732
|
+
} catch {
|
|
49733
|
+
return false;
|
|
49734
|
+
}
|
|
49735
|
+
}
|
|
49736
|
+
function writeCodexMcp(configPath) {
|
|
49737
|
+
try {
|
|
49738
|
+
const dir = import_path3.default.dirname(configPath);
|
|
49739
|
+
if (!import_fs3.default.existsSync(dir)) import_fs3.default.mkdirSync(dir, { recursive: true });
|
|
49740
|
+
const existing = import_fs3.default.existsSync(configPath) ? import_fs3.default.readFileSync(configPath, "utf-8") : "";
|
|
49741
|
+
if (existing.includes("[mcp_servers.bootspring]")) return true;
|
|
49742
|
+
const block = '[mcp_servers.bootspring]\ncommand = "bootspring"\nargs = ["mcp"]\nenv = { BOOTSPRING_ASSISTANT = "codex" }\n';
|
|
49743
|
+
const content = existing.length > 0 ? `${existing.trimEnd()}
|
|
49744
|
+
|
|
49745
|
+
${block}` : block;
|
|
49746
|
+
import_fs3.default.writeFileSync(configPath, content, "utf-8");
|
|
49747
|
+
return true;
|
|
49748
|
+
} catch {
|
|
49749
|
+
return false;
|
|
49750
|
+
}
|
|
49751
|
+
}
|
|
49752
|
+
function writeGeminiMcp(configPath) {
|
|
49753
|
+
try {
|
|
49754
|
+
const dir = import_path3.default.dirname(configPath);
|
|
49755
|
+
if (!import_fs3.default.existsSync(dir)) import_fs3.default.mkdirSync(dir, { recursive: true });
|
|
49756
|
+
let settings = {};
|
|
49757
|
+
if (import_fs3.default.existsSync(configPath)) {
|
|
49758
|
+
const raw = import_fs3.default.readFileSync(configPath, "utf-8");
|
|
49759
|
+
settings = raw.trim() ? JSON.parse(raw) : {};
|
|
49760
|
+
}
|
|
49761
|
+
if (!settings.mcpServers || typeof settings.mcpServers !== "object") {
|
|
49762
|
+
settings.mcpServers = {};
|
|
49763
|
+
}
|
|
49764
|
+
settings.mcpServers.bootspring = {
|
|
49765
|
+
command: "bootspring",
|
|
49766
|
+
args: ["mcp"],
|
|
49767
|
+
env: { BOOTSPRING_ASSISTANT: "gemini" }
|
|
49768
|
+
};
|
|
49769
|
+
import_fs3.default.writeFileSync(configPath, `${JSON.stringify(settings, null, 2)}
|
|
49770
|
+
`, "utf-8");
|
|
49771
|
+
return true;
|
|
49772
|
+
} catch {
|
|
49773
|
+
return false;
|
|
49774
|
+
}
|
|
49775
|
+
}
|
|
48974
49776
|
var presence_exports = {};
|
|
48975
49777
|
__export2(presence_exports, {
|
|
48976
49778
|
maybeAutoUploadTelemetry: () => maybeAutoUploadTelemetry,
|
|
@@ -48980,7 +49782,7 @@ var require_dist2 = __commonJS({
|
|
|
48980
49782
|
init_cjs_shims2();
|
|
48981
49783
|
init_auth();
|
|
48982
49784
|
init_session();
|
|
48983
|
-
var DASHBOARD_BASE = process.env.BOOTSPRING_SITE_URL || "https://
|
|
49785
|
+
var DASHBOARD_BASE = process.env.BOOTSPRING_SITE_URL || process.env.BOOTSPRING_API_URL || "https://api.bootspring.com";
|
|
48984
49786
|
var HEARTBEAT_DEBOUNCE_MS = 2e4;
|
|
48985
49787
|
var REQUEST_TIMEOUT_MS = 5e3;
|
|
48986
49788
|
var _lastHeartbeatAt = 0;
|
|
@@ -49066,6 +49868,13 @@ var require_dist2 = __commonJS({
|
|
|
49066
49868
|
const ONE_HOUR = 60 * 60 * 1e3;
|
|
49067
49869
|
if (now - _lastTelemetryUploadAt < ONE_HOUR) return;
|
|
49068
49870
|
_lastTelemetryUploadAt = now;
|
|
49871
|
+
void Promise.resolve().then(() => (init_telemetry(), telemetry_exports)).then((telemetry2) => {
|
|
49872
|
+
if (typeof telemetry2.uploadEvents === "function") {
|
|
49873
|
+
telemetry2.uploadEvents().catch(() => {
|
|
49874
|
+
});
|
|
49875
|
+
}
|
|
49876
|
+
}).catch(() => {
|
|
49877
|
+
});
|
|
49069
49878
|
}
|
|
49070
49879
|
var self_update_exports = {};
|
|
49071
49880
|
__export2(self_update_exports, {
|
|
@@ -49081,26 +49890,26 @@ var require_dist2 = __commonJS({
|
|
|
49081
49890
|
getLatestVersion: () => getLatestVersion
|
|
49082
49891
|
});
|
|
49083
49892
|
init_cjs_shims2();
|
|
49084
|
-
var
|
|
49893
|
+
var fs5 = __toESM2(require("fs"));
|
|
49085
49894
|
var os3 = __toESM2(require("os"));
|
|
49086
|
-
var
|
|
49895
|
+
var path5 = __toESM2(require("path"));
|
|
49087
49896
|
var import_child_process2 = require("child_process");
|
|
49088
|
-
var
|
|
49089
|
-
var PACKAGE_NAME =
|
|
49090
|
-
var CURRENT_VERSION =
|
|
49897
|
+
var import_shared3 = (init_src(), __toCommonJS(src_exports));
|
|
49898
|
+
var PACKAGE_NAME = import_shared3.BOOTSPRING_PACKAGE_NAME;
|
|
49899
|
+
var CURRENT_VERSION = import_shared3.BOOTSPRING_VERSION || "0.0.0";
|
|
49091
49900
|
var DEFAULT_INTERVAL_MS = Number.parseInt(
|
|
49092
49901
|
process.env.BOOTSPRING_AUTO_UPDATE_INTERVAL_MS || `${6 * 60 * 60 * 1e3}`,
|
|
49093
49902
|
10
|
|
49094
49903
|
);
|
|
49095
|
-
var STATE_PATH =
|
|
49904
|
+
var STATE_PATH = path5.join(os3.homedir(), ".bootspring", "update-state.json");
|
|
49096
49905
|
function resolvePackageRoot() {
|
|
49097
49906
|
const candidates = [
|
|
49098
|
-
|
|
49099
|
-
|
|
49907
|
+
path5.resolve(__dirname, ".."),
|
|
49908
|
+
path5.resolve(__dirname, "../.."),
|
|
49100
49909
|
process.cwd()
|
|
49101
49910
|
];
|
|
49102
49911
|
for (const candidate of candidates) {
|
|
49103
|
-
if (
|
|
49912
|
+
if (fs5.existsSync(path5.join(candidate, "package.json"))) {
|
|
49104
49913
|
return candidate;
|
|
49105
49914
|
}
|
|
49106
49915
|
}
|
|
@@ -49123,34 +49932,34 @@ var require_dist2 = __commonJS({
|
|
|
49123
49932
|
}
|
|
49124
49933
|
function readState() {
|
|
49125
49934
|
try {
|
|
49126
|
-
return JSON.parse(
|
|
49935
|
+
return JSON.parse(fs5.readFileSync(STATE_PATH, "utf8"));
|
|
49127
49936
|
} catch {
|
|
49128
49937
|
return {};
|
|
49129
49938
|
}
|
|
49130
49939
|
}
|
|
49131
49940
|
function writeState(nextState) {
|
|
49132
49941
|
try {
|
|
49133
|
-
|
|
49134
|
-
|
|
49942
|
+
fs5.mkdirSync(path5.dirname(STATE_PATH), { recursive: true, mode: 448 });
|
|
49943
|
+
fs5.writeFileSync(STATE_PATH, JSON.stringify(nextState, null, 2));
|
|
49135
49944
|
} catch {
|
|
49136
49945
|
}
|
|
49137
49946
|
}
|
|
49138
49947
|
function getInstallContext() {
|
|
49139
49948
|
const packageRoot = resolvePackageRoot();
|
|
49140
|
-
const scriptPath =
|
|
49141
|
-
const nodeModulesSegment = `${
|
|
49949
|
+
const scriptPath = path5.resolve(process.argv[1] || path5.join(packageRoot, "bin", "bootspring.js"));
|
|
49950
|
+
const nodeModulesSegment = `${path5.sep}node_modules${path5.sep}`;
|
|
49142
49951
|
const forcedMode = process.env.BOOTSPRING_AUTO_UPDATE_INSTALL_MODE;
|
|
49143
49952
|
if (forcedMode === "global" || forcedMode === "local") {
|
|
49144
49953
|
const projectRoot = forcedMode === "local" ? process.env.BOOTSPRING_AUTO_UPDATE_PROJECT_ROOT || process.cwd() : null;
|
|
49145
49954
|
return { mode: forcedMode, packageRoot, projectRoot, scriptPath };
|
|
49146
49955
|
}
|
|
49147
|
-
if (packageRoot.includes(`${
|
|
49956
|
+
if (packageRoot.includes(`${path5.sep}_npx${path5.sep}`) || scriptPath.includes(`${path5.sep}_npx${path5.sep}`)) {
|
|
49148
49957
|
return { mode: "ephemeral", packageRoot, projectRoot: null, scriptPath };
|
|
49149
49958
|
}
|
|
49150
49959
|
if (!packageRoot.includes(nodeModulesSegment)) {
|
|
49151
49960
|
return { mode: "development", packageRoot, projectRoot: null, scriptPath };
|
|
49152
49961
|
}
|
|
49153
|
-
if (scriptPath.includes(`${nodeModulesSegment}.bin${
|
|
49962
|
+
if (scriptPath.includes(`${nodeModulesSegment}.bin${path5.sep}`) || scriptPath.includes(`${nodeModulesSegment}@girardmedia${path5.sep}bootspring${path5.sep}bin${path5.sep}`)) {
|
|
49154
49963
|
const [projectRoot] = packageRoot.split(nodeModulesSegment);
|
|
49155
49964
|
return { mode: "local", packageRoot, projectRoot: projectRoot || process.cwd(), scriptPath };
|
|
49156
49965
|
}
|
|
@@ -49284,20 +50093,20 @@ var require_dist2 = __commonJS({
|
|
|
49284
50093
|
uninstallAll: () => uninstallAll
|
|
49285
50094
|
});
|
|
49286
50095
|
init_cjs_shims2();
|
|
49287
|
-
var
|
|
50096
|
+
var fs6 = __toESM2(require("fs"));
|
|
49288
50097
|
var os4 = __toESM2(require("os"));
|
|
49289
|
-
var
|
|
50098
|
+
var path6 = __toESM2(require("path"));
|
|
49290
50099
|
function resolveCommandsSource() {
|
|
49291
50100
|
const fromEnv = process.env.BOOTSPRING_COMMANDS_SOURCE;
|
|
49292
50101
|
const candidates = [
|
|
49293
50102
|
fromEnv,
|
|
49294
|
-
|
|
49295
|
-
|
|
49296
|
-
|
|
49297
|
-
|
|
50103
|
+
path6.resolve(__dirname, "../assets/claude-commands"),
|
|
50104
|
+
path6.resolve(__dirname, "../claude-commands"),
|
|
50105
|
+
path6.resolve(__dirname, "../../../../claude-commands"),
|
|
50106
|
+
path6.resolve(process.cwd(), "claude-commands")
|
|
49298
50107
|
].filter(Boolean);
|
|
49299
50108
|
for (const candidate of candidates) {
|
|
49300
|
-
if (
|
|
50109
|
+
if (fs6.existsSync(candidate)) {
|
|
49301
50110
|
return candidate;
|
|
49302
50111
|
}
|
|
49303
50112
|
}
|
|
@@ -49305,13 +50114,13 @@ var require_dist2 = __commonJS({
|
|
|
49305
50114
|
}
|
|
49306
50115
|
var COMMANDS_SOURCE = resolveCommandsSource();
|
|
49307
50116
|
var TARGET_DIRS = [
|
|
49308
|
-
{ name: "Claude Code", path:
|
|
49309
|
-
{ name: "Codex", path:
|
|
49310
|
-
{ name: "Generic", path:
|
|
50117
|
+
{ name: "Claude Code", path: path6.join(os4.homedir(), ".claude", "commands") },
|
|
50118
|
+
{ name: "Codex", path: path6.join(os4.homedir(), ".codex", "commands") },
|
|
50119
|
+
{ name: "Generic", path: path6.join(os4.homedir(), ".ai-commands") }
|
|
49311
50120
|
];
|
|
49312
50121
|
function getCommandFiles(commandsSource = COMMANDS_SOURCE) {
|
|
49313
50122
|
try {
|
|
49314
|
-
return
|
|
50123
|
+
return fs6.readdirSync(commandsSource).filter((file) => file.endsWith(".md"));
|
|
49315
50124
|
} catch {
|
|
49316
50125
|
return [];
|
|
49317
50126
|
}
|
|
@@ -49320,8 +50129,8 @@ var require_dist2 = __commonJS({
|
|
|
49320
50129
|
const { verbose = false, force = false, commandsSource = COMMANDS_SOURCE } = options;
|
|
49321
50130
|
const results = { installed: [], skipped: [], errors: [] };
|
|
49322
50131
|
try {
|
|
49323
|
-
if (!
|
|
49324
|
-
|
|
50132
|
+
if (!fs6.existsSync(targetDir)) {
|
|
50133
|
+
fs6.mkdirSync(targetDir, { recursive: true });
|
|
49325
50134
|
if (verbose) console.log(` Created ${targetDir}`);
|
|
49326
50135
|
}
|
|
49327
50136
|
} catch (error) {
|
|
@@ -49329,14 +50138,14 @@ var require_dist2 = __commonJS({
|
|
|
49329
50138
|
return results;
|
|
49330
50139
|
}
|
|
49331
50140
|
for (const file of getCommandFiles(commandsSource)) {
|
|
49332
|
-
const src =
|
|
49333
|
-
const dest =
|
|
50141
|
+
const src = path6.join(commandsSource, file);
|
|
50142
|
+
const dest = path6.join(targetDir, file);
|
|
49334
50143
|
try {
|
|
49335
|
-
if (
|
|
50144
|
+
if (fs6.existsSync(dest) && !force) {
|
|
49336
50145
|
results.skipped.push(file);
|
|
49337
50146
|
continue;
|
|
49338
50147
|
}
|
|
49339
|
-
|
|
50148
|
+
fs6.copyFileSync(src, dest);
|
|
49340
50149
|
results.installed.push(file);
|
|
49341
50150
|
} catch (error) {
|
|
49342
50151
|
results.errors.push({ file, error: error.message });
|
|
@@ -49361,11 +50170,11 @@ Installing to ${target.name}...`);
|
|
|
49361
50170
|
function checkInstallation(commandsSource = COMMANDS_SOURCE) {
|
|
49362
50171
|
const sourceFiles = getCommandFiles(commandsSource);
|
|
49363
50172
|
return TARGET_DIRS.map((target) => {
|
|
49364
|
-
const exists =
|
|
50173
|
+
const exists = fs6.existsSync(target.path);
|
|
49365
50174
|
let commandCount = 0;
|
|
49366
50175
|
if (exists) {
|
|
49367
50176
|
try {
|
|
49368
|
-
const files =
|
|
50177
|
+
const files = fs6.readdirSync(target.path).filter((file) => sourceFiles.includes(file));
|
|
49369
50178
|
commandCount = files.length;
|
|
49370
50179
|
} catch {
|
|
49371
50180
|
commandCount = 0;
|
|
@@ -49384,12 +50193,12 @@ Installing to ${target.name}...`);
|
|
|
49384
50193
|
const sourceFiles = getCommandFiles(commandsSource);
|
|
49385
50194
|
const summary = { removed: 0, notFound: 0 };
|
|
49386
50195
|
for (const target of TARGET_DIRS) {
|
|
49387
|
-
if (!
|
|
50196
|
+
if (!fs6.existsSync(target.path)) continue;
|
|
49388
50197
|
for (const file of sourceFiles) {
|
|
49389
|
-
const filePath =
|
|
50198
|
+
const filePath = path6.join(target.path, file);
|
|
49390
50199
|
try {
|
|
49391
|
-
if (
|
|
49392
|
-
|
|
50200
|
+
if (fs6.existsSync(filePath)) {
|
|
50201
|
+
fs6.unlinkSync(filePath);
|
|
49393
50202
|
summary.removed++;
|
|
49394
50203
|
if (verbose) console.log(` Removed ${filePath}`);
|
|
49395
50204
|
} else {
|
|
@@ -49446,15 +50255,15 @@ Installing to ${target.name}...`);
|
|
|
49446
50255
|
requireTier: () => requireTier
|
|
49447
50256
|
});
|
|
49448
50257
|
init_cjs_shims2();
|
|
49449
|
-
var
|
|
50258
|
+
var fs7 = __toESM2(require("fs"));
|
|
49450
50259
|
var os5 = __toESM2(require("os"));
|
|
49451
|
-
var
|
|
50260
|
+
var path7 = __toESM2(require("path"));
|
|
49452
50261
|
init_auth();
|
|
49453
50262
|
function getAuth() {
|
|
49454
50263
|
return auth_exports;
|
|
49455
50264
|
}
|
|
49456
|
-
var BOOTSPRING_DIR2 =
|
|
49457
|
-
var ENTITLEMENTS_CACHE_FILE =
|
|
50265
|
+
var BOOTSPRING_DIR2 = path7.join(os5.homedir(), ".bootspring");
|
|
50266
|
+
var ENTITLEMENTS_CACHE_FILE = path7.join(BOOTSPRING_DIR2, "entitlements.json");
|
|
49458
50267
|
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
49459
50268
|
var TIER_HIERARCHY = {
|
|
49460
50269
|
free: 0,
|
|
@@ -49652,8 +50461,8 @@ Installing to ${target.name}...`);
|
|
|
49652
50461
|
};
|
|
49653
50462
|
function getCachedEntitlements() {
|
|
49654
50463
|
try {
|
|
49655
|
-
if (
|
|
49656
|
-
const data = JSON.parse(
|
|
50464
|
+
if (fs7.existsSync(ENTITLEMENTS_CACHE_FILE)) {
|
|
50465
|
+
const data = JSON.parse(fs7.readFileSync(ENTITLEMENTS_CACHE_FILE, "utf-8"));
|
|
49657
50466
|
if (data.cachedAt && Date.now() - new Date(data.cachedAt).getTime() < CACHE_TTL_MS) {
|
|
49658
50467
|
return data;
|
|
49659
50468
|
}
|
|
@@ -49665,10 +50474,10 @@ Installing to ${target.name}...`);
|
|
|
49665
50474
|
}
|
|
49666
50475
|
function cacheEntitlements(entitlements2) {
|
|
49667
50476
|
try {
|
|
49668
|
-
if (!
|
|
49669
|
-
|
|
50477
|
+
if (!fs7.existsSync(BOOTSPRING_DIR2)) {
|
|
50478
|
+
fs7.mkdirSync(BOOTSPRING_DIR2, { recursive: true, mode: 448 });
|
|
49670
50479
|
}
|
|
49671
|
-
|
|
50480
|
+
fs7.writeFileSync(
|
|
49672
50481
|
ENTITLEMENTS_CACHE_FILE,
|
|
49673
50482
|
JSON.stringify({ ...entitlements2, cachedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
|
|
49674
50483
|
{ mode: 384 }
|
|
@@ -49678,8 +50487,8 @@ Installing to ${target.name}...`);
|
|
|
49678
50487
|
}
|
|
49679
50488
|
function clearCache() {
|
|
49680
50489
|
try {
|
|
49681
|
-
if (
|
|
49682
|
-
|
|
50490
|
+
if (fs7.existsSync(ENTITLEMENTS_CACHE_FILE)) {
|
|
50491
|
+
fs7.unlinkSync(ENTITLEMENTS_CACHE_FILE);
|
|
49683
50492
|
}
|
|
49684
50493
|
} catch {
|
|
49685
50494
|
}
|
|
@@ -50303,8 +51112,9 @@ ${experimentLine}
|
|
|
50303
51112
|
validateSection: () => validateSection
|
|
50304
51113
|
});
|
|
50305
51114
|
init_cjs_shims2();
|
|
50306
|
-
var
|
|
50307
|
-
var
|
|
51115
|
+
var fs8 = __toESM2(require("fs"));
|
|
51116
|
+
var path8 = __toESM2(require("path"));
|
|
51117
|
+
init_cjs_shims2();
|
|
50308
51118
|
var import_zod = require_zod();
|
|
50309
51119
|
var BasePluginSchema = import_zod.z.object({
|
|
50310
51120
|
enabled: import_zod.z.boolean().optional().default(false),
|
|
@@ -50538,7 +51348,7 @@ ${experimentLine}
|
|
|
50538
51348
|
var PathsConfigSchema = import_zod.z.object({
|
|
50539
51349
|
context: import_zod.z.string().optional().default("CLAUDE.md"),
|
|
50540
51350
|
config: import_zod.z.string().optional().default("bootspring.config.js"),
|
|
50541
|
-
todo: import_zod.z.string().optional().default("
|
|
51351
|
+
todo: import_zod.z.string().optional().default("planning/TODO.md"),
|
|
50542
51352
|
roadmap: import_zod.z.string().optional().default("ROADMAP.md"),
|
|
50543
51353
|
changelog: import_zod.z.string().optional().default("CHANGELOG.md"),
|
|
50544
51354
|
state: import_zod.z.string().optional().default(".bootspring")
|
|
@@ -50604,66 +51414,6 @@ ${experimentLine}
|
|
|
50604
51414
|
})).optional()
|
|
50605
51415
|
}).optional()
|
|
50606
51416
|
}).passthrough();
|
|
50607
|
-
function formatValidationErrors(zodError) {
|
|
50608
|
-
return zodError.issues.map((issue) => {
|
|
50609
|
-
const path10 = issue.path.join(".");
|
|
50610
|
-
const prefix = path10 ? `${path10}: ` : "";
|
|
50611
|
-
const issueAny = issue;
|
|
50612
|
-
const code = issue.code;
|
|
50613
|
-
const message = issue.message;
|
|
50614
|
-
if (code === "invalid_type" && "expected" in issueAny) {
|
|
50615
|
-
return `${prefix}Expected ${issueAny.expected}, received ${typeof issueAny.input}`;
|
|
50616
|
-
}
|
|
50617
|
-
if (code === "invalid_value") {
|
|
50618
|
-
return `${prefix}Invalid value`;
|
|
50619
|
-
}
|
|
50620
|
-
if (code === "too_small" && "minimum" in issueAny) {
|
|
50621
|
-
return `${prefix}Value must be at least ${issueAny.minimum}`;
|
|
50622
|
-
}
|
|
50623
|
-
if (code === "too_big" && "maximum" in issueAny) {
|
|
50624
|
-
return `${prefix}Value must be at most ${issueAny.maximum}`;
|
|
50625
|
-
}
|
|
50626
|
-
if (code === "invalid_format") {
|
|
50627
|
-
return `${prefix}Invalid format`;
|
|
50628
|
-
}
|
|
50629
|
-
return `${prefix}${message}`;
|
|
50630
|
-
});
|
|
50631
|
-
}
|
|
50632
|
-
var sectionSchemas = {
|
|
50633
|
-
project: ProjectConfigSchema,
|
|
50634
|
-
stack: StackConfigSchema,
|
|
50635
|
-
plugins: PluginsSchema,
|
|
50636
|
-
agents: AgentsConfigSchema,
|
|
50637
|
-
skills: SkillsConfigSchema,
|
|
50638
|
-
workflows: WorkflowsConfigSchema,
|
|
50639
|
-
dashboard: DashboardConfigSchema,
|
|
50640
|
-
quality: QualityConfigSchema,
|
|
50641
|
-
context: ContextConfigSchema,
|
|
50642
|
-
paths: PathsConfigSchema
|
|
50643
|
-
};
|
|
50644
|
-
function validateSection(section, data) {
|
|
50645
|
-
const schema = sectionSchemas[section];
|
|
50646
|
-
if (!schema) {
|
|
50647
|
-
return {
|
|
50648
|
-
valid: false,
|
|
50649
|
-
errors: [`Unknown configuration section: ${section}`],
|
|
50650
|
-
data: null
|
|
50651
|
-
};
|
|
50652
|
-
}
|
|
50653
|
-
const result = schema.safeParse(data);
|
|
50654
|
-
if (result.success) {
|
|
50655
|
-
return {
|
|
50656
|
-
valid: true,
|
|
50657
|
-
errors: [],
|
|
50658
|
-
data: result.data
|
|
50659
|
-
};
|
|
50660
|
-
}
|
|
50661
|
-
return {
|
|
50662
|
-
valid: false,
|
|
50663
|
-
errors: formatValidationErrors(result.error),
|
|
50664
|
-
data: null
|
|
50665
|
-
};
|
|
50666
|
-
}
|
|
50667
51417
|
var DEFAULT_CONFIG = {
|
|
50668
51418
|
project: {
|
|
50669
51419
|
name: "My Project",
|
|
@@ -50696,17 +51446,28 @@ ${experimentLine}
|
|
|
50696
51446
|
paths: {
|
|
50697
51447
|
context: "CLAUDE.md",
|
|
50698
51448
|
config: "bootspring.config.js",
|
|
50699
|
-
todo: "
|
|
51449
|
+
todo: "planning/TODO.md"
|
|
50700
51450
|
}
|
|
50701
51451
|
};
|
|
50702
|
-
|
|
50703
|
-
|
|
50704
|
-
|
|
50705
|
-
|
|
50706
|
-
|
|
50707
|
-
|
|
50708
|
-
|
|
50709
|
-
|
|
51452
|
+
function deepMerge(target, source) {
|
|
51453
|
+
const result = { ...target };
|
|
51454
|
+
for (const key of Object.keys(source)) {
|
|
51455
|
+
const sourceValue = source[key];
|
|
51456
|
+
const targetValue = target[key];
|
|
51457
|
+
if (Array.isArray(sourceValue)) {
|
|
51458
|
+
result[key] = [...sourceValue];
|
|
51459
|
+
} else if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
51460
|
+
result[key] = deepMerge(
|
|
51461
|
+
targetValue,
|
|
51462
|
+
sourceValue
|
|
51463
|
+
);
|
|
51464
|
+
} else if (sourceValue !== void 0) {
|
|
51465
|
+
result[key] = sourceValue;
|
|
51466
|
+
}
|
|
51467
|
+
}
|
|
51468
|
+
return result;
|
|
51469
|
+
}
|
|
51470
|
+
init_cjs_shims2();
|
|
50710
51471
|
var CONFIG_PRESETS = {
|
|
50711
51472
|
"saas-starter": {
|
|
50712
51473
|
name: "SaaS Starter",
|
|
@@ -50884,1048 +51645,572 @@ ${experimentLine}
|
|
|
50884
51645
|
}
|
|
50885
51646
|
}
|
|
50886
51647
|
};
|
|
50887
|
-
function
|
|
50888
|
-
|
|
50889
|
-
for (const key of Object.keys(source)) {
|
|
50890
|
-
const sourceValue = source[key];
|
|
50891
|
-
const targetValue = target[key];
|
|
50892
|
-
if (Array.isArray(sourceValue)) {
|
|
50893
|
-
result[key] = [...sourceValue];
|
|
50894
|
-
} else if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && targetValue !== null && typeof targetValue === "object" && !Array.isArray(targetValue)) {
|
|
50895
|
-
result[key] = deepMerge(
|
|
50896
|
-
targetValue,
|
|
50897
|
-
sourceValue
|
|
50898
|
-
);
|
|
50899
|
-
} else if (sourceValue !== void 0) {
|
|
50900
|
-
result[key] = sourceValue;
|
|
50901
|
-
}
|
|
50902
|
-
}
|
|
50903
|
-
return result;
|
|
50904
|
-
}
|
|
50905
|
-
function findProjectRoot() {
|
|
50906
|
-
let dir = process.cwd();
|
|
50907
|
-
const root = path7.parse(dir).root;
|
|
50908
|
-
while (dir !== root) {
|
|
50909
|
-
if (fs7.existsSync(path7.join(dir, "package.json")) || fs7.existsSync(path7.join(dir, "bootspring.config.js")) || fs7.existsSync(path7.join(dir, ".git"))) {
|
|
50910
|
-
return dir;
|
|
50911
|
-
}
|
|
50912
|
-
dir = path7.dirname(dir);
|
|
50913
|
-
}
|
|
50914
|
-
return process.cwd();
|
|
50915
|
-
}
|
|
50916
|
-
function findConfigFile(projectRoot) {
|
|
50917
|
-
for (const filename of CONFIG_FILES) {
|
|
50918
|
-
const filepath = path7.join(projectRoot, filename);
|
|
50919
|
-
if (fs7.existsSync(filepath)) {
|
|
50920
|
-
return filepath;
|
|
50921
|
-
}
|
|
50922
|
-
}
|
|
50923
|
-
return null;
|
|
50924
|
-
}
|
|
50925
|
-
function getPreset(presetName) {
|
|
50926
|
-
return CONFIG_PRESETS[presetName] ?? null;
|
|
50927
|
-
}
|
|
50928
|
-
function resolvePresetChain(presetName, seen = /* @__PURE__ */ new Set()) {
|
|
50929
|
-
const preset = CONFIG_PRESETS[presetName];
|
|
50930
|
-
if (!preset) {
|
|
50931
|
-
throw new Error(`Unknown preset: ${presetName}. Available: ${Object.keys(CONFIG_PRESETS).join(", ")}`);
|
|
50932
|
-
}
|
|
50933
|
-
if (seen.has(presetName)) {
|
|
50934
|
-
throw new Error(`Circular preset inheritance detected: ${presetName}`);
|
|
50935
|
-
}
|
|
50936
|
-
seen.add(presetName);
|
|
50937
|
-
let config2 = { ...DEFAULT_CONFIG };
|
|
50938
|
-
if (preset.extends) {
|
|
50939
|
-
const parentConfig = resolvePresetChain(preset.extends, seen);
|
|
50940
|
-
config2 = deepMerge(config2, parentConfig);
|
|
50941
|
-
}
|
|
50942
|
-
config2 = deepMerge(config2, preset.config);
|
|
50943
|
-
return config2;
|
|
50944
|
-
}
|
|
50945
|
-
function applyPreset(presetNames, overrides = {}) {
|
|
50946
|
-
const presets = Array.isArray(presetNames) ? presetNames : [presetNames];
|
|
50947
|
-
if (presets.length === 0) {
|
|
50948
|
-
throw new Error("At least one preset name is required");
|
|
50949
|
-
}
|
|
50950
|
-
let config2 = { ...DEFAULT_CONFIG };
|
|
50951
|
-
for (const presetName of presets) {
|
|
50952
|
-
const trimmedName = presetName.trim();
|
|
50953
|
-
const presetConfig = resolvePresetChain(trimmedName);
|
|
50954
|
-
config2 = deepMerge(config2, presetConfig);
|
|
50955
|
-
}
|
|
50956
|
-
config2 = deepMerge(config2, overrides);
|
|
50957
|
-
return config2;
|
|
50958
|
-
}
|
|
50959
|
-
function combinePresets(presetNames, overrides = {}) {
|
|
50960
|
-
if (!Array.isArray(presetNames) || presetNames.length === 0) {
|
|
50961
|
-
throw new Error("combinePresets requires a non-empty array of preset names");
|
|
50962
|
-
}
|
|
50963
|
-
return applyPreset(presetNames, overrides);
|
|
50964
|
-
}
|
|
50965
|
-
function parsePresetString(presetString) {
|
|
50966
|
-
if (!presetString || typeof presetString !== "string") {
|
|
50967
|
-
return [];
|
|
50968
|
-
}
|
|
50969
|
-
return presetString.split(",").map((s) => s.trim()).filter(Boolean);
|
|
50970
|
-
}
|
|
50971
|
-
function validatePresets(presetNames) {
|
|
50972
|
-
const presets = Array.isArray(presetNames) ? presetNames : [presetNames];
|
|
50973
|
-
const errors = [];
|
|
50974
|
-
const validPresets = [];
|
|
50975
|
-
const availablePresets = Object.keys(CONFIG_PRESETS);
|
|
50976
|
-
for (const preset of presets) {
|
|
50977
|
-
if (CONFIG_PRESETS[preset]) {
|
|
50978
|
-
validPresets.push(preset);
|
|
50979
|
-
} else {
|
|
50980
|
-
errors.push(`Unknown preset: "${preset}". Available: ${availablePresets.join(", ")}`);
|
|
50981
|
-
}
|
|
50982
|
-
}
|
|
50983
|
-
return { valid: errors.length === 0, errors, validPresets };
|
|
50984
|
-
}
|
|
50985
|
-
function getPresetsByTag(tag) {
|
|
50986
|
-
return Object.entries(CONFIG_PRESETS).filter(([, preset]) => preset.tags && preset.tags.includes(tag)).map(([key]) => key);
|
|
50987
|
-
}
|
|
50988
|
-
function createCustomPreset(baseName, newName, customConfig = {}) {
|
|
50989
|
-
const basePreset = CONFIG_PRESETS[baseName];
|
|
50990
|
-
if (!basePreset) {
|
|
50991
|
-
throw new Error(`Unknown base preset: ${baseName}`);
|
|
50992
|
-
}
|
|
50993
|
-
return {
|
|
50994
|
-
name: newName,
|
|
50995
|
-
description: `Custom preset based on ${basePreset.name}`,
|
|
50996
|
-
tags: [...basePreset.tags || [], "custom"],
|
|
50997
|
-
extends: baseName,
|
|
50998
|
-
config: customConfig
|
|
50999
|
-
};
|
|
51000
|
-
}
|
|
51001
|
-
function listPresets(options = {}) {
|
|
51002
|
-
let entries = Object.entries(CONFIG_PRESETS);
|
|
51003
|
-
if (options.tag) {
|
|
51004
|
-
entries = entries.filter(
|
|
51005
|
-
([, preset]) => preset.tags && preset.tags.includes(options.tag)
|
|
51006
|
-
);
|
|
51007
|
-
}
|
|
51008
|
-
return entries.map(([key, preset]) => {
|
|
51009
|
-
const info = {
|
|
51010
|
-
key,
|
|
51011
|
-
name: preset.name,
|
|
51012
|
-
description: preset.description
|
|
51013
|
-
};
|
|
51014
|
-
if (options.verbose) {
|
|
51015
|
-
info.tags = preset.tags || [];
|
|
51016
|
-
info.extends = preset.extends;
|
|
51017
|
-
}
|
|
51018
|
-
return info;
|
|
51019
|
-
});
|
|
51020
|
-
}
|
|
51021
|
-
function load(projectRoot = null) {
|
|
51022
|
-
const root = projectRoot ?? findProjectRoot();
|
|
51023
|
-
const configPath = findConfigFile(root);
|
|
51024
|
-
let userConfig = {};
|
|
51025
|
-
if (configPath) {
|
|
51026
|
-
try {
|
|
51027
|
-
if (configPath.endsWith(".json") || configPath.endsWith(".bootspringrc")) {
|
|
51028
|
-
const content = fs7.readFileSync(configPath, "utf-8");
|
|
51029
|
-
userConfig = JSON.parse(content);
|
|
51030
|
-
} else {
|
|
51031
|
-
delete require.cache[require.resolve(configPath)];
|
|
51032
|
-
userConfig = require(configPath);
|
|
51033
|
-
}
|
|
51034
|
-
} catch (error) {
|
|
51035
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
51036
|
-
console.warn(`Warning: Could not load config from ${configPath}: ${message}`);
|
|
51037
|
-
}
|
|
51038
|
-
}
|
|
51039
|
-
const config2 = deepMerge(DEFAULT_CONFIG, userConfig);
|
|
51040
|
-
config2._projectRoot = root;
|
|
51041
|
-
config2._configPath = configPath;
|
|
51042
|
-
config2._bootspringDir = path7.join(root, ".bootspring");
|
|
51043
|
-
return config2;
|
|
51044
|
-
}
|
|
51045
|
-
function save(config2, filepath = null) {
|
|
51046
|
-
const root = config2._projectRoot ?? findProjectRoot();
|
|
51047
|
-
const targetPath = filepath ?? path7.join(root, "bootspring.config.js");
|
|
51048
|
-
const cleanConfig = { ...config2 };
|
|
51049
|
-
delete cleanConfig._projectRoot;
|
|
51050
|
-
delete cleanConfig._configPath;
|
|
51051
|
-
delete cleanConfig._bootspringDir;
|
|
51052
|
-
delete cleanConfig._validation;
|
|
51053
|
-
const content = `/**
|
|
51054
|
-
* Bootspring Configuration
|
|
51055
|
-
* https://bootspring.com/docs/configuration
|
|
51056
|
-
*/
|
|
51057
|
-
|
|
51058
|
-
module.exports = ${JSON.stringify(cleanConfig, null, 2)};
|
|
51059
|
-
`;
|
|
51060
|
-
try {
|
|
51061
|
-
fs7.writeFileSync(targetPath, content, "utf-8");
|
|
51062
|
-
return true;
|
|
51063
|
-
} catch (error) {
|
|
51064
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
51065
|
-
console.error(`Error saving config: ${message}`);
|
|
51066
|
-
return false;
|
|
51067
|
-
}
|
|
51068
|
-
}
|
|
51069
|
-
function validate(config2, options = {}) {
|
|
51070
|
-
const configToValidate = { ...config2 };
|
|
51071
|
-
delete configToValidate._projectRoot;
|
|
51072
|
-
delete configToValidate._configPath;
|
|
51073
|
-
delete configToValidate._bootspringDir;
|
|
51074
|
-
delete configToValidate._validation;
|
|
51075
|
-
const errors = [];
|
|
51076
|
-
const warnings = [];
|
|
51077
|
-
if (options.sections && options.sections.length > 0) {
|
|
51078
|
-
let allValid = true;
|
|
51079
|
-
const validatedData = {};
|
|
51080
|
-
for (const section of options.sections) {
|
|
51081
|
-
const sectionValue = configToValidate[section];
|
|
51082
|
-
if (sectionValue !== void 0) {
|
|
51083
|
-
const result2 = validateSection(section, sectionValue);
|
|
51084
|
-
if (!result2.valid) {
|
|
51085
|
-
allValid = false;
|
|
51086
|
-
errors.push(...result2.errors);
|
|
51087
|
-
} else {
|
|
51088
|
-
validatedData[section] = result2.data;
|
|
51089
|
-
}
|
|
51090
|
-
}
|
|
51091
|
-
}
|
|
51092
|
-
return {
|
|
51093
|
-
valid: allValid,
|
|
51094
|
-
errors,
|
|
51095
|
-
warnings,
|
|
51096
|
-
data: allValid ? validatedData : null
|
|
51097
|
-
};
|
|
51098
|
-
}
|
|
51099
|
-
const result = ConfigSchema.safeParse(configToValidate);
|
|
51100
|
-
if (result.success) {
|
|
51101
|
-
return {
|
|
51102
|
-
valid: true,
|
|
51103
|
-
errors: [],
|
|
51104
|
-
warnings,
|
|
51105
|
-
data: result.data
|
|
51106
|
-
};
|
|
51107
|
-
}
|
|
51108
|
-
return {
|
|
51109
|
-
valid: false,
|
|
51110
|
-
errors: formatValidationErrors(result.error),
|
|
51111
|
-
warnings,
|
|
51112
|
-
data: null
|
|
51113
|
-
};
|
|
51114
|
-
}
|
|
51115
|
-
function loadWithValidation(projectRoot = null, options = {}) {
|
|
51116
|
-
const { validate: shouldValidate = true, strict = false, silent = false } = options;
|
|
51117
|
-
const config2 = load(projectRoot);
|
|
51118
|
-
if (!shouldValidate) {
|
|
51119
|
-
config2._validation = { skipped: true };
|
|
51120
|
-
return config2;
|
|
51121
|
-
}
|
|
51122
|
-
const validation = validate(config2);
|
|
51123
|
-
config2._validation = {
|
|
51124
|
-
valid: validation.valid,
|
|
51125
|
-
errors: validation.errors,
|
|
51126
|
-
warnings: validation.warnings ?? [],
|
|
51127
|
-
validatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51128
|
-
};
|
|
51129
|
-
if (!validation.valid) {
|
|
51130
|
-
if (strict) {
|
|
51131
|
-
const errorMessage = `Configuration validation failed:
|
|
51132
|
-
${validation.errors.map((e) => ` - ${e}`).join("\n")}`;
|
|
51133
|
-
throw new Error(errorMessage);
|
|
51134
|
-
}
|
|
51135
|
-
if (!silent) {
|
|
51136
|
-
console.warn("\x1B[33mWarning: Configuration has validation issues:\x1B[0m");
|
|
51137
|
-
validation.errors.forEach((error) => {
|
|
51138
|
-
console.warn(` \x1B[33m- ${error}\x1B[0m`);
|
|
51139
|
-
});
|
|
51140
|
-
console.warn("\x1B[33mThe configuration will still be used, but some features may not work correctly.\x1B[0m");
|
|
51141
|
-
}
|
|
51142
|
-
}
|
|
51143
|
-
return config2;
|
|
51144
|
-
}
|
|
51145
|
-
function getValidationHint(errorPath) {
|
|
51146
|
-
const hints = {
|
|
51147
|
-
"stack.framework": "Valid frameworks: nextjs, remix, nuxt, sveltekit, astro, express, fastify, hono, custom",
|
|
51148
|
-
"stack.language": "Valid languages: typescript, javascript",
|
|
51149
|
-
"stack.database": "Valid databases: postgresql, mysql, mongodb, sqlite, supabase, planetscale, none",
|
|
51150
|
-
"stack.hosting": "Valid hosting options: vercel, railway, render, fly, aws, gcp, azure, cloudflare, self-hosted, custom",
|
|
51151
|
-
"plugins.auth.provider": "Valid auth providers: clerk, nextauth, auth0, supabase, jwt, custom",
|
|
51152
|
-
"plugins.payments.provider": "Valid payment providers: stripe, paddle, lemonsqueezy, paypal, custom",
|
|
51153
|
-
"plugins.database.provider": "Valid database ORMs: prisma, drizzle, typeorm, kysely, custom",
|
|
51154
|
-
"plugins.testing.provider": "Valid test frameworks: vitest, jest, playwright, cypress, custom",
|
|
51155
|
-
"plugins.ai.providers": "Valid AI providers: anthropic, openai, google, cohere, huggingface, custom",
|
|
51156
|
-
"dashboard.port": "Port must be between 1024 and 65535",
|
|
51157
|
-
"project.version": "Version must follow semver format (e.g., 1.0.0)"
|
|
51158
|
-
};
|
|
51159
|
-
return hints[errorPath] ?? null;
|
|
51160
|
-
}
|
|
51161
|
-
function parseConfig(config2) {
|
|
51162
|
-
const configToParse = { ...config2 };
|
|
51163
|
-
delete configToParse._projectRoot;
|
|
51164
|
-
delete configToParse._configPath;
|
|
51165
|
-
delete configToParse._bootspringDir;
|
|
51166
|
-
delete configToParse._validation;
|
|
51167
|
-
const result = ConfigSchema.safeParse(configToParse);
|
|
51168
|
-
if (result.success) {
|
|
51169
|
-
return result.data;
|
|
51170
|
-
}
|
|
51171
|
-
return configToParse;
|
|
51172
|
-
}
|
|
51173
|
-
function getDefaults() {
|
|
51174
|
-
return { ...DEFAULT_CONFIG };
|
|
51175
|
-
}
|
|
51176
|
-
var context_exports = {};
|
|
51177
|
-
__export2(context_exports, {
|
|
51178
|
-
generateSummary: () => generateSummary,
|
|
51179
|
-
get: () => get,
|
|
51180
|
-
getEnabledPlugins: () => getEnabledPlugins,
|
|
51181
|
-
getGitInfo: () => getGitInfo,
|
|
51182
|
-
getProjectFiles: () => getProjectFiles,
|
|
51183
|
-
getProjectState: () => getProjectState,
|
|
51184
|
-
validate: () => validate2
|
|
51185
|
-
});
|
|
51186
|
-
init_cjs_shims2();
|
|
51187
|
-
var path8 = __toESM2(require("path"));
|
|
51188
|
-
var utils = __toESM2((init_src(), __toCommonJS(src_exports)));
|
|
51189
|
-
function get(options = {}) {
|
|
51190
|
-
const cfg = options.config ?? load();
|
|
51191
|
-
const projectRoot = cfg._projectRoot ?? process.cwd();
|
|
51192
|
-
const context2 = {
|
|
51193
|
-
project: cfg.project,
|
|
51194
|
-
stack: cfg.stack,
|
|
51195
|
-
plugins: getEnabledPlugins(cfg),
|
|
51196
|
-
files: getProjectFiles(projectRoot),
|
|
51197
|
-
git: getGitInfo(projectRoot),
|
|
51198
|
-
state: getProjectState(projectRoot, cfg),
|
|
51199
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
51200
|
-
};
|
|
51201
|
-
return context2;
|
|
51202
|
-
}
|
|
51203
|
-
function getEnabledPlugins(cfg) {
|
|
51204
|
-
const enabled = {};
|
|
51205
|
-
const plugins = cfg.plugins ?? {};
|
|
51206
|
-
for (const [name, plugin] of Object.entries(plugins)) {
|
|
51207
|
-
if (plugin && plugin.enabled !== false) {
|
|
51208
|
-
enabled[name] = {
|
|
51209
|
-
provider: plugin.provider ?? "default",
|
|
51210
|
-
features: plugin.features ?? []
|
|
51211
|
-
};
|
|
51212
|
-
}
|
|
51213
|
-
}
|
|
51214
|
-
return enabled;
|
|
51215
|
-
}
|
|
51216
|
-
function getProjectFiles(projectRoot) {
|
|
51217
|
-
const files = {
|
|
51218
|
-
hasPackageJson: utils.fileExists(path8.join(projectRoot, "package.json")),
|
|
51219
|
-
hasTsConfig: utils.fileExists(path8.join(projectRoot, "tsconfig.json")),
|
|
51220
|
-
hasClaudeMd: utils.fileExists(path8.join(projectRoot, "CLAUDE.md")),
|
|
51221
|
-
hasBootspringConfig: utils.fileExists(path8.join(projectRoot, "bootspring.config.js")),
|
|
51222
|
-
hasTodoMd: utils.fileExists(path8.join(projectRoot, "todo.md")),
|
|
51223
|
-
hasGit: utils.fileExists(path8.join(projectRoot, ".git")),
|
|
51224
|
-
hasSrcDir: utils.fileExists(path8.join(projectRoot, "src")),
|
|
51225
|
-
hasAppDir: utils.fileExists(path8.join(projectRoot, "app")),
|
|
51226
|
-
hasPagesDir: utils.fileExists(path8.join(projectRoot, "pages")),
|
|
51227
|
-
structure: "flat"
|
|
51228
|
-
};
|
|
51229
|
-
if (files.hasAppDir) {
|
|
51230
|
-
files.structure = "app-router";
|
|
51231
|
-
} else if (files.hasPagesDir) {
|
|
51232
|
-
files.structure = "pages-router";
|
|
51233
|
-
} else if (files.hasSrcDir) {
|
|
51234
|
-
files.structure = "src-based";
|
|
51235
|
-
}
|
|
51236
|
-
return files;
|
|
51237
|
-
}
|
|
51238
|
-
function getGitInfo(projectRoot) {
|
|
51239
|
-
const gitDir = path8.join(projectRoot, ".git");
|
|
51240
|
-
if (!utils.fileExists(gitDir)) {
|
|
51241
|
-
return { initialized: false };
|
|
51242
|
-
}
|
|
51243
|
-
const info = { initialized: true };
|
|
51244
|
-
const headPath = path8.join(gitDir, "HEAD");
|
|
51245
|
-
if (utils.fileExists(headPath)) {
|
|
51246
|
-
const head = utils.readFile(headPath);
|
|
51247
|
-
if (head) {
|
|
51248
|
-
const trimmedHead = head.trim();
|
|
51249
|
-
if (trimmedHead.startsWith("ref: refs/heads/")) {
|
|
51250
|
-
info.branch = trimmedHead.replace("ref: refs/heads/", "");
|
|
51251
|
-
}
|
|
51252
|
-
}
|
|
51253
|
-
}
|
|
51254
|
-
const configPath = path8.join(gitDir, "config");
|
|
51255
|
-
if (utils.fileExists(configPath)) {
|
|
51256
|
-
const gitConfig = utils.readFile(configPath);
|
|
51257
|
-
if (gitConfig) {
|
|
51258
|
-
info.hasRemote = gitConfig.includes('[remote "origin"]');
|
|
51259
|
-
}
|
|
51260
|
-
}
|
|
51261
|
-
return info;
|
|
51262
|
-
}
|
|
51263
|
-
function getProjectState(projectRoot, cfg) {
|
|
51264
|
-
const state = {
|
|
51265
|
-
phase: "unknown",
|
|
51266
|
-
health: "unknown",
|
|
51267
|
-
todos: 0,
|
|
51268
|
-
lastGenerated: null
|
|
51269
|
-
};
|
|
51270
|
-
const todoPath = path8.join(projectRoot, cfg.paths?.todo ?? "todo.md");
|
|
51271
|
-
if (utils.fileExists(todoPath)) {
|
|
51272
|
-
const content = utils.readFile(todoPath);
|
|
51273
|
-
if (content) {
|
|
51274
|
-
const todoMatches = content.match(/- \[ \]/g);
|
|
51275
|
-
state.todos = todoMatches ? todoMatches.length : 0;
|
|
51276
|
-
}
|
|
51277
|
-
}
|
|
51278
|
-
const claudePath = path8.join(projectRoot, cfg.paths?.context ?? "CLAUDE.md");
|
|
51279
|
-
if (utils.fileExists(claudePath)) {
|
|
51280
|
-
state.lastGenerated = utils.getFileTime(claudePath);
|
|
51281
|
-
}
|
|
51282
|
-
const loadedCfg = cfg;
|
|
51283
|
-
if (!loadedCfg._configPath) {
|
|
51284
|
-
state.phase = "uninitialized";
|
|
51285
|
-
} else if (!state.lastGenerated) {
|
|
51286
|
-
state.phase = "initialized";
|
|
51287
|
-
} else {
|
|
51288
|
-
state.phase = "active";
|
|
51289
|
-
}
|
|
51290
|
-
const issues = [];
|
|
51291
|
-
if (!utils.fileExists(path8.join(projectRoot, "package.json"))) {
|
|
51292
|
-
issues.push("missing-package-json");
|
|
51293
|
-
}
|
|
51294
|
-
if (!loadedCfg._configPath) {
|
|
51295
|
-
issues.push("missing-config");
|
|
51296
|
-
}
|
|
51297
|
-
if (!state.lastGenerated) {
|
|
51298
|
-
issues.push("missing-context");
|
|
51299
|
-
}
|
|
51300
|
-
if (issues.length === 0) {
|
|
51301
|
-
state.health = "good";
|
|
51302
|
-
} else if (issues.length <= 2) {
|
|
51303
|
-
state.health = "fair";
|
|
51304
|
-
} else {
|
|
51305
|
-
state.health = "needs-attention";
|
|
51306
|
-
}
|
|
51307
|
-
state.issues = issues;
|
|
51308
|
-
return state;
|
|
51648
|
+
function getPreset(presetName) {
|
|
51649
|
+
return CONFIG_PRESETS[presetName] ?? null;
|
|
51309
51650
|
}
|
|
51310
|
-
function
|
|
51311
|
-
const
|
|
51312
|
-
|
|
51313
|
-
|
|
51314
|
-
let score = 0;
|
|
51315
|
-
const maxScore = 10;
|
|
51316
|
-
if (cfg._configPath) {
|
|
51317
|
-
checks.push({ name: "Configuration", status: "pass", message: "bootspring.config.js found" });
|
|
51318
|
-
score += 2;
|
|
51319
|
-
} else {
|
|
51320
|
-
checks.push({ name: "Configuration", status: "fail", message: "bootspring.config.js missing" });
|
|
51651
|
+
function resolvePresetChain(presetName, seen = /* @__PURE__ */ new Set()) {
|
|
51652
|
+
const preset = CONFIG_PRESETS[presetName];
|
|
51653
|
+
if (!preset) {
|
|
51654
|
+
throw new Error(`Unknown preset: ${presetName}. Available: ${Object.keys(CONFIG_PRESETS).join(", ")}`);
|
|
51321
51655
|
}
|
|
51322
|
-
|
|
51323
|
-
|
|
51324
|
-
checks.push({ name: "AI Context", status: "pass", message: "CLAUDE.md exists" });
|
|
51325
|
-
score += 2;
|
|
51326
|
-
} else {
|
|
51327
|
-
checks.push({ name: "AI Context", status: "fail", message: "CLAUDE.md missing - run bootspring generate" });
|
|
51656
|
+
if (seen.has(presetName)) {
|
|
51657
|
+
throw new Error(`Circular preset inheritance detected: ${presetName}`);
|
|
51328
51658
|
}
|
|
51329
|
-
|
|
51330
|
-
|
|
51331
|
-
|
|
51332
|
-
|
|
51333
|
-
|
|
51659
|
+
seen.add(presetName);
|
|
51660
|
+
let config2 = { ...DEFAULT_CONFIG };
|
|
51661
|
+
if (preset.extends) {
|
|
51662
|
+
const parentConfig = resolvePresetChain(preset.extends, seen);
|
|
51663
|
+
config2 = deepMerge(config2, parentConfig);
|
|
51334
51664
|
}
|
|
51335
|
-
|
|
51336
|
-
|
|
51337
|
-
|
|
51338
|
-
|
|
51339
|
-
|
|
51665
|
+
config2 = deepMerge(config2, preset.config);
|
|
51666
|
+
return config2;
|
|
51667
|
+
}
|
|
51668
|
+
function applyPreset(presetNames, overrides = {}) {
|
|
51669
|
+
const presets = Array.isArray(presetNames) ? presetNames : [presetNames];
|
|
51670
|
+
if (presets.length === 0) {
|
|
51671
|
+
throw new Error("At least one preset name is required");
|
|
51340
51672
|
}
|
|
51341
|
-
|
|
51342
|
-
|
|
51343
|
-
|
|
51344
|
-
|
|
51345
|
-
|
|
51346
|
-
checks.push({ name: "TypeScript", status: "fail", message: "tsconfig.json missing for TypeScript project" });
|
|
51347
|
-
}
|
|
51348
|
-
} else {
|
|
51349
|
-
score += 1;
|
|
51673
|
+
let config2 = { ...DEFAULT_CONFIG };
|
|
51674
|
+
for (const presetName of presets) {
|
|
51675
|
+
const trimmedName = presetName.trim();
|
|
51676
|
+
const presetConfig = resolvePresetChain(trimmedName);
|
|
51677
|
+
config2 = deepMerge(config2, presetConfig);
|
|
51350
51678
|
}
|
|
51351
|
-
|
|
51352
|
-
|
|
51353
|
-
|
|
51354
|
-
|
|
51355
|
-
|
|
51356
|
-
|
|
51679
|
+
config2 = deepMerge(config2, overrides);
|
|
51680
|
+
return config2;
|
|
51681
|
+
}
|
|
51682
|
+
function combinePresets(presetNames, overrides = {}) {
|
|
51683
|
+
if (!Array.isArray(presetNames) || presetNames.length === 0) {
|
|
51684
|
+
throw new Error("combinePresets requires a non-empty array of preset names");
|
|
51357
51685
|
}
|
|
51358
|
-
|
|
51359
|
-
|
|
51360
|
-
|
|
51361
|
-
|
|
51362
|
-
|
|
51686
|
+
return applyPreset(presetNames, overrides);
|
|
51687
|
+
}
|
|
51688
|
+
function parsePresetString(presetString) {
|
|
51689
|
+
if (!presetString || typeof presetString !== "string") {
|
|
51690
|
+
return [];
|
|
51363
51691
|
}
|
|
51364
|
-
return
|
|
51365
|
-
valid: score >= maxScore * 0.6,
|
|
51366
|
-
score,
|
|
51367
|
-
maxScore,
|
|
51368
|
-
percentage: Math.round(score / maxScore * 100),
|
|
51369
|
-
checks
|
|
51370
|
-
};
|
|
51692
|
+
return presetString.split(",").map((s) => s.trim()).filter(Boolean);
|
|
51371
51693
|
}
|
|
51372
|
-
function
|
|
51373
|
-
const
|
|
51374
|
-
const
|
|
51375
|
-
|
|
51376
|
-
|
|
51377
|
-
|
|
51378
|
-
|
|
51379
|
-
|
|
51380
|
-
|
|
51381
|
-
|
|
51382
|
-
`- Language: ${ctx.stack?.language ?? "unknown"}`,
|
|
51383
|
-
`- Database: ${ctx.stack?.database ?? "unknown"}`,
|
|
51384
|
-
`- Hosting: ${ctx.stack?.hosting ?? "unknown"}`,
|
|
51385
|
-
""
|
|
51386
|
-
];
|
|
51387
|
-
const enabledPlugins = Object.keys(ctx.plugins);
|
|
51388
|
-
if (enabledPlugins.length > 0) {
|
|
51389
|
-
lines.push("## Enabled Plugins");
|
|
51390
|
-
for (const [name, plugin] of Object.entries(ctx.plugins)) {
|
|
51391
|
-
lines.push(`- **${name}**: ${plugin.provider}`);
|
|
51694
|
+
function validatePresets(presetNames) {
|
|
51695
|
+
const presets = Array.isArray(presetNames) ? presetNames : [presetNames];
|
|
51696
|
+
const errors = [];
|
|
51697
|
+
const validPresets = [];
|
|
51698
|
+
const availablePresets = Object.keys(CONFIG_PRESETS);
|
|
51699
|
+
for (const preset of presets) {
|
|
51700
|
+
if (CONFIG_PRESETS[preset]) {
|
|
51701
|
+
validPresets.push(preset);
|
|
51702
|
+
} else {
|
|
51703
|
+
errors.push(`Unknown preset: "${preset}". Available: ${availablePresets.join(", ")}`);
|
|
51392
51704
|
}
|
|
51393
|
-
lines.push("");
|
|
51394
|
-
}
|
|
51395
|
-
lines.push("## Project State");
|
|
51396
|
-
lines.push(`- Phase: ${ctx.state.phase}`);
|
|
51397
|
-
lines.push(`- Health: ${ctx.state.health}`);
|
|
51398
|
-
lines.push(`- Open Todos: ${ctx.state.todos}`);
|
|
51399
|
-
if (ctx.state.lastGenerated) {
|
|
51400
|
-
lines.push(`- Context Last Generated: ${utils.formatRelativeTime(ctx.state.lastGenerated)}`);
|
|
51401
|
-
}
|
|
51402
|
-
lines.push("");
|
|
51403
|
-
if (ctx.git.initialized) {
|
|
51404
|
-
lines.push("## Git");
|
|
51405
|
-
lines.push(`- Branch: ${ctx.git.branch ?? "unknown"}`);
|
|
51406
|
-
lines.push(`- Remote: ${ctx.git.hasRemote ? "configured" : "not configured"}`);
|
|
51407
|
-
lines.push("");
|
|
51408
51705
|
}
|
|
51409
|
-
return
|
|
51410
|
-
}
|
|
51411
|
-
var telemetry_exports = {};
|
|
51412
|
-
__export2(telemetry_exports, {
|
|
51413
|
-
ASSISTANTS: () => ASSISTANTS,
|
|
51414
|
-
ASSISTANT_FIRST_SUCCESS_EVENT: () => ASSISTANT_FIRST_SUCCESS_EVENT,
|
|
51415
|
-
ASSISTANT_RETURN_EVENT: () => ASSISTANT_RETURN_EVENT,
|
|
51416
|
-
ASSISTANT_SETUP_EVENT: () => ASSISTANT_SETUP_EVENT,
|
|
51417
|
-
BILLING_UPGRADE_STARTED_EVENT: () => BILLING_UPGRADE_STARTED_EVENT,
|
|
51418
|
-
MAX_EVENTS_LIMIT: () => MAX_EVENTS_LIMIT,
|
|
51419
|
-
UPGRADE_COMPLETED_EVENT: () => UPGRADE_COMPLETED_EVENT,
|
|
51420
|
-
UPGRADE_PROMPT_EVENT: () => UPGRADE_PROMPT_EVENT,
|
|
51421
|
-
clearEvents: () => clearEvents,
|
|
51422
|
-
emitEvent: () => emitEvent,
|
|
51423
|
-
ensureTelemetryDir: () => ensureTelemetryDir,
|
|
51424
|
-
getAssistantActivationFunnel: () => getAssistantActivationFunnel,
|
|
51425
|
-
getStatus: () => getStatus,
|
|
51426
|
-
getTelemetryDir: () => getTelemetryDir,
|
|
51427
|
-
getTelemetryFile: () => getTelemetryFile,
|
|
51428
|
-
getUpgradeConversionFunnel: () => getUpgradeConversionFunnel,
|
|
51429
|
-
inferAssistantFromEnvironment: () => inferAssistantFromEnvironment,
|
|
51430
|
-
listEvents: () => listEvents,
|
|
51431
|
-
track: () => track,
|
|
51432
|
-
trackAssistantSetup: () => trackAssistantSetup,
|
|
51433
|
-
trackAssistantUsageSuccess: () => trackAssistantUsageSuccess,
|
|
51434
|
-
uploadEvents: () => uploadEvents
|
|
51435
|
-
});
|
|
51436
|
-
init_cjs_shims2();
|
|
51437
|
-
var fs8 = __toESM2(require("fs"));
|
|
51438
|
-
var path9 = __toESM2(require("path"));
|
|
51439
|
-
var crypto2 = __toESM2(require("crypto"));
|
|
51440
|
-
var import_shared3 = (init_src(), __toCommonJS(src_exports));
|
|
51441
|
-
var MAX_EVENTS_LIMIT = 1e4;
|
|
51442
|
-
var ASSISTANTS = ["claude", "codex", "gemini"];
|
|
51443
|
-
var ASSISTANT_SETUP_EVENT = "assistant_setup";
|
|
51444
|
-
var ASSISTANT_FIRST_SUCCESS_EVENT = "assistant_first_success";
|
|
51445
|
-
var ASSISTANT_RETURN_EVENT = "assistant_return";
|
|
51446
|
-
var BILLING_UPGRADE_STARTED_EVENT = "billing_upgrade_started";
|
|
51447
|
-
var UPGRADE_PROMPT_EVENT = "premium_prompted";
|
|
51448
|
-
var UPGRADE_COMPLETED_EVENT = "premium_unlocked";
|
|
51449
|
-
var ASSISTANT_STATUS_ALLOWLIST = /* @__PURE__ */ new Set(["installed", "updated", "skipped", "failed", "created", "unchanged"]);
|
|
51450
|
-
var ASSISTANT_SOURCE_ALLOWLIST = /* @__PURE__ */ new Set(["mcp", "cli", "setup", "dashboard", "api", "unknown"]);
|
|
51451
|
-
function normalizeAssistantId(value) {
|
|
51452
|
-
const normalized = String(value || "").trim().toLowerCase();
|
|
51453
|
-
if (!normalized) return null;
|
|
51454
|
-
const compact = normalized.replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51455
|
-
if (compact === "claude" || compact === "claude-code") return "claude";
|
|
51456
|
-
if (compact === "codex" || compact === "openai-codex") return "codex";
|
|
51457
|
-
if (compact === "gemini" || compact === "gemini-cli") return "gemini";
|
|
51458
|
-
return null;
|
|
51459
|
-
}
|
|
51460
|
-
function inferAssistantFromEnvironment(env = process.env) {
|
|
51461
|
-
const explicit = normalizeAssistantId(env.BOOTSPRING_ASSISTANT);
|
|
51462
|
-
if (explicit) return explicit;
|
|
51463
|
-
if (env.CLAUDE_CODE || env.CLAUDECODE) return "claude";
|
|
51464
|
-
if (env.CODEX_SANDBOX || env.CODEX_ENV || env.OPENAI_CODEX) return "codex";
|
|
51465
|
-
if (env.GEMINI_CLI || env.GOOGLE_GEMINI_CLI) return "gemini";
|
|
51466
|
-
return null;
|
|
51467
|
-
}
|
|
51468
|
-
function normalizeCardinalityValue(value, fallback = "unknown") {
|
|
51469
|
-
const normalized = String(value || "").trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
51470
|
-
return normalized || fallback;
|
|
51471
|
-
}
|
|
51472
|
-
function normalizeAssistantStatus(value) {
|
|
51473
|
-
const normalized = normalizeCardinalityValue(value, "updated");
|
|
51474
|
-
return ASSISTANT_STATUS_ALLOWLIST.has(normalized) ? normalized : "other";
|
|
51475
|
-
}
|
|
51476
|
-
function normalizeAssistantSource(value) {
|
|
51477
|
-
const normalized = normalizeCardinalityValue(value, "unknown");
|
|
51478
|
-
return ASSISTANT_SOURCE_ALLOWLIST.has(normalized) ? normalized : "other";
|
|
51479
|
-
}
|
|
51480
|
-
function getTelemetryDir(projectRoot = process.cwd()) {
|
|
51481
|
-
return path9.join(projectRoot, ".bootspring", "telemetry");
|
|
51482
|
-
}
|
|
51483
|
-
function getTelemetryFile(projectRoot = process.cwd()) {
|
|
51484
|
-
return path9.join(getTelemetryDir(projectRoot), "events.jsonl");
|
|
51706
|
+
return { valid: errors.length === 0, errors, validPresets };
|
|
51485
51707
|
}
|
|
51486
|
-
function
|
|
51487
|
-
|
|
51488
|
-
fs8.mkdirSync(dir, { recursive: true });
|
|
51489
|
-
return dir;
|
|
51708
|
+
function getPresetsByTag(tag) {
|
|
51709
|
+
return Object.entries(CONFIG_PRESETS).filter(([, preset]) => preset.tags && preset.tags.includes(tag)).map(([key]) => key);
|
|
51490
51710
|
}
|
|
51491
|
-
function
|
|
51492
|
-
const
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
|
|
51496
|
-
|
|
51497
|
-
|
|
51498
|
-
|
|
51499
|
-
|
|
51711
|
+
function createCustomPreset(baseName, newName, customConfig = {}) {
|
|
51712
|
+
const basePreset = CONFIG_PRESETS[baseName];
|
|
51713
|
+
if (!basePreset) {
|
|
51714
|
+
throw new Error(`Unknown base preset: ${baseName}`);
|
|
51715
|
+
}
|
|
51716
|
+
return {
|
|
51717
|
+
name: newName,
|
|
51718
|
+
description: `Custom preset based on ${basePreset.name}`,
|
|
51719
|
+
tags: [...basePreset.tags || [], "custom"],
|
|
51720
|
+
extends: baseName,
|
|
51721
|
+
config: customConfig
|
|
51500
51722
|
};
|
|
51501
|
-
fs8.appendFileSync(file, `${JSON.stringify(record)}
|
|
51502
|
-
`, "utf-8");
|
|
51503
|
-
return record;
|
|
51504
|
-
}
|
|
51505
|
-
function getAssistantRecords(assistant, options = {}) {
|
|
51506
|
-
return listEvents({
|
|
51507
|
-
projectRoot: options.projectRoot
|
|
51508
|
-
}).filter((record) => normalizeAssistantId(record?.payload?.assistant) === assistant);
|
|
51509
51723
|
}
|
|
51510
|
-
function
|
|
51511
|
-
|
|
51512
|
-
if (
|
|
51513
|
-
|
|
51514
|
-
|
|
51515
|
-
|
|
51516
|
-
function eventTimeMs(record) {
|
|
51517
|
-
const occurredAt = String(record?.payload?.occurredAt || "").trim();
|
|
51518
|
-
const source = occurredAt || String(record?.timestamp || "").trim();
|
|
51519
|
-
const ts = new Date(source).getTime();
|
|
51520
|
-
return Number.isFinite(ts) ? ts : null;
|
|
51521
|
-
}
|
|
51522
|
-
function eventTimeIso(record) {
|
|
51523
|
-
const occurredAt = String(record?.payload?.occurredAt || "").trim();
|
|
51524
|
-
if (occurredAt) return occurredAt;
|
|
51525
|
-
const fallback = String(record?.timestamp || "").trim();
|
|
51526
|
-
return fallback || null;
|
|
51527
|
-
}
|
|
51528
|
-
function trackAssistantSetup(assistant, payload = {}, options = {}) {
|
|
51529
|
-
const normalized = normalizeAssistantId(assistant);
|
|
51530
|
-
if (!normalized) {
|
|
51531
|
-
return null;
|
|
51724
|
+
function listPresets(options = {}) {
|
|
51725
|
+
let entries = Object.entries(CONFIG_PRESETS);
|
|
51726
|
+
if (options.tag) {
|
|
51727
|
+
entries = entries.filter(
|
|
51728
|
+
([, preset]) => preset.tags && preset.tags.includes(options.tag)
|
|
51729
|
+
);
|
|
51532
51730
|
}
|
|
51533
|
-
return
|
|
51534
|
-
|
|
51535
|
-
|
|
51536
|
-
|
|
51537
|
-
|
|
51538
|
-
function trackAssistantUsageSuccess(assistant, payload = {}, options = {}) {
|
|
51539
|
-
const normalized = normalizeAssistantId(assistant);
|
|
51540
|
-
if (!normalized) {
|
|
51541
|
-
return {
|
|
51542
|
-
assistant: null,
|
|
51543
|
-
firstSuccessTracked: false,
|
|
51544
|
-
returnTracked: false,
|
|
51545
|
-
daysSinceFirst: null
|
|
51731
|
+
return entries.map(([key, preset]) => {
|
|
51732
|
+
const info = {
|
|
51733
|
+
key,
|
|
51734
|
+
name: preset.name,
|
|
51735
|
+
description: preset.description
|
|
51546
51736
|
};
|
|
51547
|
-
|
|
51548
|
-
|
|
51549
|
-
|
|
51550
|
-
|
|
51551
|
-
|
|
51552
|
-
|
|
51553
|
-
|
|
51554
|
-
|
|
51555
|
-
|
|
51556
|
-
|
|
51737
|
+
if (options.verbose) {
|
|
51738
|
+
info.tags = preset.tags || [];
|
|
51739
|
+
info.extends = preset.extends;
|
|
51740
|
+
}
|
|
51741
|
+
return info;
|
|
51742
|
+
});
|
|
51743
|
+
}
|
|
51744
|
+
var CONFIG_FILES = [
|
|
51745
|
+
"bootspring.config.js",
|
|
51746
|
+
"bootspring.config.mjs",
|
|
51747
|
+
"bootspring.config.json",
|
|
51748
|
+
".bootspringrc",
|
|
51749
|
+
".bootspringrc.js",
|
|
51750
|
+
".bootspringrc.json"
|
|
51751
|
+
];
|
|
51752
|
+
function formatValidationErrors(zodError) {
|
|
51753
|
+
return zodError.issues.map((issue) => {
|
|
51754
|
+
const path10 = issue.path.join(".");
|
|
51755
|
+
const prefix = path10 ? `${path10}: ` : "";
|
|
51756
|
+
const issueAny = issue;
|
|
51757
|
+
const code = issue.code;
|
|
51758
|
+
const message = issue.message;
|
|
51759
|
+
if (code === "invalid_type" && "expected" in issueAny) {
|
|
51760
|
+
return `${prefix}Expected ${issueAny.expected}, received ${typeof issueAny.input}`;
|
|
51761
|
+
}
|
|
51762
|
+
if (code === "invalid_value") {
|
|
51763
|
+
return `${prefix}Invalid value`;
|
|
51764
|
+
}
|
|
51765
|
+
if (code === "too_small" && "minimum" in issueAny) {
|
|
51766
|
+
return `${prefix}Value must be at least ${issueAny.minimum}`;
|
|
51767
|
+
}
|
|
51768
|
+
if (code === "too_big" && "maximum" in issueAny) {
|
|
51769
|
+
return `${prefix}Value must be at most ${issueAny.maximum}`;
|
|
51770
|
+
}
|
|
51771
|
+
if (code === "invalid_format") {
|
|
51772
|
+
return `${prefix}Invalid format`;
|
|
51773
|
+
}
|
|
51774
|
+
return `${prefix}${message}`;
|
|
51775
|
+
});
|
|
51776
|
+
}
|
|
51777
|
+
var sectionSchemas = {
|
|
51778
|
+
project: ProjectConfigSchema,
|
|
51779
|
+
stack: StackConfigSchema,
|
|
51780
|
+
plugins: PluginsSchema,
|
|
51781
|
+
agents: AgentsConfigSchema,
|
|
51782
|
+
skills: SkillsConfigSchema,
|
|
51783
|
+
workflows: WorkflowsConfigSchema,
|
|
51784
|
+
dashboard: DashboardConfigSchema,
|
|
51785
|
+
quality: QualityConfigSchema,
|
|
51786
|
+
context: ContextConfigSchema,
|
|
51787
|
+
paths: PathsConfigSchema
|
|
51788
|
+
};
|
|
51789
|
+
function validateSection(section, data) {
|
|
51790
|
+
const schema = sectionSchemas[section];
|
|
51791
|
+
if (!schema) {
|
|
51557
51792
|
return {
|
|
51558
|
-
|
|
51559
|
-
|
|
51560
|
-
|
|
51561
|
-
daysSinceFirst: 0
|
|
51793
|
+
valid: false,
|
|
51794
|
+
errors: [`Unknown configuration section: ${section}`],
|
|
51795
|
+
data: null
|
|
51562
51796
|
};
|
|
51563
51797
|
}
|
|
51564
|
-
const
|
|
51565
|
-
|
|
51566
|
-
|
|
51567
|
-
const window = returnWindow(daysSinceFirst);
|
|
51568
|
-
const alreadyTrackedWindow = records.some((record) => {
|
|
51569
|
-
if (record.event !== ASSISTANT_RETURN_EVENT) return false;
|
|
51570
|
-
return String(record?.payload?.window || "") === window;
|
|
51571
|
-
});
|
|
51572
|
-
if (!alreadyTrackedWindow) {
|
|
51573
|
-
emitEvent(ASSISTANT_RETURN_EVENT, {
|
|
51574
|
-
assistant: normalized,
|
|
51575
|
-
source: normalizeAssistantSource(payload.source || "mcp"),
|
|
51576
|
-
window
|
|
51577
|
-
}, { projectRoot, now });
|
|
51578
|
-
return {
|
|
51579
|
-
assistant: normalized,
|
|
51580
|
-
firstSuccessTracked: false,
|
|
51581
|
-
returnTracked: true,
|
|
51582
|
-
daysSinceFirst
|
|
51583
|
-
};
|
|
51584
|
-
}
|
|
51798
|
+
const result = schema.safeParse(data);
|
|
51799
|
+
if (result.success) {
|
|
51800
|
+
return { valid: true, errors: [], data: result.data };
|
|
51585
51801
|
}
|
|
51586
51802
|
return {
|
|
51587
|
-
|
|
51588
|
-
|
|
51589
|
-
|
|
51590
|
-
daysSinceFirst
|
|
51803
|
+
valid: false,
|
|
51804
|
+
errors: formatValidationErrors(result.error),
|
|
51805
|
+
data: null
|
|
51591
51806
|
};
|
|
51592
51807
|
}
|
|
51593
|
-
function
|
|
51594
|
-
|
|
51595
|
-
|
|
51596
|
-
|
|
51597
|
-
|
|
51808
|
+
function findProjectRoot() {
|
|
51809
|
+
let dir = process.cwd();
|
|
51810
|
+
const root = path8.parse(dir).root;
|
|
51811
|
+
while (dir !== root) {
|
|
51812
|
+
if (fs8.existsSync(path8.join(dir, "package.json")) || fs8.existsSync(path8.join(dir, "bootspring.config.js")) || fs8.existsSync(path8.join(dir, ".git"))) {
|
|
51813
|
+
return dir;
|
|
51814
|
+
}
|
|
51815
|
+
dir = path8.dirname(dir);
|
|
51598
51816
|
}
|
|
51817
|
+
return process.cwd();
|
|
51599
51818
|
}
|
|
51600
|
-
function
|
|
51601
|
-
const
|
|
51602
|
-
|
|
51603
|
-
|
|
51604
|
-
|
|
51605
|
-
|
|
51606
|
-
const to = options.to ? new Date(options.to).getTime() : null;
|
|
51607
|
-
const limit = Number(options.limit);
|
|
51608
|
-
const lines = fs8.readFileSync(file, "utf-8").split("\n").filter(Boolean);
|
|
51609
|
-
let records = lines.map(parseEventLine).filter((record) => record !== null).filter((record) => {
|
|
51610
|
-
if (eventFilter && record.event !== eventFilter) return false;
|
|
51611
|
-
const ts = new Date(record.timestamp).getTime();
|
|
51612
|
-
if (Number.isFinite(from) && from !== null && ts < from) return false;
|
|
51613
|
-
if (Number.isFinite(to) && to !== null && ts > to) return false;
|
|
51614
|
-
return true;
|
|
51615
|
-
});
|
|
51616
|
-
const effectiveLimit = Number.isFinite(limit) && limit > 0 ? Math.min(limit, MAX_EVENTS_LIMIT) : MAX_EVENTS_LIMIT;
|
|
51617
|
-
records = records.slice(-effectiveLimit);
|
|
51618
|
-
return records;
|
|
51619
|
-
}
|
|
51620
|
-
function clearEvents(options = {}) {
|
|
51621
|
-
const projectRoot = options.projectRoot || process.cwd();
|
|
51622
|
-
const file = getTelemetryFile(projectRoot);
|
|
51623
|
-
const records = listEvents({ projectRoot });
|
|
51624
|
-
if (fs8.existsSync(file)) {
|
|
51625
|
-
fs8.writeFileSync(file, "", "utf-8");
|
|
51819
|
+
function findConfigFile(projectRoot) {
|
|
51820
|
+
for (const filename of CONFIG_FILES) {
|
|
51821
|
+
const filepath = path8.join(projectRoot, filename);
|
|
51822
|
+
if (fs8.existsSync(filepath)) {
|
|
51823
|
+
return filepath;
|
|
51824
|
+
}
|
|
51626
51825
|
}
|
|
51627
|
-
return
|
|
51628
|
-
cleared: records.length,
|
|
51629
|
-
file
|
|
51630
|
-
};
|
|
51826
|
+
return null;
|
|
51631
51827
|
}
|
|
51632
|
-
function
|
|
51633
|
-
const
|
|
51634
|
-
const
|
|
51635
|
-
|
|
51636
|
-
|
|
51637
|
-
|
|
51638
|
-
|
|
51639
|
-
|
|
51640
|
-
|
|
51641
|
-
|
|
51642
|
-
|
|
51828
|
+
function load(projectRoot = null) {
|
|
51829
|
+
const root = projectRoot ?? findProjectRoot();
|
|
51830
|
+
const configPath = findConfigFile(root);
|
|
51831
|
+
let userConfig = {};
|
|
51832
|
+
if (configPath) {
|
|
51833
|
+
try {
|
|
51834
|
+
if (configPath.endsWith(".json") || configPath.endsWith(".bootspringrc")) {
|
|
51835
|
+
const content = fs8.readFileSync(configPath, "utf-8");
|
|
51836
|
+
userConfig = JSON.parse(content);
|
|
51837
|
+
} else {
|
|
51838
|
+
delete require.cache[require.resolve(configPath)];
|
|
51839
|
+
userConfig = require(configPath);
|
|
51840
|
+
}
|
|
51841
|
+
} catch (error) {
|
|
51842
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51843
|
+
console.warn(`Warning: Could not load config from ${configPath}: ${message}`);
|
|
51844
|
+
}
|
|
51845
|
+
}
|
|
51846
|
+
const config2 = deepMerge(DEFAULT_CONFIG, userConfig);
|
|
51847
|
+
config2._projectRoot = root;
|
|
51848
|
+
config2._configPath = configPath;
|
|
51849
|
+
config2._bootspringDir = path8.join(root, ".bootspring");
|
|
51850
|
+
return config2;
|
|
51643
51851
|
}
|
|
51644
|
-
function
|
|
51645
|
-
const
|
|
51646
|
-
const
|
|
51647
|
-
|
|
51648
|
-
|
|
51852
|
+
function save(config2, filepath = null) {
|
|
51853
|
+
const root = config2._projectRoot ?? findProjectRoot();
|
|
51854
|
+
const targetPath = filepath ?? path8.join(root, "bootspring.config.js");
|
|
51855
|
+
const cleanConfig = { ...config2 };
|
|
51856
|
+
delete cleanConfig._projectRoot;
|
|
51857
|
+
delete cleanConfig._configPath;
|
|
51858
|
+
delete cleanConfig._bootspringDir;
|
|
51859
|
+
delete cleanConfig._validation;
|
|
51860
|
+
const content = `/**
|
|
51861
|
+
* Bootspring Configuration
|
|
51862
|
+
* https://bootspring.com/docs/configuration
|
|
51863
|
+
*/
|
|
51864
|
+
|
|
51865
|
+
module.exports = ${JSON.stringify(cleanConfig, null, 2)};
|
|
51866
|
+
`;
|
|
51867
|
+
try {
|
|
51868
|
+
fs8.writeFileSync(targetPath, content, "utf-8");
|
|
51869
|
+
return true;
|
|
51870
|
+
} catch (error) {
|
|
51871
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
51872
|
+
console.error(`Error saving config: ${message}`);
|
|
51873
|
+
return false;
|
|
51649
51874
|
}
|
|
51650
|
-
return Math.floor((to - from) / (24 * 60 * 60 * 1e3));
|
|
51651
51875
|
}
|
|
51652
|
-
function
|
|
51653
|
-
const
|
|
51654
|
-
|
|
51655
|
-
|
|
51656
|
-
|
|
51657
|
-
|
|
51658
|
-
|
|
51659
|
-
|
|
51660
|
-
|
|
51661
|
-
|
|
51662
|
-
const
|
|
51663
|
-
|
|
51664
|
-
|
|
51665
|
-
|
|
51876
|
+
function validate(config2, options = {}) {
|
|
51877
|
+
const configToValidate = { ...config2 };
|
|
51878
|
+
delete configToValidate._projectRoot;
|
|
51879
|
+
delete configToValidate._configPath;
|
|
51880
|
+
delete configToValidate._bootspringDir;
|
|
51881
|
+
delete configToValidate._validation;
|
|
51882
|
+
const errors = [];
|
|
51883
|
+
const warnings = [];
|
|
51884
|
+
if (options.sections && options.sections.length > 0) {
|
|
51885
|
+
let allValid = true;
|
|
51886
|
+
const validatedData = {};
|
|
51887
|
+
for (const section of options.sections) {
|
|
51888
|
+
const sectionValue = configToValidate[section];
|
|
51889
|
+
if (sectionValue !== void 0) {
|
|
51890
|
+
const result2 = validateSection(section, sectionValue);
|
|
51891
|
+
if (!result2.valid) {
|
|
51892
|
+
allValid = false;
|
|
51893
|
+
errors.push(...result2.errors);
|
|
51894
|
+
} else {
|
|
51895
|
+
validatedData[section] = result2.data;
|
|
51896
|
+
}
|
|
51897
|
+
}
|
|
51898
|
+
}
|
|
51899
|
+
return {
|
|
51900
|
+
valid: allValid,
|
|
51901
|
+
errors,
|
|
51902
|
+
warnings,
|
|
51903
|
+
data: allValid ? validatedData : null
|
|
51904
|
+
};
|
|
51905
|
+
}
|
|
51906
|
+
const result = ConfigSchema.safeParse(configToValidate);
|
|
51907
|
+
if (result.success) {
|
|
51908
|
+
return { valid: true, errors: [], warnings, data: result.data };
|
|
51909
|
+
}
|
|
51666
51910
|
return {
|
|
51667
|
-
|
|
51668
|
-
|
|
51669
|
-
|
|
51670
|
-
|
|
51671
|
-
d7,
|
|
51672
|
-
setupAt: eventTimeIso(setupEvent),
|
|
51673
|
-
firstSuccessAt: eventTimeIso(firstSuccessEvent),
|
|
51674
|
-
lastReturnAt: eventTimeIso(lastReturn)
|
|
51911
|
+
valid: false,
|
|
51912
|
+
errors: formatValidationErrors(result.error),
|
|
51913
|
+
warnings,
|
|
51914
|
+
data: null
|
|
51675
51915
|
};
|
|
51676
51916
|
}
|
|
51677
|
-
function
|
|
51678
|
-
const
|
|
51679
|
-
const
|
|
51680
|
-
|
|
51681
|
-
|
|
51682
|
-
|
|
51683
|
-
|
|
51684
|
-
|
|
51685
|
-
|
|
51686
|
-
|
|
51687
|
-
|
|
51688
|
-
|
|
51917
|
+
function loadWithValidation(projectRoot = null, options = {}) {
|
|
51918
|
+
const { validate: shouldValidate = true, strict = false, silent = false } = options;
|
|
51919
|
+
const config2 = load(projectRoot);
|
|
51920
|
+
if (!shouldValidate) {
|
|
51921
|
+
config2._validation = { skipped: true };
|
|
51922
|
+
return config2;
|
|
51923
|
+
}
|
|
51924
|
+
const validation = validate(config2);
|
|
51925
|
+
config2._validation = {
|
|
51926
|
+
valid: validation.valid,
|
|
51927
|
+
errors: validation.errors,
|
|
51928
|
+
warnings: validation.warnings ?? [],
|
|
51929
|
+
validatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
51689
51930
|
};
|
|
51690
|
-
|
|
51691
|
-
|
|
51692
|
-
|
|
51693
|
-
|
|
51694
|
-
|
|
51695
|
-
|
|
51696
|
-
if (
|
|
51697
|
-
|
|
51698
|
-
|
|
51699
|
-
|
|
51700
|
-
|
|
51701
|
-
|
|
51702
|
-
|
|
51703
|
-
|
|
51704
|
-
|
|
51705
|
-
|
|
51706
|
-
|
|
51707
|
-
|
|
51708
|
-
|
|
51931
|
+
if (!validation.valid) {
|
|
51932
|
+
if (strict) {
|
|
51933
|
+
const errorMessage = `Configuration validation failed:
|
|
51934
|
+
${validation.errors.map((e) => ` - ${e}`).join("\n")}`;
|
|
51935
|
+
throw new Error(errorMessage);
|
|
51936
|
+
}
|
|
51937
|
+
if (!silent) {
|
|
51938
|
+
console.warn("\x1B[33mWarning: Configuration has validation issues:\x1B[0m");
|
|
51939
|
+
validation.errors.forEach((error) => {
|
|
51940
|
+
console.warn(` \x1B[33m- ${error}\x1B[0m`);
|
|
51941
|
+
});
|
|
51942
|
+
console.warn("\x1B[33mThe configuration will still be used, but some features may not work correctly.\x1B[0m");
|
|
51943
|
+
}
|
|
51944
|
+
}
|
|
51945
|
+
return config2;
|
|
51946
|
+
}
|
|
51947
|
+
function getValidationHint(errorPath) {
|
|
51948
|
+
const hints = {
|
|
51949
|
+
"stack.framework": "Valid frameworks: nextjs, remix, nuxt, sveltekit, astro, express, fastify, hono, custom",
|
|
51950
|
+
"stack.language": "Valid languages: typescript, javascript",
|
|
51951
|
+
"stack.database": "Valid databases: postgresql, mysql, mongodb, sqlite, supabase, planetscale, none",
|
|
51952
|
+
"stack.hosting": "Valid hosting options: vercel, railway, render, fly, aws, gcp, azure, cloudflare, self-hosted, custom",
|
|
51953
|
+
"plugins.auth.provider": "Valid auth providers: clerk, nextauth, auth0, supabase, jwt, custom",
|
|
51954
|
+
"plugins.payments.provider": "Valid payment providers: stripe, paddle, lemonsqueezy, paypal, custom",
|
|
51955
|
+
"plugins.database.provider": "Valid database ORMs: prisma, drizzle, typeorm, kysely, custom",
|
|
51956
|
+
"plugins.testing.provider": "Valid test frameworks: vitest, jest, playwright, cypress, custom",
|
|
51957
|
+
"plugins.ai.providers": "Valid AI providers: anthropic, openai, google, cohere, huggingface, custom",
|
|
51958
|
+
"dashboard.port": "Port must be between 1024 and 65535",
|
|
51959
|
+
"project.version": "Version must follow semver format (e.g., 1.0.0)"
|
|
51709
51960
|
};
|
|
51961
|
+
return hints[errorPath] ?? null;
|
|
51710
51962
|
}
|
|
51711
|
-
function
|
|
51712
|
-
|
|
51713
|
-
|
|
51963
|
+
function parseConfig(config2) {
|
|
51964
|
+
const configToParse = { ...config2 };
|
|
51965
|
+
delete configToParse._projectRoot;
|
|
51966
|
+
delete configToParse._configPath;
|
|
51967
|
+
delete configToParse._bootspringDir;
|
|
51968
|
+
delete configToParse._validation;
|
|
51969
|
+
const result = ConfigSchema.safeParse(configToParse);
|
|
51970
|
+
if (result.success) {
|
|
51971
|
+
return result.data;
|
|
51972
|
+
}
|
|
51973
|
+
return configToParse;
|
|
51714
51974
|
}
|
|
51715
|
-
function
|
|
51716
|
-
|
|
51717
|
-
return normalized || fallback;
|
|
51975
|
+
function getDefaults() {
|
|
51976
|
+
return { ...DEFAULT_CONFIG };
|
|
51718
51977
|
}
|
|
51719
|
-
|
|
51720
|
-
|
|
51721
|
-
|
|
51722
|
-
|
|
51723
|
-
|
|
51724
|
-
|
|
51725
|
-
|
|
51726
|
-
|
|
51978
|
+
var context_exports = {};
|
|
51979
|
+
__export2(context_exports, {
|
|
51980
|
+
generateSummary: () => generateSummary,
|
|
51981
|
+
get: () => get,
|
|
51982
|
+
getEnabledPlugins: () => getEnabledPlugins,
|
|
51983
|
+
getGitInfo: () => getGitInfo,
|
|
51984
|
+
getProjectFiles: () => getProjectFiles,
|
|
51985
|
+
getProjectState: () => getProjectState,
|
|
51986
|
+
validate: () => validate2
|
|
51987
|
+
});
|
|
51988
|
+
init_cjs_shims2();
|
|
51989
|
+
var path9 = __toESM2(require("path"));
|
|
51990
|
+
var utils = __toESM2((init_src(), __toCommonJS(src_exports)));
|
|
51991
|
+
function get(options = {}) {
|
|
51992
|
+
const cfg = options.config ?? load();
|
|
51993
|
+
const projectRoot = cfg._projectRoot ?? process.cwd();
|
|
51994
|
+
const context2 = {
|
|
51995
|
+
project: cfg.project,
|
|
51996
|
+
stack: cfg.stack,
|
|
51997
|
+
plugins: getEnabledPlugins(cfg),
|
|
51998
|
+
files: getProjectFiles(projectRoot),
|
|
51999
|
+
git: getGitInfo(projectRoot),
|
|
52000
|
+
state: getProjectState(projectRoot, cfg),
|
|
52001
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
51727
52002
|
};
|
|
52003
|
+
return context2;
|
|
51728
52004
|
}
|
|
51729
|
-
function
|
|
51730
|
-
const
|
|
51731
|
-
const
|
|
51732
|
-
const
|
|
51733
|
-
|
|
51734
|
-
|
|
51735
|
-
|
|
51736
|
-
|
|
51737
|
-
const context2 = getUpgradeEventContext(record.payload);
|
|
51738
|
-
const key = `${context2.capability}:${context2.featureType}:${context2.feature}`;
|
|
51739
|
-
if (!capabilities[key]) {
|
|
51740
|
-
capabilities[key] = {
|
|
51741
|
-
capability: context2.capability,
|
|
51742
|
-
featureType: context2.featureType,
|
|
51743
|
-
feature: context2.feature,
|
|
51744
|
-
prompted: 0,
|
|
51745
|
-
started: 0,
|
|
51746
|
-
completed: 0,
|
|
51747
|
-
converted: 0,
|
|
51748
|
-
conversionRate: 0,
|
|
51749
|
-
placements: {},
|
|
51750
|
-
variants: {}
|
|
52005
|
+
function getEnabledPlugins(cfg) {
|
|
52006
|
+
const enabled = {};
|
|
52007
|
+
const plugins = cfg.plugins ?? {};
|
|
52008
|
+
for (const [name, plugin] of Object.entries(plugins)) {
|
|
52009
|
+
if (plugin && plugin.enabled !== false) {
|
|
52010
|
+
enabled[name] = {
|
|
52011
|
+
provider: plugin.provider ?? "default",
|
|
52012
|
+
features: plugin.features ?? []
|
|
51751
52013
|
};
|
|
51752
52014
|
}
|
|
51753
|
-
const bucket = capabilities[key];
|
|
51754
|
-
if (!bucket) continue;
|
|
51755
|
-
if (record.event === UPGRADE_PROMPT_EVENT) {
|
|
51756
|
-
bucket.prompted += 1;
|
|
51757
|
-
bucket.placements[context2.placement] = (bucket.placements[context2.placement] || 0) + 1;
|
|
51758
|
-
bucket.variants[context2.variant] = (bucket.variants[context2.variant] || 0) + 1;
|
|
51759
|
-
continue;
|
|
51760
|
-
}
|
|
51761
|
-
if (record.event === BILLING_UPGRADE_STARTED_EVENT) {
|
|
51762
|
-
bucket.started += 1;
|
|
51763
|
-
continue;
|
|
51764
|
-
}
|
|
51765
|
-
bucket.completed += 1;
|
|
51766
52015
|
}
|
|
51767
|
-
|
|
51768
|
-
bucket.converted = Math.min(bucket.prompted, bucket.completed);
|
|
51769
|
-
bucket.conversionRate = safeRate(bucket.converted, bucket.prompted);
|
|
51770
|
-
acc.prompted += bucket.prompted;
|
|
51771
|
-
acc.started += bucket.started;
|
|
51772
|
-
acc.completed += bucket.completed;
|
|
51773
|
-
acc.converted += bucket.converted;
|
|
51774
|
-
return acc;
|
|
51775
|
-
}, {
|
|
51776
|
-
prompted: 0,
|
|
51777
|
-
started: 0,
|
|
51778
|
-
completed: 0,
|
|
51779
|
-
converted: 0
|
|
51780
|
-
});
|
|
51781
|
-
return {
|
|
51782
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
51783
|
-
totals: {
|
|
51784
|
-
...totals,
|
|
51785
|
-
startRate: safeRate(totals.started, totals.prompted),
|
|
51786
|
-
conversionRate: safeRate(totals.converted, totals.prompted)
|
|
51787
|
-
},
|
|
51788
|
-
capabilities
|
|
51789
|
-
};
|
|
51790
|
-
}
|
|
51791
|
-
function sleep(ms) {
|
|
51792
|
-
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
52016
|
+
return enabled;
|
|
51793
52017
|
}
|
|
51794
|
-
function
|
|
51795
|
-
const
|
|
51796
|
-
|
|
51797
|
-
|
|
52018
|
+
function getProjectFiles(projectRoot) {
|
|
52019
|
+
const files = {
|
|
52020
|
+
hasPackageJson: utils.fileExists(path9.join(projectRoot, "package.json")),
|
|
52021
|
+
hasTsConfig: utils.fileExists(path9.join(projectRoot, "tsconfig.json")),
|
|
52022
|
+
hasClaudeMd: utils.fileExists(path9.join(projectRoot, "CLAUDE.md")),
|
|
52023
|
+
hasBootspringConfig: utils.fileExists(path9.join(projectRoot, "bootspring.config.js")),
|
|
52024
|
+
hasTodoMd: utils.fileExists(path9.join(projectRoot, "planning", "TODO.md")),
|
|
52025
|
+
hasGit: utils.fileExists(path9.join(projectRoot, ".git")),
|
|
52026
|
+
hasSrcDir: utils.fileExists(path9.join(projectRoot, "src")),
|
|
52027
|
+
hasAppDir: utils.fileExists(path9.join(projectRoot, "app")),
|
|
52028
|
+
hasPagesDir: utils.fileExists(path9.join(projectRoot, "pages")),
|
|
52029
|
+
structure: "flat"
|
|
52030
|
+
};
|
|
52031
|
+
if (files.hasAppDir) {
|
|
52032
|
+
files.structure = "app-router";
|
|
52033
|
+
} else if (files.hasPagesDir) {
|
|
52034
|
+
files.structure = "pages-router";
|
|
52035
|
+
} else if (files.hasSrcDir) {
|
|
52036
|
+
files.structure = "src-based";
|
|
51798
52037
|
}
|
|
51799
|
-
return
|
|
52038
|
+
return files;
|
|
51800
52039
|
}
|
|
51801
|
-
|
|
51802
|
-
const
|
|
51803
|
-
|
|
51804
|
-
|
|
51805
|
-
|
|
51806
|
-
|
|
51807
|
-
|
|
51808
|
-
|
|
51809
|
-
|
|
51810
|
-
|
|
51811
|
-
|
|
51812
|
-
|
|
51813
|
-
|
|
51814
|
-
if (!response.ok) {
|
|
51815
|
-
throw new Error(`HTTP ${response.status}`);
|
|
51816
|
-
}
|
|
51817
|
-
return { success: true, attempts: attempt + 1 };
|
|
51818
|
-
} catch (error) {
|
|
51819
|
-
if (attempt >= retries) {
|
|
51820
|
-
return {
|
|
51821
|
-
success: false,
|
|
51822
|
-
attempts: attempt + 1,
|
|
51823
|
-
error: (0, import_shared3.redactErrorMessage)(error)
|
|
51824
|
-
};
|
|
52040
|
+
function getGitInfo(projectRoot) {
|
|
52041
|
+
const gitDir = path9.join(projectRoot, ".git");
|
|
52042
|
+
if (!utils.fileExists(gitDir)) {
|
|
52043
|
+
return { initialized: false };
|
|
52044
|
+
}
|
|
52045
|
+
const info = { initialized: true };
|
|
52046
|
+
const headPath = path9.join(gitDir, "HEAD");
|
|
52047
|
+
if (utils.fileExists(headPath)) {
|
|
52048
|
+
const head = utils.readFile(headPath);
|
|
52049
|
+
if (head) {
|
|
52050
|
+
const trimmedHead = head.trim();
|
|
52051
|
+
if (trimmedHead.startsWith("ref: refs/heads/")) {
|
|
52052
|
+
info.branch = trimmedHead.replace("ref: refs/heads/", "");
|
|
51825
52053
|
}
|
|
51826
|
-
attempt += 1;
|
|
51827
|
-
const delay = delayBase * 2 ** (attempt - 1);
|
|
51828
|
-
await sleep(delay);
|
|
51829
52054
|
}
|
|
51830
52055
|
}
|
|
52056
|
+
const configPath = path9.join(gitDir, "config");
|
|
52057
|
+
if (utils.fileExists(configPath)) {
|
|
52058
|
+
const gitConfig = utils.readFile(configPath);
|
|
52059
|
+
if (gitConfig) {
|
|
52060
|
+
info.hasRemote = gitConfig.includes('[remote "origin"]');
|
|
52061
|
+
}
|
|
52062
|
+
}
|
|
52063
|
+
return info;
|
|
51831
52064
|
}
|
|
51832
|
-
|
|
51833
|
-
const
|
|
51834
|
-
|
|
51835
|
-
|
|
51836
|
-
|
|
51837
|
-
|
|
51838
|
-
|
|
51839
|
-
const
|
|
51840
|
-
|
|
51841
|
-
|
|
51842
|
-
|
|
51843
|
-
|
|
51844
|
-
|
|
51845
|
-
|
|
51846
|
-
uploaded: 0,
|
|
51847
|
-
remaining: 0,
|
|
51848
|
-
endpoint
|
|
51849
|
-
};
|
|
52065
|
+
function getProjectState(projectRoot, cfg) {
|
|
52066
|
+
const state = {
|
|
52067
|
+
phase: "unknown",
|
|
52068
|
+
health: "unknown",
|
|
52069
|
+
todos: 0,
|
|
52070
|
+
lastGenerated: null
|
|
52071
|
+
};
|
|
52072
|
+
const todoPath = path9.join(projectRoot, cfg.paths?.todo ?? "planning/TODO.md");
|
|
52073
|
+
if (utils.fileExists(todoPath)) {
|
|
52074
|
+
const content = utils.readFile(todoPath);
|
|
52075
|
+
if (content) {
|
|
52076
|
+
const todoMatches = content.match(/- \[ \]/g);
|
|
52077
|
+
state.todos = todoMatches ? todoMatches.length : 0;
|
|
52078
|
+
}
|
|
51850
52079
|
}
|
|
51851
|
-
|
|
51852
|
-
|
|
51853
|
-
|
|
51854
|
-
const auth3 = await Promise.resolve().then(() => (init_auth(), auth_exports));
|
|
51855
|
-
const session2 = await Promise.resolve().then(() => (init_session(), session_exports));
|
|
51856
|
-
apiKey = auth3.getApiKey();
|
|
51857
|
-
const project = session2.getEffectiveProject();
|
|
51858
|
-
projectId = project?.id ?? null;
|
|
51859
|
-
} catch {
|
|
52080
|
+
const claudePath = path9.join(projectRoot, cfg.paths?.context ?? "CLAUDE.md");
|
|
52081
|
+
if (utils.fileExists(claudePath)) {
|
|
52082
|
+
state.lastGenerated = utils.getFileTime(claudePath);
|
|
51860
52083
|
}
|
|
51861
|
-
const
|
|
51862
|
-
|
|
51863
|
-
|
|
51864
|
-
|
|
51865
|
-
"
|
|
51866
|
-
}
|
|
51867
|
-
|
|
51868
|
-
headers["x-api-key"] = apiKey;
|
|
51869
|
-
} else if (token) {
|
|
51870
|
-
headers.authorization = `Bearer ${token}`;
|
|
52084
|
+
const loadedCfg = cfg;
|
|
52085
|
+
if (!loadedCfg._configPath) {
|
|
52086
|
+
state.phase = "uninitialized";
|
|
52087
|
+
} else if (!state.lastGenerated) {
|
|
52088
|
+
state.phase = "initialized";
|
|
52089
|
+
} else {
|
|
52090
|
+
state.phase = "active";
|
|
51871
52091
|
}
|
|
51872
|
-
|
|
51873
|
-
|
|
52092
|
+
const issues = [];
|
|
52093
|
+
if (!utils.fileExists(path9.join(projectRoot, "package.json"))) {
|
|
52094
|
+
issues.push("missing-package-json");
|
|
51874
52095
|
}
|
|
51875
|
-
|
|
51876
|
-
|
|
51877
|
-
|
|
51878
|
-
|
|
51879
|
-
|
|
51880
|
-
|
|
51881
|
-
|
|
51882
|
-
|
|
51883
|
-
|
|
51884
|
-
|
|
51885
|
-
|
|
51886
|
-
|
|
51887
|
-
|
|
51888
|
-
|
|
51889
|
-
|
|
51890
|
-
|
|
51891
|
-
|
|
51892
|
-
|
|
51893
|
-
|
|
51894
|
-
|
|
51895
|
-
|
|
51896
|
-
|
|
51897
|
-
|
|
51898
|
-
|
|
51899
|
-
|
|
51900
|
-
|
|
51901
|
-
|
|
51902
|
-
|
|
51903
|
-
|
|
51904
|
-
|
|
51905
|
-
|
|
51906
|
-
|
|
51907
|
-
|
|
52096
|
+
if (!loadedCfg._configPath) {
|
|
52097
|
+
issues.push("missing-config");
|
|
52098
|
+
}
|
|
52099
|
+
if (!state.lastGenerated) {
|
|
52100
|
+
issues.push("missing-context");
|
|
52101
|
+
}
|
|
52102
|
+
if (issues.length === 0) {
|
|
52103
|
+
state.health = "good";
|
|
52104
|
+
} else if (issues.length <= 2) {
|
|
52105
|
+
state.health = "fair";
|
|
52106
|
+
} else {
|
|
52107
|
+
state.health = "needs-attention";
|
|
52108
|
+
}
|
|
52109
|
+
state.issues = issues;
|
|
52110
|
+
return state;
|
|
52111
|
+
}
|
|
52112
|
+
function validate2(options = {}) {
|
|
52113
|
+
const cfg = options.config ?? load();
|
|
52114
|
+
const projectRoot = cfg._projectRoot ?? process.cwd();
|
|
52115
|
+
const checks = [];
|
|
52116
|
+
let score = 0;
|
|
52117
|
+
const maxScore = 10;
|
|
52118
|
+
if (cfg._configPath) {
|
|
52119
|
+
checks.push({ name: "Configuration", status: "pass", message: "bootspring.config.js found" });
|
|
52120
|
+
score += 2;
|
|
52121
|
+
} else {
|
|
52122
|
+
checks.push({ name: "Configuration", status: "fail", message: "bootspring.config.js missing" });
|
|
52123
|
+
}
|
|
52124
|
+
const claudePath = path9.join(projectRoot, cfg.paths?.context ?? "CLAUDE.md");
|
|
52125
|
+
if (utils.fileExists(claudePath)) {
|
|
52126
|
+
checks.push({ name: "AI Context", status: "pass", message: "CLAUDE.md exists" });
|
|
52127
|
+
score += 2;
|
|
52128
|
+
} else {
|
|
52129
|
+
checks.push({ name: "AI Context", status: "fail", message: "CLAUDE.md missing - run bootspring generate" });
|
|
52130
|
+
}
|
|
52131
|
+
if (utils.fileExists(path9.join(projectRoot, "package.json"))) {
|
|
52132
|
+
checks.push({ name: "Package", status: "pass", message: "package.json found" });
|
|
52133
|
+
score += 1;
|
|
52134
|
+
} else {
|
|
52135
|
+
checks.push({ name: "Package", status: "warn", message: "package.json missing" });
|
|
52136
|
+
}
|
|
52137
|
+
if (utils.fileExists(path9.join(projectRoot, ".git"))) {
|
|
52138
|
+
checks.push({ name: "Git", status: "pass", message: "Git repository initialized" });
|
|
52139
|
+
score += 1;
|
|
52140
|
+
} else {
|
|
52141
|
+
checks.push({ name: "Git", status: "warn", message: "Git not initialized" });
|
|
52142
|
+
}
|
|
52143
|
+
if (cfg.stack?.language === "typescript") {
|
|
52144
|
+
if (utils.fileExists(path9.join(projectRoot, "tsconfig.json"))) {
|
|
52145
|
+
checks.push({ name: "TypeScript", status: "pass", message: "tsconfig.json found" });
|
|
52146
|
+
score += 1;
|
|
52147
|
+
} else {
|
|
52148
|
+
checks.push({ name: "TypeScript", status: "fail", message: "tsconfig.json missing for TypeScript project" });
|
|
51908
52149
|
}
|
|
51909
|
-
|
|
52150
|
+
} else {
|
|
52151
|
+
score += 1;
|
|
51910
52152
|
}
|
|
51911
|
-
|
|
51912
|
-
|
|
52153
|
+
const configValidation = validate(cfg);
|
|
52154
|
+
if (configValidation.valid) {
|
|
52155
|
+
checks.push({ name: "Config Validation", status: "pass", message: "Configuration is valid" });
|
|
52156
|
+
score += 2;
|
|
52157
|
+
} else {
|
|
52158
|
+
checks.push({ name: "Config Validation", status: "fail", message: configValidation.errors.join(", ") });
|
|
51913
52159
|
}
|
|
51914
|
-
if (
|
|
51915
|
-
|
|
52160
|
+
if (utils.fileExists(path9.join(projectRoot, cfg.paths?.todo ?? "planning/TODO.md"))) {
|
|
52161
|
+
checks.push({ name: "Todo Tracking", status: "pass", message: "planning/TODO.md exists" });
|
|
52162
|
+
score += 1;
|
|
52163
|
+
} else {
|
|
52164
|
+
checks.push({ name: "Todo Tracking", status: "fail", message: "planning/TODO.md not found" });
|
|
51916
52165
|
}
|
|
51917
|
-
const remaining = clearOnSuccess ? 0 : listEvents({ projectRoot }).length;
|
|
51918
52166
|
return {
|
|
51919
|
-
|
|
51920
|
-
|
|
51921
|
-
|
|
51922
|
-
|
|
51923
|
-
|
|
51924
|
-
endpoint,
|
|
51925
|
-
failedBatches
|
|
52167
|
+
valid: score >= maxScore * 0.6,
|
|
52168
|
+
score,
|
|
52169
|
+
maxScore,
|
|
52170
|
+
percentage: Math.round(score / maxScore * 100),
|
|
52171
|
+
checks
|
|
51926
52172
|
};
|
|
51927
52173
|
}
|
|
51928
|
-
|
|
52174
|
+
function generateSummary(options = {}) {
|
|
52175
|
+
const ctx = get(options);
|
|
52176
|
+
const lines = [
|
|
52177
|
+
"# Project Context",
|
|
52178
|
+
"",
|
|
52179
|
+
`**Project**: ${ctx.project?.name ?? "Unknown"}`,
|
|
52180
|
+
`**Generated**: ${ctx.timestamp}`,
|
|
52181
|
+
"",
|
|
52182
|
+
"## Stack",
|
|
52183
|
+
`- Framework: ${ctx.stack?.framework ?? "unknown"}`,
|
|
52184
|
+
`- Language: ${ctx.stack?.language ?? "unknown"}`,
|
|
52185
|
+
`- Database: ${ctx.stack?.database ?? "unknown"}`,
|
|
52186
|
+
`- Hosting: ${ctx.stack?.hosting ?? "unknown"}`,
|
|
52187
|
+
""
|
|
52188
|
+
];
|
|
52189
|
+
const enabledPlugins = Object.keys(ctx.plugins);
|
|
52190
|
+
if (enabledPlugins.length > 0) {
|
|
52191
|
+
lines.push("## Enabled Plugins");
|
|
52192
|
+
for (const [name, plugin] of Object.entries(ctx.plugins)) {
|
|
52193
|
+
lines.push(`- **${name}**: ${plugin.provider}`);
|
|
52194
|
+
}
|
|
52195
|
+
lines.push("");
|
|
52196
|
+
}
|
|
52197
|
+
lines.push("## Project State");
|
|
52198
|
+
lines.push(`- Phase: ${ctx.state.phase}`);
|
|
52199
|
+
lines.push(`- Health: ${ctx.state.health}`);
|
|
52200
|
+
lines.push(`- Open Todos: ${ctx.state.todos}`);
|
|
52201
|
+
if (ctx.state.lastGenerated) {
|
|
52202
|
+
lines.push(`- Context Last Generated: ${utils.formatRelativeTime(ctx.state.lastGenerated)}`);
|
|
52203
|
+
}
|
|
52204
|
+
lines.push("");
|
|
52205
|
+
if (ctx.git.initialized) {
|
|
52206
|
+
lines.push("## Git");
|
|
52207
|
+
lines.push(`- Branch: ${ctx.git.branch ?? "unknown"}`);
|
|
52208
|
+
lines.push(`- Remote: ${ctx.git.hasRemote ? "configured" : "not configured"}`);
|
|
52209
|
+
lines.push("");
|
|
52210
|
+
}
|
|
52211
|
+
return lines.join("\n");
|
|
52212
|
+
}
|
|
52213
|
+
init_telemetry();
|
|
51929
52214
|
}
|
|
51930
52215
|
});
|
|
51931
52216
|
|
|
@@ -51934,7 +52219,7 @@ var require_package = __commonJS({
|
|
|
51934
52219
|
"../../../package.json"(exports2, module2) {
|
|
51935
52220
|
module2.exports = {
|
|
51936
52221
|
name: "bootspring-workspace",
|
|
51937
|
-
version: "2.5.
|
|
52222
|
+
version: "2.5.8",
|
|
51938
52223
|
private: true,
|
|
51939
52224
|
description: "Workspace tooling for the Bootspring monorepo",
|
|
51940
52225
|
keywords: [
|
|
@@ -51954,9 +52239,6 @@ var require_package = __commonJS({
|
|
|
51954
52239
|
type: "git",
|
|
51955
52240
|
url: "git+https://github.com/Girard-Media/bootspring.git"
|
|
51956
52241
|
},
|
|
51957
|
-
bin: {
|
|
51958
|
-
bootspring: "./monorepo/apps/cli/bin/bootspring.js"
|
|
51959
|
-
},
|
|
51960
52242
|
homepage: "https://bootspring.com",
|
|
51961
52243
|
bugs: {
|
|
51962
52244
|
url: "https://github.com/Girard-Media/bootspring/issues"
|
|
@@ -52033,7 +52315,16 @@ var require_package = __commonJS({
|
|
|
52033
52315
|
minimatch: "^10.2.1",
|
|
52034
52316
|
hono: "4.12.4",
|
|
52035
52317
|
"@hono/node-server": "1.19.10",
|
|
52036
|
-
"express-rate-limit": "^8.2.2"
|
|
52318
|
+
"express-rate-limit": "^8.2.2",
|
|
52319
|
+
"path-to-regexp@<0.1.13": "0.1.13",
|
|
52320
|
+
"path-to-regexp@>=8.0.0 <8.4.0": "8.4.0",
|
|
52321
|
+
"flatted@<3.4.2": "3.4.2",
|
|
52322
|
+
"picomatch@>=4.0.0 <4.0.4": "4.0.4",
|
|
52323
|
+
"brace-expansion@<1.1.13": "1.1.13",
|
|
52324
|
+
"brace-expansion@>=2.0.0 <2.0.3": "2.0.3",
|
|
52325
|
+
"brace-expansion@>=3.0.0 <3.0.2": "3.0.2",
|
|
52326
|
+
"brace-expansion@>=4.0.0 <5.0.5": "5.0.5",
|
|
52327
|
+
"vite@>=7.0.0 <7.3.2": "7.3.2"
|
|
52037
52328
|
},
|
|
52038
52329
|
packageManager: "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
|
|
52039
52330
|
};
|
|
@@ -52190,10 +52481,59 @@ function createAuthError(message) {
|
|
|
52190
52481
|
isError: true
|
|
52191
52482
|
};
|
|
52192
52483
|
}
|
|
52484
|
+
function diagnoseApiSurface() {
|
|
52485
|
+
const required = ["callMcpTool", "listMcpTools", "listMcpResources", "getMcpResource"];
|
|
52486
|
+
const missing = required.filter((fn) => typeof api2?.[fn] !== "function");
|
|
52487
|
+
if (missing.length === 0) return null;
|
|
52488
|
+
return [
|
|
52489
|
+
`Bootspring MCP server v${VERSION} is missing required API methods: ${missing.join(", ")}.`,
|
|
52490
|
+
`This usually means the installed @girardmedia/bootspring package is out of date.`,
|
|
52491
|
+
`Fix:`,
|
|
52492
|
+
` 1. Quit Claude Code completely`,
|
|
52493
|
+
` 2. npm i -g @girardmedia/bootspring@latest`,
|
|
52494
|
+
` 3. Restart Claude Code so the MCP server reloads`
|
|
52495
|
+
].join("\n");
|
|
52496
|
+
}
|
|
52497
|
+
function formatProxyError(error) {
|
|
52498
|
+
if (error?.status === 401) {
|
|
52499
|
+
return "Authentication expired. Run `bootspring auth login` to re-authenticate.";
|
|
52500
|
+
}
|
|
52501
|
+
if (error?.status === 403) {
|
|
52502
|
+
return "This MCP capability requires a paid Bootspring plan.";
|
|
52503
|
+
}
|
|
52504
|
+
if (error?.status === 404) {
|
|
52505
|
+
const serverMessage = typeof error?.message === "string" ? error.message : "";
|
|
52506
|
+
if (serverMessage && /mcp tool/i.test(serverMessage)) {
|
|
52507
|
+
return `${serverMessage}. This typically means the hosted API doesn't yet route that tool, or the CLI catalog is ahead of the server catalog.`;
|
|
52508
|
+
}
|
|
52509
|
+
return "This MCP tool is not available on the connected Bootspring API. Check that you are pointed at a current API server.";
|
|
52510
|
+
}
|
|
52511
|
+
if (error?.code === "ECONNREFUSED" || error?.code === "ENOTFOUND" || error?.code === "ETIMEDOUT" || error?.code === "EHOSTUNREACH") {
|
|
52512
|
+
return `Cannot reach Bootspring API (${error.code}). Check your internet connection or BOOTSPRING_API_URL.`;
|
|
52513
|
+
}
|
|
52514
|
+
return error?.message || "Unknown error from Bootspring API.";
|
|
52515
|
+
}
|
|
52516
|
+
var LOCAL_TOOLS = /* @__PURE__ */ new Set(["bootspring_build", "bootspring_seed", "bootspring_todo"]);
|
|
52517
|
+
function formatLocalToolGuidance(name, args) {
|
|
52518
|
+
const action = args && typeof args.action === "string" ? args.action : "";
|
|
52519
|
+
const base = name.replace(/^bootspring_/, "bootspring ");
|
|
52520
|
+
const cmd = action ? `${base} ${action}` : base;
|
|
52521
|
+
return [
|
|
52522
|
+
`\`${name}\` is a local-state tool \u2014 it reads and writes files in your project (.bootspring/state, planning/, etc.) and therefore cannot be executed from the hosted MCP API.`,
|
|
52523
|
+
``,
|
|
52524
|
+
`Run this in your project terminal:`,
|
|
52525
|
+
` ${cmd}`,
|
|
52526
|
+
``,
|
|
52527
|
+
`Everything else in this conversation will still work \u2014 only local-state tools need to run from your shell.`
|
|
52528
|
+
].join("\n");
|
|
52529
|
+
}
|
|
52193
52530
|
async function resolveTools() {
|
|
52194
52531
|
if (!auth2.isAuthenticated()) {
|
|
52195
52532
|
return FALLBACK_TOOLS;
|
|
52196
52533
|
}
|
|
52534
|
+
if (typeof api2?.listMcpTools !== "function") {
|
|
52535
|
+
return FALLBACK_TOOLS;
|
|
52536
|
+
}
|
|
52197
52537
|
try {
|
|
52198
52538
|
const response = await api2.listMcpTools();
|
|
52199
52539
|
const apiTools = Array.isArray(response) ? response : response.tools || [];
|
|
@@ -52208,6 +52548,9 @@ async function resolveResources() {
|
|
|
52208
52548
|
if (!auth2.isAuthenticated()) {
|
|
52209
52549
|
return FALLBACK_RESOURCES;
|
|
52210
52550
|
}
|
|
52551
|
+
if (typeof api2?.listMcpResources !== "function") {
|
|
52552
|
+
return FALLBACK_RESOURCES;
|
|
52553
|
+
}
|
|
52211
52554
|
try {
|
|
52212
52555
|
const response = await api2.listMcpResources();
|
|
52213
52556
|
return Array.isArray(response) ? response : response.resources || FALLBACK_RESOURCES;
|
|
@@ -52216,18 +52559,34 @@ async function resolveResources() {
|
|
|
52216
52559
|
}
|
|
52217
52560
|
}
|
|
52218
52561
|
async function proxyToolCall(name, args) {
|
|
52562
|
+
if (LOCAL_TOOLS.has(name)) {
|
|
52563
|
+
return {
|
|
52564
|
+
content: [{ type: "text", text: formatLocalToolGuidance(name, args) }]
|
|
52565
|
+
};
|
|
52566
|
+
}
|
|
52219
52567
|
if (!auth2.isAuthenticated()) {
|
|
52220
52568
|
return createAuthError("Authentication required. Run `bootspring auth login` first.");
|
|
52221
52569
|
}
|
|
52570
|
+
const surfaceError = diagnoseApiSurface();
|
|
52571
|
+
if (surfaceError) {
|
|
52572
|
+
return {
|
|
52573
|
+
content: [{ type: "text", text: surfaceError }],
|
|
52574
|
+
isError: true
|
|
52575
|
+
};
|
|
52576
|
+
}
|
|
52222
52577
|
try {
|
|
52223
52578
|
const response = await api2.callMcpTool(name, args || {});
|
|
52579
|
+
if (response && response.result && response.result.status === "local_execution_required") {
|
|
52580
|
+
return {
|
|
52581
|
+
content: [{ type: "text", text: response.result.message || formatLocalToolGuidance(name, args) }]
|
|
52582
|
+
};
|
|
52583
|
+
}
|
|
52224
52584
|
return {
|
|
52225
52585
|
content: [{ type: "text", text: formatTextContent(response.result || response) }]
|
|
52226
52586
|
};
|
|
52227
52587
|
} catch (error) {
|
|
52228
|
-
const message = error.status === 403 ? "This MCP capability requires a paid Bootspring plan." : error.message;
|
|
52229
52588
|
return {
|
|
52230
|
-
content: [{ type: "text", text: `Error: ${
|
|
52589
|
+
content: [{ type: "text", text: `Error: ${formatProxyError(error)} (bootspring v${VERSION})` }],
|
|
52231
52590
|
isError: true
|
|
52232
52591
|
};
|
|
52233
52592
|
}
|
|
@@ -52242,6 +52601,16 @@ async function proxyResourceRead(uri) {
|
|
|
52242
52601
|
}]
|
|
52243
52602
|
};
|
|
52244
52603
|
}
|
|
52604
|
+
const surfaceError = diagnoseApiSurface();
|
|
52605
|
+
if (surfaceError) {
|
|
52606
|
+
return {
|
|
52607
|
+
contents: [{
|
|
52608
|
+
uri,
|
|
52609
|
+
mimeType: "text/plain",
|
|
52610
|
+
text: surfaceError
|
|
52611
|
+
}]
|
|
52612
|
+
};
|
|
52613
|
+
}
|
|
52245
52614
|
try {
|
|
52246
52615
|
const response = await api2.getMcpResource(uri);
|
|
52247
52616
|
return {
|
|
@@ -52256,7 +52625,7 @@ async function proxyResourceRead(uri) {
|
|
|
52256
52625
|
contents: [{
|
|
52257
52626
|
uri,
|
|
52258
52627
|
mimeType: "text/plain",
|
|
52259
|
-
text: `Error: ${error
|
|
52628
|
+
text: `Error: ${formatProxyError(error)} (bootspring v${VERSION})`
|
|
52260
52629
|
}]
|
|
52261
52630
|
};
|
|
52262
52631
|
}
|
|
@@ -52286,6 +52655,10 @@ async function main() {
|
|
|
52286
52655
|
const transport = new StdioServerTransport();
|
|
52287
52656
|
await server.connect(transport);
|
|
52288
52657
|
console.error(`Bootspring MCP proxy v${VERSION} started`);
|
|
52658
|
+
const surfaceError = diagnoseApiSurface();
|
|
52659
|
+
if (surfaceError) {
|
|
52660
|
+
console.error("[bootspring-mcp] WARNING: " + surfaceError.split("\n").join(" "));
|
|
52661
|
+
}
|
|
52289
52662
|
}
|
|
52290
52663
|
if (require.main === module) {
|
|
52291
52664
|
main().catch((error) => {
|
|
@@ -52300,5 +52673,24 @@ module.exports = {
|
|
|
52300
52673
|
resourceHandlers,
|
|
52301
52674
|
FALLBACK_TOOLS,
|
|
52302
52675
|
FALLBACK_RESOURCES,
|
|
52303
|
-
main
|
|
52676
|
+
main,
|
|
52677
|
+
// Exposed for tests — lock in the stale-install regression guard
|
|
52678
|
+
_diagnoseApiSurface: diagnoseApiSurface,
|
|
52679
|
+
_formatProxyError: formatProxyError,
|
|
52680
|
+
_LOCAL_TOOLS: LOCAL_TOOLS,
|
|
52681
|
+
_formatLocalToolGuidance: formatLocalToolGuidance,
|
|
52682
|
+
_proxyToolCall: proxyToolCall,
|
|
52683
|
+
_diagnoseFromApi: function diagnoseFromApi(apiShim, version) {
|
|
52684
|
+
const required = ["callMcpTool", "listMcpTools", "listMcpResources", "getMcpResource"];
|
|
52685
|
+
const missing = required.filter((fn) => typeof apiShim?.[fn] !== "function");
|
|
52686
|
+
if (missing.length === 0) return null;
|
|
52687
|
+
return [
|
|
52688
|
+
`Bootspring MCP server v${version} is missing required API methods: ${missing.join(", ")}.`,
|
|
52689
|
+
`This usually means the installed @girardmedia/bootspring package is out of date.`,
|
|
52690
|
+
`Fix:`,
|
|
52691
|
+
` 1. Quit Claude Code completely`,
|
|
52692
|
+
` 2. npm i -g @girardmedia/bootspring@latest`,
|
|
52693
|
+
` 3. Restart Claude Code so the MCP server reloads`
|
|
52694
|
+
].join("\n");
|
|
52695
|
+
}
|
|
52304
52696
|
};
|