heyspex 0.2.2 → 0.2.4
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/.claude-plugin/marketplace.json +2 -1
- package/README.md +11 -0
- package/bin/hs-vault-binding.mjs +157 -0
- package/bin/hs.mjs +83 -79
- package/bin/spexcode.mjs +91 -0
- package/dev-factory/engine/worktree.mjs +36 -7
- package/dev-factory/lib/epic-detect.mjs +2 -2
- package/dev-factory/lib/fleet-readiness.mjs +3 -5
- package/dev-factory/lib/fleet-state.mjs +2 -2
- package/dev-factory/lib/sufficiency-score.mjs +3 -5
- package/dist/cli/hs-check.mjs +76 -46
- package/dist/cli/hs-claim.mjs +63 -33
- package/dist/cli/hs-connect.mjs +520 -214
- package/dist/cli/hs-defer.mjs +161 -19
- package/dist/cli/hs-dev.mjs +11 -5
- package/dist/cli/hs-env.mjs +187 -161
- package/dist/cli/hs-index-rebuild.mjs +123 -78
- package/dist/cli/hs-index-reconcile.mjs +203 -107
- package/dist/cli/hs-init.mjs +426 -179
- package/dist/cli/hs-install.mjs +759 -437
- package/dist/cli/hs-join.mjs +590 -383
- package/dist/cli/hs-vault-pull.mjs +359 -254
- package/dist/cli/hs-vault-push.mjs +151 -113
- package/dist/cli/hs-vault.mjs +271 -104
- package/dist/cli/hs-workspace.mjs +90 -57
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +178 -91
- package/docs/copilot-plugin-install.md +200 -177
- package/docs/driving-heyspex-from-copilot.md +174 -165
- package/docs/mcp-client-config.md +93 -25
- package/package.json +257 -250
- package/plugins/heyspex/.claude-plugin/plugin.json +13 -12
- package/plugins/heyspex/.cursor-plugin/plugin.json +16 -15
- package/plugins/heyspex/.mcp.json +3 -4
- package/plugins/heyspex/README.md +323 -312
- package/plugins/heyspex/assets/heyspex-glyph-128.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph-256.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph.svg +12 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +21 -7
- package/plugins/heyspex/mcp.json +12 -13
- package/scripts/check-mcp-freshness.mjs +6 -4
- package/scripts/claude-hooks/_intent-classifier-router.mjs +518 -456
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +305 -279
- package/scripts/claude-hooks/research-method-guard.mjs +2 -2
- package/scripts/claude-hooks/wip-checkpoint.mjs +33 -9
- package/scripts/claude-statusline/fonts/HeySpexIcons.ttf +0 -0
- package/scripts/claude-statusline/statusline-command.mjs +1073 -0
- package/scripts/copilot-statusline.mjs +130 -0
- package/scripts/dev-server-status.mjs +3 -2
- package/scripts/dev-server-stop.mjs +3 -2
- package/scripts/hs-capture-cli.mjs +2 -2
- package/scripts/hs-settings.mjs +2 -2
- package/scripts/hs-view.mjs +3 -2
- package/scripts/install-copilot-hooks.mjs +152 -36
- package/scripts/lib/copilot-cli.mjs +108 -0
- package/scripts/lib/customer-kit.mjs +223 -30
- package/scripts/lib/dev-mode.mjs +28 -2
- package/scripts/lib/shared-path-helpers.mjs +32 -0
- package/scripts/lib/standalone-doctor.mjs +131 -32
- package/scripts/wip-ledger-health.mjs +3 -2
- package/spexharness/src/gates/vault-mirror-catchup.mjs +113 -24
- package/spexharness/src/gates/vault-mirror-catchup.runner.mjs +52 -0
- package/spexharness/src/intent-directive.mjs +839 -626
- package/spexharness/src/rule-table.mjs +1 -1
- package/vendor/heyspex-mcp/cli-verbs.mjs +16 -2
- package/vendor/heyspex-mcp/cli.mjs +20 -4
- package/vendor/heyspex-mcp/console-fetch.mjs +15 -3
- package/vendor/heyspex-mcp/dev-tools.mjs +11 -4
- package/vendor/heyspex-mcp/events-tools.mjs +1 -1
- package/vendor/heyspex-mcp/factory-run-status.mjs +42 -0
- package/vendor/heyspex-mcp/http-transport.mjs +6 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +4 -2
- package/vendor/heyspex-mcp/server-identity.mjs +13 -0
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +26 -1
- package/vendor/heyspex-mcp/test-helpers.mjs +5 -2
- package/vendor/heyspex-mcp/tool-catalog.mjs +12 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +63 -23
- package/vendor/heyspex-mcp/usable-dir-env.mjs +82 -0
- package/vendor/heyspex-mcp/vault-binding.mjs +839 -0
- package/vendor/heyspex-mcp/vault-resolve.mjs +353 -245
package/dist/cli/hs-env.mjs
CHANGED
|
@@ -112,7 +112,7 @@ var require_main = __commonJS({
|
|
|
112
112
|
"node_modules/dotenv/lib/main.js"(exports, module) {
|
|
113
113
|
"use strict";
|
|
114
114
|
var fs = __require("fs");
|
|
115
|
-
var
|
|
115
|
+
var path8 = __require("path");
|
|
116
116
|
var os2 = __require("os");
|
|
117
117
|
var crypto3 = __require("crypto");
|
|
118
118
|
var packageJson = require_package();
|
|
@@ -228,7 +228,7 @@ var require_main = __commonJS({
|
|
|
228
228
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
229
229
|
}
|
|
230
230
|
} else {
|
|
231
|
-
possibleVaultPath =
|
|
231
|
+
possibleVaultPath = path8.resolve(process.cwd(), ".env.vault");
|
|
232
232
|
}
|
|
233
233
|
if (fs.existsSync(possibleVaultPath)) {
|
|
234
234
|
return possibleVaultPath;
|
|
@@ -236,7 +236,7 @@ var require_main = __commonJS({
|
|
|
236
236
|
return null;
|
|
237
237
|
}
|
|
238
238
|
function _resolveHome(envPath) {
|
|
239
|
-
return envPath[0] === "~" ?
|
|
239
|
+
return envPath[0] === "~" ? path8.join(os2.homedir(), envPath.slice(1)) : envPath;
|
|
240
240
|
}
|
|
241
241
|
function _configVault(options) {
|
|
242
242
|
const debug = Boolean(options && options.debug);
|
|
@@ -253,7 +253,7 @@ var require_main = __commonJS({
|
|
|
253
253
|
return { parsed };
|
|
254
254
|
}
|
|
255
255
|
function configDotenv(options) {
|
|
256
|
-
const dotenvPath2 =
|
|
256
|
+
const dotenvPath2 = path8.resolve(process.cwd(), ".env");
|
|
257
257
|
let encoding = "utf8";
|
|
258
258
|
const debug = Boolean(options && options.debug);
|
|
259
259
|
const quiet = options && "quiet" in options ? options.quiet : true;
|
|
@@ -277,13 +277,13 @@ var require_main = __commonJS({
|
|
|
277
277
|
}
|
|
278
278
|
let lastError;
|
|
279
279
|
const parsedAll = {};
|
|
280
|
-
for (const
|
|
280
|
+
for (const path9 of optionPaths) {
|
|
281
281
|
try {
|
|
282
|
-
const parsed = DotenvModule.parse(fs.readFileSync(
|
|
282
|
+
const parsed = DotenvModule.parse(fs.readFileSync(path9, { encoding }));
|
|
283
283
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
284
284
|
} catch (e) {
|
|
285
285
|
if (debug) {
|
|
286
|
-
_debug(`Failed to load ${
|
|
286
|
+
_debug(`Failed to load ${path9} ${e.message}`);
|
|
287
287
|
}
|
|
288
288
|
lastError = e;
|
|
289
289
|
}
|
|
@@ -298,7 +298,7 @@ var require_main = __commonJS({
|
|
|
298
298
|
const shortPaths = [];
|
|
299
299
|
for (const filePath of optionPaths) {
|
|
300
300
|
try {
|
|
301
|
-
const relative =
|
|
301
|
+
const relative = path8.relative(process.cwd(), filePath);
|
|
302
302
|
shortPaths.push(relative);
|
|
303
303
|
} catch (e) {
|
|
304
304
|
if (debug) {
|
|
@@ -475,17 +475,17 @@ var require_visit = __commonJS({
|
|
|
475
475
|
visit.BREAK = BREAK;
|
|
476
476
|
visit.SKIP = SKIP;
|
|
477
477
|
visit.REMOVE = REMOVE;
|
|
478
|
-
function visit_(key, node, visitor,
|
|
479
|
-
const ctrl = callVisitor(key, node, visitor,
|
|
478
|
+
function visit_(key, node, visitor, path8) {
|
|
479
|
+
const ctrl = callVisitor(key, node, visitor, path8);
|
|
480
480
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
481
|
-
replaceNode(key,
|
|
482
|
-
return visit_(key, ctrl, visitor,
|
|
481
|
+
replaceNode(key, path8, ctrl);
|
|
482
|
+
return visit_(key, ctrl, visitor, path8);
|
|
483
483
|
}
|
|
484
484
|
if (typeof ctrl !== "symbol") {
|
|
485
485
|
if (identity.isCollection(node)) {
|
|
486
|
-
|
|
486
|
+
path8 = Object.freeze(path8.concat(node));
|
|
487
487
|
for (let i = 0; i < node.items.length; ++i) {
|
|
488
|
-
const ci = visit_(i, node.items[i], visitor,
|
|
488
|
+
const ci = visit_(i, node.items[i], visitor, path8);
|
|
489
489
|
if (typeof ci === "number")
|
|
490
490
|
i = ci - 1;
|
|
491
491
|
else if (ci === BREAK)
|
|
@@ -496,13 +496,13 @@ var require_visit = __commonJS({
|
|
|
496
496
|
}
|
|
497
497
|
}
|
|
498
498
|
} else if (identity.isPair(node)) {
|
|
499
|
-
|
|
500
|
-
const ck = visit_("key", node.key, visitor,
|
|
499
|
+
path8 = Object.freeze(path8.concat(node));
|
|
500
|
+
const ck = visit_("key", node.key, visitor, path8);
|
|
501
501
|
if (ck === BREAK)
|
|
502
502
|
return BREAK;
|
|
503
503
|
else if (ck === REMOVE)
|
|
504
504
|
node.key = null;
|
|
505
|
-
const cv = visit_("value", node.value, visitor,
|
|
505
|
+
const cv = visit_("value", node.value, visitor, path8);
|
|
506
506
|
if (cv === BREAK)
|
|
507
507
|
return BREAK;
|
|
508
508
|
else if (cv === REMOVE)
|
|
@@ -523,17 +523,17 @@ var require_visit = __commonJS({
|
|
|
523
523
|
visitAsync.BREAK = BREAK;
|
|
524
524
|
visitAsync.SKIP = SKIP;
|
|
525
525
|
visitAsync.REMOVE = REMOVE;
|
|
526
|
-
async function visitAsync_(key, node, visitor,
|
|
527
|
-
const ctrl = await callVisitor(key, node, visitor,
|
|
526
|
+
async function visitAsync_(key, node, visitor, path8) {
|
|
527
|
+
const ctrl = await callVisitor(key, node, visitor, path8);
|
|
528
528
|
if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
|
|
529
|
-
replaceNode(key,
|
|
530
|
-
return visitAsync_(key, ctrl, visitor,
|
|
529
|
+
replaceNode(key, path8, ctrl);
|
|
530
|
+
return visitAsync_(key, ctrl, visitor, path8);
|
|
531
531
|
}
|
|
532
532
|
if (typeof ctrl !== "symbol") {
|
|
533
533
|
if (identity.isCollection(node)) {
|
|
534
|
-
|
|
534
|
+
path8 = Object.freeze(path8.concat(node));
|
|
535
535
|
for (let i = 0; i < node.items.length; ++i) {
|
|
536
|
-
const ci = await visitAsync_(i, node.items[i], visitor,
|
|
536
|
+
const ci = await visitAsync_(i, node.items[i], visitor, path8);
|
|
537
537
|
if (typeof ci === "number")
|
|
538
538
|
i = ci - 1;
|
|
539
539
|
else if (ci === BREAK)
|
|
@@ -544,13 +544,13 @@ var require_visit = __commonJS({
|
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
546
|
} else if (identity.isPair(node)) {
|
|
547
|
-
|
|
548
|
-
const ck = await visitAsync_("key", node.key, visitor,
|
|
547
|
+
path8 = Object.freeze(path8.concat(node));
|
|
548
|
+
const ck = await visitAsync_("key", node.key, visitor, path8);
|
|
549
549
|
if (ck === BREAK)
|
|
550
550
|
return BREAK;
|
|
551
551
|
else if (ck === REMOVE)
|
|
552
552
|
node.key = null;
|
|
553
|
-
const cv = await visitAsync_("value", node.value, visitor,
|
|
553
|
+
const cv = await visitAsync_("value", node.value, visitor, path8);
|
|
554
554
|
if (cv === BREAK)
|
|
555
555
|
return BREAK;
|
|
556
556
|
else if (cv === REMOVE)
|
|
@@ -577,23 +577,23 @@ var require_visit = __commonJS({
|
|
|
577
577
|
}
|
|
578
578
|
return visitor;
|
|
579
579
|
}
|
|
580
|
-
function callVisitor(key, node, visitor,
|
|
580
|
+
function callVisitor(key, node, visitor, path8) {
|
|
581
581
|
if (typeof visitor === "function")
|
|
582
|
-
return visitor(key, node,
|
|
582
|
+
return visitor(key, node, path8);
|
|
583
583
|
if (identity.isMap(node))
|
|
584
|
-
return visitor.Map?.(key, node,
|
|
584
|
+
return visitor.Map?.(key, node, path8);
|
|
585
585
|
if (identity.isSeq(node))
|
|
586
|
-
return visitor.Seq?.(key, node,
|
|
586
|
+
return visitor.Seq?.(key, node, path8);
|
|
587
587
|
if (identity.isPair(node))
|
|
588
|
-
return visitor.Pair?.(key, node,
|
|
588
|
+
return visitor.Pair?.(key, node, path8);
|
|
589
589
|
if (identity.isScalar(node))
|
|
590
|
-
return visitor.Scalar?.(key, node,
|
|
590
|
+
return visitor.Scalar?.(key, node, path8);
|
|
591
591
|
if (identity.isAlias(node))
|
|
592
|
-
return visitor.Alias?.(key, node,
|
|
592
|
+
return visitor.Alias?.(key, node, path8);
|
|
593
593
|
return void 0;
|
|
594
594
|
}
|
|
595
|
-
function replaceNode(key,
|
|
596
|
-
const parent =
|
|
595
|
+
function replaceNode(key, path8, node) {
|
|
596
|
+
const parent = path8[path8.length - 1];
|
|
597
597
|
if (identity.isCollection(parent)) {
|
|
598
598
|
parent.items[key] = node;
|
|
599
599
|
} else if (identity.isPair(parent)) {
|
|
@@ -1203,10 +1203,10 @@ var require_Collection = __commonJS({
|
|
|
1203
1203
|
var createNode = require_createNode();
|
|
1204
1204
|
var identity = require_identity();
|
|
1205
1205
|
var Node = require_Node();
|
|
1206
|
-
function collectionFromPath(schema,
|
|
1206
|
+
function collectionFromPath(schema, path8, value) {
|
|
1207
1207
|
let v = value;
|
|
1208
|
-
for (let i =
|
|
1209
|
-
const k =
|
|
1208
|
+
for (let i = path8.length - 1; i >= 0; --i) {
|
|
1209
|
+
const k = path8[i];
|
|
1210
1210
|
if (typeof k === "number" && Number.isInteger(k) && k >= 0) {
|
|
1211
1211
|
const a = [];
|
|
1212
1212
|
a[k] = v;
|
|
@@ -1225,7 +1225,7 @@ var require_Collection = __commonJS({
|
|
|
1225
1225
|
sourceObjects: /* @__PURE__ */ new Map()
|
|
1226
1226
|
});
|
|
1227
1227
|
}
|
|
1228
|
-
var isEmptyPath = (
|
|
1228
|
+
var isEmptyPath = (path8) => path8 == null || typeof path8 === "object" && !!path8[Symbol.iterator]().next().done;
|
|
1229
1229
|
var Collection = class extends Node.NodeBase {
|
|
1230
1230
|
constructor(type, schema) {
|
|
1231
1231
|
super(type);
|
|
@@ -1255,11 +1255,11 @@ var require_Collection = __commonJS({
|
|
|
1255
1255
|
* be a Pair instance or a `{ key, value }` object, which may not have a key
|
|
1256
1256
|
* that already exists in the map.
|
|
1257
1257
|
*/
|
|
1258
|
-
addIn(
|
|
1259
|
-
if (isEmptyPath(
|
|
1258
|
+
addIn(path8, value) {
|
|
1259
|
+
if (isEmptyPath(path8))
|
|
1260
1260
|
this.add(value);
|
|
1261
1261
|
else {
|
|
1262
|
-
const [key, ...rest] =
|
|
1262
|
+
const [key, ...rest] = path8;
|
|
1263
1263
|
const node = this.get(key, true);
|
|
1264
1264
|
if (identity.isCollection(node))
|
|
1265
1265
|
node.addIn(rest, value);
|
|
@@ -1273,8 +1273,8 @@ var require_Collection = __commonJS({
|
|
|
1273
1273
|
* Removes a value from the collection.
|
|
1274
1274
|
* @returns `true` if the item was found and removed.
|
|
1275
1275
|
*/
|
|
1276
|
-
deleteIn(
|
|
1277
|
-
const [key, ...rest] =
|
|
1276
|
+
deleteIn(path8) {
|
|
1277
|
+
const [key, ...rest] = path8;
|
|
1278
1278
|
if (rest.length === 0)
|
|
1279
1279
|
return this.delete(key);
|
|
1280
1280
|
const node = this.get(key, true);
|
|
@@ -1288,8 +1288,8 @@ var require_Collection = __commonJS({
|
|
|
1288
1288
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
1289
1289
|
* `true` (collections are always returned intact).
|
|
1290
1290
|
*/
|
|
1291
|
-
getIn(
|
|
1292
|
-
const [key, ...rest] =
|
|
1291
|
+
getIn(path8, keepScalar) {
|
|
1292
|
+
const [key, ...rest] = path8;
|
|
1293
1293
|
const node = this.get(key, true);
|
|
1294
1294
|
if (rest.length === 0)
|
|
1295
1295
|
return !keepScalar && identity.isScalar(node) ? node.value : node;
|
|
@@ -1307,8 +1307,8 @@ var require_Collection = __commonJS({
|
|
|
1307
1307
|
/**
|
|
1308
1308
|
* Checks if the collection includes a value with the key `key`.
|
|
1309
1309
|
*/
|
|
1310
|
-
hasIn(
|
|
1311
|
-
const [key, ...rest] =
|
|
1310
|
+
hasIn(path8) {
|
|
1311
|
+
const [key, ...rest] = path8;
|
|
1312
1312
|
if (rest.length === 0)
|
|
1313
1313
|
return this.has(key);
|
|
1314
1314
|
const node = this.get(key, true);
|
|
@@ -1318,8 +1318,8 @@ var require_Collection = __commonJS({
|
|
|
1318
1318
|
* Sets a value in this collection. For `!!set`, `value` needs to be a
|
|
1319
1319
|
* boolean to add/remove the item from the set.
|
|
1320
1320
|
*/
|
|
1321
|
-
setIn(
|
|
1322
|
-
const [key, ...rest] =
|
|
1321
|
+
setIn(path8, value) {
|
|
1322
|
+
const [key, ...rest] = path8;
|
|
1323
1323
|
if (rest.length === 0) {
|
|
1324
1324
|
this.set(key, value);
|
|
1325
1325
|
} else {
|
|
@@ -3834,9 +3834,9 @@ var require_Document = __commonJS({
|
|
|
3834
3834
|
this.contents.add(value);
|
|
3835
3835
|
}
|
|
3836
3836
|
/** Adds a value to the document. */
|
|
3837
|
-
addIn(
|
|
3837
|
+
addIn(path8, value) {
|
|
3838
3838
|
if (assertCollection(this.contents))
|
|
3839
|
-
this.contents.addIn(
|
|
3839
|
+
this.contents.addIn(path8, value);
|
|
3840
3840
|
}
|
|
3841
3841
|
/**
|
|
3842
3842
|
* Create a new `Alias` node, ensuring that the target `node` has the required anchor.
|
|
@@ -3911,14 +3911,14 @@ var require_Document = __commonJS({
|
|
|
3911
3911
|
* Removes a value from the document.
|
|
3912
3912
|
* @returns `true` if the item was found and removed.
|
|
3913
3913
|
*/
|
|
3914
|
-
deleteIn(
|
|
3915
|
-
if (Collection.isEmptyPath(
|
|
3914
|
+
deleteIn(path8) {
|
|
3915
|
+
if (Collection.isEmptyPath(path8)) {
|
|
3916
3916
|
if (this.contents == null)
|
|
3917
3917
|
return false;
|
|
3918
3918
|
this.contents = null;
|
|
3919
3919
|
return true;
|
|
3920
3920
|
}
|
|
3921
|
-
return assertCollection(this.contents) ? this.contents.deleteIn(
|
|
3921
|
+
return assertCollection(this.contents) ? this.contents.deleteIn(path8) : false;
|
|
3922
3922
|
}
|
|
3923
3923
|
/**
|
|
3924
3924
|
* Returns item at `key`, or `undefined` if not found. By default unwraps
|
|
@@ -3933,10 +3933,10 @@ var require_Document = __commonJS({
|
|
|
3933
3933
|
* scalar values from their surrounding node; to disable set `keepScalar` to
|
|
3934
3934
|
* `true` (collections are always returned intact).
|
|
3935
3935
|
*/
|
|
3936
|
-
getIn(
|
|
3937
|
-
if (Collection.isEmptyPath(
|
|
3936
|
+
getIn(path8, keepScalar) {
|
|
3937
|
+
if (Collection.isEmptyPath(path8))
|
|
3938
3938
|
return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
|
|
3939
|
-
return identity.isCollection(this.contents) ? this.contents.getIn(
|
|
3939
|
+
return identity.isCollection(this.contents) ? this.contents.getIn(path8, keepScalar) : void 0;
|
|
3940
3940
|
}
|
|
3941
3941
|
/**
|
|
3942
3942
|
* Checks if the document includes a value with the key `key`.
|
|
@@ -3947,10 +3947,10 @@ var require_Document = __commonJS({
|
|
|
3947
3947
|
/**
|
|
3948
3948
|
* Checks if the document includes a value at `path`.
|
|
3949
3949
|
*/
|
|
3950
|
-
hasIn(
|
|
3951
|
-
if (Collection.isEmptyPath(
|
|
3950
|
+
hasIn(path8) {
|
|
3951
|
+
if (Collection.isEmptyPath(path8))
|
|
3952
3952
|
return this.contents !== void 0;
|
|
3953
|
-
return identity.isCollection(this.contents) ? this.contents.hasIn(
|
|
3953
|
+
return identity.isCollection(this.contents) ? this.contents.hasIn(path8) : false;
|
|
3954
3954
|
}
|
|
3955
3955
|
/**
|
|
3956
3956
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
@@ -3967,13 +3967,13 @@ var require_Document = __commonJS({
|
|
|
3967
3967
|
* Sets a value in this document. For `!!set`, `value` needs to be a
|
|
3968
3968
|
* boolean to add/remove the item from the set.
|
|
3969
3969
|
*/
|
|
3970
|
-
setIn(
|
|
3971
|
-
if (Collection.isEmptyPath(
|
|
3970
|
+
setIn(path8, value) {
|
|
3971
|
+
if (Collection.isEmptyPath(path8)) {
|
|
3972
3972
|
this.contents = value;
|
|
3973
3973
|
} else if (this.contents == null) {
|
|
3974
|
-
this.contents = Collection.collectionFromPath(this.schema, Array.from(
|
|
3974
|
+
this.contents = Collection.collectionFromPath(this.schema, Array.from(path8), value);
|
|
3975
3975
|
} else if (assertCollection(this.contents)) {
|
|
3976
|
-
this.contents.setIn(
|
|
3976
|
+
this.contents.setIn(path8, value);
|
|
3977
3977
|
}
|
|
3978
3978
|
}
|
|
3979
3979
|
/**
|
|
@@ -5933,9 +5933,9 @@ var require_cst_visit = __commonJS({
|
|
|
5933
5933
|
visit.BREAK = BREAK;
|
|
5934
5934
|
visit.SKIP = SKIP;
|
|
5935
5935
|
visit.REMOVE = REMOVE;
|
|
5936
|
-
visit.itemAtPath = (cst,
|
|
5936
|
+
visit.itemAtPath = (cst, path8) => {
|
|
5937
5937
|
let item = cst;
|
|
5938
|
-
for (const [field, index] of
|
|
5938
|
+
for (const [field, index] of path8) {
|
|
5939
5939
|
const tok = item?.[field];
|
|
5940
5940
|
if (tok && "items" in tok) {
|
|
5941
5941
|
item = tok.items[index];
|
|
@@ -5944,23 +5944,23 @@ var require_cst_visit = __commonJS({
|
|
|
5944
5944
|
}
|
|
5945
5945
|
return item;
|
|
5946
5946
|
};
|
|
5947
|
-
visit.parentCollection = (cst,
|
|
5948
|
-
const parent = visit.itemAtPath(cst,
|
|
5949
|
-
const field =
|
|
5947
|
+
visit.parentCollection = (cst, path8) => {
|
|
5948
|
+
const parent = visit.itemAtPath(cst, path8.slice(0, -1));
|
|
5949
|
+
const field = path8[path8.length - 1][0];
|
|
5950
5950
|
const coll = parent?.[field];
|
|
5951
5951
|
if (coll && "items" in coll)
|
|
5952
5952
|
return coll;
|
|
5953
5953
|
throw new Error("Parent collection not found");
|
|
5954
5954
|
};
|
|
5955
|
-
function _visit(
|
|
5956
|
-
let ctrl = visitor(item,
|
|
5955
|
+
function _visit(path8, item, visitor) {
|
|
5956
|
+
let ctrl = visitor(item, path8);
|
|
5957
5957
|
if (typeof ctrl === "symbol")
|
|
5958
5958
|
return ctrl;
|
|
5959
5959
|
for (const field of ["key", "value"]) {
|
|
5960
5960
|
const token = item[field];
|
|
5961
5961
|
if (token && "items" in token) {
|
|
5962
5962
|
for (let i = 0; i < token.items.length; ++i) {
|
|
5963
|
-
const ci = _visit(Object.freeze(
|
|
5963
|
+
const ci = _visit(Object.freeze(path8.concat([[field, i]])), token.items[i], visitor);
|
|
5964
5964
|
if (typeof ci === "number")
|
|
5965
5965
|
i = ci - 1;
|
|
5966
5966
|
else if (ci === BREAK)
|
|
@@ -5971,10 +5971,10 @@ var require_cst_visit = __commonJS({
|
|
|
5971
5971
|
}
|
|
5972
5972
|
}
|
|
5973
5973
|
if (typeof ctrl === "function" && field === "key")
|
|
5974
|
-
ctrl = ctrl(item,
|
|
5974
|
+
ctrl = ctrl(item, path8);
|
|
5975
5975
|
}
|
|
5976
5976
|
}
|
|
5977
|
-
return typeof ctrl === "function" ? ctrl(item,
|
|
5977
|
+
return typeof ctrl === "function" ? ctrl(item, path8) : ctrl;
|
|
5978
5978
|
}
|
|
5979
5979
|
exports.visit = visit;
|
|
5980
5980
|
}
|
|
@@ -9829,11 +9829,11 @@ var require_baseGet = __commonJS({
|
|
|
9829
9829
|
"use strict";
|
|
9830
9830
|
var castPath = require_castPath();
|
|
9831
9831
|
var toKey = require_toKey();
|
|
9832
|
-
function baseGet(object,
|
|
9833
|
-
|
|
9834
|
-
var index = 0, length =
|
|
9832
|
+
function baseGet(object, path8) {
|
|
9833
|
+
path8 = castPath(path8, object);
|
|
9834
|
+
var index = 0, length = path8.length;
|
|
9835
9835
|
while (object != null && index < length) {
|
|
9836
|
-
object = object[toKey(
|
|
9836
|
+
object = object[toKey(path8[index++])];
|
|
9837
9837
|
}
|
|
9838
9838
|
return index && index == length ? object : void 0;
|
|
9839
9839
|
}
|
|
@@ -9846,8 +9846,8 @@ var require_get = __commonJS({
|
|
|
9846
9846
|
"node_modules/lodash/get.js"(exports, module) {
|
|
9847
9847
|
"use strict";
|
|
9848
9848
|
var baseGet = require_baseGet();
|
|
9849
|
-
function get2(object,
|
|
9850
|
-
var result = object == null ? void 0 : baseGet(object,
|
|
9849
|
+
function get2(object, path8, defaultValue) {
|
|
9850
|
+
var result = object == null ? void 0 : baseGet(object, path8);
|
|
9851
9851
|
return result === void 0 ? defaultValue : result;
|
|
9852
9852
|
}
|
|
9853
9853
|
module.exports = get2;
|
|
@@ -21810,14 +21810,16 @@ var init_dev_mode = __esm({
|
|
|
21810
21810
|
|
|
21811
21811
|
// spex-console/bin/hs-env.ts
|
|
21812
21812
|
import { spawn } from "node:child_process";
|
|
21813
|
-
import { existsSync as
|
|
21813
|
+
import { existsSync as existsSync11 } from "node:fs";
|
|
21814
21814
|
import { networkInterfaces } from "node:os";
|
|
21815
|
-
import
|
|
21815
|
+
import path7 from "node:path";
|
|
21816
21816
|
import process3 from "node:process";
|
|
21817
|
-
import { fileURLToPath as
|
|
21817
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
21818
21818
|
|
|
21819
21819
|
// scripts/lib/shared-path-helpers.mjs
|
|
21820
|
+
import { realpathSync } from "node:fs";
|
|
21820
21821
|
import { isAbsolute, resolve, sep } from "node:path";
|
|
21822
|
+
import { fileURLToPath } from "node:url";
|
|
21821
21823
|
function resolveCodeRoot({
|
|
21822
21824
|
explicit,
|
|
21823
21825
|
packageRoot,
|
|
@@ -26299,17 +26301,17 @@ import { spawnSync as spawnSync2 } from "node:child_process";
|
|
|
26299
26301
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
26300
26302
|
import {
|
|
26301
26303
|
chmodSync,
|
|
26302
|
-
existsSync as
|
|
26303
|
-
mkdirSync as
|
|
26304
|
+
existsSync as existsSync10,
|
|
26305
|
+
mkdirSync as mkdirSync9,
|
|
26304
26306
|
readdirSync as readdirSync2,
|
|
26305
|
-
readFileSync as
|
|
26306
|
-
renameSync as
|
|
26307
|
-
statSync as
|
|
26308
|
-
unlinkSync as
|
|
26309
|
-
writeFileSync as
|
|
26307
|
+
readFileSync as readFileSync13,
|
|
26308
|
+
renameSync as renameSync8,
|
|
26309
|
+
statSync as statSync6,
|
|
26310
|
+
unlinkSync as unlinkSync4,
|
|
26311
|
+
writeFileSync as writeFileSync9
|
|
26310
26312
|
} from "node:fs";
|
|
26311
|
-
import { homedir as
|
|
26312
|
-
import
|
|
26313
|
+
import { homedir as homedir12 } from "node:os";
|
|
26314
|
+
import path6 from "node:path";
|
|
26313
26315
|
|
|
26314
26316
|
// node_modules/sops-age/dist/index.js
|
|
26315
26317
|
var import_dotenv = __toESM(require_main(), 1);
|
|
@@ -26793,8 +26795,8 @@ function getErrorMap() {
|
|
|
26793
26795
|
|
|
26794
26796
|
// node_modules/zod/v3/helpers/parseUtil.js
|
|
26795
26797
|
var makeIssue = (params) => {
|
|
26796
|
-
const { data, path:
|
|
26797
|
-
const fullPath = [...
|
|
26798
|
+
const { data, path: path8, errorMaps, issueData } = params;
|
|
26799
|
+
const fullPath = [...path8, ...issueData.path || []];
|
|
26798
26800
|
const fullIssue = {
|
|
26799
26801
|
...issueData,
|
|
26800
26802
|
path: fullPath
|
|
@@ -26910,11 +26912,11 @@ var errorUtil;
|
|
|
26910
26912
|
|
|
26911
26913
|
// node_modules/zod/v3/types.js
|
|
26912
26914
|
var ParseInputLazyPath = class {
|
|
26913
|
-
constructor(parent, value,
|
|
26915
|
+
constructor(parent, value, path8, key) {
|
|
26914
26916
|
this._cachedPath = [];
|
|
26915
26917
|
this.parent = parent;
|
|
26916
26918
|
this.data = value;
|
|
26917
|
-
this._path =
|
|
26919
|
+
this._path = path8;
|
|
26918
26920
|
this._key = key;
|
|
26919
26921
|
}
|
|
26920
26922
|
get path() {
|
|
@@ -34983,18 +34985,18 @@ import { homedir as homedir2, platform } from "node:os";
|
|
|
34983
34985
|
import { exec } from "node:child_process";
|
|
34984
34986
|
import { promisify } from "node:util";
|
|
34985
34987
|
var import_sshpk = __toESM(require_lib2(), 1);
|
|
34986
|
-
async function loadFromFile(
|
|
34988
|
+
async function loadFromFile(path8) {
|
|
34987
34989
|
if (globalThis.Deno) {
|
|
34988
|
-
return Deno.readTextFile(
|
|
34990
|
+
return Deno.readTextFile(path8);
|
|
34989
34991
|
}
|
|
34990
34992
|
if (globalThis.Bun) {
|
|
34991
|
-
return Bun.file(
|
|
34993
|
+
return Bun.file(path8).text();
|
|
34992
34994
|
}
|
|
34993
34995
|
if (typeof process !== "undefined" && process.versions?.node) {
|
|
34994
34996
|
const fs = await import("fs/promises");
|
|
34995
|
-
return fs.readFile(
|
|
34997
|
+
return fs.readFile(path8, "utf-8");
|
|
34996
34998
|
}
|
|
34997
|
-
throw new Error(`Unable to determine method to load file "${
|
|
34999
|
+
throw new Error(`Unable to determine method to load file "${path8}"`);
|
|
34998
35000
|
}
|
|
34999
35001
|
function isSopsInput(value) {
|
|
35000
35002
|
if (!value) {
|
|
@@ -35102,13 +35104,13 @@ async function parseSops(input, sopsFileType) {
|
|
|
35102
35104
|
});
|
|
35103
35105
|
}
|
|
35104
35106
|
}
|
|
35105
|
-
async function loadSopsFile(
|
|
35107
|
+
async function loadSopsFile(path8, sopsFileType) {
|
|
35106
35108
|
try {
|
|
35107
|
-
const content = await loadFromFile(
|
|
35109
|
+
const content = await loadFromFile(path8);
|
|
35108
35110
|
return await parseSops(content, sopsFileType);
|
|
35109
35111
|
} catch (err) {
|
|
35110
35112
|
throw new Error(
|
|
35111
|
-
`Failed to load SOPS file '${
|
|
35113
|
+
`Failed to load SOPS file '${path8}': ${err.message}`,
|
|
35112
35114
|
{
|
|
35113
35115
|
cause: err
|
|
35114
35116
|
}
|
|
@@ -35525,15 +35527,15 @@ async function getSopsEncryptionKey(sops, secretKeys) {
|
|
|
35525
35527
|
${errors.join("\n")}`
|
|
35526
35528
|
);
|
|
35527
35529
|
}
|
|
35528
|
-
function path2gopath(
|
|
35529
|
-
return `${
|
|
35530
|
+
function path2gopath(path8) {
|
|
35531
|
+
return `${path8.filter((x) => !/^\d+$/.test(x)).join(":")}:`;
|
|
35530
35532
|
}
|
|
35531
|
-
function decryptSOPSValue(ciphertext, decryptionKey,
|
|
35533
|
+
function decryptSOPSValue(ciphertext, decryptionKey, path8) {
|
|
35532
35534
|
if (!ciphertext) {
|
|
35533
35535
|
return "";
|
|
35534
35536
|
}
|
|
35535
35537
|
const encryptedValue = parse(ciphertext);
|
|
35536
|
-
const aad = path2gopath(
|
|
35538
|
+
const aad = path2gopath(path8);
|
|
35537
35539
|
let decrypted;
|
|
35538
35540
|
try {
|
|
35539
35541
|
decrypted = decryptAesGcm(
|
|
@@ -35543,22 +35545,22 @@ function decryptSOPSValue(ciphertext, decryptionKey, path7) {
|
|
|
35543
35545
|
);
|
|
35544
35546
|
} catch (err) {
|
|
35545
35547
|
throw new Error(
|
|
35546
|
-
`AES-GCM decryption failed at path ${JSON.stringify(
|
|
35548
|
+
`AES-GCM decryption failed at path ${JSON.stringify(path8)} for value "${ciphertext}": ${err instanceof Error ? err.message : String(err)}`
|
|
35547
35549
|
);
|
|
35548
35550
|
}
|
|
35549
35551
|
const decryptedValue = new TextDecoder().decode(decrypted);
|
|
35550
35552
|
return convertDecryptedValue(decryptedValue, encryptedValue.datatype);
|
|
35551
35553
|
}
|
|
35552
|
-
function decryptObject(obj, decryptionKey,
|
|
35554
|
+
function decryptObject(obj, decryptionKey, path8 = []) {
|
|
35553
35555
|
if (typeof obj !== "object" || obj === null) {
|
|
35554
35556
|
return obj;
|
|
35555
35557
|
}
|
|
35556
35558
|
for (const key of Object.keys(obj)) {
|
|
35557
35559
|
const value = obj[key];
|
|
35558
35560
|
if (typeof value === "string" && value.startsWith("ENC[AES256_GCM,data:")) {
|
|
35559
|
-
obj[key] = decryptSOPSValue(value, decryptionKey, [...
|
|
35561
|
+
obj[key] = decryptSOPSValue(value, decryptionKey, [...path8, key]);
|
|
35560
35562
|
} else if (typeof value === "object") {
|
|
35561
|
-
obj[key] = decryptObject(value, decryptionKey, [...
|
|
35563
|
+
obj[key] = decryptObject(value, decryptionKey, [...path8, key]);
|
|
35562
35564
|
}
|
|
35563
35565
|
}
|
|
35564
35566
|
return obj;
|
|
@@ -35637,16 +35639,16 @@ import { homedir as homedir6 } from "node:os";
|
|
|
35637
35639
|
import { join as join7 } from "node:path";
|
|
35638
35640
|
|
|
35639
35641
|
// spex-console/src/lib/cli/control-shared.ts
|
|
35640
|
-
import
|
|
35642
|
+
import path5 from "node:path";
|
|
35641
35643
|
|
|
35642
35644
|
// scripts/lib/hs-command.mjs
|
|
35643
35645
|
import { existsSync as existsSync5 } from "node:fs";
|
|
35644
35646
|
import { delimiter, dirname as dirname2, join as join8 } from "node:path";
|
|
35645
|
-
import { fileURLToPath } from "node:url";
|
|
35647
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
35646
35648
|
var HS_BIN_NAME = "hs";
|
|
35647
35649
|
var HS_DISPATCHER_PATH = (() => {
|
|
35648
35650
|
try {
|
|
35649
|
-
const here = dirname2(
|
|
35651
|
+
const here = dirname2(fileURLToPath2(import.meta.url));
|
|
35650
35652
|
return join8(dirname2(dirname2(here)), "bin", "hs.mjs");
|
|
35651
35653
|
} catch {
|
|
35652
35654
|
return null;
|
|
@@ -35660,8 +35662,8 @@ var HS_DISPATCHER_PREFIX = HS_DISPATCHER_PATH ? `node ${shellQuote(HS_DISPATCHER
|
|
|
35660
35662
|
// vendor/heyspex-mcp/console-fetch.mjs
|
|
35661
35663
|
init_heyspex_home();
|
|
35662
35664
|
init_credentials();
|
|
35663
|
-
import { readFileSync as
|
|
35664
|
-
import { homedir as
|
|
35665
|
+
import { readFileSync as readFileSync11 } from "node:fs";
|
|
35666
|
+
import { homedir as homedir10 } from "node:os";
|
|
35665
35667
|
import { join as join12 } from "node:path";
|
|
35666
35668
|
|
|
35667
35669
|
// vendor/heyspex-mcp/session-owner.mjs
|
|
@@ -35696,9 +35698,30 @@ import { basename, join as join10, isAbsolute as isAbsolute2 } from "node:path";
|
|
|
35696
35698
|
|
|
35697
35699
|
// vendor/heyspex-mcp/vault-resolve.mjs
|
|
35698
35700
|
init_heyspex_home();
|
|
35699
|
-
import { existsSync as
|
|
35700
|
-
import { homedir as
|
|
35701
|
-
|
|
35701
|
+
import { existsSync as existsSync8, readFileSync as readFileSync10, realpathSync as realpathSync3, statSync as statSync5 } from "node:fs";
|
|
35702
|
+
import { homedir as homedir9, tmpdir } from "node:os";
|
|
35703
|
+
|
|
35704
|
+
// vendor/heyspex-mcp/usable-dir-env.mjs
|
|
35705
|
+
import { statSync as statSync3 } from "node:fs";
|
|
35706
|
+
import { isAbsolute as isAbsolute3 } from "node:path";
|
|
35707
|
+
|
|
35708
|
+
// vendor/heyspex-mcp/vault-resolve.mjs
|
|
35709
|
+
import { basename as basename2, dirname as dirname3, join as join11, resolve as resolve3 } from "node:path";
|
|
35710
|
+
|
|
35711
|
+
// vendor/heyspex-mcp/vault-binding.mjs
|
|
35712
|
+
import {
|
|
35713
|
+
copyFileSync,
|
|
35714
|
+
existsSync as existsSync7,
|
|
35715
|
+
mkdirSync as mkdirSync7,
|
|
35716
|
+
readFileSync as readFileSync9,
|
|
35717
|
+
realpathSync as realpathSync2,
|
|
35718
|
+
renameSync as renameSync6,
|
|
35719
|
+
statSync as statSync4,
|
|
35720
|
+
unlinkSync as unlinkSync3,
|
|
35721
|
+
writeFileSync as writeFileSync7
|
|
35722
|
+
} from "node:fs";
|
|
35723
|
+
import { homedir as homedir8 } from "node:os";
|
|
35724
|
+
import path4 from "node:path";
|
|
35702
35725
|
|
|
35703
35726
|
// vendor/heyspex-mcp/console-fetch.mjs
|
|
35704
35727
|
var SCOPE_REFUSAL_CODES = Object.freeze(["VAULT_SCOPE_MISMATCH", "ACCOUNT_MISMATCH", "VAULT_NOT_REGISTERED"]);
|
|
@@ -35707,11 +35730,11 @@ var SCOPE_REFUSAL_CODES = Object.freeze(["VAULT_SCOPE_MISMATCH", "ACCOUNT_MISMAT
|
|
|
35707
35730
|
init_credentials();
|
|
35708
35731
|
|
|
35709
35732
|
// spex-console/src/lib/vault-registry/registry-file.ts
|
|
35710
|
-
import { existsSync as
|
|
35733
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync8, readFileSync as readFileSync12, renameSync as renameSync7, writeFileSync as writeFileSync8 } from "node:fs";
|
|
35711
35734
|
import { dirname as dirname4, join as join13, resolve as resolve4 } from "node:path";
|
|
35712
35735
|
|
|
35713
35736
|
// spex-console/src/lib/heyspex-home.ts
|
|
35714
|
-
import { homedir as
|
|
35737
|
+
import { homedir as homedir11 } from "node:os";
|
|
35715
35738
|
|
|
35716
35739
|
// spex-console/src/lib/cli/init.ts
|
|
35717
35740
|
function parseVaultId(content) {
|
|
@@ -35746,12 +35769,15 @@ var HELP2 = [
|
|
|
35746
35769
|
"(spex-console/src/lib/cli/template-manifest.ts) \u2014 universal docs",
|
|
35747
35770
|
"copied verbatim, template-shape docs written as author-prompt skeletons \u2014",
|
|
35748
35771
|
"plus a generated CLAUDE.md, the kept-principles index, and the template_version",
|
|
35749
|
-
"pin; with --git, one initial `git init` + commit.
|
|
35750
|
-
"holds heyspex.yaml
|
|
35751
|
-
"
|
|
35752
|
-
"
|
|
35753
|
-
"
|
|
35754
|
-
"
|
|
35772
|
+
"pin; with --git, one initial `git init` + commit. On an EXISTING vault (<dir>",
|
|
35773
|
+
"holds heyspex.yaml with a vault_id) it is a REFRESH \u2014 the repair `hs doctor`'s",
|
|
35774
|
+
"vault-template row names: only missing shipped files are added, template_version",
|
|
35775
|
+
"is written/updated in heyspex.yaml (every other byte and the vault_id kept),",
|
|
35776
|
+
"nothing existing is ever overwritten (an existing CLAUDE.md gets a",
|
|
35777
|
+
"CLAUDE.md.template beside it), the result lists each manifest row as created or",
|
|
35778
|
+
"kept, and a second run writes nothing. <dir> may be any path (a satellite repo",
|
|
35779
|
+
"names its vault, e.g. `hs init --customer-vault ../my-specs`). Refuses only a",
|
|
35780
|
+
"non-empty <dir> that has no heyspex.yaml. See init.customer-vault.ts.",
|
|
35755
35781
|
"",
|
|
35756
35782
|
"Flags:",
|
|
35757
35783
|
" --console-url <url> console_url value (default: the mode-aware console --",
|
|
@@ -36057,23 +36083,23 @@ function isExpiredDate(expires, today = todayIso()) {
|
|
|
36057
36083
|
return expires !== null && today > expires;
|
|
36058
36084
|
}
|
|
36059
36085
|
function envDir(vaultRoot) {
|
|
36060
|
-
return
|
|
36086
|
+
return path6.join(vaultRoot, ".heyspex", "env");
|
|
36061
36087
|
}
|
|
36062
36088
|
function profilePath(vaultRoot, name) {
|
|
36063
|
-
return
|
|
36089
|
+
return path6.join(envDir(vaultRoot), `${name}.env`);
|
|
36064
36090
|
}
|
|
36065
36091
|
function keysPath(vaultRoot) {
|
|
36066
|
-
return
|
|
36092
|
+
return path6.join(vaultRoot, ".heyspex", "env.keys");
|
|
36067
36093
|
}
|
|
36068
36094
|
function homeKeysPath() {
|
|
36069
|
-
return
|
|
36095
|
+
return path6.join(process.env.HEYSPEX_ENV_KEYS_HOME || homedir12(), ".heyspex", "env.keys");
|
|
36070
36096
|
}
|
|
36071
36097
|
function dotenvPath(vaultRoot) {
|
|
36072
|
-
return
|
|
36098
|
+
return path6.join(vaultRoot, ".env");
|
|
36073
36099
|
}
|
|
36074
36100
|
function readOrNull(file) {
|
|
36075
36101
|
try {
|
|
36076
|
-
return
|
|
36102
|
+
return readFileSync13(file, "utf-8");
|
|
36077
36103
|
} catch {
|
|
36078
36104
|
return null;
|
|
36079
36105
|
}
|
|
@@ -36087,7 +36113,7 @@ function renameWithRetry(tmp, file) {
|
|
|
36087
36113
|
const retryable = /* @__PURE__ */ new Set(["EPERM", "EBUSY", "EACCES"]);
|
|
36088
36114
|
for (let attempt = 0; ; attempt++) {
|
|
36089
36115
|
try {
|
|
36090
|
-
|
|
36116
|
+
renameSync8(tmp, file);
|
|
36091
36117
|
return;
|
|
36092
36118
|
} catch (err) {
|
|
36093
36119
|
const code = err.code ?? "";
|
|
@@ -36098,21 +36124,21 @@ function renameWithRetry(tmp, file) {
|
|
|
36098
36124
|
}
|
|
36099
36125
|
function unlinkQuiet(file) {
|
|
36100
36126
|
try {
|
|
36101
|
-
|
|
36127
|
+
unlinkSync4(file);
|
|
36102
36128
|
} catch {
|
|
36103
36129
|
}
|
|
36104
36130
|
}
|
|
36105
36131
|
function atomicWrite(file, content, mode = 420) {
|
|
36106
36132
|
const secret = mode === SECRET_MODE;
|
|
36107
|
-
const dir =
|
|
36108
|
-
|
|
36109
|
-
const tmp =
|
|
36133
|
+
const dir = path6.dirname(file);
|
|
36134
|
+
mkdirSync9(dir, { recursive: true, ...secret ? { mode: SECRET_DIR_MODE } : {} });
|
|
36135
|
+
const tmp = path6.join(
|
|
36110
36136
|
dir,
|
|
36111
|
-
`.${
|
|
36137
|
+
`.${path6.basename(file)}.${process.pid}.${randomBytes5(4).toString("hex")}.tmp`
|
|
36112
36138
|
);
|
|
36113
36139
|
let renamed = false;
|
|
36114
36140
|
try {
|
|
36115
|
-
|
|
36141
|
+
writeFileSync9(tmp, content, { encoding: "utf-8", mode });
|
|
36116
36142
|
if (secret) chmodOwnerOnly(tmp);
|
|
36117
36143
|
renameWithRetry(tmp, file);
|
|
36118
36144
|
renamed = true;
|
|
@@ -36126,18 +36152,18 @@ var LOCK_RETRY_MS3 = 50;
|
|
|
36126
36152
|
var LOCK_STALE_MS3 = 5e3;
|
|
36127
36153
|
function withFileLock(file, fn) {
|
|
36128
36154
|
const lock = `${file}.lock`;
|
|
36129
|
-
|
|
36155
|
+
mkdirSync9(path6.dirname(file), { recursive: true, mode: SECRET_DIR_MODE });
|
|
36130
36156
|
let held = false;
|
|
36131
36157
|
for (let attempt = 0; attempt < LOCK_RETRIES && !held; attempt++) {
|
|
36132
36158
|
try {
|
|
36133
|
-
|
|
36159
|
+
writeFileSync9(lock, `${process.pid}
|
|
36134
36160
|
`, { flag: "wx" });
|
|
36135
36161
|
held = true;
|
|
36136
36162
|
} catch (err) {
|
|
36137
36163
|
if (err.code !== "EEXIST") throw err;
|
|
36138
36164
|
let ageMs = Infinity;
|
|
36139
36165
|
try {
|
|
36140
|
-
ageMs = Date.now() -
|
|
36166
|
+
ageMs = Date.now() - statSync6(lock).mtimeMs;
|
|
36141
36167
|
} catch {
|
|
36142
36168
|
ageMs = Infinity;
|
|
36143
36169
|
}
|
|
@@ -36179,7 +36205,7 @@ function writeHomeKeyLine(profileName, privateKey, vaultId) {
|
|
|
36179
36205
|
}
|
|
36180
36206
|
function readVaultId(vaultRoot) {
|
|
36181
36207
|
try {
|
|
36182
|
-
const raw = readOrNull(
|
|
36208
|
+
const raw = readOrNull(path6.join(vaultRoot, "heyspex.yaml"));
|
|
36183
36209
|
return raw === null ? null : parseVaultId(raw);
|
|
36184
36210
|
} catch {
|
|
36185
36211
|
return null;
|
|
@@ -36322,7 +36348,7 @@ function legacyDecryptAllSync(vaultRoot, name) {
|
|
|
36322
36348
|
}
|
|
36323
36349
|
function initProfile(vaultRoot, name = DEFAULT_PROFILE2, opts = {}) {
|
|
36324
36350
|
const pFile = profilePath(vaultRoot, name);
|
|
36325
|
-
if (
|
|
36351
|
+
if (existsSync10(pFile) && !opts.force) {
|
|
36326
36352
|
throw new EnvVaultConfigError(
|
|
36327
36353
|
`Env profile "${name}" already exists at ${pFile}. Pass --force to re-key it (this discards existing values and mints a new keypair).`
|
|
36328
36354
|
);
|
|
@@ -36364,7 +36390,7 @@ function saveProfile(vaultRoot, name, profile) {
|
|
|
36364
36390
|
function listProfiles(vaultRoot) {
|
|
36365
36391
|
const dir = envDir(vaultRoot);
|
|
36366
36392
|
try {
|
|
36367
|
-
if (!
|
|
36393
|
+
if (!statSync6(dir).isDirectory()) return [];
|
|
36368
36394
|
} catch {
|
|
36369
36395
|
return [];
|
|
36370
36396
|
}
|
|
@@ -36708,7 +36734,7 @@ function removeGrant(vaultRoot, profileName, name, opts = {}) {
|
|
|
36708
36734
|
}
|
|
36709
36735
|
async function exportProfile(vaultRoot, name = DEFAULT_PROFILE2, opts = {}) {
|
|
36710
36736
|
const target = dotenvPath(vaultRoot);
|
|
36711
|
-
if (
|
|
36737
|
+
if (existsSync10(target) && !opts.force) {
|
|
36712
36738
|
throw new EnvVaultConfigError(
|
|
36713
36739
|
`${target} already exists. Pass --force to overwrite it (it is disposable \u2014 the encrypted profile is the system of record).`
|
|
36714
36740
|
);
|
|
@@ -36720,10 +36746,10 @@ async function exportProfile(vaultRoot, name = DEFAULT_PROFILE2, opts = {}) {
|
|
|
36720
36746
|
return { path: target };
|
|
36721
36747
|
}
|
|
36722
36748
|
function resolveVaultPath(vaultRoot, filePath) {
|
|
36723
|
-
const root =
|
|
36724
|
-
const resolved =
|
|
36725
|
-
const rel =
|
|
36726
|
-
if (
|
|
36749
|
+
const root = path6.resolve(vaultRoot);
|
|
36750
|
+
const resolved = path6.resolve(root, filePath);
|
|
36751
|
+
const rel = path6.relative(root, resolved);
|
|
36752
|
+
if (path6.isAbsolute(filePath) || path6.isAbsolute(rel) || rel === ".." || rel.startsWith(`..${path6.sep}`)) {
|
|
36727
36753
|
throw new EnvVaultConfigError(
|
|
36728
36754
|
`Refusing to touch "${filePath}" \u2014 it resolves outside the vault root (${root}). Vault file paths must stay inside the repo (no "..", no absolute paths).`
|
|
36729
36755
|
);
|
|
@@ -36737,12 +36763,12 @@ function writeTextFile(vaultRoot, filePath, content) {
|
|
|
36737
36763
|
atomicWrite(resolveVaultPath(vaultRoot, filePath), content, SECRET_MODE);
|
|
36738
36764
|
}
|
|
36739
36765
|
function pathExists(vaultRoot, filePath) {
|
|
36740
|
-
return
|
|
36766
|
+
return existsSync10(resolveVaultPath(vaultRoot, filePath));
|
|
36741
36767
|
}
|
|
36742
36768
|
function fileMtime(vaultRoot, filePath) {
|
|
36743
36769
|
const resolved = resolveVaultPath(vaultRoot, filePath);
|
|
36744
36770
|
try {
|
|
36745
|
-
return
|
|
36771
|
+
return statSync6(resolved).mtimeMs;
|
|
36746
36772
|
} catch {
|
|
36747
36773
|
return null;
|
|
36748
36774
|
}
|
|
@@ -36771,7 +36797,7 @@ function listRepoSourceFiles(vaultRoot) {
|
|
|
36771
36797
|
for (const entry of entries) {
|
|
36772
36798
|
const childRel = rel === "" ? entry.name : `${rel}/${entry.name}`;
|
|
36773
36799
|
if (entry.isDirectory()) {
|
|
36774
|
-
if (!WALK_SKIP_DIRS.has(entry.name)) walk(
|
|
36800
|
+
if (!WALK_SKIP_DIRS.has(entry.name)) walk(path6.join(dir, entry.name), childRel);
|
|
36775
36801
|
} else if (entry.isFile()) {
|
|
36776
36802
|
out.push(childRel);
|
|
36777
36803
|
}
|
|
@@ -36797,7 +36823,7 @@ function isKeysFileGitignored(vaultRoot) {
|
|
|
36797
36823
|
if (res.status === 1) return false;
|
|
36798
36824
|
} catch {
|
|
36799
36825
|
}
|
|
36800
|
-
const gitignore = readOrNull(
|
|
36826
|
+
const gitignore = readOrNull(path6.join(vaultRoot, ".gitignore"));
|
|
36801
36827
|
if (gitignore === null) return false;
|
|
36802
36828
|
const ignorePatterns = /* @__PURE__ */ new Set([
|
|
36803
36829
|
".heyspex/env.keys",
|
|
@@ -36857,13 +36883,13 @@ function runEntry(name, main2, options = {}) {
|
|
|
36857
36883
|
|
|
36858
36884
|
// spex-console/bin/hs-env.ts
|
|
36859
36885
|
function hsSelfCommand() {
|
|
36860
|
-
const here =
|
|
36886
|
+
const here = path7.dirname(fileURLToPath3(import.meta.url));
|
|
36861
36887
|
const pkgRoot = resolveCodeRoot({});
|
|
36862
36888
|
const candidates = [
|
|
36863
|
-
...pkgRoot ? [
|
|
36864
|
-
|
|
36889
|
+
...pkgRoot ? [path7.join(pkgRoot, "bin", "hs.mjs")] : [],
|
|
36890
|
+
path7.resolve(here, "..", "..", "bin", "hs.mjs")
|
|
36865
36891
|
];
|
|
36866
|
-
const launcher = candidates.find((c) =>
|
|
36892
|
+
const launcher = candidates.find((c) => existsSync11(c));
|
|
36867
36893
|
return launcher ? [process3.execPath, launcher] : null;
|
|
36868
36894
|
}
|
|
36869
36895
|
var VIRTUAL_ADAPTER = /nordlynx|tailscale|zerotier|hamachi|wireguard|openvpn|proton|tap-|tun\d|vethernet|\bwsl\b|hyper-v|docker|vmware|virtualbox|vbox|utun|bridge/i;
|