heyspex 0.2.2 → 0.2.3
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 +10 -0
- package/bin/hs-vault-binding.mjs +157 -0
- package/bin/hs.mjs +81 -77
- 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 +189 -177
- package/docs/driving-heyspex-from-copilot.md +174 -165
- package/docs/mcp-client-config.md +93 -25
- package/package.json +255 -250
- package/plugins/heyspex/.mcp.json +3 -4
- package/plugins/heyspex/README.md +323 -312
- 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 +1058 -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 +64 -34
- 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/mcp-config.mjs +4 -2
- 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 +59 -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
|
@@ -165,9 +165,9 @@ function parseCredentialsStore(raw) {
|
|
|
165
165
|
accounts
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
function readTextOrNull(read,
|
|
168
|
+
function readTextOrNull(read, path16) {
|
|
169
169
|
try {
|
|
170
|
-
const raw = read(
|
|
170
|
+
const raw = read(path16);
|
|
171
171
|
return typeof raw === "string" ? raw : null;
|
|
172
172
|
} catch {
|
|
173
173
|
return null;
|
|
@@ -219,14 +219,14 @@ var init_session_owner = __esm({
|
|
|
219
219
|
});
|
|
220
220
|
|
|
221
221
|
// vendor/heyspex-mcp/vault-less-endpoints.mjs
|
|
222
|
-
function pathnameOf(
|
|
223
|
-
const raw = String(
|
|
222
|
+
function pathnameOf(path16) {
|
|
223
|
+
const raw = String(path16 ?? "").split("?")[0].split("#")[0];
|
|
224
224
|
const noTrailing = raw.length > 1 ? raw.replace(/\/+$/, "") : raw;
|
|
225
225
|
return noTrailing || "/";
|
|
226
226
|
}
|
|
227
|
-
function isVaultLessEndpoint(method,
|
|
227
|
+
function isVaultLessEndpoint(method, path16) {
|
|
228
228
|
const m = String(method || "GET").toUpperCase();
|
|
229
|
-
const pathname = pathnameOf(
|
|
229
|
+
const pathname = pathnameOf(path16);
|
|
230
230
|
return VAULT_LESS_ENDPOINTS.some((row) => {
|
|
231
231
|
const [rowMethod, rowPath] = row.split(" ");
|
|
232
232
|
return rowPath === pathname && (rowMethod === "*" || rowMethod === m);
|
|
@@ -249,7 +249,9 @@ var init_vault_less_endpoints = __esm({
|
|
|
249
249
|
});
|
|
250
250
|
|
|
251
251
|
// scripts/lib/shared-path-helpers.mjs
|
|
252
|
+
import { realpathSync } from "node:fs";
|
|
252
253
|
import { isAbsolute, resolve as resolve2, sep } from "node:path";
|
|
254
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
253
255
|
var init_shared_path_helpers = __esm({
|
|
254
256
|
"scripts/lib/shared-path-helpers.mjs"() {
|
|
255
257
|
"use strict";
|
|
@@ -274,20 +276,52 @@ var init_write_outbox = __esm({
|
|
|
274
276
|
}
|
|
275
277
|
});
|
|
276
278
|
|
|
279
|
+
// vendor/heyspex-mcp/usable-dir-env.mjs
|
|
280
|
+
import { statSync } from "node:fs";
|
|
281
|
+
import { isAbsolute as isAbsolute3 } from "node:path";
|
|
282
|
+
var init_usable_dir_env = __esm({
|
|
283
|
+
"vendor/heyspex-mcp/usable-dir-env.mjs"() {
|
|
284
|
+
"use strict";
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// vendor/heyspex-mcp/vault-binding.mjs
|
|
289
|
+
import {
|
|
290
|
+
copyFileSync,
|
|
291
|
+
existsSync as existsSync3,
|
|
292
|
+
mkdirSync as mkdirSync3,
|
|
293
|
+
readFileSync as readFileSync4,
|
|
294
|
+
realpathSync as realpathSync2,
|
|
295
|
+
renameSync as renameSync3,
|
|
296
|
+
statSync as statSync2,
|
|
297
|
+
unlinkSync,
|
|
298
|
+
writeFileSync as writeFileSync3
|
|
299
|
+
} from "node:fs";
|
|
300
|
+
import { homedir as homedir4 } from "node:os";
|
|
301
|
+
import path from "node:path";
|
|
302
|
+
var init_vault_binding = __esm({
|
|
303
|
+
"vendor/heyspex-mcp/vault-binding.mjs"() {
|
|
304
|
+
"use strict";
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
|
|
277
308
|
// vendor/heyspex-mcp/vault-resolve.mjs
|
|
278
|
-
import { existsSync as
|
|
279
|
-
import { homedir as
|
|
280
|
-
import { dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
|
|
309
|
+
import { existsSync as existsSync4, readFileSync as readFileSync5, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
|
|
310
|
+
import { homedir as homedir5, tmpdir } from "node:os";
|
|
311
|
+
import { basename as basename2, dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
|
|
281
312
|
var init_vault_resolve = __esm({
|
|
282
313
|
"vendor/heyspex-mcp/vault-resolve.mjs"() {
|
|
283
314
|
"use strict";
|
|
284
315
|
init_heyspex_home();
|
|
316
|
+
init_usable_dir_env();
|
|
317
|
+
init_vault_binding();
|
|
318
|
+
init_vault_binding();
|
|
285
319
|
}
|
|
286
320
|
});
|
|
287
321
|
|
|
288
322
|
// vendor/heyspex-mcp/console-fetch.mjs
|
|
289
|
-
import { readFileSync as
|
|
290
|
-
import { homedir as
|
|
323
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
324
|
+
import { homedir as homedir6 } from "node:os";
|
|
291
325
|
import { join as join6 } from "node:path";
|
|
292
326
|
function isCloudVaultId(value) {
|
|
293
327
|
return typeof value === "string" && CLOUD_VAULT_ID_RE.test(value.trim());
|
|
@@ -309,13 +343,13 @@ var init_console_fetch = __esm({
|
|
|
309
343
|
});
|
|
310
344
|
|
|
311
345
|
// spex-console/src/lib/heyspex-home.ts
|
|
312
|
-
import { homedir as
|
|
346
|
+
import { homedir as homedir7 } from "node:os";
|
|
313
347
|
function heyspexHome2(env = process.env) {
|
|
314
348
|
const override = env?.HEYSPEX_HOME;
|
|
315
349
|
if (typeof override === "string" && override.trim().length > 0) {
|
|
316
350
|
return override.trim();
|
|
317
351
|
}
|
|
318
|
-
return
|
|
352
|
+
return homedir7();
|
|
319
353
|
}
|
|
320
354
|
var init_heyspex_home2 = __esm({
|
|
321
355
|
"spex-console/src/lib/heyspex-home.ts"() {
|
|
@@ -343,7 +377,7 @@ var init_types = __esm({
|
|
|
343
377
|
});
|
|
344
378
|
|
|
345
379
|
// spex-console/src/lib/vault-registry/registry-file.ts
|
|
346
|
-
import { existsSync as
|
|
380
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
|
|
347
381
|
import { dirname as dirname4, join as join7, resolve as resolve4 } from "node:path";
|
|
348
382
|
function vaultRegistryDir(opts = {}) {
|
|
349
383
|
return opts.registryDir ?? join7(heyspexHome2(), ".heyspex");
|
|
@@ -450,9 +484,9 @@ function parseVaultRegistryFile(json) {
|
|
|
450
484
|
}
|
|
451
485
|
function readRegistryJson(opts) {
|
|
452
486
|
const filePath = vaultRegistryFilePath(opts);
|
|
453
|
-
if (!
|
|
487
|
+
if (!existsSync5(filePath)) return { kind: "missing" };
|
|
454
488
|
try {
|
|
455
|
-
const raw =
|
|
489
|
+
const raw = readFileSync7(filePath, "utf8");
|
|
456
490
|
const json = JSON.parse(raw);
|
|
457
491
|
if (registryFileSchemaOf(json) === null) return { kind: "unreadable" };
|
|
458
492
|
return { kind: "ok", raw, json };
|
|
@@ -488,8 +522,8 @@ var init_registry_file = __esm({
|
|
|
488
522
|
});
|
|
489
523
|
|
|
490
524
|
// scripts/lib/dev-mode.mjs
|
|
491
|
-
import { mkdirSync as
|
|
492
|
-
import { homedir as
|
|
525
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
|
|
526
|
+
import { homedir as homedir8 } from "node:os";
|
|
493
527
|
import { join as join8 } from "node:path";
|
|
494
528
|
var init_dev_mode = __esm({
|
|
495
529
|
"scripts/lib/dev-mode.mjs"() {
|
|
@@ -500,8 +534,8 @@ var init_dev_mode = __esm({
|
|
|
500
534
|
});
|
|
501
535
|
|
|
502
536
|
// scripts/lib/console-url-resolver.mjs
|
|
503
|
-
import { readFileSync as
|
|
504
|
-
import { homedir as
|
|
537
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
538
|
+
import { homedir as homedir9 } from "node:os";
|
|
505
539
|
import { join as join9 } from "node:path";
|
|
506
540
|
var init_console_url_resolver = __esm({
|
|
507
541
|
"scripts/lib/console-url-resolver.mjs"() {
|
|
@@ -512,9 +546,9 @@ var init_console_url_resolver = __esm({
|
|
|
512
546
|
});
|
|
513
547
|
|
|
514
548
|
// spex-console/src/lib/vault-registry/repo-identity.ts
|
|
515
|
-
import
|
|
549
|
+
import path3 from "node:path";
|
|
516
550
|
function normalizeRepoRoot(p) {
|
|
517
|
-
let resolved =
|
|
551
|
+
let resolved = path3.resolve(p);
|
|
518
552
|
while (resolved.length > 1 && (resolved.endsWith("/") || resolved.endsWith("\\"))) {
|
|
519
553
|
resolved = resolved.slice(0, -1);
|
|
520
554
|
}
|
|
@@ -523,8 +557,8 @@ function normalizeRepoRoot(p) {
|
|
|
523
557
|
function repoRootCandidates(p) {
|
|
524
558
|
const norm = normalizeRepoRoot(p);
|
|
525
559
|
const candidates = [norm];
|
|
526
|
-
if (
|
|
527
|
-
const parent =
|
|
560
|
+
if (path3.basename(norm) === "specs") {
|
|
561
|
+
const parent = path3.dirname(norm);
|
|
528
562
|
if (parent !== norm) candidates.push(parent);
|
|
529
563
|
}
|
|
530
564
|
return candidates;
|
|
@@ -549,22 +583,22 @@ var init_default_workspace = __esm({
|
|
|
549
583
|
});
|
|
550
584
|
|
|
551
585
|
// spex-console/src/lib/cli/vault-workspace-shared.ts
|
|
552
|
-
import { readFileSync as
|
|
586
|
+
import { readFileSync as readFileSync10 } from "node:fs";
|
|
553
587
|
function resolveConfiguredAccountId(opts = {}) {
|
|
554
588
|
return resolveSessionOwnerUncached({
|
|
555
589
|
env: opts.env ?? process.env,
|
|
556
590
|
homeDir: opts.homeDir ?? heyspexHome2(),
|
|
557
|
-
readFile: opts.readFile ?? ((p) =>
|
|
591
|
+
readFile: opts.readFile ?? ((p) => readFileSync10(p, "utf-8"))
|
|
558
592
|
});
|
|
559
593
|
}
|
|
560
594
|
function resolveCloudAccountIdOrRefuse(opts = {}) {
|
|
561
595
|
const accountId = resolveConfiguredAccountId(opts);
|
|
562
596
|
return accountId ? { ok: true, accountId } : { ok: false, message: CLOUD_ACCOUNT_ID_REQUIRED_MESSAGE };
|
|
563
597
|
}
|
|
564
|
-
async function cloudHttpRequest(http, method,
|
|
565
|
-
const scopeHeaders = http.scope ? http.scope.headersFor(method,
|
|
598
|
+
async function cloudHttpRequest(http, method, path16, body) {
|
|
599
|
+
const scopeHeaders = http.scope ? http.scope.headersFor(method, path16) : {};
|
|
566
600
|
try {
|
|
567
|
-
const res = await http.fetchImpl(`${http.consoleUrl}${
|
|
601
|
+
const res = await http.fetchImpl(`${http.consoleUrl}${path16}`, {
|
|
568
602
|
method,
|
|
569
603
|
headers: {
|
|
570
604
|
"content-type": "application/json",
|
|
@@ -3177,9 +3211,9 @@ var init_satellite = __esm({
|
|
|
3177
3211
|
});
|
|
3178
3212
|
|
|
3179
3213
|
// spex-console/src/lib/vault-resolve/index.ts
|
|
3180
|
-
import { existsSync as
|
|
3214
|
+
import { existsSync as existsSync6, readFileSync as readFileSync12, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
|
|
3181
3215
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
3182
|
-
import
|
|
3216
|
+
import path5 from "node:path";
|
|
3183
3217
|
var init_vault_resolve2 = __esm({
|
|
3184
3218
|
"spex-console/src/lib/vault-resolve/index.ts"() {
|
|
3185
3219
|
"use strict";
|
|
@@ -3216,12 +3250,12 @@ var init_resolve_status = __esm({
|
|
|
3216
3250
|
});
|
|
3217
3251
|
|
|
3218
3252
|
// spex-console/src/lib/vault-resolve/active.ts
|
|
3219
|
-
import { existsSync as
|
|
3220
|
-
import
|
|
3253
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
3254
|
+
import path6 from "node:path";
|
|
3221
3255
|
function fallbackSpecsDir() {
|
|
3222
3256
|
const override = process.env.HEYSPEX_VAULT_DIR;
|
|
3223
|
-
if (override) return
|
|
3224
|
-
return
|
|
3257
|
+
if (override) return path6.resolve(override);
|
|
3258
|
+
return path6.resolve(process.cwd(), "..", "specs");
|
|
3225
3259
|
}
|
|
3226
3260
|
function getActiveSpecsDir() {
|
|
3227
3261
|
return cacheStore.value ? cacheStore.value.specsDirAbs : fallbackSpecsDir();
|
|
@@ -3250,7 +3284,7 @@ var init_active = __esm({
|
|
|
3250
3284
|
|
|
3251
3285
|
// spex-console/src/lib/control-plane/statusline-focus-cache.ts
|
|
3252
3286
|
import fs4 from "node:fs";
|
|
3253
|
-
import
|
|
3287
|
+
import path7 from "node:path";
|
|
3254
3288
|
var init_statusline_focus_cache = __esm({
|
|
3255
3289
|
"spex-console/src/lib/control-plane/statusline-focus-cache.ts"() {
|
|
3256
3290
|
"use strict";
|
|
@@ -4002,10 +4036,10 @@ function trashPathFor(relPath, now) {
|
|
|
4002
4036
|
const normalized = relPath.split("\\").join("/");
|
|
4003
4037
|
const slashIdx = normalized.lastIndexOf("/");
|
|
4004
4038
|
const folder = slashIdx === -1 ? "" : normalized.slice(0, slashIdx);
|
|
4005
|
-
const
|
|
4039
|
+
const basename5 = slashIdx === -1 ? normalized : normalized.slice(slashIdx + 1);
|
|
4006
4040
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
4007
4041
|
const trashDir = folder ? `${folder}/.trash` : ".trash";
|
|
4008
|
-
return `${trashDir}/${stamp}-${
|
|
4042
|
+
return `${trashDir}/${stamp}-${basename5}`;
|
|
4009
4043
|
}
|
|
4010
4044
|
function materializeSpecMarkdown(bundle) {
|
|
4011
4045
|
return stringifySpecMarkdown(bundle.bodyText, bundle.frontmatter);
|
|
@@ -4127,10 +4161,10 @@ var init_export_status = __esm({
|
|
|
4127
4161
|
function isGitHubFailure(value) {
|
|
4128
4162
|
return typeof value === "object" && value !== null && "status" in value;
|
|
4129
4163
|
}
|
|
4130
|
-
async function githubJson(
|
|
4164
|
+
async function githubJson(path16, target, fetchImpl, init) {
|
|
4131
4165
|
let response;
|
|
4132
4166
|
try {
|
|
4133
|
-
response = await fetchImpl(`${GITHUB_API_BASE2}${
|
|
4167
|
+
response = await fetchImpl(`${GITHUB_API_BASE2}${path16}`, {
|
|
4134
4168
|
...init,
|
|
4135
4169
|
headers: {
|
|
4136
4170
|
...githubHeaders(target.token),
|
|
@@ -5008,7 +5042,7 @@ var init_diagnose_spawned = __esm({
|
|
|
5008
5042
|
|
|
5009
5043
|
// spex-console/src/lib/guardrail-naming.ts
|
|
5010
5044
|
import fs5 from "node:fs";
|
|
5011
|
-
import
|
|
5045
|
+
import path8 from "node:path";
|
|
5012
5046
|
var init_guardrail_naming = __esm({
|
|
5013
5047
|
"spex-console/src/lib/guardrail-naming.ts"() {
|
|
5014
5048
|
"use strict";
|
|
@@ -5018,7 +5052,7 @@ var init_guardrail_naming = __esm({
|
|
|
5018
5052
|
// spex-console/src/lib/indexer/parser.ts
|
|
5019
5053
|
import { createHash as createHash3 } from "node:crypto";
|
|
5020
5054
|
import { promises as fs6 } from "node:fs";
|
|
5021
|
-
import
|
|
5055
|
+
import path9 from "node:path";
|
|
5022
5056
|
var import_gray_matter2;
|
|
5023
5057
|
var init_parser = __esm({
|
|
5024
5058
|
"spex-console/src/lib/indexer/parser.ts"() {
|
|
@@ -5125,7 +5159,7 @@ var init_scoped_context = __esm({
|
|
|
5125
5159
|
// spex-console/src/lib/indexer/indexer-service.ts
|
|
5126
5160
|
import { spawnSync } from "node:child_process";
|
|
5127
5161
|
import { promises as fs7 } from "node:fs";
|
|
5128
|
-
import
|
|
5162
|
+
import path10 from "node:path";
|
|
5129
5163
|
var init_indexer_service = __esm({
|
|
5130
5164
|
"spex-console/src/lib/indexer/indexer-service.ts"() {
|
|
5131
5165
|
"use strict";
|
|
@@ -5144,7 +5178,7 @@ var init_indexer_service = __esm({
|
|
|
5144
5178
|
|
|
5145
5179
|
// spex-console/src/lib/indexer/outbox-index-feeder.ts
|
|
5146
5180
|
import { promises as fs8 } from "node:fs";
|
|
5147
|
-
import
|
|
5181
|
+
import path11 from "node:path";
|
|
5148
5182
|
var init_outbox_index_feeder = __esm({
|
|
5149
5183
|
"spex-console/src/lib/indexer/outbox-index-feeder.ts"() {
|
|
5150
5184
|
"use strict";
|
|
@@ -5423,7 +5457,7 @@ var init_list_filter = __esm({
|
|
|
5423
5457
|
});
|
|
5424
5458
|
|
|
5425
5459
|
// spex-console/src/lib/specs/list-query.ts
|
|
5426
|
-
import
|
|
5460
|
+
import path12 from "node:path";
|
|
5427
5461
|
var init_list_query = __esm({
|
|
5428
5462
|
"spex-console/src/lib/specs/list-query.ts"() {
|
|
5429
5463
|
"use strict";
|
|
@@ -5466,7 +5500,7 @@ var init_pipeline_neighborhood = __esm({
|
|
|
5466
5500
|
});
|
|
5467
5501
|
|
|
5468
5502
|
// spex-console/src/lib/specs/spec-by-id.ts
|
|
5469
|
-
import
|
|
5503
|
+
import path13 from "node:path";
|
|
5470
5504
|
var init_spec_by_id = __esm({
|
|
5471
5505
|
"spex-console/src/lib/specs/spec-by-id.ts"() {
|
|
5472
5506
|
"use strict";
|
|
@@ -5523,9 +5557,9 @@ var init_search_body_hit = __esm({
|
|
|
5523
5557
|
|
|
5524
5558
|
// spex-console/src/lib/vault.ts
|
|
5525
5559
|
import { spawn } from "node:child_process";
|
|
5526
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
5560
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync13, statSync as statSync5 } from "node:fs";
|
|
5527
5561
|
import { promises as fs9 } from "node:fs";
|
|
5528
|
-
import
|
|
5562
|
+
import path14 from "node:path";
|
|
5529
5563
|
import yaml3 from "js-yaml";
|
|
5530
5564
|
function normalizeDateField(value) {
|
|
5531
5565
|
let d = null;
|
|
@@ -5566,18 +5600,18 @@ function extractBodyLinks(body) {
|
|
|
5566
5600
|
return links;
|
|
5567
5601
|
}
|
|
5568
5602
|
function toSummary(absPath, root, fm, body) {
|
|
5569
|
-
const
|
|
5570
|
-
const relPath =
|
|
5603
|
+
const basename5 = path14.basename(absPath).replace(/\.md$/i, "");
|
|
5604
|
+
const relPath = path14.relative(root, absPath).split(path14.sep).join("/");
|
|
5571
5605
|
return {
|
|
5572
|
-
id: typeof fm.id === "string" && fm.id ? fm.id :
|
|
5573
|
-
name: typeof fm.name === "string" && fm.name ? fm.name :
|
|
5606
|
+
id: typeof fm.id === "string" && fm.id ? fm.id : basename5,
|
|
5607
|
+
name: typeof fm.name === "string" && fm.name ? fm.name : basename5,
|
|
5574
5608
|
type: typeof fm.type === "string" ? fm.type : "unknown",
|
|
5575
5609
|
status: typeof fm.status === "string" ? fm.status : "unknown",
|
|
5576
5610
|
effort: typeof fm.effort === "number" ? fm.effort : null,
|
|
5577
5611
|
owner: typeof fm.owner === "string" ? fm.owner : null,
|
|
5578
5612
|
tags: Array.isArray(fm.tags) ? fm.tags.map(String) : [],
|
|
5579
5613
|
archived: fm.archived === true,
|
|
5580
|
-
basename:
|
|
5614
|
+
basename: basename5,
|
|
5581
5615
|
relPath,
|
|
5582
5616
|
links: extractBodyLinks(body),
|
|
5583
5617
|
created: normalizeDateField(fm.created),
|
|
@@ -5663,9 +5697,9 @@ function invalidateVaultCacheForFile(absPath) {
|
|
|
5663
5697
|
else evictProcessVaultHotRows();
|
|
5664
5698
|
}
|
|
5665
5699
|
function specIdFromAbsPath(absPath) {
|
|
5666
|
-
const
|
|
5667
|
-
if (!
|
|
5668
|
-
const parsed = parseSpecId(
|
|
5700
|
+
const basename5 = path14.basename(absPath).replace(/\.md$/i, "");
|
|
5701
|
+
if (!basename5) return null;
|
|
5702
|
+
const parsed = parseSpecId(basename5);
|
|
5669
5703
|
if (parsed?.era === 3 && parsed.fileKey) return `HS-${parsed.fileKey.toUpperCase()}`;
|
|
5670
5704
|
return null;
|
|
5671
5705
|
}
|
|
@@ -5754,8 +5788,8 @@ function isLocalVaultMode() {
|
|
|
5754
5788
|
}
|
|
5755
5789
|
async function writeSpecBytesToVault(relPath, content) {
|
|
5756
5790
|
try {
|
|
5757
|
-
const absPath =
|
|
5758
|
-
const dir =
|
|
5791
|
+
const absPath = path14.join(vaultRoot(), relPath);
|
|
5792
|
+
const dir = path14.dirname(absPath);
|
|
5759
5793
|
await fs9.mkdir(dir, { recursive: true });
|
|
5760
5794
|
await fs9.writeFile(absPath, content, "utf8");
|
|
5761
5795
|
} catch (err) {
|
|
@@ -6009,7 +6043,7 @@ var init_esm = __esm({
|
|
|
6009
6043
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
6010
6044
|
const statMethod = opts.lstat ? lstat : stat;
|
|
6011
6045
|
if (wantBigintFsStats) {
|
|
6012
|
-
this._stat = (
|
|
6046
|
+
this._stat = (path16) => statMethod(path16, { bigint: true });
|
|
6013
6047
|
} else {
|
|
6014
6048
|
this._stat = statMethod;
|
|
6015
6049
|
}
|
|
@@ -6034,8 +6068,8 @@ var init_esm = __esm({
|
|
|
6034
6068
|
const par = this.parent;
|
|
6035
6069
|
const fil = par && par.files;
|
|
6036
6070
|
if (fil && fil.length > 0) {
|
|
6037
|
-
const { path:
|
|
6038
|
-
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent,
|
|
6071
|
+
const { path: path16, depth } = par;
|
|
6072
|
+
const slice = fil.splice(0, batch).map((dirent) => this._formatEntry(dirent, path16));
|
|
6039
6073
|
const awaited = await Promise.all(slice);
|
|
6040
6074
|
for (const entry of awaited) {
|
|
6041
6075
|
if (!entry)
|
|
@@ -6075,21 +6109,21 @@ var init_esm = __esm({
|
|
|
6075
6109
|
this.reading = false;
|
|
6076
6110
|
}
|
|
6077
6111
|
}
|
|
6078
|
-
async _exploreDir(
|
|
6112
|
+
async _exploreDir(path16, depth) {
|
|
6079
6113
|
let files;
|
|
6080
6114
|
try {
|
|
6081
|
-
files = await readdir(
|
|
6115
|
+
files = await readdir(path16, this._rdOptions);
|
|
6082
6116
|
} catch (error) {
|
|
6083
6117
|
this._onError(error);
|
|
6084
6118
|
}
|
|
6085
|
-
return { files, depth, path:
|
|
6119
|
+
return { files, depth, path: path16 };
|
|
6086
6120
|
}
|
|
6087
|
-
async _formatEntry(dirent,
|
|
6121
|
+
async _formatEntry(dirent, path16) {
|
|
6088
6122
|
let entry;
|
|
6089
|
-
const
|
|
6123
|
+
const basename5 = this._isDirent ? dirent.name : dirent;
|
|
6090
6124
|
try {
|
|
6091
|
-
const fullPath = presolve(pjoin(
|
|
6092
|
-
entry = { path: prelative(this._root, fullPath), fullPath, basename:
|
|
6125
|
+
const fullPath = presolve(pjoin(path16, basename5));
|
|
6126
|
+
entry = { path: prelative(this._root, fullPath), fullPath, basename: basename5 };
|
|
6093
6127
|
entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath);
|
|
6094
6128
|
} catch (err) {
|
|
6095
6129
|
this._onError(err);
|
|
@@ -6149,16 +6183,16 @@ import { watchFile, unwatchFile, watch as fs_watch } from "fs";
|
|
|
6149
6183
|
import { open, stat as stat2, lstat as lstat2, realpath as fsrealpath } from "fs/promises";
|
|
6150
6184
|
import * as sysPath from "path";
|
|
6151
6185
|
import { type as osType } from "os";
|
|
6152
|
-
function createFsWatchInstance(
|
|
6186
|
+
function createFsWatchInstance(path16, options2, listener, errHandler, emitRaw) {
|
|
6153
6187
|
const handleEvent = (rawEvent, evPath) => {
|
|
6154
|
-
listener(
|
|
6155
|
-
emitRaw(rawEvent, evPath, { watchedPath:
|
|
6156
|
-
if (evPath &&
|
|
6157
|
-
fsWatchBroadcast(sysPath.resolve(
|
|
6188
|
+
listener(path16);
|
|
6189
|
+
emitRaw(rawEvent, evPath, { watchedPath: path16 });
|
|
6190
|
+
if (evPath && path16 !== evPath) {
|
|
6191
|
+
fsWatchBroadcast(sysPath.resolve(path16, evPath), KEY_LISTENERS, sysPath.join(path16, evPath));
|
|
6158
6192
|
}
|
|
6159
6193
|
};
|
|
6160
6194
|
try {
|
|
6161
|
-
return fs_watch(
|
|
6195
|
+
return fs_watch(path16, {
|
|
6162
6196
|
persistent: options2.persistent
|
|
6163
6197
|
}, handleEvent);
|
|
6164
6198
|
} catch (error) {
|
|
@@ -6503,12 +6537,12 @@ var init_handler = __esm({
|
|
|
6503
6537
|
listener(val1, val2, val3);
|
|
6504
6538
|
});
|
|
6505
6539
|
};
|
|
6506
|
-
setFsWatchListener = (
|
|
6540
|
+
setFsWatchListener = (path16, fullPath, options2, handlers) => {
|
|
6507
6541
|
const { listener, errHandler, rawEmitter } = handlers;
|
|
6508
6542
|
let cont = FsWatchInstances.get(fullPath);
|
|
6509
6543
|
let watcher;
|
|
6510
6544
|
if (!options2.persistent) {
|
|
6511
|
-
watcher = createFsWatchInstance(
|
|
6545
|
+
watcher = createFsWatchInstance(path16, options2, listener, errHandler, rawEmitter);
|
|
6512
6546
|
if (!watcher)
|
|
6513
6547
|
return;
|
|
6514
6548
|
return watcher.close.bind(watcher);
|
|
@@ -6519,7 +6553,7 @@ var init_handler = __esm({
|
|
|
6519
6553
|
addAndConvert(cont, KEY_RAW, rawEmitter);
|
|
6520
6554
|
} else {
|
|
6521
6555
|
watcher = createFsWatchInstance(
|
|
6522
|
-
|
|
6556
|
+
path16,
|
|
6523
6557
|
options2,
|
|
6524
6558
|
fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS),
|
|
6525
6559
|
errHandler,
|
|
@@ -6534,7 +6568,7 @@ var init_handler = __esm({
|
|
|
6534
6568
|
cont.watcherUnusable = true;
|
|
6535
6569
|
if (isWindows && error.code === "EPERM") {
|
|
6536
6570
|
try {
|
|
6537
|
-
const fd = await open(
|
|
6571
|
+
const fd = await open(path16, "r");
|
|
6538
6572
|
await fd.close();
|
|
6539
6573
|
broadcastErr(error);
|
|
6540
6574
|
} catch (err) {
|
|
@@ -6565,7 +6599,7 @@ var init_handler = __esm({
|
|
|
6565
6599
|
};
|
|
6566
6600
|
};
|
|
6567
6601
|
FsWatchFileInstances = /* @__PURE__ */ new Map();
|
|
6568
|
-
setFsWatchFileListener = (
|
|
6602
|
+
setFsWatchFileListener = (path16, fullPath, options2, handlers) => {
|
|
6569
6603
|
const { listener, rawEmitter } = handlers;
|
|
6570
6604
|
let cont = FsWatchFileInstances.get(fullPath);
|
|
6571
6605
|
const copts = cont && cont.options;
|
|
@@ -6587,7 +6621,7 @@ var init_handler = __esm({
|
|
|
6587
6621
|
});
|
|
6588
6622
|
const currmtime = curr.mtimeMs;
|
|
6589
6623
|
if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
|
|
6590
|
-
foreach(cont.listeners, (listener2) => listener2(
|
|
6624
|
+
foreach(cont.listeners, (listener2) => listener2(path16, curr));
|
|
6591
6625
|
}
|
|
6592
6626
|
})
|
|
6593
6627
|
};
|
|
@@ -6615,13 +6649,13 @@ var init_handler = __esm({
|
|
|
6615
6649
|
* @param listener on fs change
|
|
6616
6650
|
* @returns closer for the watcher instance
|
|
6617
6651
|
*/
|
|
6618
|
-
_watchWithNodeFs(
|
|
6652
|
+
_watchWithNodeFs(path16, listener) {
|
|
6619
6653
|
const opts = this.fsw.options;
|
|
6620
|
-
const directory = sysPath.dirname(
|
|
6621
|
-
const
|
|
6654
|
+
const directory = sysPath.dirname(path16);
|
|
6655
|
+
const basename5 = sysPath.basename(path16);
|
|
6622
6656
|
const parent = this.fsw._getWatchedDir(directory);
|
|
6623
|
-
parent.add(
|
|
6624
|
-
const absolutePath = sysPath.resolve(
|
|
6657
|
+
parent.add(basename5);
|
|
6658
|
+
const absolutePath = sysPath.resolve(path16);
|
|
6625
6659
|
const options2 = {
|
|
6626
6660
|
persistent: opts.persistent
|
|
6627
6661
|
};
|
|
@@ -6630,13 +6664,13 @@ var init_handler = __esm({
|
|
|
6630
6664
|
let closer;
|
|
6631
6665
|
if (opts.usePolling) {
|
|
6632
6666
|
const enableBin = opts.interval !== opts.binaryInterval;
|
|
6633
|
-
options2.interval = enableBin && isBinaryPath(
|
|
6634
|
-
closer = setFsWatchFileListener(
|
|
6667
|
+
options2.interval = enableBin && isBinaryPath(basename5) ? opts.binaryInterval : opts.interval;
|
|
6668
|
+
closer = setFsWatchFileListener(path16, absolutePath, options2, {
|
|
6635
6669
|
listener,
|
|
6636
6670
|
rawEmitter: this.fsw._emitRaw
|
|
6637
6671
|
});
|
|
6638
6672
|
} else {
|
|
6639
|
-
closer = setFsWatchListener(
|
|
6673
|
+
closer = setFsWatchListener(path16, absolutePath, options2, {
|
|
6640
6674
|
listener,
|
|
6641
6675
|
errHandler: this._boundHandleError,
|
|
6642
6676
|
rawEmitter: this.fsw._emitRaw
|
|
@@ -6653,12 +6687,12 @@ var init_handler = __esm({
|
|
|
6653
6687
|
return;
|
|
6654
6688
|
}
|
|
6655
6689
|
const dirname7 = sysPath.dirname(file);
|
|
6656
|
-
const
|
|
6690
|
+
const basename5 = sysPath.basename(file);
|
|
6657
6691
|
const parent = this.fsw._getWatchedDir(dirname7);
|
|
6658
6692
|
let prevStats = stats;
|
|
6659
|
-
if (parent.has(
|
|
6693
|
+
if (parent.has(basename5))
|
|
6660
6694
|
return;
|
|
6661
|
-
const listener = async (
|
|
6695
|
+
const listener = async (path16, newStats) => {
|
|
6662
6696
|
if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
|
|
6663
6697
|
return;
|
|
6664
6698
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
@@ -6672,18 +6706,18 @@ var init_handler = __esm({
|
|
|
6672
6706
|
this.fsw._emit(EV.CHANGE, file, newStats2);
|
|
6673
6707
|
}
|
|
6674
6708
|
if ((isMacos || isLinux || isFreeBSD) && prevStats.ino !== newStats2.ino) {
|
|
6675
|
-
this.fsw._closeFile(
|
|
6709
|
+
this.fsw._closeFile(path16);
|
|
6676
6710
|
prevStats = newStats2;
|
|
6677
6711
|
const closer2 = this._watchWithNodeFs(file, listener);
|
|
6678
6712
|
if (closer2)
|
|
6679
|
-
this.fsw._addPathCloser(
|
|
6713
|
+
this.fsw._addPathCloser(path16, closer2);
|
|
6680
6714
|
} else {
|
|
6681
6715
|
prevStats = newStats2;
|
|
6682
6716
|
}
|
|
6683
6717
|
} catch (error) {
|
|
6684
|
-
this.fsw._remove(dirname7,
|
|
6718
|
+
this.fsw._remove(dirname7, basename5);
|
|
6685
6719
|
}
|
|
6686
|
-
} else if (parent.has(
|
|
6720
|
+
} else if (parent.has(basename5)) {
|
|
6687
6721
|
const at = newStats.atimeMs;
|
|
6688
6722
|
const mt = newStats.mtimeMs;
|
|
6689
6723
|
if (!at || at <= mt || mt !== prevStats.mtimeMs) {
|
|
@@ -6708,7 +6742,7 @@ var init_handler = __esm({
|
|
|
6708
6742
|
* @param item basename of this item
|
|
6709
6743
|
* @returns true if no more processing is needed for this entry.
|
|
6710
6744
|
*/
|
|
6711
|
-
async _handleSymlink(entry, directory,
|
|
6745
|
+
async _handleSymlink(entry, directory, path16, item) {
|
|
6712
6746
|
if (this.fsw.closed) {
|
|
6713
6747
|
return;
|
|
6714
6748
|
}
|
|
@@ -6718,7 +6752,7 @@ var init_handler = __esm({
|
|
|
6718
6752
|
this.fsw._incrReadyCount();
|
|
6719
6753
|
let linkPath;
|
|
6720
6754
|
try {
|
|
6721
|
-
linkPath = await fsrealpath(
|
|
6755
|
+
linkPath = await fsrealpath(path16);
|
|
6722
6756
|
} catch (e) {
|
|
6723
6757
|
this.fsw._emitReady();
|
|
6724
6758
|
return true;
|
|
@@ -6728,12 +6762,12 @@ var init_handler = __esm({
|
|
|
6728
6762
|
if (dir.has(item)) {
|
|
6729
6763
|
if (this.fsw._symlinkPaths.get(full) !== linkPath) {
|
|
6730
6764
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
6731
|
-
this.fsw._emit(EV.CHANGE,
|
|
6765
|
+
this.fsw._emit(EV.CHANGE, path16, entry.stats);
|
|
6732
6766
|
}
|
|
6733
6767
|
} else {
|
|
6734
6768
|
dir.add(item);
|
|
6735
6769
|
this.fsw._symlinkPaths.set(full, linkPath);
|
|
6736
|
-
this.fsw._emit(EV.ADD,
|
|
6770
|
+
this.fsw._emit(EV.ADD, path16, entry.stats);
|
|
6737
6771
|
}
|
|
6738
6772
|
this.fsw._emitReady();
|
|
6739
6773
|
return true;
|
|
@@ -6762,9 +6796,9 @@ var init_handler = __esm({
|
|
|
6762
6796
|
return;
|
|
6763
6797
|
}
|
|
6764
6798
|
const item = entry.path;
|
|
6765
|
-
let
|
|
6799
|
+
let path16 = sysPath.join(directory, item);
|
|
6766
6800
|
current.add(item);
|
|
6767
|
-
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory,
|
|
6801
|
+
if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path16, item)) {
|
|
6768
6802
|
return;
|
|
6769
6803
|
}
|
|
6770
6804
|
if (this.fsw.closed) {
|
|
@@ -6773,8 +6807,8 @@ var init_handler = __esm({
|
|
|
6773
6807
|
}
|
|
6774
6808
|
if (item === target || !target && !previous.has(item)) {
|
|
6775
6809
|
this.fsw._incrReadyCount();
|
|
6776
|
-
|
|
6777
|
-
this._addToNodeFs(
|
|
6810
|
+
path16 = sysPath.join(dir, sysPath.relative(dir, path16));
|
|
6811
|
+
this._addToNodeFs(path16, initialAdd, wh, depth + 1);
|
|
6778
6812
|
}
|
|
6779
6813
|
}).on(EV.ERROR, this._boundHandleError);
|
|
6780
6814
|
return new Promise((resolve7, reject) => {
|
|
@@ -6843,13 +6877,13 @@ var init_handler = __esm({
|
|
|
6843
6877
|
* @param depth Child path actually targeted for watch
|
|
6844
6878
|
* @param target Child path actually targeted for watch
|
|
6845
6879
|
*/
|
|
6846
|
-
async _addToNodeFs(
|
|
6880
|
+
async _addToNodeFs(path16, initialAdd, priorWh, depth, target) {
|
|
6847
6881
|
const ready = this.fsw._emitReady;
|
|
6848
|
-
if (this.fsw._isIgnored(
|
|
6882
|
+
if (this.fsw._isIgnored(path16) || this.fsw.closed) {
|
|
6849
6883
|
ready();
|
|
6850
6884
|
return false;
|
|
6851
6885
|
}
|
|
6852
|
-
const wh = this.fsw._getWatchHelpers(
|
|
6886
|
+
const wh = this.fsw._getWatchHelpers(path16);
|
|
6853
6887
|
if (priorWh) {
|
|
6854
6888
|
wh.filterPath = (entry) => priorWh.filterPath(entry);
|
|
6855
6889
|
wh.filterDir = (entry) => priorWh.filterDir(entry);
|
|
@@ -6865,8 +6899,8 @@ var init_handler = __esm({
|
|
|
6865
6899
|
const follow = this.fsw.options.followSymlinks;
|
|
6866
6900
|
let closer;
|
|
6867
6901
|
if (stats.isDirectory()) {
|
|
6868
|
-
const absPath = sysPath.resolve(
|
|
6869
|
-
const targetPath = follow ? await fsrealpath(
|
|
6902
|
+
const absPath = sysPath.resolve(path16);
|
|
6903
|
+
const targetPath = follow ? await fsrealpath(path16) : path16;
|
|
6870
6904
|
if (this.fsw.closed)
|
|
6871
6905
|
return;
|
|
6872
6906
|
closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
|
|
@@ -6876,29 +6910,29 @@ var init_handler = __esm({
|
|
|
6876
6910
|
this.fsw._symlinkPaths.set(absPath, targetPath);
|
|
6877
6911
|
}
|
|
6878
6912
|
} else if (stats.isSymbolicLink()) {
|
|
6879
|
-
const targetPath = follow ? await fsrealpath(
|
|
6913
|
+
const targetPath = follow ? await fsrealpath(path16) : path16;
|
|
6880
6914
|
if (this.fsw.closed)
|
|
6881
6915
|
return;
|
|
6882
6916
|
const parent = sysPath.dirname(wh.watchPath);
|
|
6883
6917
|
this.fsw._getWatchedDir(parent).add(wh.watchPath);
|
|
6884
6918
|
this.fsw._emit(EV.ADD, wh.watchPath, stats);
|
|
6885
|
-
closer = await this._handleDir(parent, stats, initialAdd, depth,
|
|
6919
|
+
closer = await this._handleDir(parent, stats, initialAdd, depth, path16, wh, targetPath);
|
|
6886
6920
|
if (this.fsw.closed)
|
|
6887
6921
|
return;
|
|
6888
6922
|
if (targetPath !== void 0) {
|
|
6889
|
-
this.fsw._symlinkPaths.set(sysPath.resolve(
|
|
6923
|
+
this.fsw._symlinkPaths.set(sysPath.resolve(path16), targetPath);
|
|
6890
6924
|
}
|
|
6891
6925
|
} else {
|
|
6892
6926
|
closer = this._handleFile(wh.watchPath, stats, initialAdd);
|
|
6893
6927
|
}
|
|
6894
6928
|
ready();
|
|
6895
6929
|
if (closer)
|
|
6896
|
-
this.fsw._addPathCloser(
|
|
6930
|
+
this.fsw._addPathCloser(path16, closer);
|
|
6897
6931
|
return false;
|
|
6898
6932
|
} catch (error) {
|
|
6899
6933
|
if (this.fsw._handleError(error)) {
|
|
6900
6934
|
ready();
|
|
6901
|
-
return
|
|
6935
|
+
return path16;
|
|
6902
6936
|
}
|
|
6903
6937
|
}
|
|
6904
6938
|
}
|
|
@@ -6944,26 +6978,26 @@ function createPattern(matcher) {
|
|
|
6944
6978
|
}
|
|
6945
6979
|
return () => false;
|
|
6946
6980
|
}
|
|
6947
|
-
function normalizePath(
|
|
6948
|
-
if (typeof
|
|
6981
|
+
function normalizePath(path16) {
|
|
6982
|
+
if (typeof path16 !== "string")
|
|
6949
6983
|
throw new Error("string expected");
|
|
6950
|
-
|
|
6951
|
-
|
|
6984
|
+
path16 = sysPath2.normalize(path16);
|
|
6985
|
+
path16 = path16.replace(/\\/g, "/");
|
|
6952
6986
|
let prepend = false;
|
|
6953
|
-
if (
|
|
6987
|
+
if (path16.startsWith("//"))
|
|
6954
6988
|
prepend = true;
|
|
6955
6989
|
const DOUBLE_SLASH_RE2 = /\/\//;
|
|
6956
|
-
while (
|
|
6957
|
-
|
|
6990
|
+
while (path16.match(DOUBLE_SLASH_RE2))
|
|
6991
|
+
path16 = path16.replace(DOUBLE_SLASH_RE2, "/");
|
|
6958
6992
|
if (prepend)
|
|
6959
|
-
|
|
6960
|
-
return
|
|
6993
|
+
path16 = "/" + path16;
|
|
6994
|
+
return path16;
|
|
6961
6995
|
}
|
|
6962
6996
|
function matchPatterns(patterns, testString, stats) {
|
|
6963
|
-
const
|
|
6997
|
+
const path16 = normalizePath(testString);
|
|
6964
6998
|
for (let index2 = 0; index2 < patterns.length; index2++) {
|
|
6965
6999
|
const pattern = patterns[index2];
|
|
6966
|
-
if (pattern(
|
|
7000
|
+
if (pattern(path16, stats)) {
|
|
6967
7001
|
return true;
|
|
6968
7002
|
}
|
|
6969
7003
|
}
|
|
@@ -7024,19 +7058,19 @@ var init_esm2 = __esm({
|
|
|
7024
7058
|
}
|
|
7025
7059
|
return str2;
|
|
7026
7060
|
};
|
|
7027
|
-
normalizePathToUnix = (
|
|
7028
|
-
normalizeIgnored = (cwd = "") => (
|
|
7029
|
-
if (typeof
|
|
7030
|
-
return normalizePathToUnix(sysPath2.isAbsolute(
|
|
7061
|
+
normalizePathToUnix = (path16) => toUnix(sysPath2.normalize(toUnix(path16)));
|
|
7062
|
+
normalizeIgnored = (cwd = "") => (path16) => {
|
|
7063
|
+
if (typeof path16 === "string") {
|
|
7064
|
+
return normalizePathToUnix(sysPath2.isAbsolute(path16) ? path16 : sysPath2.join(cwd, path16));
|
|
7031
7065
|
} else {
|
|
7032
|
-
return
|
|
7066
|
+
return path16;
|
|
7033
7067
|
}
|
|
7034
7068
|
};
|
|
7035
|
-
getAbsolutePath = (
|
|
7036
|
-
if (sysPath2.isAbsolute(
|
|
7037
|
-
return
|
|
7069
|
+
getAbsolutePath = (path16, cwd) => {
|
|
7070
|
+
if (sysPath2.isAbsolute(path16)) {
|
|
7071
|
+
return path16;
|
|
7038
7072
|
}
|
|
7039
|
-
return sysPath2.join(cwd,
|
|
7073
|
+
return sysPath2.join(cwd, path16);
|
|
7040
7074
|
};
|
|
7041
7075
|
EMPTY_SET = Object.freeze(/* @__PURE__ */ new Set());
|
|
7042
7076
|
DirEntry = class {
|
|
@@ -7091,10 +7125,10 @@ var init_esm2 = __esm({
|
|
|
7091
7125
|
STAT_METHOD_F = "stat";
|
|
7092
7126
|
STAT_METHOD_L = "lstat";
|
|
7093
7127
|
WatchHelper = class {
|
|
7094
|
-
constructor(
|
|
7128
|
+
constructor(path16, follow, fsw) {
|
|
7095
7129
|
this.fsw = fsw;
|
|
7096
|
-
const watchPath =
|
|
7097
|
-
this.path =
|
|
7130
|
+
const watchPath = path16;
|
|
7131
|
+
this.path = path16 = path16.replace(REPLACER_RE, "");
|
|
7098
7132
|
this.watchPath = watchPath;
|
|
7099
7133
|
this.fullWatchPath = sysPath2.resolve(watchPath);
|
|
7100
7134
|
this.dirParts = [];
|
|
@@ -7216,20 +7250,20 @@ var init_esm2 = __esm({
|
|
|
7216
7250
|
this._closePromise = void 0;
|
|
7217
7251
|
let paths = unifyPaths(paths_);
|
|
7218
7252
|
if (cwd) {
|
|
7219
|
-
paths = paths.map((
|
|
7220
|
-
const absPath = getAbsolutePath(
|
|
7253
|
+
paths = paths.map((path16) => {
|
|
7254
|
+
const absPath = getAbsolutePath(path16, cwd);
|
|
7221
7255
|
return absPath;
|
|
7222
7256
|
});
|
|
7223
7257
|
}
|
|
7224
|
-
paths.forEach((
|
|
7225
|
-
this._removeIgnoredPath(
|
|
7258
|
+
paths.forEach((path16) => {
|
|
7259
|
+
this._removeIgnoredPath(path16);
|
|
7226
7260
|
});
|
|
7227
7261
|
this._userIgnored = void 0;
|
|
7228
7262
|
if (!this._readyCount)
|
|
7229
7263
|
this._readyCount = 0;
|
|
7230
7264
|
this._readyCount += paths.length;
|
|
7231
|
-
Promise.all(paths.map(async (
|
|
7232
|
-
const res = await this._nodeFsHandler._addToNodeFs(
|
|
7265
|
+
Promise.all(paths.map(async (path16) => {
|
|
7266
|
+
const res = await this._nodeFsHandler._addToNodeFs(path16, !_internal, void 0, 0, _origAdd);
|
|
7233
7267
|
if (res)
|
|
7234
7268
|
this._emitReady();
|
|
7235
7269
|
return res;
|
|
@@ -7251,17 +7285,17 @@ var init_esm2 = __esm({
|
|
|
7251
7285
|
return this;
|
|
7252
7286
|
const paths = unifyPaths(paths_);
|
|
7253
7287
|
const { cwd } = this.options;
|
|
7254
|
-
paths.forEach((
|
|
7255
|
-
if (!sysPath2.isAbsolute(
|
|
7288
|
+
paths.forEach((path16) => {
|
|
7289
|
+
if (!sysPath2.isAbsolute(path16) && !this._closers.has(path16)) {
|
|
7256
7290
|
if (cwd)
|
|
7257
|
-
|
|
7258
|
-
|
|
7291
|
+
path16 = sysPath2.join(cwd, path16);
|
|
7292
|
+
path16 = sysPath2.resolve(path16);
|
|
7259
7293
|
}
|
|
7260
|
-
this._closePath(
|
|
7261
|
-
this._addIgnoredPath(
|
|
7262
|
-
if (this._watched.has(
|
|
7294
|
+
this._closePath(path16);
|
|
7295
|
+
this._addIgnoredPath(path16);
|
|
7296
|
+
if (this._watched.has(path16)) {
|
|
7263
7297
|
this._addIgnoredPath({
|
|
7264
|
-
path:
|
|
7298
|
+
path: path16,
|
|
7265
7299
|
recursive: true
|
|
7266
7300
|
});
|
|
7267
7301
|
}
|
|
@@ -7325,38 +7359,38 @@ var init_esm2 = __esm({
|
|
|
7325
7359
|
* @param stats arguments to be passed with event
|
|
7326
7360
|
* @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag
|
|
7327
7361
|
*/
|
|
7328
|
-
async _emit(event,
|
|
7362
|
+
async _emit(event, path16, stats) {
|
|
7329
7363
|
if (this.closed)
|
|
7330
7364
|
return;
|
|
7331
7365
|
const opts = this.options;
|
|
7332
7366
|
if (isWindows)
|
|
7333
|
-
|
|
7367
|
+
path16 = sysPath2.normalize(path16);
|
|
7334
7368
|
if (opts.cwd)
|
|
7335
|
-
|
|
7336
|
-
const args = [
|
|
7369
|
+
path16 = sysPath2.relative(opts.cwd, path16);
|
|
7370
|
+
const args = [path16];
|
|
7337
7371
|
if (stats != null)
|
|
7338
7372
|
args.push(stats);
|
|
7339
7373
|
const awf = opts.awaitWriteFinish;
|
|
7340
7374
|
let pw;
|
|
7341
|
-
if (awf && (pw = this._pendingWrites.get(
|
|
7375
|
+
if (awf && (pw = this._pendingWrites.get(path16))) {
|
|
7342
7376
|
pw.lastChange = /* @__PURE__ */ new Date();
|
|
7343
7377
|
return this;
|
|
7344
7378
|
}
|
|
7345
7379
|
if (opts.atomic) {
|
|
7346
7380
|
if (event === EVENTS.UNLINK) {
|
|
7347
|
-
this._pendingUnlinks.set(
|
|
7381
|
+
this._pendingUnlinks.set(path16, [event, ...args]);
|
|
7348
7382
|
setTimeout(() => {
|
|
7349
|
-
this._pendingUnlinks.forEach((entry,
|
|
7383
|
+
this._pendingUnlinks.forEach((entry, path17) => {
|
|
7350
7384
|
this.emit(...entry);
|
|
7351
7385
|
this.emit(EVENTS.ALL, ...entry);
|
|
7352
|
-
this._pendingUnlinks.delete(
|
|
7386
|
+
this._pendingUnlinks.delete(path17);
|
|
7353
7387
|
});
|
|
7354
7388
|
}, typeof opts.atomic === "number" ? opts.atomic : 100);
|
|
7355
7389
|
return this;
|
|
7356
7390
|
}
|
|
7357
|
-
if (event === EVENTS.ADD && this._pendingUnlinks.has(
|
|
7391
|
+
if (event === EVENTS.ADD && this._pendingUnlinks.has(path16)) {
|
|
7358
7392
|
event = EVENTS.CHANGE;
|
|
7359
|
-
this._pendingUnlinks.delete(
|
|
7393
|
+
this._pendingUnlinks.delete(path16);
|
|
7360
7394
|
}
|
|
7361
7395
|
}
|
|
7362
7396
|
if (awf && (event === EVENTS.ADD || event === EVENTS.CHANGE) && this._readyEmitted) {
|
|
@@ -7374,16 +7408,16 @@ var init_esm2 = __esm({
|
|
|
7374
7408
|
this.emitWithAll(event, args);
|
|
7375
7409
|
}
|
|
7376
7410
|
};
|
|
7377
|
-
this._awaitWriteFinish(
|
|
7411
|
+
this._awaitWriteFinish(path16, awf.stabilityThreshold, event, awfEmit);
|
|
7378
7412
|
return this;
|
|
7379
7413
|
}
|
|
7380
7414
|
if (event === EVENTS.CHANGE) {
|
|
7381
|
-
const isThrottled = !this._throttle(EVENTS.CHANGE,
|
|
7415
|
+
const isThrottled = !this._throttle(EVENTS.CHANGE, path16, 50);
|
|
7382
7416
|
if (isThrottled)
|
|
7383
7417
|
return this;
|
|
7384
7418
|
}
|
|
7385
7419
|
if (opts.alwaysStat && stats === void 0 && (event === EVENTS.ADD || event === EVENTS.ADD_DIR || event === EVENTS.CHANGE)) {
|
|
7386
|
-
const fullPath = opts.cwd ? sysPath2.join(opts.cwd,
|
|
7420
|
+
const fullPath = opts.cwd ? sysPath2.join(opts.cwd, path16) : path16;
|
|
7387
7421
|
let stats2;
|
|
7388
7422
|
try {
|
|
7389
7423
|
stats2 = await stat3(fullPath);
|
|
@@ -7414,23 +7448,23 @@ var init_esm2 = __esm({
|
|
|
7414
7448
|
* @param timeout duration of time to suppress duplicate actions
|
|
7415
7449
|
* @returns tracking object or false if action should be suppressed
|
|
7416
7450
|
*/
|
|
7417
|
-
_throttle(actionType,
|
|
7451
|
+
_throttle(actionType, path16, timeout) {
|
|
7418
7452
|
if (!this._throttled.has(actionType)) {
|
|
7419
7453
|
this._throttled.set(actionType, /* @__PURE__ */ new Map());
|
|
7420
7454
|
}
|
|
7421
7455
|
const action = this._throttled.get(actionType);
|
|
7422
7456
|
if (!action)
|
|
7423
7457
|
throw new Error("invalid throttle");
|
|
7424
|
-
const actionPath = action.get(
|
|
7458
|
+
const actionPath = action.get(path16);
|
|
7425
7459
|
if (actionPath) {
|
|
7426
7460
|
actionPath.count++;
|
|
7427
7461
|
return false;
|
|
7428
7462
|
}
|
|
7429
7463
|
let timeoutObject;
|
|
7430
7464
|
const clear = () => {
|
|
7431
|
-
const item = action.get(
|
|
7465
|
+
const item = action.get(path16);
|
|
7432
7466
|
const count2 = item ? item.count : 0;
|
|
7433
|
-
action.delete(
|
|
7467
|
+
action.delete(path16);
|
|
7434
7468
|
clearTimeout(timeoutObject);
|
|
7435
7469
|
if (item)
|
|
7436
7470
|
clearTimeout(item.timeoutObject);
|
|
@@ -7438,7 +7472,7 @@ var init_esm2 = __esm({
|
|
|
7438
7472
|
};
|
|
7439
7473
|
timeoutObject = setTimeout(clear, timeout);
|
|
7440
7474
|
const thr = { timeoutObject, clear, count: 0 };
|
|
7441
|
-
action.set(
|
|
7475
|
+
action.set(path16, thr);
|
|
7442
7476
|
return thr;
|
|
7443
7477
|
}
|
|
7444
7478
|
_incrReadyCount() {
|
|
@@ -7452,44 +7486,44 @@ var init_esm2 = __esm({
|
|
|
7452
7486
|
* @param event
|
|
7453
7487
|
* @param awfEmit Callback to be called when ready for event to be emitted.
|
|
7454
7488
|
*/
|
|
7455
|
-
_awaitWriteFinish(
|
|
7489
|
+
_awaitWriteFinish(path16, threshold, event, awfEmit) {
|
|
7456
7490
|
const awf = this.options.awaitWriteFinish;
|
|
7457
7491
|
if (typeof awf !== "object")
|
|
7458
7492
|
return;
|
|
7459
7493
|
const pollInterval = awf.pollInterval;
|
|
7460
7494
|
let timeoutHandler;
|
|
7461
|
-
let fullPath =
|
|
7462
|
-
if (this.options.cwd && !sysPath2.isAbsolute(
|
|
7463
|
-
fullPath = sysPath2.join(this.options.cwd,
|
|
7495
|
+
let fullPath = path16;
|
|
7496
|
+
if (this.options.cwd && !sysPath2.isAbsolute(path16)) {
|
|
7497
|
+
fullPath = sysPath2.join(this.options.cwd, path16);
|
|
7464
7498
|
}
|
|
7465
7499
|
const now = /* @__PURE__ */ new Date();
|
|
7466
7500
|
const writes = this._pendingWrites;
|
|
7467
7501
|
function awaitWriteFinishFn(prevStat) {
|
|
7468
7502
|
statcb(fullPath, (err, curStat) => {
|
|
7469
|
-
if (err || !writes.has(
|
|
7503
|
+
if (err || !writes.has(path16)) {
|
|
7470
7504
|
if (err && err.code !== "ENOENT")
|
|
7471
7505
|
awfEmit(err);
|
|
7472
7506
|
return;
|
|
7473
7507
|
}
|
|
7474
7508
|
const now2 = Number(/* @__PURE__ */ new Date());
|
|
7475
7509
|
if (prevStat && curStat.size !== prevStat.size) {
|
|
7476
|
-
writes.get(
|
|
7510
|
+
writes.get(path16).lastChange = now2;
|
|
7477
7511
|
}
|
|
7478
|
-
const pw = writes.get(
|
|
7512
|
+
const pw = writes.get(path16);
|
|
7479
7513
|
const df = now2 - pw.lastChange;
|
|
7480
7514
|
if (df >= threshold) {
|
|
7481
|
-
writes.delete(
|
|
7515
|
+
writes.delete(path16);
|
|
7482
7516
|
awfEmit(void 0, curStat);
|
|
7483
7517
|
} else {
|
|
7484
7518
|
timeoutHandler = setTimeout(awaitWriteFinishFn, pollInterval, curStat);
|
|
7485
7519
|
}
|
|
7486
7520
|
});
|
|
7487
7521
|
}
|
|
7488
|
-
if (!writes.has(
|
|
7489
|
-
writes.set(
|
|
7522
|
+
if (!writes.has(path16)) {
|
|
7523
|
+
writes.set(path16, {
|
|
7490
7524
|
lastChange: now,
|
|
7491
7525
|
cancelWait: () => {
|
|
7492
|
-
writes.delete(
|
|
7526
|
+
writes.delete(path16);
|
|
7493
7527
|
clearTimeout(timeoutHandler);
|
|
7494
7528
|
return event;
|
|
7495
7529
|
}
|
|
@@ -7500,8 +7534,8 @@ var init_esm2 = __esm({
|
|
|
7500
7534
|
/**
|
|
7501
7535
|
* Determines whether user has asked to ignore this path.
|
|
7502
7536
|
*/
|
|
7503
|
-
_isIgnored(
|
|
7504
|
-
if (this.options.atomic && DOT_RE.test(
|
|
7537
|
+
_isIgnored(path16, stats) {
|
|
7538
|
+
if (this.options.atomic && DOT_RE.test(path16))
|
|
7505
7539
|
return true;
|
|
7506
7540
|
if (!this._userIgnored) {
|
|
7507
7541
|
const { cwd } = this.options;
|
|
@@ -7511,17 +7545,17 @@ var init_esm2 = __esm({
|
|
|
7511
7545
|
const list = [...ignoredPaths.map(normalizeIgnored(cwd)), ...ignored];
|
|
7512
7546
|
this._userIgnored = anymatch(list, void 0);
|
|
7513
7547
|
}
|
|
7514
|
-
return this._userIgnored(
|
|
7548
|
+
return this._userIgnored(path16, stats);
|
|
7515
7549
|
}
|
|
7516
|
-
_isntIgnored(
|
|
7517
|
-
return !this._isIgnored(
|
|
7550
|
+
_isntIgnored(path16, stat4) {
|
|
7551
|
+
return !this._isIgnored(path16, stat4);
|
|
7518
7552
|
}
|
|
7519
7553
|
/**
|
|
7520
7554
|
* Provides a set of common helpers and properties relating to symlink handling.
|
|
7521
7555
|
* @param path file or directory pattern being watched
|
|
7522
7556
|
*/
|
|
7523
|
-
_getWatchHelpers(
|
|
7524
|
-
return new WatchHelper(
|
|
7557
|
+
_getWatchHelpers(path16) {
|
|
7558
|
+
return new WatchHelper(path16, this.options.followSymlinks, this);
|
|
7525
7559
|
}
|
|
7526
7560
|
// Directory helpers
|
|
7527
7561
|
// -----------------
|
|
@@ -7553,63 +7587,63 @@ var init_esm2 = __esm({
|
|
|
7553
7587
|
* @param item base path of item/directory
|
|
7554
7588
|
*/
|
|
7555
7589
|
_remove(directory, item, isDirectory) {
|
|
7556
|
-
const
|
|
7557
|
-
const fullPath = sysPath2.resolve(
|
|
7558
|
-
isDirectory = isDirectory != null ? isDirectory : this._watched.has(
|
|
7559
|
-
if (!this._throttle("remove",
|
|
7590
|
+
const path16 = sysPath2.join(directory, item);
|
|
7591
|
+
const fullPath = sysPath2.resolve(path16);
|
|
7592
|
+
isDirectory = isDirectory != null ? isDirectory : this._watched.has(path16) || this._watched.has(fullPath);
|
|
7593
|
+
if (!this._throttle("remove", path16, 100))
|
|
7560
7594
|
return;
|
|
7561
7595
|
if (!isDirectory && this._watched.size === 1) {
|
|
7562
7596
|
this.add(directory, item, true);
|
|
7563
7597
|
}
|
|
7564
|
-
const wp = this._getWatchedDir(
|
|
7598
|
+
const wp = this._getWatchedDir(path16);
|
|
7565
7599
|
const nestedDirectoryChildren = wp.getChildren();
|
|
7566
|
-
nestedDirectoryChildren.forEach((nested) => this._remove(
|
|
7600
|
+
nestedDirectoryChildren.forEach((nested) => this._remove(path16, nested));
|
|
7567
7601
|
const parent = this._getWatchedDir(directory);
|
|
7568
7602
|
const wasTracked = parent.has(item);
|
|
7569
7603
|
parent.remove(item);
|
|
7570
7604
|
if (this._symlinkPaths.has(fullPath)) {
|
|
7571
7605
|
this._symlinkPaths.delete(fullPath);
|
|
7572
7606
|
}
|
|
7573
|
-
let relPath =
|
|
7607
|
+
let relPath = path16;
|
|
7574
7608
|
if (this.options.cwd)
|
|
7575
|
-
relPath = sysPath2.relative(this.options.cwd,
|
|
7609
|
+
relPath = sysPath2.relative(this.options.cwd, path16);
|
|
7576
7610
|
if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) {
|
|
7577
7611
|
const event = this._pendingWrites.get(relPath).cancelWait();
|
|
7578
7612
|
if (event === EVENTS.ADD)
|
|
7579
7613
|
return;
|
|
7580
7614
|
}
|
|
7581
|
-
this._watched.delete(
|
|
7615
|
+
this._watched.delete(path16);
|
|
7582
7616
|
this._watched.delete(fullPath);
|
|
7583
7617
|
const eventName = isDirectory ? EVENTS.UNLINK_DIR : EVENTS.UNLINK;
|
|
7584
|
-
if (wasTracked && !this._isIgnored(
|
|
7585
|
-
this._emit(eventName,
|
|
7586
|
-
this._closePath(
|
|
7618
|
+
if (wasTracked && !this._isIgnored(path16))
|
|
7619
|
+
this._emit(eventName, path16);
|
|
7620
|
+
this._closePath(path16);
|
|
7587
7621
|
}
|
|
7588
7622
|
/**
|
|
7589
7623
|
* Closes all watchers for a path
|
|
7590
7624
|
*/
|
|
7591
|
-
_closePath(
|
|
7592
|
-
this._closeFile(
|
|
7593
|
-
const dir = sysPath2.dirname(
|
|
7594
|
-
this._getWatchedDir(dir).remove(sysPath2.basename(
|
|
7625
|
+
_closePath(path16) {
|
|
7626
|
+
this._closeFile(path16);
|
|
7627
|
+
const dir = sysPath2.dirname(path16);
|
|
7628
|
+
this._getWatchedDir(dir).remove(sysPath2.basename(path16));
|
|
7595
7629
|
}
|
|
7596
7630
|
/**
|
|
7597
7631
|
* Closes only file-specific watchers
|
|
7598
7632
|
*/
|
|
7599
|
-
_closeFile(
|
|
7600
|
-
const closers = this._closers.get(
|
|
7633
|
+
_closeFile(path16) {
|
|
7634
|
+
const closers = this._closers.get(path16);
|
|
7601
7635
|
if (!closers)
|
|
7602
7636
|
return;
|
|
7603
7637
|
closers.forEach((closer) => closer());
|
|
7604
|
-
this._closers.delete(
|
|
7638
|
+
this._closers.delete(path16);
|
|
7605
7639
|
}
|
|
7606
|
-
_addPathCloser(
|
|
7640
|
+
_addPathCloser(path16, closer) {
|
|
7607
7641
|
if (!closer)
|
|
7608
7642
|
return;
|
|
7609
|
-
let list = this._closers.get(
|
|
7643
|
+
let list = this._closers.get(path16);
|
|
7610
7644
|
if (!list) {
|
|
7611
7645
|
list = [];
|
|
7612
|
-
this._closers.set(
|
|
7646
|
+
this._closers.set(path16, list);
|
|
7613
7647
|
}
|
|
7614
7648
|
list.push(closer);
|
|
7615
7649
|
}
|
|
@@ -7636,8 +7670,8 @@ var init_esm2 = __esm({
|
|
|
7636
7670
|
});
|
|
7637
7671
|
|
|
7638
7672
|
// spex-console/bin/hs-vault-pull.ts
|
|
7639
|
-
import { readFileSync as
|
|
7640
|
-
import
|
|
7673
|
+
import { readFileSync as readFileSync15 } from "node:fs";
|
|
7674
|
+
import path15 from "node:path";
|
|
7641
7675
|
import process4 from "node:process";
|
|
7642
7676
|
|
|
7643
7677
|
// spex-console/src/lib/cli/control-shared.ts
|
|
@@ -7647,14 +7681,14 @@ init_credentials();
|
|
|
7647
7681
|
init_session_owner();
|
|
7648
7682
|
init_vault_less_endpoints();
|
|
7649
7683
|
init_registry_file();
|
|
7650
|
-
import
|
|
7684
|
+
import path2 from "node:path";
|
|
7651
7685
|
var VAULT_ID_HEADER = "x-heyspex-vault-id";
|
|
7652
7686
|
var ACCOUNT_ID_HEADER = "x-heyspex-account-id";
|
|
7653
|
-
function scopeHeadersFor(scope, method,
|
|
7687
|
+
function scopeHeadersFor(scope, method, path16) {
|
|
7654
7688
|
if (scope === "none") {
|
|
7655
|
-
if (!isVaultLessEndpoint(method,
|
|
7689
|
+
if (!isVaultLessEndpoint(method, path16)) {
|
|
7656
7690
|
throw new Error(
|
|
7657
|
-
`controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${
|
|
7691
|
+
`controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${path16} is vault-scoped and must name { accountId, vaultId }.`
|
|
7658
7692
|
);
|
|
7659
7693
|
}
|
|
7660
7694
|
return {};
|
|
@@ -7665,7 +7699,7 @@ function cloudRequestScope(scope) {
|
|
|
7665
7699
|
const named = { accountId: scope.accountId, vaultId: scope.vaultId };
|
|
7666
7700
|
return {
|
|
7667
7701
|
...named,
|
|
7668
|
-
headersFor: (method,
|
|
7702
|
+
headersFor: (method, path16) => isVaultLessEndpoint(method, path16) ? {} : scopeHeadersFor(named, method, path16)
|
|
7669
7703
|
};
|
|
7670
7704
|
}
|
|
7671
7705
|
|
|
@@ -7704,12 +7738,15 @@ var HELP = [
|
|
|
7704
7738
|
"(spex-console/src/lib/cli/template-manifest.ts) \u2014 universal docs",
|
|
7705
7739
|
"copied verbatim, template-shape docs written as author-prompt skeletons \u2014",
|
|
7706
7740
|
"plus a generated CLAUDE.md, the kept-principles index, and the template_version",
|
|
7707
|
-
"pin; with --git, one initial `git init` + commit.
|
|
7708
|
-
"holds heyspex.yaml
|
|
7709
|
-
"
|
|
7710
|
-
"
|
|
7711
|
-
"
|
|
7712
|
-
"
|
|
7741
|
+
"pin; with --git, one initial `git init` + commit. On an EXISTING vault (<dir>",
|
|
7742
|
+
"holds heyspex.yaml with a vault_id) it is a REFRESH \u2014 the repair `hs doctor`'s",
|
|
7743
|
+
"vault-template row names: only missing shipped files are added, template_version",
|
|
7744
|
+
"is written/updated in heyspex.yaml (every other byte and the vault_id kept),",
|
|
7745
|
+
"nothing existing is ever overwritten (an existing CLAUDE.md gets a",
|
|
7746
|
+
"CLAUDE.md.template beside it), the result lists each manifest row as created or",
|
|
7747
|
+
"kept, and a second run writes nothing. <dir> may be any path (a satellite repo",
|
|
7748
|
+
"names its vault, e.g. `hs init --customer-vault ../my-specs`). Refuses only a",
|
|
7749
|
+
"non-empty <dir> that has no heyspex.yaml. See init.customer-vault.ts.",
|
|
7713
7750
|
"",
|
|
7714
7751
|
"Flags:",
|
|
7715
7752
|
" --console-url <url> console_url value (default: the mode-aware console --",
|
|
@@ -7769,7 +7806,8 @@ var PULL_HELP = [
|
|
|
7769
7806
|
" 0 Done (or plan reported)",
|
|
7770
7807
|
" 1 Runtime failure (unreadable source, a spec failed to write)",
|
|
7771
7808
|
" 2 Usage error",
|
|
7772
|
-
" 11 No vault could be resolved, or --apply would write another vault into this repo",
|
|
7809
|
+
" 11 No vault could be resolved, or --apply would write another vault into this repo,",
|
|
7810
|
+
" or this repo is a satellite / repo-binding code repo (its specs/ live in the vault)",
|
|
7773
7811
|
"",
|
|
7774
7812
|
"Without --push: cloud \u2192 disk only; never deletes. A spec already on disk is",
|
|
7775
7813
|
"skipped and reported, except one the last sync wrote and nobody edited since",
|
|
@@ -7883,7 +7921,7 @@ init_console_fetch();
|
|
|
7883
7921
|
init_registry_file();
|
|
7884
7922
|
init_repo_identity();
|
|
7885
7923
|
import { promises as fs } from "node:fs";
|
|
7886
|
-
import
|
|
7924
|
+
import path4 from "node:path";
|
|
7887
7925
|
init_vault_workspace_shared();
|
|
7888
7926
|
var SYNC_VAULT_EXIT_UNRESOLVED = 11;
|
|
7889
7927
|
function refuse(message) {
|
|
@@ -7934,7 +7972,7 @@ async function resolveSyncVaultTargetFromEnv(deps) {
|
|
|
7934
7972
|
let markerVaultId = null;
|
|
7935
7973
|
try {
|
|
7936
7974
|
markerVaultId = parseVaultId(
|
|
7937
|
-
await fs.readFile(
|
|
7975
|
+
await fs.readFile(path4.join(deps.vaultRoot, "heyspex.yaml"), "utf8")
|
|
7938
7976
|
);
|
|
7939
7977
|
} catch {
|
|
7940
7978
|
markerVaultId = null;
|
|
@@ -8126,6 +8164,28 @@ function watchDirtyMarker(vaultRoot2, onDirty, { debounceMs = 100 } = {}) {
|
|
|
8126
8164
|
}
|
|
8127
8165
|
|
|
8128
8166
|
// spex-console/src/lib/vault-sync/pull.ts
|
|
8167
|
+
function detectEol(text2) {
|
|
8168
|
+
const crlf = (text2.match(/\r\n/g) ?? []).length;
|
|
8169
|
+
const all = (text2.match(/\n/g) ?? []).length;
|
|
8170
|
+
if (all === 0) return null;
|
|
8171
|
+
return crlf * 2 >= all ? "\r\n" : "\n";
|
|
8172
|
+
}
|
|
8173
|
+
function normalizeEol(text2, eol) {
|
|
8174
|
+
return text2.replace(/\r\n|\r|\n/g, eol);
|
|
8175
|
+
}
|
|
8176
|
+
function classifyHeyspexYaml(text2) {
|
|
8177
|
+
if (text2 === null) return "none";
|
|
8178
|
+
if (/^vault_path:[ \t]*[^\s#]/m.test(text2)) return "satellite";
|
|
8179
|
+
if (/^kind:[ \t]*["']?repo-binding["']?[ \t]*$/m.test(text2)) return "repo-binding";
|
|
8180
|
+
const markerKey = /^(vault_id|vault_root):/m.test(text2);
|
|
8181
|
+
if (!markerKey && /^vault:/m.test(text2)) return "repo-binding";
|
|
8182
|
+
return "vault";
|
|
8183
|
+
}
|
|
8184
|
+
function pullTargetRefusal(repoRoot, markerText) {
|
|
8185
|
+
const kind = classifyHeyspexYaml(markerText);
|
|
8186
|
+
if (kind !== "satellite" && kind !== "repo-binding") return null;
|
|
8187
|
+
return `refusing to write specs/ into ${repoRoot}: its heyspex.yaml is a ${kind} marker (a code repo that names its vault elsewhere), not a vault checkout. Nothing was written. Run \`hs pull\` inside the vault's own checkout (\`hs vault resolve\` shows which one this repo is bound to).`;
|
|
8188
|
+
}
|
|
8129
8189
|
function normalizeSpecRelPath(raw) {
|
|
8130
8190
|
if (typeof raw !== "string") return null;
|
|
8131
8191
|
let p = raw.trim();
|
|
@@ -8157,11 +8217,11 @@ function selectRemoteRefs(remote, only) {
|
|
|
8157
8217
|
const selected = [];
|
|
8158
8218
|
for (const ref of remote) {
|
|
8159
8219
|
const id = (ref.id ?? "").toLowerCase();
|
|
8160
|
-
const
|
|
8220
|
+
const basename5 = (ref.basename ?? "").toLowerCase();
|
|
8161
8221
|
let hit = null;
|
|
8162
8222
|
for (const sel of selectors) {
|
|
8163
8223
|
const s = sel.toLowerCase();
|
|
8164
|
-
if (id === s ||
|
|
8224
|
+
if (id === s || basename5 === s || id.startsWith(`${s}-`) || basename5.startsWith(`${s}-`)) {
|
|
8165
8225
|
hit = sel;
|
|
8166
8226
|
break;
|
|
8167
8227
|
}
|
|
@@ -8212,7 +8272,7 @@ function decidePullPlan({
|
|
|
8212
8272
|
});
|
|
8213
8273
|
continue;
|
|
8214
8274
|
}
|
|
8215
|
-
const
|
|
8275
|
+
const basename5 = basenameOfRelPath(relPath);
|
|
8216
8276
|
if (hasDotSegment(relPath)) {
|
|
8217
8277
|
skip2.push({
|
|
8218
8278
|
id: ref.id,
|
|
@@ -8228,7 +8288,7 @@ function decidePullPlan({
|
|
|
8228
8288
|
pull.push({
|
|
8229
8289
|
id: ref.id,
|
|
8230
8290
|
relPath,
|
|
8231
|
-
basename:
|
|
8291
|
+
basename: basename5,
|
|
8232
8292
|
overwrites: true,
|
|
8233
8293
|
remoteUpdatedAt: ref.updatedAt ?? void 0
|
|
8234
8294
|
});
|
|
@@ -8236,7 +8296,7 @@ function decidePullPlan({
|
|
|
8236
8296
|
pull.push({
|
|
8237
8297
|
id: ref.id,
|
|
8238
8298
|
relPath,
|
|
8239
|
-
basename:
|
|
8299
|
+
basename: basename5,
|
|
8240
8300
|
overwrites: true,
|
|
8241
8301
|
remoteUpdatedAt: ref.updatedAt ?? void 0,
|
|
8242
8302
|
fastForwardFromHash: ffHash
|
|
@@ -8246,7 +8306,7 @@ function decidePullPlan({
|
|
|
8246
8306
|
}
|
|
8247
8307
|
continue;
|
|
8248
8308
|
}
|
|
8249
|
-
const elsewhere = localByBasename.get(
|
|
8309
|
+
const elsewhere = localByBasename.get(basename5.toLowerCase());
|
|
8250
8310
|
if (elsewhere) {
|
|
8251
8311
|
skip2.push({
|
|
8252
8312
|
id: ref.id,
|
|
@@ -8259,7 +8319,7 @@ function decidePullPlan({
|
|
|
8259
8319
|
pull.push({
|
|
8260
8320
|
id: ref.id,
|
|
8261
8321
|
relPath,
|
|
8262
|
-
basename:
|
|
8322
|
+
basename: basename5,
|
|
8263
8323
|
overwrites: false,
|
|
8264
8324
|
remoteUpdatedAt: ref.updatedAt ?? void 0
|
|
8265
8325
|
});
|
|
@@ -8320,7 +8380,8 @@ async function runVaultPull(deps, options2 = {}) {
|
|
|
8320
8380
|
});
|
|
8321
8381
|
continue;
|
|
8322
8382
|
}
|
|
8323
|
-
const
|
|
8383
|
+
const serialized = deps.serialize(content.body, content.frontmatter);
|
|
8384
|
+
const bytes = deps.eolFor ? normalizeEol(serialized, await deps.eolFor(item.relPath)) : serialized;
|
|
8324
8385
|
if (item.fastForwardFromHash && deps.hashLocal) {
|
|
8325
8386
|
const nowHash = await deps.hashLocal(item.relPath);
|
|
8326
8387
|
if (nowHash !== item.fastForwardFromHash) {
|
|
@@ -8434,16 +8495,17 @@ function formatPullSummary(result, { detail = false, sampleSize = 5 } = {}) {
|
|
|
8434
8495
|
}
|
|
8435
8496
|
|
|
8436
8497
|
// spex-console/src/lib/vault-sync/pull-io.ts
|
|
8437
|
-
import { promises as fs10 } from "node:fs";
|
|
8498
|
+
import { promises as fs10, readFileSync as readFileSync14 } from "node:fs";
|
|
8499
|
+
import { EOL } from "node:os";
|
|
8438
8500
|
import nodePath3 from "node:path";
|
|
8439
8501
|
|
|
8440
8502
|
// spex-console/src/lib/dev-mode.ts
|
|
8441
8503
|
init_heyspex_home2();
|
|
8442
8504
|
init_credentials();
|
|
8443
|
-
import { mkdirSync as
|
|
8505
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
8444
8506
|
import { join as join10 } from "node:path";
|
|
8445
8507
|
var CLOUD_CONSOLE_URL2 = "https://app.heyspex.com";
|
|
8446
|
-
var defaultReadFile = (p) =>
|
|
8508
|
+
var defaultReadFile = (p) => readFileSync11(p, "utf8");
|
|
8447
8509
|
function readCredentialsMcpToken({
|
|
8448
8510
|
homeDir = heyspexHome2(),
|
|
8449
8511
|
readFile = defaultReadFile
|
|
@@ -8461,6 +8523,30 @@ function readCredentialsMcpToken({
|
|
|
8461
8523
|
init_heyspex_home2();
|
|
8462
8524
|
init_vault();
|
|
8463
8525
|
init_vault_frontmatter();
|
|
8526
|
+
var DEFAULT_PULL_EOL = EOL === "\r\n" ? "\r\n" : "\n";
|
|
8527
|
+
async function eolForPath(abs, fallback = DEFAULT_PULL_EOL) {
|
|
8528
|
+
try {
|
|
8529
|
+
return detectEol(await fs10.readFile(abs, "utf8")) ?? fallback;
|
|
8530
|
+
} catch {
|
|
8531
|
+
return fallback;
|
|
8532
|
+
}
|
|
8533
|
+
}
|
|
8534
|
+
var PullTargetNotVaultError = class extends Error {
|
|
8535
|
+
constructor(message) {
|
|
8536
|
+
super(message);
|
|
8537
|
+
this.name = "PullTargetNotVaultError";
|
|
8538
|
+
}
|
|
8539
|
+
};
|
|
8540
|
+
function assertPullTargetIsVault(repoRoot) {
|
|
8541
|
+
let text2;
|
|
8542
|
+
try {
|
|
8543
|
+
text2 = readFileSync14(nodePath3.join(repoRoot, "heyspex.yaml"), "utf8");
|
|
8544
|
+
} catch {
|
|
8545
|
+
text2 = null;
|
|
8546
|
+
}
|
|
8547
|
+
const refusal = pullTargetRefusal(repoRoot, text2);
|
|
8548
|
+
if (refusal) throw new PullTargetNotVaultError(refusal);
|
|
8549
|
+
}
|
|
8464
8550
|
var LIST_FIELDS = "id,basename,relPath,type,status,updated,updatedAt";
|
|
8465
8551
|
var PULL_LIST_PAGE_LIMIT = 500;
|
|
8466
8552
|
var PULL_LIST_MAX_PAGES = 2e3;
|
|
@@ -8484,10 +8570,10 @@ function resolvePullSourceUrl(explicit) {
|
|
|
8484
8570
|
const raw = explicit?.trim() || process.env.HEYSPEX_PULL_SOURCE_URL?.trim() || CLOUD_CONSOLE_URL2;
|
|
8485
8571
|
return raw.replace(/\/+$/, "");
|
|
8486
8572
|
}
|
|
8487
|
-
async function getJson({ baseUrl, token, fetchImpl = fetch, scopeHeaders = {} },
|
|
8573
|
+
async function getJson({ baseUrl, token, fetchImpl = fetch, scopeHeaders = {} }, path16) {
|
|
8488
8574
|
const headers = { Accept: "application/json", ...scopeHeaders };
|
|
8489
8575
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
8490
|
-
const res = await fetchImpl(`${baseUrl}/${
|
|
8576
|
+
const res = await fetchImpl(`${baseUrl}/${path16.replace(/^\/+/, "")}`, { headers });
|
|
8491
8577
|
const text2 = await res.text();
|
|
8492
8578
|
let json = null;
|
|
8493
8579
|
try {
|
|
@@ -8652,6 +8738,12 @@ function createVaultPullDeps({
|
|
|
8652
8738
|
}) {
|
|
8653
8739
|
const http = { baseUrl, token, fetchImpl, scopeHeaders };
|
|
8654
8740
|
const prefetched = /* @__PURE__ */ new Map();
|
|
8741
|
+
let targetChecked = false;
|
|
8742
|
+
const guardTarget = () => {
|
|
8743
|
+
if (!localRoot || targetChecked) return;
|
|
8744
|
+
assertPullTargetIsVault(nodePath3.dirname(localRoot));
|
|
8745
|
+
targetChecked = true;
|
|
8746
|
+
};
|
|
8655
8747
|
return {
|
|
8656
8748
|
listRemote: () => listRemoteSpecs(http),
|
|
8657
8749
|
getRemoteRef: async (selector) => {
|
|
@@ -8673,7 +8765,9 @@ function createVaultPullDeps({
|
|
|
8673
8765
|
finish: ledger ? () => ledger.flush() : void 0,
|
|
8674
8766
|
listLocal: () => listLocalSpecRelPaths(localRoot ?? vaultRoot()),
|
|
8675
8767
|
serialize: stringifySpecMarkdown,
|
|
8768
|
+
eolFor: (relPath) => eolForPath(nodePath3.join(localRoot ?? vaultRoot(), relPath)),
|
|
8676
8769
|
writeSpec: localRoot ? async (relPath, content, opts) => {
|
|
8770
|
+
guardTarget();
|
|
8677
8771
|
const abs = nodePath3.join(localRoot, relPath);
|
|
8678
8772
|
await fs10.mkdir(nodePath3.dirname(abs), { recursive: true });
|
|
8679
8773
|
onLocalWrite?.(relPath);
|
|
@@ -8923,9 +9017,9 @@ async function runVaultPush(deps, options2 = {}) {
|
|
|
8923
9017
|
result.skipped.push(item(pre.reason, pre.detail));
|
|
8924
9018
|
continue;
|
|
8925
9019
|
}
|
|
8926
|
-
const
|
|
9020
|
+
const basename5 = basenameOfRelPath(relPath);
|
|
8927
9021
|
if (remoteIndex) {
|
|
8928
|
-
const stamp = remoteIndex.get(
|
|
9022
|
+
const stamp = remoteIndex.get(basename5.toLowerCase());
|
|
8929
9023
|
if (stamp === void 0) {
|
|
8930
9024
|
result.skipped.push(
|
|
8931
9025
|
item("new-on-disk", "no remote row - hs never creates cloud specs from a disk file")
|
|
@@ -8944,7 +9038,7 @@ async function runVaultPush(deps, options2 = {}) {
|
|
|
8944
9038
|
}
|
|
8945
9039
|
let remote;
|
|
8946
9040
|
try {
|
|
8947
|
-
remote = await deps.fetchRemote(
|
|
9041
|
+
remote = await deps.fetchRemote(basename5);
|
|
8948
9042
|
} catch (err) {
|
|
8949
9043
|
result.failed.push({
|
|
8950
9044
|
relPath,
|
|
@@ -8992,7 +9086,7 @@ async function runVaultPush(deps, options2 = {}) {
|
|
|
8992
9086
|
puts += 1;
|
|
8993
9087
|
let put;
|
|
8994
9088
|
try {
|
|
8995
|
-
put = await deps.putRemote(
|
|
9089
|
+
put = await deps.putRemote(basename5, {
|
|
8996
9090
|
frontmatter: payload.frontmatter,
|
|
8997
9091
|
body: payload.body
|
|
8998
9092
|
});
|
|
@@ -9046,7 +9140,7 @@ import nodePath4 from "node:path";
|
|
|
9046
9140
|
init_vault_frontmatter();
|
|
9047
9141
|
async function putRemoteSpec(http, id, payload) {
|
|
9048
9142
|
const { baseUrl, token, fetchImpl = fetch } = http;
|
|
9049
|
-
const
|
|
9143
|
+
const path16 = `/api/specs/${encodeURIComponent(id)}`;
|
|
9050
9144
|
const scope = http.accountId && http.vaultId ? cloudRequestScope({ accountId: http.accountId, vaultId: http.vaultId }).headersFor(
|
|
9051
9145
|
"PUT",
|
|
9052
9146
|
"/api/specs/:id"
|
|
@@ -9057,7 +9151,7 @@ async function putRemoteSpec(http, id, payload) {
|
|
|
9057
9151
|
...scope
|
|
9058
9152
|
};
|
|
9059
9153
|
if (token) headers.Authorization = `Bearer ${token}`;
|
|
9060
|
-
const res = await fetchImpl(`${baseUrl}${
|
|
9154
|
+
const res = await fetchImpl(`${baseUrl}${path16}`, {
|
|
9061
9155
|
method: "PUT",
|
|
9062
9156
|
headers,
|
|
9063
9157
|
body: JSON.stringify({ frontmatter: payload.frontmatter, body: payload.body })
|
|
@@ -9073,7 +9167,7 @@ async function putRemoteSpec(http, id, payload) {
|
|
|
9073
9167
|
return {
|
|
9074
9168
|
ok: false,
|
|
9075
9169
|
status: res.status,
|
|
9076
|
-
error: `PUT ${
|
|
9170
|
+
error: `PUT ${path16} returned ${res.status}: ${text2.slice(0, 200)}`,
|
|
9077
9171
|
...res.status === 429 && Number.isFinite(retry) && retry > 0 ? { retryAfterSec: retry } : {}
|
|
9078
9172
|
};
|
|
9079
9173
|
}
|
|
@@ -9085,19 +9179,19 @@ async function putRemoteSpec(http, id, payload) {
|
|
|
9085
9179
|
statusIgnored: json?.status_ignored === true
|
|
9086
9180
|
};
|
|
9087
9181
|
}
|
|
9088
|
-
async function fetchPushRemote(http,
|
|
9089
|
-
const { status, json, text: text2 } = await getJson(http, `api/specs/${encodeURIComponent(
|
|
9182
|
+
async function fetchPushRemote(http, basename5) {
|
|
9183
|
+
const { status, json, text: text2 } = await getJson(http, `api/specs/${encodeURIComponent(basename5)}`);
|
|
9090
9184
|
if (status === 404) return null;
|
|
9091
9185
|
if (status !== 200) {
|
|
9092
9186
|
throw new VaultPullSourceError(
|
|
9093
|
-
`GET /api/specs/${
|
|
9187
|
+
`GET /api/specs/${basename5} returned ${status}: ${text2.slice(0, 200)}`,
|
|
9094
9188
|
status
|
|
9095
9189
|
);
|
|
9096
9190
|
}
|
|
9097
9191
|
const spec = json?.spec;
|
|
9098
9192
|
const fm = spec?.frontmatter && typeof spec.frontmatter === "object" ? spec.frontmatter : null;
|
|
9099
9193
|
if (!spec || typeof spec.body !== "string" || !fm) {
|
|
9100
|
-
throw new VaultPullSourceError(`GET /api/specs/${
|
|
9194
|
+
throw new VaultPullSourceError(`GET /api/specs/${basename5} returned no usable spec`, status);
|
|
9101
9195
|
}
|
|
9102
9196
|
return {
|
|
9103
9197
|
id: String(spec.id ?? fm.id ?? ""),
|
|
@@ -9139,10 +9233,10 @@ function createVaultPushDeps({
|
|
|
9139
9233
|
}
|
|
9140
9234
|
},
|
|
9141
9235
|
readLedger: () => ledger.snapshot(),
|
|
9142
|
-
fetchRemote: (
|
|
9236
|
+
fetchRemote: (basename5) => fetchPushRemote(http, basename5),
|
|
9143
9237
|
listRemote: withListIndex ? () => listRemoteSpecs(http) : void 0,
|
|
9144
9238
|
serialize: stringifySpecMarkdown,
|
|
9145
|
-
putRemote: (
|
|
9239
|
+
putRemote: (basename5, payload) => putRemoteSpec(http, basename5, payload),
|
|
9146
9240
|
recordLedger: (relPath, entry) => ledger.record(relPath, entry),
|
|
9147
9241
|
flushLedger: () => ledger.flush(),
|
|
9148
9242
|
markDirty
|
|
@@ -9348,7 +9442,7 @@ function makeSleeper() {
|
|
|
9348
9442
|
}
|
|
9349
9443
|
function readMarkerVaultId(vaultRoot2) {
|
|
9350
9444
|
try {
|
|
9351
|
-
return parseVaultId(
|
|
9445
|
+
return parseVaultId(readFileSync15(path15.join(vaultRoot2, "heyspex.yaml"), "utf8"));
|
|
9352
9446
|
} catch {
|
|
9353
9447
|
return null;
|
|
9354
9448
|
}
|
|
@@ -9386,6 +9480,17 @@ ${PULL_HELP}
|
|
|
9386
9480
|
process4.exitCode = PULL_EXIT.RUNTIME;
|
|
9387
9481
|
return;
|
|
9388
9482
|
}
|
|
9483
|
+
if (args.apply) {
|
|
9484
|
+
try {
|
|
9485
|
+
assertPullTargetIsVault(vaultRoot2);
|
|
9486
|
+
} catch (err) {
|
|
9487
|
+
if (!(err instanceof PullTargetNotVaultError)) throw err;
|
|
9488
|
+
process4.stderr.write(`hs pull: ${err.message}
|
|
9489
|
+
`);
|
|
9490
|
+
process4.exitCode = PULL_EXIT.VAULT_UNRESOLVED;
|
|
9491
|
+
return;
|
|
9492
|
+
}
|
|
9493
|
+
}
|
|
9389
9494
|
const baseUrl = resolvePullSourceUrl(args.from);
|
|
9390
9495
|
const token = resolvePullToken();
|
|
9391
9496
|
if (!token && /^https:/i.test(baseUrl)) {
|
|
@@ -9414,7 +9519,7 @@ ${PULL_HELP}
|
|
|
9414
9519
|
const markerVaultId = readMarkerVaultId(vaultRoot2);
|
|
9415
9520
|
if (args.apply && markerVaultId && markerVaultId !== target.vaultId) {
|
|
9416
9521
|
process4.stderr.write(
|
|
9417
|
-
`hs pull: refusing --apply: it would write vault ${target.vaultId} into ${
|
|
9522
|
+
`hs pull: refusing --apply: it would write vault ${target.vaultId} into ${path15.join(vaultRoot2, "specs")}, but that repo's heyspex.yaml names vault ${markerVaultId}. Nothing was written.
|
|
9418
9523
|
Drop --vault to pull ${markerVaultId}, or run from the repo that holds ${target.vaultId}.
|
|
9419
9524
|
`
|
|
9420
9525
|
);
|
|
@@ -9431,7 +9536,7 @@ ${PULL_HELP}
|
|
|
9431
9536
|
baseUrl,
|
|
9432
9537
|
token,
|
|
9433
9538
|
scopeHeaders,
|
|
9434
|
-
localRoot:
|
|
9539
|
+
localRoot: path15.join(vaultRoot2, "specs"),
|
|
9435
9540
|
ledger,
|
|
9436
9541
|
onLocalWrite: (relPath) => pushScheduler?.notePullWrite(relPath)
|
|
9437
9542
|
});
|
|
@@ -9499,7 +9604,7 @@ watch: every ${args.intervalSec}s while active, backing off to ${Math.round(Math
|
|
|
9499
9604
|
`relay: push startup sweep failed \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
9500
9605
|
);
|
|
9501
9606
|
}
|
|
9502
|
-
closePushWatch = await startPushFileWatch(
|
|
9607
|
+
closePushWatch = await startPushFileWatch(path15.join(vaultRoot2, "specs"), pushScheduler);
|
|
9503
9608
|
}
|
|
9504
9609
|
const summary = await runPullWatch(
|
|
9505
9610
|
{
|