switchroom 0.7.11 → 0.7.15
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/README.md +4 -4
- package/dist/agent-scheduler/index.js +81 -81
- package/dist/cli/switchroom.js +2643 -1766
- package/dist/vault/approvals/kernel-server.js +89 -86
- package/dist/vault/broker/server.js +647 -181
- package/package.json +2 -2
- package/telegram-plugin/bridge/bridge.ts +17 -0
- package/telegram-plugin/dist/bridge/bridge.js +128 -112
- package/telegram-plugin/dist/foreman/foreman.js +198 -181
- package/telegram-plugin/dist/gateway/gateway.js +559 -171
- package/telegram-plugin/dist/server.js +176 -160
- package/telegram-plugin/gateway/gateway.ts +495 -7
- package/telegram-plugin/secret-detect/vault-error.test.ts +134 -0
- package/telegram-plugin/secret-detect/vault-error.ts +202 -0
- package/skills/docx/scripts/office/validators/__pycache__/__init__.cpython-313.pyc +0 -0
- package/skills/docx/scripts/office/validators/__pycache__/base.cpython-313.pyc +0 -0
- package/telegram-plugin/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
- package/telegram-plugin/server.js +0 -41795
|
@@ -17,7 +17,7 @@ var __export = (target, all) => {
|
|
|
17
17
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
18
18
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
19
19
|
|
|
20
|
-
// node_modules
|
|
20
|
+
// node_modules/yaml/dist/nodes/identity.js
|
|
21
21
|
var require_identity = __commonJS((exports) => {
|
|
22
22
|
var ALIAS = Symbol.for("yaml.alias");
|
|
23
23
|
var DOC = Symbol.for("yaml.document");
|
|
@@ -71,7 +71,7 @@ var require_identity = __commonJS((exports) => {
|
|
|
71
71
|
exports.isSeq = isSeq;
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
// node_modules
|
|
74
|
+
// node_modules/yaml/dist/visit.js
|
|
75
75
|
var require_visit = __commonJS((exports) => {
|
|
76
76
|
var identity = require_identity();
|
|
77
77
|
var BREAK = Symbol("break visit");
|
|
@@ -226,7 +226,7 @@ var require_visit = __commonJS((exports) => {
|
|
|
226
226
|
exports.visitAsync = visitAsync;
|
|
227
227
|
});
|
|
228
228
|
|
|
229
|
-
// node_modules
|
|
229
|
+
// node_modules/yaml/dist/doc/directives.js
|
|
230
230
|
var require_directives = __commonJS((exports) => {
|
|
231
231
|
var identity = require_identity();
|
|
232
232
|
var visit = require_visit();
|
|
@@ -378,7 +378,7 @@ var require_directives = __commonJS((exports) => {
|
|
|
378
378
|
exports.Directives = Directives;
|
|
379
379
|
});
|
|
380
380
|
|
|
381
|
-
// node_modules
|
|
381
|
+
// node_modules/yaml/dist/doc/anchors.js
|
|
382
382
|
var require_anchors = __commonJS((exports) => {
|
|
383
383
|
var identity = require_identity();
|
|
384
384
|
var visit = require_visit();
|
|
@@ -440,7 +440,7 @@ var require_anchors = __commonJS((exports) => {
|
|
|
440
440
|
exports.findNewAnchor = findNewAnchor;
|
|
441
441
|
});
|
|
442
442
|
|
|
443
|
-
// node_modules
|
|
443
|
+
// node_modules/yaml/dist/doc/applyReviver.js
|
|
444
444
|
var require_applyReviver = __commonJS((exports) => {
|
|
445
445
|
function applyReviver(reviver, obj, key, val) {
|
|
446
446
|
if (val && typeof val === "object") {
|
|
@@ -487,7 +487,7 @@ var require_applyReviver = __commonJS((exports) => {
|
|
|
487
487
|
exports.applyReviver = applyReviver;
|
|
488
488
|
});
|
|
489
489
|
|
|
490
|
-
// node_modules
|
|
490
|
+
// node_modules/yaml/dist/nodes/toJS.js
|
|
491
491
|
var require_toJS = __commonJS((exports) => {
|
|
492
492
|
var identity = require_identity();
|
|
493
493
|
function toJS(value, arg, ctx) {
|
|
@@ -514,7 +514,7 @@ var require_toJS = __commonJS((exports) => {
|
|
|
514
514
|
exports.toJS = toJS;
|
|
515
515
|
});
|
|
516
516
|
|
|
517
|
-
// node_modules
|
|
517
|
+
// node_modules/yaml/dist/nodes/Node.js
|
|
518
518
|
var require_Node = __commonJS((exports) => {
|
|
519
519
|
var applyReviver = require_applyReviver();
|
|
520
520
|
var identity = require_identity();
|
|
@@ -551,7 +551,7 @@ var require_Node = __commonJS((exports) => {
|
|
|
551
551
|
exports.NodeBase = NodeBase;
|
|
552
552
|
});
|
|
553
553
|
|
|
554
|
-
// node_modules
|
|
554
|
+
// node_modules/yaml/dist/nodes/Alias.js
|
|
555
555
|
var require_Alias = __commonJS((exports) => {
|
|
556
556
|
var anchors = require_anchors();
|
|
557
557
|
var visit = require_visit();
|
|
@@ -659,7 +659,7 @@ var require_Alias = __commonJS((exports) => {
|
|
|
659
659
|
exports.Alias = Alias;
|
|
660
660
|
});
|
|
661
661
|
|
|
662
|
-
// node_modules
|
|
662
|
+
// node_modules/yaml/dist/nodes/Scalar.js
|
|
663
663
|
var require_Scalar = __commonJS((exports) => {
|
|
664
664
|
var identity = require_identity();
|
|
665
665
|
var Node = require_Node();
|
|
@@ -687,7 +687,7 @@ var require_Scalar = __commonJS((exports) => {
|
|
|
687
687
|
exports.isScalarValue = isScalarValue;
|
|
688
688
|
});
|
|
689
689
|
|
|
690
|
-
// node_modules
|
|
690
|
+
// node_modules/yaml/dist/doc/createNode.js
|
|
691
691
|
var require_createNode = __commonJS((exports) => {
|
|
692
692
|
var Alias = require_Alias();
|
|
693
693
|
var identity = require_identity();
|
|
@@ -759,7 +759,7 @@ var require_createNode = __commonJS((exports) => {
|
|
|
759
759
|
exports.createNode = createNode;
|
|
760
760
|
});
|
|
761
761
|
|
|
762
|
-
// node_modules
|
|
762
|
+
// node_modules/yaml/dist/nodes/Collection.js
|
|
763
763
|
var require_Collection = __commonJS((exports) => {
|
|
764
764
|
var createNode = require_createNode();
|
|
765
765
|
var identity = require_identity();
|
|
@@ -874,7 +874,7 @@ var require_Collection = __commonJS((exports) => {
|
|
|
874
874
|
exports.isEmptyPath = isEmptyPath;
|
|
875
875
|
});
|
|
876
876
|
|
|
877
|
-
// node_modules
|
|
877
|
+
// node_modules/yaml/dist/stringify/stringifyComment.js
|
|
878
878
|
var require_stringifyComment = __commonJS((exports) => {
|
|
879
879
|
var stringifyComment = (str) => str.replace(/^(?!$)(?: $)?/gm, "#");
|
|
880
880
|
function indentComment(comment, indent) {
|
|
@@ -891,7 +891,7 @@ var require_stringifyComment = __commonJS((exports) => {
|
|
|
891
891
|
exports.stringifyComment = stringifyComment;
|
|
892
892
|
});
|
|
893
893
|
|
|
894
|
-
// node_modules
|
|
894
|
+
// node_modules/yaml/dist/stringify/foldFlowLines.js
|
|
895
895
|
var require_foldFlowLines = __commonJS((exports) => {
|
|
896
896
|
var FOLD_FLOW = "flow";
|
|
897
897
|
var FOLD_BLOCK = "block";
|
|
@@ -1028,7 +1028,7 @@ ${indent}${text.slice(fold + 1, end2)}`;
|
|
|
1028
1028
|
exports.foldFlowLines = foldFlowLines;
|
|
1029
1029
|
});
|
|
1030
1030
|
|
|
1031
|
-
// node_modules
|
|
1031
|
+
// node_modules/yaml/dist/stringify/stringifyString.js
|
|
1032
1032
|
var require_stringifyString = __commonJS((exports) => {
|
|
1033
1033
|
var Scalar = require_Scalar();
|
|
1034
1034
|
var foldFlowLines = require_foldFlowLines();
|
|
@@ -1326,7 +1326,7 @@ ${indent}`);
|
|
|
1326
1326
|
exports.stringifyString = stringifyString;
|
|
1327
1327
|
});
|
|
1328
1328
|
|
|
1329
|
-
// node_modules
|
|
1329
|
+
// node_modules/yaml/dist/stringify/stringify.js
|
|
1330
1330
|
var require_stringify = __commonJS((exports) => {
|
|
1331
1331
|
var anchors = require_anchors();
|
|
1332
1332
|
var identity = require_identity();
|
|
@@ -1447,7 +1447,7 @@ ${ctx.indent}${str}`;
|
|
|
1447
1447
|
exports.stringify = stringify;
|
|
1448
1448
|
});
|
|
1449
1449
|
|
|
1450
|
-
// node_modules
|
|
1450
|
+
// node_modules/yaml/dist/stringify/stringifyPair.js
|
|
1451
1451
|
var require_stringifyPair = __commonJS((exports) => {
|
|
1452
1452
|
var identity = require_identity();
|
|
1453
1453
|
var Scalar = require_Scalar();
|
|
@@ -1583,7 +1583,7 @@ ${ctx.indent}`;
|
|
|
1583
1583
|
exports.stringifyPair = stringifyPair;
|
|
1584
1584
|
});
|
|
1585
1585
|
|
|
1586
|
-
// node_modules
|
|
1586
|
+
// node_modules/yaml/dist/log.js
|
|
1587
1587
|
var require_log = __commonJS((exports) => {
|
|
1588
1588
|
var node_process = __require("process");
|
|
1589
1589
|
function debug(logLevel, ...messages) {
|
|
@@ -1602,7 +1602,7 @@ var require_log = __commonJS((exports) => {
|
|
|
1602
1602
|
exports.warn = warn;
|
|
1603
1603
|
});
|
|
1604
1604
|
|
|
1605
|
-
// node_modules
|
|
1605
|
+
// node_modules/yaml/dist/schema/yaml-1.1/merge.js
|
|
1606
1606
|
var require_merge = __commonJS((exports) => {
|
|
1607
1607
|
var identity = require_identity();
|
|
1608
1608
|
var Scalar = require_Scalar();
|
|
@@ -1656,7 +1656,7 @@ var require_merge = __commonJS((exports) => {
|
|
|
1656
1656
|
exports.merge = merge;
|
|
1657
1657
|
});
|
|
1658
1658
|
|
|
1659
|
-
// node_modules
|
|
1659
|
+
// node_modules/yaml/dist/nodes/addPairToJSMap.js
|
|
1660
1660
|
var require_addPairToJSMap = __commonJS((exports) => {
|
|
1661
1661
|
var log = require_log();
|
|
1662
1662
|
var merge = require_merge();
|
|
@@ -1717,7 +1717,7 @@ var require_addPairToJSMap = __commonJS((exports) => {
|
|
|
1717
1717
|
exports.addPairToJSMap = addPairToJSMap;
|
|
1718
1718
|
});
|
|
1719
1719
|
|
|
1720
|
-
// node_modules
|
|
1720
|
+
// node_modules/yaml/dist/nodes/Pair.js
|
|
1721
1721
|
var require_Pair = __commonJS((exports) => {
|
|
1722
1722
|
var createNode = require_createNode();
|
|
1723
1723
|
var stringifyPair = require_stringifyPair();
|
|
@@ -1755,7 +1755,7 @@ var require_Pair = __commonJS((exports) => {
|
|
|
1755
1755
|
exports.createPair = createPair;
|
|
1756
1756
|
});
|
|
1757
1757
|
|
|
1758
|
-
// node_modules
|
|
1758
|
+
// node_modules/yaml/dist/stringify/stringifyCollection.js
|
|
1759
1759
|
var require_stringifyCollection = __commonJS((exports) => {
|
|
1760
1760
|
var identity = require_identity();
|
|
1761
1761
|
var stringify = require_stringify();
|
|
@@ -1907,7 +1907,7 @@ ${indent}${end}`;
|
|
|
1907
1907
|
exports.stringifyCollection = stringifyCollection;
|
|
1908
1908
|
});
|
|
1909
1909
|
|
|
1910
|
-
// node_modules
|
|
1910
|
+
// node_modules/yaml/dist/nodes/YAMLMap.js
|
|
1911
1911
|
var require_YAMLMap = __commonJS((exports) => {
|
|
1912
1912
|
var stringifyCollection = require_stringifyCollection();
|
|
1913
1913
|
var addPairToJSMap = require_addPairToJSMap();
|
|
@@ -2034,7 +2034,7 @@ var require_YAMLMap = __commonJS((exports) => {
|
|
|
2034
2034
|
exports.findPair = findPair;
|
|
2035
2035
|
});
|
|
2036
2036
|
|
|
2037
|
-
// node_modules
|
|
2037
|
+
// node_modules/yaml/dist/schema/common/map.js
|
|
2038
2038
|
var require_map = __commonJS((exports) => {
|
|
2039
2039
|
var identity = require_identity();
|
|
2040
2040
|
var YAMLMap = require_YAMLMap();
|
|
@@ -2053,7 +2053,7 @@ var require_map = __commonJS((exports) => {
|
|
|
2053
2053
|
exports.map = map;
|
|
2054
2054
|
});
|
|
2055
2055
|
|
|
2056
|
-
// node_modules
|
|
2056
|
+
// node_modules/yaml/dist/nodes/YAMLSeq.js
|
|
2057
2057
|
var require_YAMLSeq = __commonJS((exports) => {
|
|
2058
2058
|
var createNode = require_createNode();
|
|
2059
2059
|
var stringifyCollection = require_stringifyCollection();
|
|
@@ -2146,7 +2146,7 @@ var require_YAMLSeq = __commonJS((exports) => {
|
|
|
2146
2146
|
exports.YAMLSeq = YAMLSeq;
|
|
2147
2147
|
});
|
|
2148
2148
|
|
|
2149
|
-
// node_modules
|
|
2149
|
+
// node_modules/yaml/dist/schema/common/seq.js
|
|
2150
2150
|
var require_seq = __commonJS((exports) => {
|
|
2151
2151
|
var identity = require_identity();
|
|
2152
2152
|
var YAMLSeq = require_YAMLSeq();
|
|
@@ -2165,7 +2165,7 @@ var require_seq = __commonJS((exports) => {
|
|
|
2165
2165
|
exports.seq = seq;
|
|
2166
2166
|
});
|
|
2167
2167
|
|
|
2168
|
-
// node_modules
|
|
2168
|
+
// node_modules/yaml/dist/schema/common/string.js
|
|
2169
2169
|
var require_string = __commonJS((exports) => {
|
|
2170
2170
|
var stringifyString = require_stringifyString();
|
|
2171
2171
|
var string = {
|
|
@@ -2181,7 +2181,7 @@ var require_string = __commonJS((exports) => {
|
|
|
2181
2181
|
exports.string = string;
|
|
2182
2182
|
});
|
|
2183
2183
|
|
|
2184
|
-
// node_modules
|
|
2184
|
+
// node_modules/yaml/dist/schema/common/null.js
|
|
2185
2185
|
var require_null = __commonJS((exports) => {
|
|
2186
2186
|
var Scalar = require_Scalar();
|
|
2187
2187
|
var nullTag = {
|
|
@@ -2196,7 +2196,7 @@ var require_null = __commonJS((exports) => {
|
|
|
2196
2196
|
exports.nullTag = nullTag;
|
|
2197
2197
|
});
|
|
2198
2198
|
|
|
2199
|
-
// node_modules
|
|
2199
|
+
// node_modules/yaml/dist/schema/core/bool.js
|
|
2200
2200
|
var require_bool = __commonJS((exports) => {
|
|
2201
2201
|
var Scalar = require_Scalar();
|
|
2202
2202
|
var boolTag = {
|
|
@@ -2217,7 +2217,7 @@ var require_bool = __commonJS((exports) => {
|
|
|
2217
2217
|
exports.boolTag = boolTag;
|
|
2218
2218
|
});
|
|
2219
2219
|
|
|
2220
|
-
// node_modules
|
|
2220
|
+
// node_modules/yaml/dist/stringify/stringifyNumber.js
|
|
2221
2221
|
var require_stringifyNumber = __commonJS((exports) => {
|
|
2222
2222
|
function stringifyNumber({ format, minFractionDigits, tag, value }) {
|
|
2223
2223
|
if (typeof value === "bigint")
|
|
@@ -2241,7 +2241,7 @@ var require_stringifyNumber = __commonJS((exports) => {
|
|
|
2241
2241
|
exports.stringifyNumber = stringifyNumber;
|
|
2242
2242
|
});
|
|
2243
2243
|
|
|
2244
|
-
// node_modules
|
|
2244
|
+
// node_modules/yaml/dist/schema/core/float.js
|
|
2245
2245
|
var require_float = __commonJS((exports) => {
|
|
2246
2246
|
var Scalar = require_Scalar();
|
|
2247
2247
|
var stringifyNumber = require_stringifyNumber();
|
|
@@ -2284,7 +2284,7 @@ var require_float = __commonJS((exports) => {
|
|
|
2284
2284
|
exports.floatNaN = floatNaN;
|
|
2285
2285
|
});
|
|
2286
2286
|
|
|
2287
|
-
// node_modules
|
|
2287
|
+
// node_modules/yaml/dist/schema/core/int.js
|
|
2288
2288
|
var require_int = __commonJS((exports) => {
|
|
2289
2289
|
var stringifyNumber = require_stringifyNumber();
|
|
2290
2290
|
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
|
@@ -2326,7 +2326,7 @@ var require_int = __commonJS((exports) => {
|
|
|
2326
2326
|
exports.intOct = intOct;
|
|
2327
2327
|
});
|
|
2328
2328
|
|
|
2329
|
-
// node_modules
|
|
2329
|
+
// node_modules/yaml/dist/schema/core/schema.js
|
|
2330
2330
|
var require_schema = __commonJS((exports) => {
|
|
2331
2331
|
var map = require_map();
|
|
2332
2332
|
var _null = require_null();
|
|
@@ -2351,7 +2351,7 @@ var require_schema = __commonJS((exports) => {
|
|
|
2351
2351
|
exports.schema = schema;
|
|
2352
2352
|
});
|
|
2353
2353
|
|
|
2354
|
-
// node_modules
|
|
2354
|
+
// node_modules/yaml/dist/schema/json/schema.js
|
|
2355
2355
|
var require_schema2 = __commonJS((exports) => {
|
|
2356
2356
|
var Scalar = require_Scalar();
|
|
2357
2357
|
var map = require_map();
|
|
@@ -2415,7 +2415,7 @@ var require_schema2 = __commonJS((exports) => {
|
|
|
2415
2415
|
exports.schema = schema;
|
|
2416
2416
|
});
|
|
2417
2417
|
|
|
2418
|
-
// node_modules
|
|
2418
|
+
// node_modules/yaml/dist/schema/yaml-1.1/binary.js
|
|
2419
2419
|
var require_binary = __commonJS((exports) => {
|
|
2420
2420
|
var node_buffer = __require("buffer");
|
|
2421
2421
|
var Scalar = require_Scalar();
|
|
@@ -2470,7 +2470,7 @@ var require_binary = __commonJS((exports) => {
|
|
|
2470
2470
|
exports.binary = binary;
|
|
2471
2471
|
});
|
|
2472
2472
|
|
|
2473
|
-
// node_modules
|
|
2473
|
+
// node_modules/yaml/dist/schema/yaml-1.1/pairs.js
|
|
2474
2474
|
var require_pairs = __commonJS((exports) => {
|
|
2475
2475
|
var identity = require_identity();
|
|
2476
2476
|
var Pair = require_Pair();
|
|
@@ -2545,7 +2545,7 @@ ${cn.comment}` : item.comment;
|
|
|
2545
2545
|
exports.resolvePairs = resolvePairs;
|
|
2546
2546
|
});
|
|
2547
2547
|
|
|
2548
|
-
// node_modules
|
|
2548
|
+
// node_modules/yaml/dist/schema/yaml-1.1/omap.js
|
|
2549
2549
|
var require_omap = __commonJS((exports) => {
|
|
2550
2550
|
var identity = require_identity();
|
|
2551
2551
|
var toJS = require_toJS();
|
|
@@ -2617,7 +2617,7 @@ var require_omap = __commonJS((exports) => {
|
|
|
2617
2617
|
exports.omap = omap;
|
|
2618
2618
|
});
|
|
2619
2619
|
|
|
2620
|
-
// node_modules
|
|
2620
|
+
// node_modules/yaml/dist/schema/yaml-1.1/bool.js
|
|
2621
2621
|
var require_bool2 = __commonJS((exports) => {
|
|
2622
2622
|
var Scalar = require_Scalar();
|
|
2623
2623
|
function boolStringify({ value, source }, ctx) {
|
|
@@ -2646,7 +2646,7 @@ var require_bool2 = __commonJS((exports) => {
|
|
|
2646
2646
|
exports.trueTag = trueTag;
|
|
2647
2647
|
});
|
|
2648
2648
|
|
|
2649
|
-
// node_modules
|
|
2649
|
+
// node_modules/yaml/dist/schema/yaml-1.1/float.js
|
|
2650
2650
|
var require_float2 = __commonJS((exports) => {
|
|
2651
2651
|
var Scalar = require_Scalar();
|
|
2652
2652
|
var stringifyNumber = require_stringifyNumber();
|
|
@@ -2692,7 +2692,7 @@ var require_float2 = __commonJS((exports) => {
|
|
|
2692
2692
|
exports.floatNaN = floatNaN;
|
|
2693
2693
|
});
|
|
2694
2694
|
|
|
2695
|
-
// node_modules
|
|
2695
|
+
// node_modules/yaml/dist/schema/yaml-1.1/int.js
|
|
2696
2696
|
var require_int2 = __commonJS((exports) => {
|
|
2697
2697
|
var stringifyNumber = require_stringifyNumber();
|
|
2698
2698
|
var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
|
|
@@ -2768,7 +2768,7 @@ var require_int2 = __commonJS((exports) => {
|
|
|
2768
2768
|
exports.intOct = intOct;
|
|
2769
2769
|
});
|
|
2770
2770
|
|
|
2771
|
-
// node_modules
|
|
2771
|
+
// node_modules/yaml/dist/schema/yaml-1.1/set.js
|
|
2772
2772
|
var require_set = __commonJS((exports) => {
|
|
2773
2773
|
var identity = require_identity();
|
|
2774
2774
|
var Pair = require_Pair();
|
|
@@ -2851,7 +2851,7 @@ var require_set = __commonJS((exports) => {
|
|
|
2851
2851
|
exports.set = set;
|
|
2852
2852
|
});
|
|
2853
2853
|
|
|
2854
|
-
// node_modules
|
|
2854
|
+
// node_modules/yaml/dist/schema/yaml-1.1/timestamp.js
|
|
2855
2855
|
var require_timestamp = __commonJS((exports) => {
|
|
2856
2856
|
var stringifyNumber = require_stringifyNumber();
|
|
2857
2857
|
function parseSexagesimal(str, asBigInt) {
|
|
@@ -2933,7 +2933,7 @@ var require_timestamp = __commonJS((exports) => {
|
|
|
2933
2933
|
exports.timestamp = timestamp;
|
|
2934
2934
|
});
|
|
2935
2935
|
|
|
2936
|
-
// node_modules
|
|
2936
|
+
// node_modules/yaml/dist/schema/yaml-1.1/schema.js
|
|
2937
2937
|
var require_schema3 = __commonJS((exports) => {
|
|
2938
2938
|
var map = require_map();
|
|
2939
2939
|
var _null = require_null();
|
|
@@ -2974,7 +2974,7 @@ var require_schema3 = __commonJS((exports) => {
|
|
|
2974
2974
|
exports.schema = schema;
|
|
2975
2975
|
});
|
|
2976
2976
|
|
|
2977
|
-
// node_modules
|
|
2977
|
+
// node_modules/yaml/dist/schema/tags.js
|
|
2978
2978
|
var require_tags = __commonJS((exports) => {
|
|
2979
2979
|
var map = require_map();
|
|
2980
2980
|
var _null = require_null();
|
|
@@ -3065,7 +3065,7 @@ var require_tags = __commonJS((exports) => {
|
|
|
3065
3065
|
exports.getTags = getTags;
|
|
3066
3066
|
});
|
|
3067
3067
|
|
|
3068
|
-
// node_modules
|
|
3068
|
+
// node_modules/yaml/dist/schema/Schema.js
|
|
3069
3069
|
var require_Schema = __commonJS((exports) => {
|
|
3070
3070
|
var identity = require_identity();
|
|
3071
3071
|
var map = require_map();
|
|
@@ -3095,7 +3095,7 @@ var require_Schema = __commonJS((exports) => {
|
|
|
3095
3095
|
exports.Schema = Schema;
|
|
3096
3096
|
});
|
|
3097
3097
|
|
|
3098
|
-
// node_modules
|
|
3098
|
+
// node_modules/yaml/dist/stringify/stringifyDocument.js
|
|
3099
3099
|
var require_stringifyDocument = __commonJS((exports) => {
|
|
3100
3100
|
var identity = require_identity();
|
|
3101
3101
|
var stringify = require_stringify();
|
|
@@ -3175,7 +3175,7 @@ var require_stringifyDocument = __commonJS((exports) => {
|
|
|
3175
3175
|
exports.stringifyDocument = stringifyDocument;
|
|
3176
3176
|
});
|
|
3177
3177
|
|
|
3178
|
-
// node_modules
|
|
3178
|
+
// node_modules/yaml/dist/doc/Document.js
|
|
3179
3179
|
var require_Document = __commonJS((exports) => {
|
|
3180
3180
|
var Alias = require_Alias();
|
|
3181
3181
|
var Collection = require_Collection();
|
|
@@ -3410,7 +3410,7 @@ var require_Document = __commonJS((exports) => {
|
|
|
3410
3410
|
exports.Document = Document;
|
|
3411
3411
|
});
|
|
3412
3412
|
|
|
3413
|
-
// node_modules
|
|
3413
|
+
// node_modules/yaml/dist/errors.js
|
|
3414
3414
|
var require_errors = __commonJS((exports) => {
|
|
3415
3415
|
class YAMLError extends Error {
|
|
3416
3416
|
constructor(name, pos, code, message) {
|
|
@@ -3475,7 +3475,7 @@ ${pointer}
|
|
|
3475
3475
|
exports.prettifyError = prettifyError;
|
|
3476
3476
|
});
|
|
3477
3477
|
|
|
3478
|
-
// node_modules
|
|
3478
|
+
// node_modules/yaml/dist/compose/resolve-props.js
|
|
3479
3479
|
var require_resolve_props = __commonJS((exports) => {
|
|
3480
3480
|
function resolveProps(tokens, { flow, indicator, next, offset, onError, parentIndent, startOnNewline }) {
|
|
3481
3481
|
let spaceBefore = false;
|
|
@@ -3605,7 +3605,7 @@ var require_resolve_props = __commonJS((exports) => {
|
|
|
3605
3605
|
exports.resolveProps = resolveProps;
|
|
3606
3606
|
});
|
|
3607
3607
|
|
|
3608
|
-
// node_modules
|
|
3608
|
+
// node_modules/yaml/dist/compose/util-contains-newline.js
|
|
3609
3609
|
var require_util_contains_newline = __commonJS((exports) => {
|
|
3610
3610
|
function containsNewline(key) {
|
|
3611
3611
|
if (!key)
|
|
@@ -3645,7 +3645,7 @@ var require_util_contains_newline = __commonJS((exports) => {
|
|
|
3645
3645
|
exports.containsNewline = containsNewline;
|
|
3646
3646
|
});
|
|
3647
3647
|
|
|
3648
|
-
// node_modules
|
|
3648
|
+
// node_modules/yaml/dist/compose/util-flow-indent-check.js
|
|
3649
3649
|
var require_util_flow_indent_check = __commonJS((exports) => {
|
|
3650
3650
|
var utilContainsNewline = require_util_contains_newline();
|
|
3651
3651
|
function flowIndentCheck(indent, fc, onError) {
|
|
@@ -3660,7 +3660,7 @@ var require_util_flow_indent_check = __commonJS((exports) => {
|
|
|
3660
3660
|
exports.flowIndentCheck = flowIndentCheck;
|
|
3661
3661
|
});
|
|
3662
3662
|
|
|
3663
|
-
// node_modules
|
|
3663
|
+
// node_modules/yaml/dist/compose/util-map-includes.js
|
|
3664
3664
|
var require_util_map_includes = __commonJS((exports) => {
|
|
3665
3665
|
var identity = require_identity();
|
|
3666
3666
|
function mapIncludes(ctx, items, search) {
|
|
@@ -3673,7 +3673,7 @@ var require_util_map_includes = __commonJS((exports) => {
|
|
|
3673
3673
|
exports.mapIncludes = mapIncludes;
|
|
3674
3674
|
});
|
|
3675
3675
|
|
|
3676
|
-
// node_modules
|
|
3676
|
+
// node_modules/yaml/dist/compose/resolve-block-map.js
|
|
3677
3677
|
var require_resolve_block_map = __commonJS((exports) => {
|
|
3678
3678
|
var Pair = require_Pair();
|
|
3679
3679
|
var YAMLMap = require_YAMLMap();
|
|
@@ -3780,7 +3780,7 @@ var require_resolve_block_map = __commonJS((exports) => {
|
|
|
3780
3780
|
exports.resolveBlockMap = resolveBlockMap;
|
|
3781
3781
|
});
|
|
3782
3782
|
|
|
3783
|
-
// node_modules
|
|
3783
|
+
// node_modules/yaml/dist/compose/resolve-block-seq.js
|
|
3784
3784
|
var require_resolve_block_seq = __commonJS((exports) => {
|
|
3785
3785
|
var YAMLSeq = require_YAMLSeq();
|
|
3786
3786
|
var resolveProps = require_resolve_props();
|
|
@@ -3828,7 +3828,7 @@ var require_resolve_block_seq = __commonJS((exports) => {
|
|
|
3828
3828
|
exports.resolveBlockSeq = resolveBlockSeq;
|
|
3829
3829
|
});
|
|
3830
3830
|
|
|
3831
|
-
// node_modules
|
|
3831
|
+
// node_modules/yaml/dist/compose/resolve-end.js
|
|
3832
3832
|
var require_resolve_end = __commonJS((exports) => {
|
|
3833
3833
|
function resolveEnd(end, offset, reqSpace, onError) {
|
|
3834
3834
|
let comment = "";
|
|
@@ -3868,7 +3868,7 @@ var require_resolve_end = __commonJS((exports) => {
|
|
|
3868
3868
|
exports.resolveEnd = resolveEnd;
|
|
3869
3869
|
});
|
|
3870
3870
|
|
|
3871
|
-
// node_modules
|
|
3871
|
+
// node_modules/yaml/dist/compose/resolve-flow-collection.js
|
|
3872
3872
|
var require_resolve_flow_collection = __commonJS((exports) => {
|
|
3873
3873
|
var identity = require_identity();
|
|
3874
3874
|
var Pair = require_Pair();
|
|
@@ -4059,7 +4059,7 @@ var require_resolve_flow_collection = __commonJS((exports) => {
|
|
|
4059
4059
|
exports.resolveFlowCollection = resolveFlowCollection;
|
|
4060
4060
|
});
|
|
4061
4061
|
|
|
4062
|
-
// node_modules
|
|
4062
|
+
// node_modules/yaml/dist/compose/compose-collection.js
|
|
4063
4063
|
var require_compose_collection = __commonJS((exports) => {
|
|
4064
4064
|
var identity = require_identity();
|
|
4065
4065
|
var Scalar = require_Scalar();
|
|
@@ -4121,7 +4121,7 @@ var require_compose_collection = __commonJS((exports) => {
|
|
|
4121
4121
|
exports.composeCollection = composeCollection;
|
|
4122
4122
|
});
|
|
4123
4123
|
|
|
4124
|
-
// node_modules
|
|
4124
|
+
// node_modules/yaml/dist/compose/resolve-block-scalar.js
|
|
4125
4125
|
var require_resolve_block_scalar = __commonJS((exports) => {
|
|
4126
4126
|
var Scalar = require_Scalar();
|
|
4127
4127
|
function resolveBlockScalar(ctx, scalar, onError) {
|
|
@@ -4314,7 +4314,7 @@ var require_resolve_block_scalar = __commonJS((exports) => {
|
|
|
4314
4314
|
exports.resolveBlockScalar = resolveBlockScalar;
|
|
4315
4315
|
});
|
|
4316
4316
|
|
|
4317
|
-
// node_modules
|
|
4317
|
+
// node_modules/yaml/dist/compose/resolve-flow-scalar.js
|
|
4318
4318
|
var require_resolve_flow_scalar = __commonJS((exports) => {
|
|
4319
4319
|
var Scalar = require_Scalar();
|
|
4320
4320
|
var resolveEnd = require_resolve_end();
|
|
@@ -4530,7 +4530,7 @@ var require_resolve_flow_scalar = __commonJS((exports) => {
|
|
|
4530
4530
|
exports.resolveFlowScalar = resolveFlowScalar;
|
|
4531
4531
|
});
|
|
4532
4532
|
|
|
4533
|
-
// node_modules
|
|
4533
|
+
// node_modules/yaml/dist/compose/compose-scalar.js
|
|
4534
4534
|
var require_compose_scalar = __commonJS((exports) => {
|
|
4535
4535
|
var identity = require_identity();
|
|
4536
4536
|
var Scalar = require_Scalar();
|
|
@@ -4608,7 +4608,7 @@ var require_compose_scalar = __commonJS((exports) => {
|
|
|
4608
4608
|
exports.composeScalar = composeScalar;
|
|
4609
4609
|
});
|
|
4610
4610
|
|
|
4611
|
-
// node_modules
|
|
4611
|
+
// node_modules/yaml/dist/compose/util-empty-scalar-position.js
|
|
4612
4612
|
var require_util_empty_scalar_position = __commonJS((exports) => {
|
|
4613
4613
|
function emptyScalarPosition(offset, before, pos) {
|
|
4614
4614
|
if (before) {
|
|
@@ -4635,7 +4635,7 @@ var require_util_empty_scalar_position = __commonJS((exports) => {
|
|
|
4635
4635
|
exports.emptyScalarPosition = emptyScalarPosition;
|
|
4636
4636
|
});
|
|
4637
4637
|
|
|
4638
|
-
// node_modules
|
|
4638
|
+
// node_modules/yaml/dist/compose/compose-node.js
|
|
4639
4639
|
var require_compose_node = __commonJS((exports) => {
|
|
4640
4640
|
var Alias = require_Alias();
|
|
4641
4641
|
var identity = require_identity();
|
|
@@ -4738,7 +4738,7 @@ var require_compose_node = __commonJS((exports) => {
|
|
|
4738
4738
|
exports.composeNode = composeNode;
|
|
4739
4739
|
});
|
|
4740
4740
|
|
|
4741
|
-
// node_modules
|
|
4741
|
+
// node_modules/yaml/dist/compose/compose-doc.js
|
|
4742
4742
|
var require_compose_doc = __commonJS((exports) => {
|
|
4743
4743
|
var Document = require_Document();
|
|
4744
4744
|
var composeNode = require_compose_node();
|
|
@@ -4778,7 +4778,7 @@ var require_compose_doc = __commonJS((exports) => {
|
|
|
4778
4778
|
exports.composeDoc = composeDoc;
|
|
4779
4779
|
});
|
|
4780
4780
|
|
|
4781
|
-
// node_modules
|
|
4781
|
+
// node_modules/yaml/dist/compose/composer.js
|
|
4782
4782
|
var require_composer = __commonJS((exports) => {
|
|
4783
4783
|
var node_process = __require("process");
|
|
4784
4784
|
var directives = require_directives();
|
|
@@ -4967,7 +4967,7 @@ ${end.comment}` : end.comment;
|
|
|
4967
4967
|
exports.Composer = Composer;
|
|
4968
4968
|
});
|
|
4969
4969
|
|
|
4970
|
-
// node_modules
|
|
4970
|
+
// node_modules/yaml/dist/parse/cst-scalar.js
|
|
4971
4971
|
var require_cst_scalar = __commonJS((exports) => {
|
|
4972
4972
|
var resolveBlockScalar = require_resolve_block_scalar();
|
|
4973
4973
|
var resolveFlowScalar = require_resolve_flow_scalar();
|
|
@@ -5157,7 +5157,7 @@ var require_cst_scalar = __commonJS((exports) => {
|
|
|
5157
5157
|
exports.setScalarValue = setScalarValue;
|
|
5158
5158
|
});
|
|
5159
5159
|
|
|
5160
|
-
// node_modules
|
|
5160
|
+
// node_modules/yaml/dist/parse/cst-stringify.js
|
|
5161
5161
|
var require_cst_stringify = __commonJS((exports) => {
|
|
5162
5162
|
var stringify = (cst) => ("type" in cst) ? stringifyToken(cst) : stringifyItem(cst);
|
|
5163
5163
|
function stringifyToken(token) {
|
|
@@ -5215,7 +5215,7 @@ var require_cst_stringify = __commonJS((exports) => {
|
|
|
5215
5215
|
exports.stringify = stringify;
|
|
5216
5216
|
});
|
|
5217
5217
|
|
|
5218
|
-
// node_modules
|
|
5218
|
+
// node_modules/yaml/dist/parse/cst-visit.js
|
|
5219
5219
|
var require_cst_visit = __commonJS((exports) => {
|
|
5220
5220
|
var BREAK = Symbol("break visit");
|
|
5221
5221
|
var SKIP = Symbol("skip children");
|
|
@@ -5274,7 +5274,7 @@ var require_cst_visit = __commonJS((exports) => {
|
|
|
5274
5274
|
exports.visit = visit;
|
|
5275
5275
|
});
|
|
5276
5276
|
|
|
5277
|
-
// node_modules
|
|
5277
|
+
// node_modules/yaml/dist/parse/cst.js
|
|
5278
5278
|
var require_cst = __commonJS((exports) => {
|
|
5279
5279
|
var cstScalar = require_cst_scalar();
|
|
5280
5280
|
var cstStringify = require_cst_stringify();
|
|
@@ -5375,7 +5375,7 @@ var require_cst = __commonJS((exports) => {
|
|
|
5375
5375
|
exports.tokenType = tokenType;
|
|
5376
5376
|
});
|
|
5377
5377
|
|
|
5378
|
-
// node_modules
|
|
5378
|
+
// node_modules/yaml/dist/parse/lexer.js
|
|
5379
5379
|
var require_lexer = __commonJS((exports) => {
|
|
5380
5380
|
var cst = require_cst();
|
|
5381
5381
|
function isEmpty(ch) {
|
|
@@ -5961,7 +5961,7 @@ var require_lexer = __commonJS((exports) => {
|
|
|
5961
5961
|
exports.Lexer = Lexer;
|
|
5962
5962
|
});
|
|
5963
5963
|
|
|
5964
|
-
// node_modules
|
|
5964
|
+
// node_modules/yaml/dist/parse/line-counter.js
|
|
5965
5965
|
var require_line_counter = __commonJS((exports) => {
|
|
5966
5966
|
class LineCounter {
|
|
5967
5967
|
constructor() {
|
|
@@ -5989,7 +5989,7 @@ var require_line_counter = __commonJS((exports) => {
|
|
|
5989
5989
|
exports.LineCounter = LineCounter;
|
|
5990
5990
|
});
|
|
5991
5991
|
|
|
5992
|
-
// node_modules
|
|
5992
|
+
// node_modules/yaml/dist/parse/parser.js
|
|
5993
5993
|
var require_parser = __commonJS((exports) => {
|
|
5994
5994
|
var node_process = __require("process");
|
|
5995
5995
|
var cst = require_cst();
|
|
@@ -6838,7 +6838,7 @@ var require_parser = __commonJS((exports) => {
|
|
|
6838
6838
|
exports.Parser = Parser;
|
|
6839
6839
|
});
|
|
6840
6840
|
|
|
6841
|
-
// node_modules
|
|
6841
|
+
// node_modules/yaml/dist/public-api.js
|
|
6842
6842
|
var require_public_api = __commonJS((exports) => {
|
|
6843
6843
|
var composer = require_composer();
|
|
6844
6844
|
var Document = require_Document();
|
|
@@ -6932,7 +6932,7 @@ var require_public_api = __commonJS((exports) => {
|
|
|
6932
6932
|
exports.stringify = stringify;
|
|
6933
6933
|
});
|
|
6934
6934
|
|
|
6935
|
-
// node_modules
|
|
6935
|
+
// node_modules/yaml/dist/index.js
|
|
6936
6936
|
var composer, Document, Schema, errors, Alias, identity, Pair, Scalar, YAMLMap, YAMLSeq, cst, lexer, lineCounter, parser, publicApi, visit, $Composer, $Document, $Schema, $YAMLError, $YAMLParseError, $YAMLWarning, $Alias, $isAlias, $isCollection, $isDocument, $isMap, $isNode, $isPair, $isScalar, $isSeq, $Pair, $Scalar, $YAMLMap, $YAMLSeq, $Lexer, $LineCounter, $Parser, $parse, $parseAllDocuments, $parseDocument, $stringify, $visit, $visitAsync;
|
|
6937
6937
|
var init_dist = __esm(() => {
|
|
6938
6938
|
composer = require_composer();
|
|
@@ -6981,7 +6981,7 @@ var init_dist = __esm(() => {
|
|
|
6981
6981
|
$visitAsync = visit.visitAsync;
|
|
6982
6982
|
});
|
|
6983
6983
|
|
|
6984
|
-
// node_modules
|
|
6984
|
+
// node_modules/zod/v3/helpers/util.js
|
|
6985
6985
|
var util, objectUtil, ZodParsedType, getParsedType = (data) => {
|
|
6986
6986
|
const t = typeof data;
|
|
6987
6987
|
switch (t) {
|
|
@@ -7112,7 +7112,7 @@ var init_util = __esm(() => {
|
|
|
7112
7112
|
]);
|
|
7113
7113
|
});
|
|
7114
7114
|
|
|
7115
|
-
// node_modules
|
|
7115
|
+
// node_modules/zod/v3/ZodError.js
|
|
7116
7116
|
var ZodIssueCode, quotelessJson = (obj) => {
|
|
7117
7117
|
const json = JSON.stringify(obj, null, 2);
|
|
7118
7118
|
return json.replace(/"([^"]+)":/g, "$1:");
|
|
@@ -7233,7 +7233,7 @@ var init_ZodError = __esm(() => {
|
|
|
7233
7233
|
};
|
|
7234
7234
|
});
|
|
7235
7235
|
|
|
7236
|
-
// node_modules
|
|
7236
|
+
// node_modules/zod/v3/locales/en.js
|
|
7237
7237
|
var errorMap = (issue, _ctx) => {
|
|
7238
7238
|
let message;
|
|
7239
7239
|
switch (issue.code) {
|
|
@@ -7340,7 +7340,7 @@ var init_en = __esm(() => {
|
|
|
7340
7340
|
en_default = errorMap;
|
|
7341
7341
|
});
|
|
7342
7342
|
|
|
7343
|
-
// node_modules
|
|
7343
|
+
// node_modules/zod/v3/errors.js
|
|
7344
7344
|
function setErrorMap(map) {
|
|
7345
7345
|
overrideErrorMap = map;
|
|
7346
7346
|
}
|
|
@@ -7353,7 +7353,7 @@ var init_errors = __esm(() => {
|
|
|
7353
7353
|
overrideErrorMap = en_default;
|
|
7354
7354
|
});
|
|
7355
7355
|
|
|
7356
|
-
// node_modules
|
|
7356
|
+
// node_modules/zod/v3/helpers/parseUtil.js
|
|
7357
7357
|
function addIssueToContext(ctx, issueData) {
|
|
7358
7358
|
const overrideMap = getErrorMap();
|
|
7359
7359
|
const issue = makeIssue({
|
|
@@ -7458,10 +7458,10 @@ var init_parseUtil = __esm(() => {
|
|
|
7458
7458
|
});
|
|
7459
7459
|
});
|
|
7460
7460
|
|
|
7461
|
-
// node_modules
|
|
7461
|
+
// node_modules/zod/v3/helpers/typeAliases.js
|
|
7462
7462
|
var init_typeAliases = () => {};
|
|
7463
7463
|
|
|
7464
|
-
// node_modules
|
|
7464
|
+
// node_modules/zod/v3/helpers/errorUtil.js
|
|
7465
7465
|
var errorUtil;
|
|
7466
7466
|
var init_errorUtil = __esm(() => {
|
|
7467
7467
|
(function(errorUtil2) {
|
|
@@ -7470,7 +7470,7 @@ var init_errorUtil = __esm(() => {
|
|
|
7470
7470
|
})(errorUtil || (errorUtil = {}));
|
|
7471
7471
|
});
|
|
7472
7472
|
|
|
7473
|
-
// node_modules
|
|
7473
|
+
// node_modules/zod/v3/types.js
|
|
7474
7474
|
class ParseInputLazyPath {
|
|
7475
7475
|
constructor(parent, value, path, key) {
|
|
7476
7476
|
this._cachedPath = [];
|
|
@@ -10821,7 +10821,7 @@ var init_types = __esm(() => {
|
|
|
10821
10821
|
NEVER = INVALID;
|
|
10822
10822
|
});
|
|
10823
10823
|
|
|
10824
|
-
// node_modules
|
|
10824
|
+
// node_modules/zod/v3/external.js
|
|
10825
10825
|
var exports_external = {};
|
|
10826
10826
|
__export(exports_external, {
|
|
10827
10827
|
void: () => voidType,
|
|
@@ -10941,7 +10941,7 @@ var init_external = __esm(() => {
|
|
|
10941
10941
|
init_ZodError();
|
|
10942
10942
|
});
|
|
10943
10943
|
|
|
10944
|
-
// node_modules
|
|
10944
|
+
// node_modules/zod/index.js
|
|
10945
10945
|
var init_zod = __esm(() => {
|
|
10946
10946
|
init_external();
|
|
10947
10947
|
init_external();
|
|
@@ -11224,7 +11224,7 @@ var init_schema = __esm(() => {
|
|
|
11224
11224
|
}).optional()
|
|
11225
11225
|
});
|
|
11226
11226
|
VaultConfigSchema = exports_external.object({
|
|
11227
|
-
path: exports_external.string().default("~/.switchroom/vault.enc").describe("Path to encrypted vault file"),
|
|
11227
|
+
path: exports_external.string().default("~/.switchroom/vault/vault.enc").describe("Path to encrypted vault file. v0.7.12+ canonical default is " + "`~/.switchroom/vault/vault.enc` (parent-dir bind-mount enables " + "atomic-rename writes from the broker container). Older installs " + "with `~/.switchroom/vault.enc` are auto-migrated on `switchroom " + "apply`; the legacy path becomes a symlink for v0.7.10/.11 CLI " + "compatibility (sunset in v0.7.14)."),
|
|
11228
11228
|
broker: exports_external.object({
|
|
11229
11229
|
socket: exports_external.string().default("~/.switchroom/vault-broker.sock").describe("Unix domain socket path for the vault-broker daemon"),
|
|
11230
11230
|
enabled: exports_external.boolean().default(true).describe("Whether to start the vault-broker daemon on agent launch"),
|
|
@@ -11257,7 +11257,7 @@ var init_schema = __esm(() => {
|
|
|
11257
11257
|
});
|
|
11258
11258
|
|
|
11259
11259
|
// src/config/paths.ts
|
|
11260
|
-
import { existsSync as
|
|
11260
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
11261
11261
|
import { resolve as resolve2 } from "node:path";
|
|
11262
11262
|
function home() {
|
|
11263
11263
|
return process.env.HOME ?? "/root";
|
|
@@ -11269,9 +11269,9 @@ function resolveDualPath(pathStr) {
|
|
|
11269
11269
|
const absolute = resolve2(h, rest);
|
|
11270
11270
|
if (rest.startsWith(`${DEFAULT_STATE_DIR}/`)) {
|
|
11271
11271
|
const frag = rest.slice(DEFAULT_STATE_DIR.length + 1);
|
|
11272
|
-
if (!
|
|
11272
|
+
if (!existsSync4(absolute)) {
|
|
11273
11273
|
const legacy = resolve2(h, LEGACY_STATE_DIR, frag);
|
|
11274
|
-
if (
|
|
11274
|
+
if (existsSync4(legacy))
|
|
11275
11275
|
return legacy;
|
|
11276
11276
|
}
|
|
11277
11277
|
}
|
|
@@ -11291,7 +11291,7 @@ __export(exports_loader, {
|
|
|
11291
11291
|
findConfigFile: () => findConfigFile,
|
|
11292
11292
|
ConfigError: () => ConfigError
|
|
11293
11293
|
});
|
|
11294
|
-
import { readFileSync as
|
|
11294
|
+
import { readFileSync as readFileSync4, existsSync as existsSync5 } from "node:fs";
|
|
11295
11295
|
import { homedir } from "node:os";
|
|
11296
11296
|
import { resolve as resolve3 } from "node:path";
|
|
11297
11297
|
function formatZodErrors(error) {
|
|
@@ -11320,7 +11320,7 @@ function findConfigFile(startDir) {
|
|
|
11320
11320
|
resolve3(userDir, "clerk.yml")
|
|
11321
11321
|
].filter(Boolean);
|
|
11322
11322
|
for (const path of searchPaths) {
|
|
11323
|
-
if (
|
|
11323
|
+
if (existsSync5(path)) {
|
|
11324
11324
|
return path;
|
|
11325
11325
|
}
|
|
11326
11326
|
}
|
|
@@ -11328,12 +11328,12 @@ function findConfigFile(startDir) {
|
|
|
11328
11328
|
}
|
|
11329
11329
|
function loadConfig(configPath) {
|
|
11330
11330
|
const filePath = configPath ?? findConfigFile();
|
|
11331
|
-
if (!
|
|
11331
|
+
if (!existsSync5(filePath)) {
|
|
11332
11332
|
throw new ConfigError(`Config file not found: ${filePath}`);
|
|
11333
11333
|
}
|
|
11334
11334
|
let raw;
|
|
11335
11335
|
try {
|
|
11336
|
-
raw =
|
|
11336
|
+
raw = readFileSync4(filePath, "utf-8");
|
|
11337
11337
|
} catch (err) {
|
|
11338
11338
|
throw new ConfigError(`Failed to read config file: ${filePath}`, [
|
|
11339
11339
|
` ${err.message}`
|
|
@@ -11385,7 +11385,7 @@ var init_loader = __esm(() => {
|
|
|
11385
11385
|
|
|
11386
11386
|
// src/vault/broker/server.ts
|
|
11387
11387
|
import * as net from "node:net";
|
|
11388
|
-
import { mkdirSync as
|
|
11388
|
+
import { mkdirSync as mkdirSync5, chmodSync as chmodSync4, chownSync, existsSync as existsSync7, readFileSync as readFileSync7, readdirSync as readdirSync2, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3, renameSync as renameSync3 } from "node:fs";
|
|
11389
11389
|
|
|
11390
11390
|
// src/agents/compose.ts
|
|
11391
11391
|
import { createHash } from "node:crypto";
|
|
@@ -11676,21 +11676,183 @@ function allocateAgentUid(name) {
|
|
|
11676
11676
|
}
|
|
11677
11677
|
|
|
11678
11678
|
// src/vault/broker/server.ts
|
|
11679
|
-
import { dirname as
|
|
11679
|
+
import { dirname as dirname4, resolve as resolve4, basename as basename3 } from "node:path";
|
|
11680
11680
|
import * as os3 from "node:os";
|
|
11681
11681
|
import * as path3 from "node:path";
|
|
11682
11682
|
|
|
11683
11683
|
// src/vault/vault.ts
|
|
11684
11684
|
import { randomBytes, scryptSync, createCipheriv, createDecipheriv } from "node:crypto";
|
|
11685
11685
|
import {
|
|
11686
|
-
readFileSync,
|
|
11686
|
+
readFileSync as readFileSync2,
|
|
11687
11687
|
writeFileSync,
|
|
11688
|
-
existsSync,
|
|
11688
|
+
existsSync as existsSync2,
|
|
11689
11689
|
renameSync,
|
|
11690
11690
|
mkdirSync,
|
|
11691
|
-
unlinkSync
|
|
11691
|
+
unlinkSync as unlinkSync2
|
|
11692
11692
|
} from "node:fs";
|
|
11693
11693
|
import { dirname, basename, resolve } from "node:path";
|
|
11694
|
+
|
|
11695
|
+
// src/vault/flock.ts
|
|
11696
|
+
import {
|
|
11697
|
+
existsSync,
|
|
11698
|
+
openSync,
|
|
11699
|
+
closeSync,
|
|
11700
|
+
writeSync,
|
|
11701
|
+
fsyncSync,
|
|
11702
|
+
unlinkSync,
|
|
11703
|
+
readFileSync,
|
|
11704
|
+
readdirSync,
|
|
11705
|
+
rmdirSync,
|
|
11706
|
+
statSync,
|
|
11707
|
+
constants as fsConstants
|
|
11708
|
+
} from "node:fs";
|
|
11709
|
+
var DEFAULT_LOCK_RETRY_MS = 5000;
|
|
11710
|
+
function lockPathFor(vaultPath) {
|
|
11711
|
+
return `${vaultPath}.lock`;
|
|
11712
|
+
}
|
|
11713
|
+
function readLockHolder(lockPath) {
|
|
11714
|
+
try {
|
|
11715
|
+
const raw = readFileSync(lockPath, "utf8");
|
|
11716
|
+
const lines = raw.split(`
|
|
11717
|
+
`);
|
|
11718
|
+
const pid = Number.parseInt(lines[0] ?? "", 10);
|
|
11719
|
+
const acquiredAtMs = Number.parseInt(lines[1] ?? "", 10);
|
|
11720
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
11721
|
+
return null;
|
|
11722
|
+
if (!Number.isFinite(acquiredAtMs) || acquiredAtMs <= 0)
|
|
11723
|
+
return null;
|
|
11724
|
+
return { pid, acquiredAtMs, argv0: lines[2] ?? "" };
|
|
11725
|
+
} catch {
|
|
11726
|
+
return null;
|
|
11727
|
+
}
|
|
11728
|
+
}
|
|
11729
|
+
function pidIsLive(pid) {
|
|
11730
|
+
if (process.platform === "linux") {
|
|
11731
|
+
return existsSync(`/proc/${pid}`);
|
|
11732
|
+
}
|
|
11733
|
+
try {
|
|
11734
|
+
process.kill(pid, 0);
|
|
11735
|
+
return true;
|
|
11736
|
+
} catch {
|
|
11737
|
+
return false;
|
|
11738
|
+
}
|
|
11739
|
+
}
|
|
11740
|
+
function clearStaleSentinelDir(lockPath) {
|
|
11741
|
+
try {
|
|
11742
|
+
if (!existsSync(lockPath))
|
|
11743
|
+
return true;
|
|
11744
|
+
const s = statSync(lockPath);
|
|
11745
|
+
if (!s.isDirectory())
|
|
11746
|
+
return true;
|
|
11747
|
+
for (const entry of readdirSync(lockPath)) {
|
|
11748
|
+
try {
|
|
11749
|
+
unlinkSync(`${lockPath}/${entry}`);
|
|
11750
|
+
} catch {}
|
|
11751
|
+
}
|
|
11752
|
+
rmdirSync(lockPath);
|
|
11753
|
+
return true;
|
|
11754
|
+
} catch {
|
|
11755
|
+
return false;
|
|
11756
|
+
}
|
|
11757
|
+
}
|
|
11758
|
+
function acquireLock(vaultPath, options = {}) {
|
|
11759
|
+
const budgetMs = options.budgetMs ?? DEFAULT_LOCK_RETRY_MS;
|
|
11760
|
+
const lockPath = lockPathFor(vaultPath);
|
|
11761
|
+
const deadline = Date.now() + budgetMs;
|
|
11762
|
+
const sleepBuf = new Int32Array(new SharedArrayBuffer(4));
|
|
11763
|
+
while (true) {
|
|
11764
|
+
let fd = null;
|
|
11765
|
+
try {
|
|
11766
|
+
fd = openSync(lockPath, fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL, 384);
|
|
11767
|
+
} catch (err) {
|
|
11768
|
+
const code = err?.code ?? "";
|
|
11769
|
+
if (code === "EEXIST") {
|
|
11770
|
+
let isDir = false;
|
|
11771
|
+
try {
|
|
11772
|
+
isDir = statSync(lockPath).isDirectory();
|
|
11773
|
+
} catch {}
|
|
11774
|
+
if (isDir) {
|
|
11775
|
+
if (clearStaleSentinelDir(lockPath))
|
|
11776
|
+
continue;
|
|
11777
|
+
}
|
|
11778
|
+
const holder = readLockHolder(lockPath);
|
|
11779
|
+
if (holder && !pidIsLive(holder.pid)) {
|
|
11780
|
+
try {
|
|
11781
|
+
unlinkSync(lockPath);
|
|
11782
|
+
} catch {}
|
|
11783
|
+
continue;
|
|
11784
|
+
}
|
|
11785
|
+
if (Date.now() >= deadline) {
|
|
11786
|
+
throw makeBusyError(vaultPath, lockPath, holder, budgetMs);
|
|
11787
|
+
}
|
|
11788
|
+
Atomics.wait(sleepBuf, 0, 0, 100);
|
|
11789
|
+
continue;
|
|
11790
|
+
} else {
|
|
11791
|
+
throw err;
|
|
11792
|
+
}
|
|
11793
|
+
}
|
|
11794
|
+
try {
|
|
11795
|
+
const meta = `${process.pid}
|
|
11796
|
+
${Date.now()}
|
|
11797
|
+
${process.argv[1] ?? ""}
|
|
11798
|
+
`;
|
|
11799
|
+
writeSync(fd, meta);
|
|
11800
|
+
fsyncSync(fd);
|
|
11801
|
+
} catch {
|
|
11802
|
+
try {
|
|
11803
|
+
closeSync(fd);
|
|
11804
|
+
} catch {}
|
|
11805
|
+
try {
|
|
11806
|
+
unlinkSync(lockPath);
|
|
11807
|
+
} catch {}
|
|
11808
|
+
throw new Error(`vault flock: failed to write holder metadata to ${lockPath}`);
|
|
11809
|
+
}
|
|
11810
|
+
const ownedFd = fd;
|
|
11811
|
+
return {
|
|
11812
|
+
release: () => {
|
|
11813
|
+
try {
|
|
11814
|
+
closeSync(ownedFd);
|
|
11815
|
+
} catch {}
|
|
11816
|
+
try {
|
|
11817
|
+
unlinkSync(lockPath);
|
|
11818
|
+
} catch {}
|
|
11819
|
+
}
|
|
11820
|
+
};
|
|
11821
|
+
}
|
|
11822
|
+
}
|
|
11823
|
+
|
|
11824
|
+
class VaultBusyError extends Error {
|
|
11825
|
+
vaultPath;
|
|
11826
|
+
lockPath;
|
|
11827
|
+
holderPid;
|
|
11828
|
+
heldForMs;
|
|
11829
|
+
budgetMs;
|
|
11830
|
+
constructor(message, fields) {
|
|
11831
|
+
super(message);
|
|
11832
|
+
this.name = "VaultBusyError";
|
|
11833
|
+
this.vaultPath = fields.vaultPath;
|
|
11834
|
+
this.lockPath = fields.lockPath;
|
|
11835
|
+
this.holderPid = fields.holderPid;
|
|
11836
|
+
this.heldForMs = fields.heldForMs;
|
|
11837
|
+
this.budgetMs = fields.budgetMs;
|
|
11838
|
+
}
|
|
11839
|
+
}
|
|
11840
|
+
function makeBusyError(vaultPath, lockPath, holder, budgetMs) {
|
|
11841
|
+
const holderPid = holder?.pid ?? null;
|
|
11842
|
+
const heldForMs = holder ? Date.now() - holder.acquiredAtMs : null;
|
|
11843
|
+
const holderClause = holder ? `held by pid ${holder.pid} (acquired ${Math.round((heldForMs ?? 0) / 1000)}s ago)` : "held by another writer (holder PID unreadable — lock file empty or unparseable)";
|
|
11844
|
+
return new VaultBusyError(`vault busy: ${holderClause} at ${lockPath} (retried for ${budgetMs}ms). ` + `Try again in a moment. If the holder process is gone, the next acquirer ` + `will clear the stale lock automatically.`, { vaultPath, lockPath, holderPid, heldForMs, budgetMs });
|
|
11845
|
+
}
|
|
11846
|
+
|
|
11847
|
+
// src/vault/vault.ts
|
|
11848
|
+
var KNOWN_VAULT_ARTIFACT_NAMES = new Set([
|
|
11849
|
+
"vault.enc",
|
|
11850
|
+
"vault.enc.bak",
|
|
11851
|
+
"vault.enc.tmp",
|
|
11852
|
+
"vault.enc.lock",
|
|
11853
|
+
".vault.enc.symlink-tmp"
|
|
11854
|
+
]);
|
|
11855
|
+
var SAVE_VAULT_LOCK_RETRY_MS = DEFAULT_LOCK_RETRY_MS;
|
|
11694
11856
|
var SCRYPT_N = 32768;
|
|
11695
11857
|
var SCRYPT_R = 8;
|
|
11696
11858
|
var SCRYPT_P = 1;
|
|
@@ -11703,17 +11865,20 @@ function atomicWriteFileSync(path, data, mode) {
|
|
|
11703
11865
|
renameSync(tmp, path);
|
|
11704
11866
|
} catch (err) {
|
|
11705
11867
|
try {
|
|
11706
|
-
if (
|
|
11707
|
-
|
|
11868
|
+
if (existsSync2(tmp))
|
|
11869
|
+
unlinkSync2(tmp);
|
|
11708
11870
|
} catch {}
|
|
11709
11871
|
throw err;
|
|
11710
11872
|
}
|
|
11711
11873
|
}
|
|
11712
11874
|
|
|
11713
11875
|
class VaultError extends Error {
|
|
11714
|
-
|
|
11876
|
+
cause;
|
|
11877
|
+
constructor(message, options) {
|
|
11715
11878
|
super(message);
|
|
11716
11879
|
this.name = "VaultError";
|
|
11880
|
+
if (options?.cause !== undefined)
|
|
11881
|
+
this.cause = options.cause;
|
|
11717
11882
|
}
|
|
11718
11883
|
}
|
|
11719
11884
|
var LEGACY_SCRYPT_N = 16384;
|
|
@@ -11759,12 +11924,12 @@ function normalizeSecrets(raw) {
|
|
|
11759
11924
|
return out;
|
|
11760
11925
|
}
|
|
11761
11926
|
function openVault(passphrase, vaultPath) {
|
|
11762
|
-
if (!
|
|
11927
|
+
if (!existsSync2(vaultPath)) {
|
|
11763
11928
|
throw new VaultError(`Vault file not found: ${vaultPath}`);
|
|
11764
11929
|
}
|
|
11765
11930
|
let vaultFile;
|
|
11766
11931
|
try {
|
|
11767
|
-
vaultFile = JSON.parse(
|
|
11932
|
+
vaultFile = JSON.parse(readFileSync2(vaultPath, "utf8"));
|
|
11768
11933
|
} catch {
|
|
11769
11934
|
throw new VaultError(`Failed to read vault file: ${vaultPath}`);
|
|
11770
11935
|
}
|
|
@@ -11786,24 +11951,181 @@ function openVault(passphrase, vaultPath) {
|
|
|
11786
11951
|
return normalizeSecrets(vaultData.secrets ?? {});
|
|
11787
11952
|
}
|
|
11788
11953
|
function saveVault(passphrase, vaultPath, secrets) {
|
|
11789
|
-
if (!
|
|
11954
|
+
if (!existsSync2(vaultPath)) {
|
|
11790
11955
|
throw new VaultError(`Vault file not found: ${vaultPath}`);
|
|
11791
11956
|
}
|
|
11792
|
-
let
|
|
11957
|
+
let releaseLock = null;
|
|
11958
|
+
try {
|
|
11959
|
+
releaseLock = acquireLock(vaultPath, { budgetMs: SAVE_VAULT_LOCK_RETRY_MS }).release;
|
|
11960
|
+
} catch (err) {
|
|
11961
|
+
if (err instanceof VaultBusyError) {
|
|
11962
|
+
throw new VaultError(err.message, { cause: err });
|
|
11963
|
+
}
|
|
11964
|
+
throw err;
|
|
11965
|
+
}
|
|
11793
11966
|
try {
|
|
11794
|
-
vaultFile
|
|
11967
|
+
let vaultFile;
|
|
11968
|
+
try {
|
|
11969
|
+
vaultFile = JSON.parse(readFileSync2(vaultPath, "utf8"));
|
|
11970
|
+
} catch {
|
|
11971
|
+
throw new VaultError(`Failed to read vault file: ${vaultPath}`);
|
|
11972
|
+
}
|
|
11973
|
+
const salt = Buffer.from(vaultFile.salt, "hex");
|
|
11974
|
+
const key = deriveKey(passphrase, salt, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P });
|
|
11975
|
+
vaultFile.kdf = { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P };
|
|
11976
|
+
const vaultData = { secrets };
|
|
11977
|
+
const { iv, data, tag } = encrypt(key, JSON.stringify(vaultData));
|
|
11978
|
+
vaultFile.iv = iv;
|
|
11979
|
+
vaultFile.data = data;
|
|
11980
|
+
vaultFile.tag = tag;
|
|
11981
|
+
atomicWriteFileSync(vaultPath, JSON.stringify(vaultFile, null, 2), 384);
|
|
11982
|
+
} finally {
|
|
11983
|
+
if (releaseLock !== null) {
|
|
11984
|
+
try {
|
|
11985
|
+
releaseLock();
|
|
11986
|
+
} catch {}
|
|
11987
|
+
}
|
|
11988
|
+
}
|
|
11989
|
+
}
|
|
11990
|
+
function acquireVaultLock(vaultPath) {
|
|
11991
|
+
try {
|
|
11992
|
+
return acquireLock(vaultPath, { budgetMs: SAVE_VAULT_LOCK_RETRY_MS }).release;
|
|
11993
|
+
} catch (err) {
|
|
11994
|
+
if (err instanceof VaultBusyError) {
|
|
11995
|
+
throw new VaultError(err.message, { cause: err });
|
|
11996
|
+
}
|
|
11997
|
+
throw err;
|
|
11998
|
+
}
|
|
11999
|
+
}
|
|
12000
|
+
|
|
12001
|
+
// src/vault/migrate-layout.ts
|
|
12002
|
+
import {
|
|
12003
|
+
copyFileSync,
|
|
12004
|
+
chmodSync,
|
|
12005
|
+
existsSync as existsSync3,
|
|
12006
|
+
fsyncSync as fsyncSync3,
|
|
12007
|
+
lstatSync,
|
|
12008
|
+
mkdirSync as mkdirSync2,
|
|
12009
|
+
openSync as openSync3,
|
|
12010
|
+
closeSync as closeSync3,
|
|
12011
|
+
readFileSync as readFileSync3,
|
|
12012
|
+
renameSync as renameSync2,
|
|
12013
|
+
statSync as statSync2,
|
|
12014
|
+
symlinkSync,
|
|
12015
|
+
unlinkSync as unlinkSync3
|
|
12016
|
+
} from "node:fs";
|
|
12017
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
12018
|
+
import { basename as basename2, dirname as dirname2, join } from "node:path";
|
|
12019
|
+
function vaultLayoutPaths(home) {
|
|
12020
|
+
const switchroomRoot = join(home, ".switchroom");
|
|
12021
|
+
return {
|
|
12022
|
+
oldPath: join(switchroomRoot, "vault.enc"),
|
|
12023
|
+
newPath: join(switchroomRoot, "vault", "vault.enc"),
|
|
12024
|
+
parent: join(switchroomRoot, "vault"),
|
|
12025
|
+
switchroomRoot
|
|
12026
|
+
};
|
|
12027
|
+
}
|
|
12028
|
+
function inspectVaultLayout(home) {
|
|
12029
|
+
return runMigration(home, { dryRun: true });
|
|
12030
|
+
}
|
|
12031
|
+
function runMigration(home, opts) {
|
|
12032
|
+
const { oldPath, newPath, parent, switchroomRoot } = vaultLayoutPaths(home);
|
|
12033
|
+
const lockTarget = existsSync3(newPath) ? newPath : existsSync3(oldPath) ? oldPath : null;
|
|
12034
|
+
const release = !opts.dryRun && lockTarget !== null ? acquireVaultLock(lockTarget) : null;
|
|
12035
|
+
try {
|
|
12036
|
+
const oldStat = lstatSyncOrNull(oldPath);
|
|
12037
|
+
const newExists = existsSync3(newPath);
|
|
12038
|
+
if (oldStat === null && !newExists) {
|
|
12039
|
+
return { kind: "no-vault" };
|
|
12040
|
+
}
|
|
12041
|
+
if (oldStat?.isSymbolicLink() && newExists) {
|
|
12042
|
+
return { kind: "already-migrated" };
|
|
12043
|
+
}
|
|
12044
|
+
if (oldStat?.isFile() && newExists) {
|
|
12045
|
+
const oldHash = sha256File(oldPath);
|
|
12046
|
+
const newHash = sha256File(newPath);
|
|
12047
|
+
if (oldHash === newHash) {
|
|
12048
|
+
if (opts.dryRun)
|
|
12049
|
+
return { kind: "completed-partial" };
|
|
12050
|
+
atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
|
|
12051
|
+
fsyncDir(switchroomRoot);
|
|
12052
|
+
return { kind: "completed-partial" };
|
|
12053
|
+
}
|
|
12054
|
+
const oldRealStat = statSync2(oldPath);
|
|
12055
|
+
const newRealStat = statSync2(newPath);
|
|
12056
|
+
return {
|
|
12057
|
+
kind: "divergent",
|
|
12058
|
+
details: {
|
|
12059
|
+
oldPath,
|
|
12060
|
+
newPath,
|
|
12061
|
+
oldHash,
|
|
12062
|
+
newHash,
|
|
12063
|
+
oldSize: oldRealStat.size,
|
|
12064
|
+
newSize: newRealStat.size,
|
|
12065
|
+
oldMtime: oldRealStat.mtime.toISOString(),
|
|
12066
|
+
newMtime: newRealStat.mtime.toISOString()
|
|
12067
|
+
}
|
|
12068
|
+
};
|
|
12069
|
+
}
|
|
12070
|
+
if (oldStat?.isFile() && !newExists) {
|
|
12071
|
+
if (opts.dryRun)
|
|
12072
|
+
return { kind: "migrated" };
|
|
12073
|
+
mkdirSync2(parent, { recursive: true, mode: 448 });
|
|
12074
|
+
const tempNew = `${newPath}.tmp`;
|
|
12075
|
+
copyFileSync(oldPath, tempNew);
|
|
12076
|
+
chmodSync(tempNew, 384);
|
|
12077
|
+
fsyncFile(tempNew);
|
|
12078
|
+
renameSync2(tempNew, newPath);
|
|
12079
|
+
fsyncDir(parent);
|
|
12080
|
+
atomicReplaceWithSymlink(oldPath, "vault/vault.enc");
|
|
12081
|
+
fsyncDir(switchroomRoot);
|
|
12082
|
+
return { kind: "migrated" };
|
|
12083
|
+
}
|
|
12084
|
+
return { kind: "no-vault" };
|
|
12085
|
+
} finally {
|
|
12086
|
+
if (release !== null) {
|
|
12087
|
+
try {
|
|
12088
|
+
release();
|
|
12089
|
+
} catch {}
|
|
12090
|
+
}
|
|
12091
|
+
}
|
|
12092
|
+
}
|
|
12093
|
+
function lstatSyncOrNull(path) {
|
|
12094
|
+
try {
|
|
12095
|
+
return lstatSync(path);
|
|
11795
12096
|
} catch {
|
|
11796
|
-
|
|
12097
|
+
return null;
|
|
12098
|
+
}
|
|
12099
|
+
}
|
|
12100
|
+
function sha256File(path) {
|
|
12101
|
+
const data = readFileSync3(path);
|
|
12102
|
+
return createHash2("sha256").update(data).digest("hex");
|
|
12103
|
+
}
|
|
12104
|
+
function atomicReplaceWithSymlink(target, linkTarget) {
|
|
12105
|
+
const tmp = join(dirname2(target), `.${basename2(target)}.symlink-tmp`);
|
|
12106
|
+
if (existsSync3(tmp)) {
|
|
12107
|
+
try {
|
|
12108
|
+
unlinkSync3(tmp);
|
|
12109
|
+
} catch {}
|
|
12110
|
+
}
|
|
12111
|
+
symlinkSync(linkTarget, tmp);
|
|
12112
|
+
renameSync2(tmp, target);
|
|
12113
|
+
}
|
|
12114
|
+
function fsyncFile(path) {
|
|
12115
|
+
const fd = openSync3(path, "r+");
|
|
12116
|
+
try {
|
|
12117
|
+
fsyncSync3(fd);
|
|
12118
|
+
} finally {
|
|
12119
|
+
closeSync3(fd);
|
|
12120
|
+
}
|
|
12121
|
+
}
|
|
12122
|
+
function fsyncDir(path) {
|
|
12123
|
+
const fd = openSync3(path, "r");
|
|
12124
|
+
try {
|
|
12125
|
+
fsyncSync3(fd);
|
|
12126
|
+
} finally {
|
|
12127
|
+
closeSync3(fd);
|
|
11797
12128
|
}
|
|
11798
|
-
const salt = Buffer.from(vaultFile.salt, "hex");
|
|
11799
|
-
const key = deriveKey(passphrase, salt, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P });
|
|
11800
|
-
vaultFile.kdf = { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P };
|
|
11801
|
-
const vaultData = { secrets };
|
|
11802
|
-
const { iv, data, tag } = encrypt(key, JSON.stringify(vaultData));
|
|
11803
|
-
vaultFile.iv = iv;
|
|
11804
|
-
vaultFile.data = data;
|
|
11805
|
-
vaultFile.tag = tag;
|
|
11806
|
-
atomicWriteFileSync(vaultPath, JSON.stringify(vaultFile, null, 2), 384);
|
|
11807
12129
|
}
|
|
11808
12130
|
|
|
11809
12131
|
// src/vault/broker/server.ts
|
|
@@ -11811,7 +12133,7 @@ init_loader();
|
|
|
11811
12133
|
|
|
11812
12134
|
// src/vault/auto-unlock.ts
|
|
11813
12135
|
import { createHmac, randomBytes as randomBytes2, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2 } from "node:crypto";
|
|
11814
|
-
import { chmodSync, existsSync as
|
|
12136
|
+
import { chmodSync as chmodSync2, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync2 } from "node:fs";
|
|
11815
12137
|
var FORMAT_VERSION = 1;
|
|
11816
12138
|
var SALT_LEN = 16;
|
|
11817
12139
|
var NONCE_LEN = 12;
|
|
@@ -11839,7 +12161,7 @@ class AutoUnlockDecryptError extends Error {
|
|
|
11839
12161
|
function readMachineId() {
|
|
11840
12162
|
for (const path of [MACHINE_ID_PRIMARY, MACHINE_ID_FALLBACK]) {
|
|
11841
12163
|
try {
|
|
11842
|
-
const id =
|
|
12164
|
+
const id = readFileSync5(path, "utf8").trim();
|
|
11843
12165
|
if (id.length > 0)
|
|
11844
12166
|
return id;
|
|
11845
12167
|
} catch {}
|
|
@@ -11876,12 +12198,12 @@ function decryptAutoUnlock(blob, machineId) {
|
|
|
11876
12198
|
}
|
|
11877
12199
|
}
|
|
11878
12200
|
function readAutoUnlockFile(filePath) {
|
|
11879
|
-
if (!
|
|
12201
|
+
if (!existsSync6(filePath)) {
|
|
11880
12202
|
throw new AutoUnlockDecryptError("io");
|
|
11881
12203
|
}
|
|
11882
12204
|
let blob;
|
|
11883
12205
|
try {
|
|
11884
|
-
blob =
|
|
12206
|
+
blob = readFileSync5(filePath);
|
|
11885
12207
|
} catch {
|
|
11886
12208
|
throw new AutoUnlockDecryptError("io");
|
|
11887
12209
|
}
|
|
@@ -11891,7 +12213,7 @@ var DEFAULT_AUTO_UNLOCK_PATH = "~/.switchroom/vault-auto-unlock";
|
|
|
11891
12213
|
|
|
11892
12214
|
// src/vault/broker/peercred.ts
|
|
11893
12215
|
import { execFileSync } from "node:child_process";
|
|
11894
|
-
import { readFileSync as
|
|
12216
|
+
import { readFileSync as readFileSync6, readlinkSync, fstatSync } from "node:fs";
|
|
11895
12217
|
|
|
11896
12218
|
// src/vault/broker/peercred-ffi.ts
|
|
11897
12219
|
function getPeerCred(fd) {
|
|
@@ -12017,7 +12339,7 @@ function findClientPidByServerInode(rows, socketPath, serverInode) {
|
|
|
12017
12339
|
}
|
|
12018
12340
|
function readUid(pid) {
|
|
12019
12341
|
try {
|
|
12020
|
-
const status =
|
|
12342
|
+
const status = readFileSync6(`/proc/${pid}/status`, "utf8");
|
|
12021
12343
|
const m = status.match(/^Uid:\s+(\d+)/m);
|
|
12022
12344
|
if (!m)
|
|
12023
12345
|
return null;
|
|
@@ -12035,7 +12357,7 @@ function readExe(pid) {
|
|
|
12035
12357
|
}
|
|
12036
12358
|
function readSystemdUnit(pid) {
|
|
12037
12359
|
try {
|
|
12038
|
-
const content =
|
|
12360
|
+
const content = readFileSync6(`/proc/${pid}/cgroup`, "utf8");
|
|
12039
12361
|
const lines = content.split(`
|
|
12040
12362
|
`);
|
|
12041
12363
|
for (const line of lines) {
|
|
@@ -12298,7 +12620,8 @@ var PutRequestSchema = exports_external.object({
|
|
|
12298
12620
|
exports_external.object({ kind: exports_external.literal("string"), value: exports_external.string() }),
|
|
12299
12621
|
exports_external.object({ kind: exports_external.literal("binary"), value: exports_external.string() })
|
|
12300
12622
|
]),
|
|
12301
|
-
token: exports_external.string().optional()
|
|
12623
|
+
token: exports_external.string().optional(),
|
|
12624
|
+
passphrase: exports_external.string().optional()
|
|
12302
12625
|
});
|
|
12303
12626
|
var ListRequestSchema = exports_external.object({
|
|
12304
12627
|
v: exports_external.literal(1),
|
|
@@ -12309,9 +12632,10 @@ var MintGrantRequestSchema = exports_external.object({
|
|
|
12309
12632
|
v: exports_external.literal(1),
|
|
12310
12633
|
op: exports_external.literal("mint_grant"),
|
|
12311
12634
|
agent: exports_external.string().min(1),
|
|
12312
|
-
keys: exports_external.array(exports_external.string().min(1))
|
|
12635
|
+
keys: exports_external.array(exports_external.string().min(1)),
|
|
12313
12636
|
ttl_seconds: exports_external.number().int().positive().nullable(),
|
|
12314
|
-
description: exports_external.string().optional()
|
|
12637
|
+
description: exports_external.string().optional(),
|
|
12638
|
+
write_keys: exports_external.array(exports_external.string().min(1)).optional()
|
|
12315
12639
|
});
|
|
12316
12640
|
var ListGrantsRequestSchema = exports_external.object({
|
|
12317
12641
|
v: exports_external.literal(1),
|
|
@@ -12452,6 +12776,7 @@ var GrantMetaSchema = exports_external.object({
|
|
|
12452
12776
|
id: exports_external.string(),
|
|
12453
12777
|
agent_slug: exports_external.string(),
|
|
12454
12778
|
key_allow: exports_external.array(exports_external.string()),
|
|
12779
|
+
write_allow: exports_external.array(exports_external.string()).default([]),
|
|
12455
12780
|
expires_at: exports_external.number().nullable(),
|
|
12456
12781
|
created_at: exports_external.number(),
|
|
12457
12782
|
description: exports_external.string().nullable()
|
|
@@ -12622,7 +12947,7 @@ function createAuditLogger(opts = {}) {
|
|
|
12622
12947
|
// src/vault/grants.ts
|
|
12623
12948
|
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
12624
12949
|
|
|
12625
|
-
// node_modules
|
|
12950
|
+
// node_modules/bcryptjs/index.js
|
|
12626
12951
|
import nodeCrypto from "crypto";
|
|
12627
12952
|
var randomFallback = null;
|
|
12628
12953
|
function randomBytes3(len) {
|
|
@@ -14307,6 +14632,11 @@ function migrateGrantsSchema(db) {
|
|
|
14307
14632
|
description TEXT
|
|
14308
14633
|
)
|
|
14309
14634
|
`);
|
|
14635
|
+
const cols = db.query(`PRAGMA table_info(vault_grants)`).all();
|
|
14636
|
+
const hasWriteAllow = cols.some((c) => c.name === "write_allow");
|
|
14637
|
+
if (!hasWriteAllow) {
|
|
14638
|
+
db.run(`ALTER TABLE vault_grants ADD COLUMN write_allow TEXT NOT NULL DEFAULT '[]'`);
|
|
14639
|
+
}
|
|
14310
14640
|
}
|
|
14311
14641
|
var BCRYPT_COST = 10;
|
|
14312
14642
|
function generateId() {
|
|
@@ -14330,21 +14660,43 @@ function rowToGrant(row) {
|
|
|
14330
14660
|
id: row.id,
|
|
14331
14661
|
agent_slug: row.agent_slug,
|
|
14332
14662
|
key_allow: parseKeyAllow(row.key_allow),
|
|
14663
|
+
write_allow: parseKeyAllow(row.write_allow ?? "[]"),
|
|
14333
14664
|
expires_at: row.expires_at ?? null,
|
|
14334
14665
|
revoked_at: row.revoked_at ?? null,
|
|
14335
14666
|
created_at: row.created_at,
|
|
14336
14667
|
description: row.description ?? null
|
|
14337
14668
|
};
|
|
14338
14669
|
}
|
|
14339
|
-
|
|
14670
|
+
function keyMatchesPatterns(patterns, key) {
|
|
14671
|
+
for (const pat of patterns) {
|
|
14672
|
+
if (pat.endsWith("*")) {
|
|
14673
|
+
const prefix = pat.slice(0, -1);
|
|
14674
|
+
if (key.startsWith(prefix))
|
|
14675
|
+
return true;
|
|
14676
|
+
} else if (pat === key) {
|
|
14677
|
+
return true;
|
|
14678
|
+
}
|
|
14679
|
+
}
|
|
14680
|
+
return false;
|
|
14681
|
+
}
|
|
14682
|
+
async function mintGrant(db, agent_slug, key_allow, ttl_seconds, description, write_allow = []) {
|
|
14340
14683
|
const id = generateId();
|
|
14341
14684
|
const secret = generateSecret();
|
|
14342
14685
|
const token = `${id}.${secret}`;
|
|
14343
14686
|
const secret_hash = await hash(secret, BCRYPT_COST);
|
|
14344
14687
|
const now = Math.floor(Date.now() / 1000);
|
|
14345
14688
|
const expires_at = ttl_seconds != null ? now + ttl_seconds : null;
|
|
14346
|
-
db.run(`INSERT INTO vault_grants (id, secret_hash, agent_slug, key_allow, expires_at, revoked_at, created_at, description)
|
|
14347
|
-
VALUES (?, ?, ?, ?, ?, NULL, ?, ?)`, [
|
|
14689
|
+
db.run(`INSERT INTO vault_grants (id, secret_hash, agent_slug, key_allow, write_allow, expires_at, revoked_at, created_at, description)
|
|
14690
|
+
VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)`, [
|
|
14691
|
+
id,
|
|
14692
|
+
secret_hash,
|
|
14693
|
+
agent_slug,
|
|
14694
|
+
JSON.stringify(key_allow),
|
|
14695
|
+
JSON.stringify(write_allow),
|
|
14696
|
+
expires_at,
|
|
14697
|
+
now,
|
|
14698
|
+
description ?? null
|
|
14699
|
+
]);
|
|
14348
14700
|
return { token, id, expires_at };
|
|
14349
14701
|
}
|
|
14350
14702
|
async function validateGrant(db, token, key) {
|
|
@@ -14385,6 +14737,41 @@ async function validateGrant(db, token, key) {
|
|
|
14385
14737
|
}
|
|
14386
14738
|
return { ok: true, grant };
|
|
14387
14739
|
}
|
|
14740
|
+
async function validateGrantForWrite(db, token, key) {
|
|
14741
|
+
const dotIdx = token.indexOf(".");
|
|
14742
|
+
if (dotIdx === -1 || !token.startsWith("vg_")) {
|
|
14743
|
+
return { ok: false, reason: "grant-invalid" };
|
|
14744
|
+
}
|
|
14745
|
+
const id = token.slice(0, dotIdx);
|
|
14746
|
+
const secret = token.slice(dotIdx + 1);
|
|
14747
|
+
if (!id || !secret) {
|
|
14748
|
+
return { ok: false, reason: "grant-invalid" };
|
|
14749
|
+
}
|
|
14750
|
+
const row = db.query(`SELECT id, secret_hash, agent_slug, key_allow, write_allow, expires_at, revoked_at, created_at, description
|
|
14751
|
+
FROM vault_grants WHERE id = ?`).get(id);
|
|
14752
|
+
if (!row)
|
|
14753
|
+
return { ok: false, reason: "grant-invalid" };
|
|
14754
|
+
const secretHash = row.secret_hash;
|
|
14755
|
+
let hashMatches;
|
|
14756
|
+
try {
|
|
14757
|
+
hashMatches = await compare(secret, secretHash);
|
|
14758
|
+
} catch {
|
|
14759
|
+
hashMatches = false;
|
|
14760
|
+
}
|
|
14761
|
+
if (!hashMatches)
|
|
14762
|
+
return { ok: false, reason: "grant-invalid" };
|
|
14763
|
+
const grant = rowToGrant(row);
|
|
14764
|
+
const now = Math.floor(Date.now() / 1000);
|
|
14765
|
+
if (grant.revoked_at !== null)
|
|
14766
|
+
return { ok: false, reason: "grant-revoked" };
|
|
14767
|
+
if (grant.expires_at !== null && grant.expires_at < now) {
|
|
14768
|
+
return { ok: false, reason: "grant-expired" };
|
|
14769
|
+
}
|
|
14770
|
+
if (!keyMatchesPatterns(grant.write_allow, key)) {
|
|
14771
|
+
return { ok: false, reason: "grant-write-not-allowed" };
|
|
14772
|
+
}
|
|
14773
|
+
return { ok: true, grant };
|
|
14774
|
+
}
|
|
14388
14775
|
function revokeGrant(db, id) {
|
|
14389
14776
|
const now = Math.floor(Date.now() / 1000);
|
|
14390
14777
|
const result = db.run(`UPDATE vault_grants SET revoked_at = ? WHERE id = ? AND revoked_at IS NULL`, [now, id]);
|
|
@@ -14393,11 +14780,11 @@ function revokeGrant(db, id) {
|
|
|
14393
14780
|
function listGrants(db, agent_slug) {
|
|
14394
14781
|
let rows;
|
|
14395
14782
|
if (agent_slug !== undefined) {
|
|
14396
|
-
rows = db.query(`SELECT id, agent_slug, key_allow, expires_at, revoked_at, created_at, description
|
|
14783
|
+
rows = db.query(`SELECT id, agent_slug, key_allow, write_allow, expires_at, revoked_at, created_at, description
|
|
14397
14784
|
FROM vault_grants WHERE revoked_at IS NULL AND agent_slug = ?
|
|
14398
14785
|
ORDER BY created_at DESC`).all(agent_slug);
|
|
14399
14786
|
} else {
|
|
14400
|
-
rows = db.query(`SELECT id, agent_slug, key_allow, expires_at, revoked_at, created_at, description
|
|
14787
|
+
rows = db.query(`SELECT id, agent_slug, key_allow, write_allow, expires_at, revoked_at, created_at, description
|
|
14401
14788
|
FROM vault_grants WHERE revoked_at IS NULL
|
|
14402
14789
|
ORDER BY created_at DESC`).all();
|
|
14403
14790
|
}
|
|
@@ -14786,9 +15173,12 @@ class VaultBroker {
|
|
|
14786
15173
|
grantsDb;
|
|
14787
15174
|
constructor(testOpts = {}) {
|
|
14788
15175
|
this.testOpts = testOpts;
|
|
14789
|
-
const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined;
|
|
15176
|
+
const usingTestOpt = testOpts._testSecrets !== undefined || testOpts._testConfig !== undefined || testOpts._testIdentify !== undefined || testOpts._testAuditLogger !== undefined || testOpts._testGrantsDb !== undefined || testOpts._testVaultPath !== undefined;
|
|
14790
15177
|
if (usingTestOpt && true) {
|
|
14791
|
-
throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
|
|
15178
|
+
throw new Error("VaultBroker: BrokerTestOpts (_testSecrets/_testConfig/_testIdentify/_testAuditLogger/_testGrantsDb/_testVaultPath) " + "must not be set outside tests. Set NODE_ENV=test if you really mean it.");
|
|
15179
|
+
}
|
|
15180
|
+
if (testOpts._testVaultPath !== undefined) {
|
|
15181
|
+
this.vaultPath = testOpts._testVaultPath;
|
|
14792
15182
|
}
|
|
14793
15183
|
this.auditLogger = testOpts._testAuditLogger ?? createAuditLogger();
|
|
14794
15184
|
if (testOpts._testGrantsDb !== undefined) {
|
|
@@ -14819,15 +15209,15 @@ class VaultBroker {
|
|
|
14819
15209
|
this.secrets = { ...this.testOpts._testSecrets };
|
|
14820
15210
|
}
|
|
14821
15211
|
process.umask(63);
|
|
14822
|
-
const parentDir =
|
|
14823
|
-
|
|
15212
|
+
const parentDir = dirname4(this.socketPath);
|
|
15213
|
+
mkdirSync5(parentDir, { recursive: true, mode: 448 });
|
|
14824
15214
|
try {
|
|
14825
|
-
|
|
15215
|
+
chmodSync4(parentDir, 448);
|
|
14826
15216
|
} catch {}
|
|
14827
15217
|
for (const p of [this.socketPath, this.unlockSocketPath]) {
|
|
14828
|
-
if (
|
|
15218
|
+
if (existsSync7(p)) {
|
|
14829
15219
|
try {
|
|
14830
|
-
|
|
15220
|
+
unlinkSync4(p);
|
|
14831
15221
|
} catch {}
|
|
14832
15222
|
}
|
|
14833
15223
|
}
|
|
@@ -14843,6 +15233,7 @@ class VaultBroker {
|
|
|
14843
15233
|
}
|
|
14844
15234
|
}
|
|
14845
15235
|
unlockFromPassphrase(passphrase) {
|
|
15236
|
+
detectVaultLayoutDrift(this.vaultPath);
|
|
14846
15237
|
const secrets = openVault(passphrase, this.vaultPath);
|
|
14847
15238
|
this.secrets = secrets;
|
|
14848
15239
|
this.passphrase = passphrase;
|
|
@@ -14874,24 +15265,24 @@ class VaultBroker {
|
|
|
14874
15265
|
try {
|
|
14875
15266
|
entry.server.close();
|
|
14876
15267
|
} catch {}
|
|
14877
|
-
if (
|
|
15268
|
+
if (existsSync7(sockPath)) {
|
|
14878
15269
|
try {
|
|
14879
|
-
|
|
15270
|
+
unlinkSync4(sockPath);
|
|
14880
15271
|
} catch {}
|
|
14881
15272
|
}
|
|
14882
15273
|
}
|
|
14883
15274
|
this.agentServers.clear();
|
|
14884
15275
|
for (const p of [this.socketPath, this.unlockSocketPath]) {
|
|
14885
|
-
if (p &&
|
|
15276
|
+
if (p && existsSync7(p)) {
|
|
14886
15277
|
try {
|
|
14887
|
-
|
|
15278
|
+
unlinkSync4(p);
|
|
14888
15279
|
} catch {}
|
|
14889
15280
|
}
|
|
14890
15281
|
}
|
|
14891
15282
|
try {
|
|
14892
15283
|
const pidPath = resolvePath(PID_FILE_DEFAULT);
|
|
14893
|
-
if (
|
|
14894
|
-
|
|
15284
|
+
if (existsSync7(pidPath))
|
|
15285
|
+
unlinkSync4(pidPath);
|
|
14895
15286
|
} catch {}
|
|
14896
15287
|
}
|
|
14897
15288
|
getStatus() {
|
|
@@ -14913,18 +15304,18 @@ class VaultBroker {
|
|
|
14913
15304
|
return new Promise((resolveP, rejectP) => {
|
|
14914
15305
|
if (abs.endsWith("/sock")) {
|
|
14915
15306
|
const dir = abs.slice(0, -"/sock".length);
|
|
14916
|
-
if (
|
|
15307
|
+
if (existsSync7(dir)) {
|
|
14917
15308
|
try {
|
|
14918
15309
|
chownSync(dir, 0, 0);
|
|
14919
15310
|
} catch {}
|
|
14920
15311
|
try {
|
|
14921
|
-
|
|
15312
|
+
chmodSync4(dir, 448);
|
|
14922
15313
|
} catch {}
|
|
14923
15314
|
}
|
|
14924
15315
|
}
|
|
14925
|
-
if (
|
|
15316
|
+
if (existsSync7(abs)) {
|
|
14926
15317
|
try {
|
|
14927
|
-
|
|
15318
|
+
unlinkSync4(abs);
|
|
14928
15319
|
} catch (err) {
|
|
14929
15320
|
const msg = err instanceof Error ? err.message : String(err);
|
|
14930
15321
|
process.stderr.write(`[vault-broker] could not unlink stale socket agent=${agentName} sock=${abs}: ${msg}
|
|
@@ -14937,7 +15328,7 @@ class VaultBroker {
|
|
|
14937
15328
|
server.on("error", (err) => rejectP(err));
|
|
14938
15329
|
server.listen(abs, () => {
|
|
14939
15330
|
try {
|
|
14940
|
-
|
|
15331
|
+
chmodSync4(abs, 432);
|
|
14941
15332
|
} catch {}
|
|
14942
15333
|
try {
|
|
14943
15334
|
const uid = allocateAgentUid(agentName);
|
|
@@ -14966,7 +15357,7 @@ class VaultBroker {
|
|
|
14966
15357
|
});
|
|
14967
15358
|
server.listen(this.socketPath, () => {
|
|
14968
15359
|
try {
|
|
14969
|
-
|
|
15360
|
+
chmodSync4(this.socketPath, 384);
|
|
14970
15361
|
} catch {}
|
|
14971
15362
|
this.server = server;
|
|
14972
15363
|
resolve5();
|
|
@@ -14983,7 +15374,7 @@ class VaultBroker {
|
|
|
14983
15374
|
});
|
|
14984
15375
|
server.listen(this.unlockSocketPath, () => {
|
|
14985
15376
|
try {
|
|
14986
|
-
|
|
15377
|
+
chmodSync4(this.unlockSocketPath, 384);
|
|
14987
15378
|
} catch {}
|
|
14988
15379
|
this.unlockServer = server;
|
|
14989
15380
|
resolve5();
|
|
@@ -15277,30 +15668,71 @@ class VaultBroker {
|
|
|
15277
15668
|
socket.write(encodeResponse(errorResponse("LOCKED", "Vault is locked")));
|
|
15278
15669
|
return;
|
|
15279
15670
|
}
|
|
15280
|
-
|
|
15281
|
-
|
|
15671
|
+
let passphraseAttested = false;
|
|
15672
|
+
if (req.passphrase !== undefined && req.passphrase !== "") {
|
|
15673
|
+
if (req.passphrase === this.passphrase) {
|
|
15674
|
+
passphraseAttested = true;
|
|
15675
|
+
} else {
|
|
15676
|
+
this.auditLogger.write({
|
|
15677
|
+
ts: new Date().toISOString(),
|
|
15678
|
+
op: "put",
|
|
15679
|
+
key: req.key,
|
|
15680
|
+
caller: auditCaller,
|
|
15681
|
+
pid: auditPid,
|
|
15682
|
+
cgroup: auditCgroup,
|
|
15683
|
+
result: "denied:passphrase-mismatch",
|
|
15684
|
+
method: "passphrase"
|
|
15685
|
+
});
|
|
15686
|
+
socket.write(encodeResponse(errorResponse("DENIED", "supplied passphrase does not match the broker's unlocked passphrase")));
|
|
15687
|
+
return;
|
|
15688
|
+
}
|
|
15689
|
+
}
|
|
15690
|
+
let writeGrantId = null;
|
|
15691
|
+
if (req.token !== undefined && req.token !== "") {
|
|
15692
|
+
const v = await validateGrantForWrite(this.grantsDb, req.token, req.key);
|
|
15693
|
+
if (v.ok) {
|
|
15694
|
+
writeGrantId = v.grant.id;
|
|
15695
|
+
} else if (v.reason === "grant-expired" || v.reason === "grant-revoked") {
|
|
15696
|
+
this.auditLogger.write({
|
|
15697
|
+
ts: new Date().toISOString(),
|
|
15698
|
+
op: "put",
|
|
15699
|
+
key: req.key,
|
|
15700
|
+
caller: auditCaller,
|
|
15701
|
+
pid: auditPid,
|
|
15702
|
+
cgroup: auditCgroup,
|
|
15703
|
+
result: `denied:${v.reason}`,
|
|
15704
|
+
method: "grant"
|
|
15705
|
+
});
|
|
15706
|
+
socket.write(encodeResponse(errorResponse("DENIED", v.reason)));
|
|
15707
|
+
return;
|
|
15708
|
+
}
|
|
15709
|
+
}
|
|
15710
|
+
if (writeGrantId === null && !passphraseAttested && agentName === null) {
|
|
15711
|
+
socket.write(encodeResponse(errorResponse("DENIED", "put requires path-as-identity, a valid write-grant token, or operator-passphrase attestation")));
|
|
15282
15712
|
return;
|
|
15283
15713
|
}
|
|
15284
15714
|
if (this.config === null) {
|
|
15285
15715
|
socket.write(encodeResponse(errorResponse("INTERNAL", "Broker config not loaded")));
|
|
15286
15716
|
return;
|
|
15287
15717
|
}
|
|
15288
|
-
|
|
15289
|
-
|
|
15290
|
-
|
|
15291
|
-
|
|
15292
|
-
|
|
15293
|
-
|
|
15294
|
-
|
|
15295
|
-
|
|
15296
|
-
|
|
15297
|
-
|
|
15298
|
-
|
|
15299
|
-
|
|
15300
|
-
|
|
15718
|
+
if (writeGrantId === null && !passphraseAttested) {
|
|
15719
|
+
const aclResult = checkAclByAgent(this.config, agentName, req.key);
|
|
15720
|
+
if (!aclResult.allow) {
|
|
15721
|
+
this.auditLogger.write({
|
|
15722
|
+
ts: new Date().toISOString(),
|
|
15723
|
+
op: "put",
|
|
15724
|
+
key: req.key,
|
|
15725
|
+
caller: auditCaller,
|
|
15726
|
+
pid: auditPid,
|
|
15727
|
+
cgroup: auditCgroup,
|
|
15728
|
+
result: `denied:${aclResult.reason}`
|
|
15729
|
+
});
|
|
15730
|
+
socket.write(encodeResponse(errorResponse("DENIED", aclResult.reason)));
|
|
15731
|
+
return;
|
|
15732
|
+
}
|
|
15301
15733
|
}
|
|
15302
15734
|
const existing = this.secrets[req.key];
|
|
15303
|
-
if (existing === undefined) {
|
|
15735
|
+
if (existing === undefined && writeGrantId === null && !passphraseAttested) {
|
|
15304
15736
|
this.auditLogger.write({
|
|
15305
15737
|
ts: new Date().toISOString(),
|
|
15306
15738
|
op: "put",
|
|
@@ -15310,10 +15742,10 @@ class VaultBroker {
|
|
|
15310
15742
|
cgroup: auditCgroup,
|
|
15311
15743
|
result: "denied:unknown_key"
|
|
15312
15744
|
});
|
|
15313
|
-
socket.write(encodeResponse(errorResponse("UNKNOWN_KEY", `Key not found: ${req.key} (broker put cannot introduce new keys; ask operator to set it once via 'switchroom vault set' from the host)`)));
|
|
15745
|
+
socket.write(encodeResponse(errorResponse("UNKNOWN_KEY", `Key not found: ${req.key} (broker put cannot introduce new keys without a write-grant; ask operator to 'switchroom vault grant <agent> --write ${req.key}' or set it once via 'switchroom vault set' from the host)`)));
|
|
15314
15746
|
return;
|
|
15315
15747
|
}
|
|
15316
|
-
if (existing.kind !== req.entry.kind) {
|
|
15748
|
+
if (existing !== undefined && existing.kind !== req.entry.kind && !passphraseAttested) {
|
|
15317
15749
|
this.auditLogger.write({
|
|
15318
15750
|
ts: new Date().toISOString(),
|
|
15319
15751
|
op: "put",
|
|
@@ -15331,7 +15763,11 @@ class VaultBroker {
|
|
|
15331
15763
|
try {
|
|
15332
15764
|
saveVault(this.passphrase, this.vaultPath, this.secrets);
|
|
15333
15765
|
} catch (err) {
|
|
15334
|
-
|
|
15766
|
+
if (previousEntry === undefined) {
|
|
15767
|
+
delete this.secrets[req.key];
|
|
15768
|
+
} else {
|
|
15769
|
+
this.secrets[req.key] = previousEntry;
|
|
15770
|
+
}
|
|
15335
15771
|
this.auditLogger.write({
|
|
15336
15772
|
ts: new Date().toISOString(),
|
|
15337
15773
|
op: "put",
|
|
@@ -15339,7 +15775,8 @@ class VaultBroker {
|
|
|
15339
15775
|
caller: auditCaller,
|
|
15340
15776
|
pid: auditPid,
|
|
15341
15777
|
cgroup: auditCgroup,
|
|
15342
|
-
result: `error:${err?.message ?? "save failed"}
|
|
15778
|
+
result: `error:${err?.message ?? "save failed"}`,
|
|
15779
|
+
...passphraseAttested ? { method: "passphrase" } : writeGrantId !== null ? { method: "grant", grant_id: writeGrantId } : {}
|
|
15343
15780
|
});
|
|
15344
15781
|
socket.write(encodeResponse(errorResponse("INTERNAL", `Failed to persist: ${err?.message ?? "unknown"}`)));
|
|
15345
15782
|
return;
|
|
@@ -15351,7 +15788,8 @@ class VaultBroker {
|
|
|
15351
15788
|
caller: auditCaller,
|
|
15352
15789
|
pid: auditPid,
|
|
15353
15790
|
cgroup: auditCgroup,
|
|
15354
|
-
result: "allowed"
|
|
15791
|
+
result: "allowed",
|
|
15792
|
+
...passphraseAttested ? { method: "passphrase" } : writeGrantId !== null ? { method: "grant", grant_id: writeGrantId } : {}
|
|
15355
15793
|
});
|
|
15356
15794
|
socket.write(encodeResponse({ ok: true, put: true, key: req.key }));
|
|
15357
15795
|
return;
|
|
@@ -15404,10 +15842,22 @@ class VaultBroker {
|
|
|
15404
15842
|
}
|
|
15405
15843
|
}
|
|
15406
15844
|
if (req.op === "mint_grant") {
|
|
15407
|
-
const { agent, keys, ttl_seconds, description } = req;
|
|
15845
|
+
const { agent, keys, ttl_seconds, description, write_keys } = req;
|
|
15846
|
+
if (keys.length === 0 && (write_keys?.length ?? 0) === 0) {
|
|
15847
|
+
this.auditLogger.write({
|
|
15848
|
+
ts: new Date().toISOString(),
|
|
15849
|
+
op: "mint_grant",
|
|
15850
|
+
caller: auditCaller,
|
|
15851
|
+
pid: auditPid,
|
|
15852
|
+
cgroup: auditCgroup,
|
|
15853
|
+
result: "denied:no-capabilities"
|
|
15854
|
+
});
|
|
15855
|
+
socket.write(encodeResponse(errorResponse("BAD_REQUEST", "mint_grant requires at least one of `keys` or `write_keys` to be non-empty")));
|
|
15856
|
+
return;
|
|
15857
|
+
}
|
|
15408
15858
|
let mintResult;
|
|
15409
15859
|
try {
|
|
15410
|
-
mintResult = await mintGrant(this.grantsDb, agent, keys, ttl_seconds, description);
|
|
15860
|
+
mintResult = await mintGrant(this.grantsDb, agent, keys, ttl_seconds, description, write_keys ?? []);
|
|
15411
15861
|
} catch (err) {
|
|
15412
15862
|
const msg = err instanceof Error ? err.message : String(err);
|
|
15413
15863
|
this.auditLogger.write({
|
|
@@ -15423,11 +15873,11 @@ class VaultBroker {
|
|
|
15423
15873
|
}
|
|
15424
15874
|
try {
|
|
15425
15875
|
const tokenDir = path3.join(os3.homedir(), ".switchroom", "agents", agent);
|
|
15426
|
-
|
|
15876
|
+
mkdirSync5(tokenDir, { recursive: true });
|
|
15427
15877
|
const tokenPath = path3.join(tokenDir, ".vault-token");
|
|
15428
15878
|
const tmpPath = `${tokenPath}.tmp.${process.pid}`;
|
|
15429
15879
|
writeFileSync3(tmpPath, mintResult.token, { mode: 384 });
|
|
15430
|
-
|
|
15880
|
+
renameSync3(tmpPath, tokenPath);
|
|
15431
15881
|
} catch (err) {
|
|
15432
15882
|
process.stderr.write(`[vault-broker] mint_grant: failed to write token file for agent ${agent}: ${err.message}
|
|
15433
15883
|
`);
|
|
@@ -15460,10 +15910,11 @@ class VaultBroker {
|
|
|
15460
15910
|
cgroup: auditCgroup,
|
|
15461
15911
|
result: `allowed:${grants.length}`
|
|
15462
15912
|
});
|
|
15463
|
-
const grantMetas = grants.map(({ id, agent_slug, key_allow, expires_at, created_at, description }) => ({
|
|
15913
|
+
const grantMetas = grants.map(({ id, agent_slug, key_allow, write_allow, expires_at, created_at, description }) => ({
|
|
15464
15914
|
id,
|
|
15465
15915
|
agent_slug,
|
|
15466
15916
|
key_allow,
|
|
15917
|
+
write_allow,
|
|
15467
15918
|
expires_at,
|
|
15468
15919
|
created_at,
|
|
15469
15920
|
description
|
|
@@ -15478,9 +15929,9 @@ class VaultBroker {
|
|
|
15478
15929
|
const row = this.grantsDb.query("SELECT agent_slug FROM vault_grants WHERE id = ?").get(id);
|
|
15479
15930
|
if (row) {
|
|
15480
15931
|
const tokenPath = path3.join(os3.homedir(), ".switchroom", "agents", row.agent_slug, ".vault-token");
|
|
15481
|
-
if (
|
|
15932
|
+
if (existsSync7(tokenPath)) {
|
|
15482
15933
|
try {
|
|
15483
|
-
|
|
15934
|
+
unlinkSync4(tokenPath);
|
|
15484
15935
|
} catch {}
|
|
15485
15936
|
}
|
|
15486
15937
|
}
|
|
@@ -15721,7 +16172,7 @@ class VaultBroker {
|
|
|
15721
16172
|
const envPath = process.env.SWITCHROOM_VAULT_BROKER_AUTO_UNLOCK_PATH;
|
|
15722
16173
|
const configuredPath = (envPath && envPath.length > 0 ? envPath : undefined) ?? this.config?.vault?.broker?.autoUnlockCredentialPath ?? DEFAULT_AUTO_UNLOCK_PATH;
|
|
15723
16174
|
const filePath = resolvePath(configuredPath);
|
|
15724
|
-
if (!
|
|
16175
|
+
if (!existsSync7(filePath))
|
|
15725
16176
|
return false;
|
|
15726
16177
|
let passphrase;
|
|
15727
16178
|
try {
|
|
@@ -15758,7 +16209,7 @@ class VaultBroker {
|
|
|
15758
16209
|
const credPath = `${dir}/vault-passphrase`;
|
|
15759
16210
|
let passphrase;
|
|
15760
16211
|
try {
|
|
15761
|
-
passphrase =
|
|
16212
|
+
passphrase = readFileSync7(credPath, "utf8").replace(/\n+$/, "");
|
|
15762
16213
|
} catch (err) {
|
|
15763
16214
|
const code = err.code;
|
|
15764
16215
|
if (code === "ENOENT") {
|
|
@@ -15795,6 +16246,21 @@ class VaultBroker {
|
|
|
15795
16246
|
} catch {}
|
|
15796
16247
|
}
|
|
15797
16248
|
}
|
|
16249
|
+
function detectVaultLayoutDrift(vaultPath) {
|
|
16250
|
+
const dir = dirname4(vaultPath);
|
|
16251
|
+
if (basename3(dir) !== "vault")
|
|
16252
|
+
return;
|
|
16253
|
+
if (basename3(vaultPath) !== "vault.enc")
|
|
16254
|
+
return;
|
|
16255
|
+
const switchroomDir = dirname4(dir);
|
|
16256
|
+
if (basename3(switchroomDir) !== ".switchroom")
|
|
16257
|
+
return;
|
|
16258
|
+
const home2 = dirname4(switchroomDir);
|
|
16259
|
+
const result = inspectVaultLayout(home2);
|
|
16260
|
+
if (result.kind === "divergent") {
|
|
16261
|
+
throw new VaultError(`Vault layout divergence detected at boot: ${result.details.oldPath} and ${result.details.newPath} are both regular files with different content. An older switchroom CLI may have written to the legacy path after migration ran. Run \`switchroom apply\` from the host to surface the recovery recipe (state E refusal with literal \`mv\` commands). See docs/operators/state-e-recovery.md.`);
|
|
16262
|
+
}
|
|
16263
|
+
}
|
|
15798
16264
|
var _globalBroker = null;
|
|
15799
16265
|
function registerShutdownHandlers(broker) {
|
|
15800
16266
|
_globalBroker = broker;
|
|
@@ -15815,8 +16281,8 @@ async function main() {
|
|
|
15815
16281
|
const vaultPath = process.env.SWITCHROOM_VAULT_PATH;
|
|
15816
16282
|
let perAgentTargets = [];
|
|
15817
16283
|
try {
|
|
15818
|
-
if (
|
|
15819
|
-
const entries =
|
|
16284
|
+
if (existsSync7(perAgentDir)) {
|
|
16285
|
+
const entries = readdirSync2(perAgentDir, { withFileTypes: true });
|
|
15820
16286
|
const flat = [];
|
|
15821
16287
|
const subdirs = [];
|
|
15822
16288
|
for (const e of entries) {
|