@spec-engine/spec-engine 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docs/agent-reference/index.html +1 -1
- package/dist/docs/pagefind/fragment/en_2ee687a.pf_fragment +0 -0
- package/dist/docs/pagefind/index/en_59c3abf.pf_index +0 -0
- package/dist/docs/pagefind/index/en_a630d23.pf_index +0 -0
- package/dist/docs/pagefind/pagefind-entry.json +1 -1
- package/dist/docs/pagefind/pagefind.en_ced49c317e.pf_meta +0 -0
- package/dist/impl.js +67 -54
- package/package.json +1 -1
- package/dist/docs/pagefind/fragment/en_b2867b9.pf_fragment +0 -0
- package/dist/docs/pagefind/index/en_6e50ed4.pf_index +0 -0
- package/dist/docs/pagefind/index/en_afc98e5.pf_index +0 -0
- package/dist/docs/pagefind/pagefind.en_d0b5c328bc.pf_meta +0 -0
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
<div class="sl-heading-wrapper level-h2"><h2 id="path-rules-for-spec-resolve">Path rules for <code dir="auto">spec resolve</code></h2><a class="sl-anchor-link" href="#path-rules-for-spec-resolve"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Path rules for spec resolve”</span></a></div>
|
|
98
98
|
<ul>
|
|
99
99
|
<li><strong>Multi-repo platform:</strong> pass <code dir="auto"><repo>/<path></code> — e.g., <code dir="auto">spec resolve api/src/renew.ts .</code></li>
|
|
100
|
-
<li><strong>Single-repo (rung-1):</strong>
|
|
100
|
+
<li><strong>Single-repo (rung-1):</strong> pass the path from the platform root (<code dir="auto">src/orders.ts</code>, <code dir="auto">.github/workflows/ci.yml</code>); a lone repository’s files carry no directory-name prefix</li>
|
|
101
101
|
<li>Absolute paths normalized against <code dir="auto">platformDir</code>; paths outside it exit 2</li>
|
|
102
102
|
</ul>
|
|
103
103
|
<div class="sl-heading-wrapper level-h2"><h2 id="gotchas">Gotchas</h2><a class="sl-anchor-link" href="#gotchas"><span aria-hidden="true" class="sl-anchor-icon"><svg width="16" height="16" viewBox="0 0 24 24"><path fill="currentcolor" d="m12.11 15.39-3.88 3.88a2.52 2.52 0 0 1-3.5 0 2.47 2.47 0 0 1 0-3.5l3.88-3.88a1 1 0 0 0-1.42-1.42l-3.88 3.89a4.48 4.48 0 0 0 6.33 6.33l3.89-3.88a1 1 0 1 0-1.42-1.42Zm8.58-12.08a4.49 4.49 0 0 0-6.33 0l-3.89 3.88a1 1 0 0 0 1.42 1.42l3.88-3.88a2.52 2.52 0 0 1 3.5 0 2.47 2.47 0 0 1 0 3.5l-3.88 3.88a1 1 0 1 0 1.42 1.42l3.88-3.89a4.49 4.49 0 0 0 0-6.33ZM8.83 15.17a1 1 0 0 0 1.1.22 1 1 0 0 0 .32-.22l4.92-4.92a1 1 0 0 0-1.42-1.42l-4.92 4.92a1 1 0 0 0 0 1.42Z"></path></svg></span><span class="sr-only" data-pagefind-ignore>Section titled “Gotchas”</span></a></div>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.5.2","languages":{"en":{"hash":"
|
|
1
|
+
{"version":"1.5.2","languages":{"en":{"hash":"en_ced49c317e","wasm":"en","page_count":12}},"include_characters":["_","‿","⁀","⁔","︳","︴","﹍","﹎","﹏","_"]}
|
|
Binary file
|
package/dist/impl.js
CHANGED
|
@@ -20,7 +20,7 @@ var package_default;
|
|
|
20
20
|
var init_package = __esm(() => {
|
|
21
21
|
package_default = {
|
|
22
22
|
name: "@spec-engine/spec-engine",
|
|
23
|
-
version: "0.8.
|
|
23
|
+
version: "0.8.1",
|
|
24
24
|
description: "Cross-repo spec engine \u2014 durable requirements with permanent IDs, bound to code via @spec tags, checked in CI. Ships the spec CLI, the local coverage webapp (spec serve), and offline docs (spec docs).",
|
|
25
25
|
license: "MIT",
|
|
26
26
|
type: "module",
|
|
@@ -73,6 +73,31 @@ var init_package = __esm(() => {
|
|
|
73
73
|
};
|
|
74
74
|
});
|
|
75
75
|
|
|
76
|
+
// src/stdout.ts
|
|
77
|
+
import { format } from "util";
|
|
78
|
+
function isEpipe(e) {
|
|
79
|
+
return typeof e === "object" && e !== null && "code" in e && (e.code === "EPIPE" || e.code === "ERR_STREAM_DESTROYED");
|
|
80
|
+
}
|
|
81
|
+
function routeStdout() {
|
|
82
|
+
process.stdout.on("error", (e) => {
|
|
83
|
+
if (!isEpipe(e))
|
|
84
|
+
throw e;
|
|
85
|
+
});
|
|
86
|
+
console.log = (...args) => {
|
|
87
|
+
const text = `${format(...args)}
|
|
88
|
+
`;
|
|
89
|
+
lastWrite = new Promise((written) => process.stdout.write(text, () => written()));
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
async function exit(code) {
|
|
93
|
+
await lastWrite;
|
|
94
|
+
process.exit(code);
|
|
95
|
+
}
|
|
96
|
+
var lastWrite;
|
|
97
|
+
var init_stdout = __esm(() => {
|
|
98
|
+
lastWrite = Promise.resolve();
|
|
99
|
+
});
|
|
100
|
+
|
|
76
101
|
// ../shared/src/diagnostics.ts
|
|
77
102
|
var DiagnosticCode, NotASpecPlatformError, InvalidDomainFilesError;
|
|
78
103
|
var init_diagnostics = __esm(() => {
|
|
@@ -2193,33 +2218,9 @@ class SqliteStorage {
|
|
|
2193
2218
|
if (files.length > FILES_MAX) {
|
|
2194
2219
|
throw new Error(`resolveByFiles: too many files (max ${FILES_MAX} per call; got ${files.length})`);
|
|
2195
2220
|
}
|
|
2196
|
-
const
|
|
2197
|
-
if (queryFiles.length > 32000) {
|
|
2198
|
-
throw new Error(`resolveByFiles: expanded bind count ${queryFiles.length} would exceed ` + "SQLITE_MAX_VARIABLE_NUMBER (32766); lower FILES_MAX");
|
|
2199
|
-
}
|
|
2200
|
-
const placeholders = queryFiles.map(() => "?").join(",");
|
|
2221
|
+
const placeholders = files.map(() => "?").join(",");
|
|
2201
2222
|
const sql = RESOLVE_BY_FILES_SQL_PREFIX + placeholders + RESOLVE_BY_FILES_SQL_SUFFIX;
|
|
2202
|
-
return this.#db.query(sql).all(...
|
|
2203
|
-
}
|
|
2204
|
-
#selfMemberName() {
|
|
2205
|
-
const canonical = this.getRepo("spec-engine");
|
|
2206
|
-
if (!canonical)
|
|
2207
|
-
return null;
|
|
2208
|
-
const platformRoot = dirname2(canonical.path);
|
|
2209
|
-
const row = this.#db.query("SELECT name FROM repos WHERE name != 'spec-engine' AND path = $path").get({ path: platformRoot });
|
|
2210
|
-
return row?.name ?? null;
|
|
2211
|
-
}
|
|
2212
|
-
#expandSelfMemberFiles(files) {
|
|
2213
|
-
const self = this.#selfMemberName();
|
|
2214
|
-
if (!self)
|
|
2215
|
-
return files;
|
|
2216
|
-
const prefix = `${self}/`;
|
|
2217
|
-
const expanded = [...files];
|
|
2218
|
-
for (const f of files) {
|
|
2219
|
-
if (!f.startsWith(prefix))
|
|
2220
|
-
expanded.push(prefix + f);
|
|
2221
|
-
}
|
|
2222
|
-
return expanded;
|
|
2223
|
+
return this.#db.query(sql).all(...files);
|
|
2223
2224
|
}
|
|
2224
2225
|
withWriteTx(fn) {
|
|
2225
2226
|
const wrapped = this.#db.transaction((arg) => fn(arg));
|
|
@@ -2702,7 +2703,10 @@ function scannedTagFile(members, platformDir, platformRel) {
|
|
|
2702
2703
|
return null;
|
|
2703
2704
|
if (!isTagSource(rel) && !isDocSource(rel))
|
|
2704
2705
|
return null;
|
|
2705
|
-
return
|
|
2706
|
+
return tagFile(member, rel);
|
|
2707
|
+
}
|
|
2708
|
+
function tagFile(member, rel) {
|
|
2709
|
+
return member.selfMember ? rel : `${member.name}/${rel}`;
|
|
2706
2710
|
}
|
|
2707
2711
|
async function scanMemberCode(member, extraIgnore) {
|
|
2708
2712
|
const hitsOut = [];
|
|
@@ -2710,7 +2714,7 @@ async function scanMemberCode(member, extraIgnore) {
|
|
|
2710
2714
|
for (const rel of codePaths) {
|
|
2711
2715
|
const absPath = join4(member.path, rel);
|
|
2712
2716
|
const text = await Bun.file(absPath).text();
|
|
2713
|
-
const platformRelative =
|
|
2717
|
+
const platformRelative = tagFile(member, rel);
|
|
2714
2718
|
const hits = scanTagsInFile(member.name, platformRelative, text);
|
|
2715
2719
|
for (const h of hits)
|
|
2716
2720
|
hitsOut.push(h);
|
|
@@ -2724,7 +2728,7 @@ async function scanMemberDocs(member, extraIgnore) {
|
|
|
2724
2728
|
for (const rel of docPaths) {
|
|
2725
2729
|
const absPath = join4(member.path, rel);
|
|
2726
2730
|
const text = await Bun.file(absPath).text();
|
|
2727
|
-
const platformRelative =
|
|
2731
|
+
const platformRelative = tagFile(member, rel);
|
|
2728
2732
|
const { tags, mentions } = scanDocFile(member.name, platformRelative, text);
|
|
2729
2733
|
for (const t of tags)
|
|
2730
2734
|
tagsOut.push(t);
|
|
@@ -3348,14 +3352,14 @@ function handleNotAPlatform(e) {
|
|
|
3348
3352
|
}
|
|
3349
3353
|
throw e;
|
|
3350
3354
|
}
|
|
3351
|
-
function handleInvalidDomainFiles(e, json, code = EXIT.FAILURE) {
|
|
3355
|
+
async function handleInvalidDomainFiles(e, json, code = EXIT.FAILURE) {
|
|
3352
3356
|
if (!(e instanceof InvalidDomainFilesError))
|
|
3353
3357
|
return;
|
|
3354
3358
|
if (json)
|
|
3355
3359
|
console.log(renderDiagnostics(e.diagnostics, "json"));
|
|
3356
3360
|
else
|
|
3357
3361
|
console.error(renderDiagnostics(e.diagnostics, "text"));
|
|
3358
|
-
|
|
3362
|
+
await exit(code);
|
|
3359
3363
|
}
|
|
3360
3364
|
function cliFreshTags(platformDir) {
|
|
3361
3365
|
const fresh = coldFreshTags(platformDir);
|
|
@@ -3363,7 +3367,7 @@ function cliFreshTags(platformDir) {
|
|
|
3363
3367
|
try {
|
|
3364
3368
|
return await fresh(reqId);
|
|
3365
3369
|
} catch (e) {
|
|
3366
|
-
handleInvalidDomainFiles(e, false, EXIT.USAGE);
|
|
3370
|
+
await handleInvalidDomainFiles(e, false, EXIT.USAGE);
|
|
3367
3371
|
throw e;
|
|
3368
3372
|
}
|
|
3369
3373
|
};
|
|
@@ -3405,7 +3409,7 @@ async function withReadStorage(opts, fn) {
|
|
|
3405
3409
|
});
|
|
3406
3410
|
} catch (e) {
|
|
3407
3411
|
handleStorageUnavailable(e, dbPath);
|
|
3408
|
-
handleInvalidDomainFiles(e, json);
|
|
3412
|
+
await handleInvalidDomainFiles(e, json);
|
|
3409
3413
|
handleNotAPlatform(e);
|
|
3410
3414
|
}
|
|
3411
3415
|
}
|
|
@@ -3414,6 +3418,7 @@ var init__shared = __esm(() => {
|
|
|
3414
3418
|
init_constants();
|
|
3415
3419
|
init_discover();
|
|
3416
3420
|
init__index();
|
|
3421
|
+
init_stdout();
|
|
3417
3422
|
init_errors();
|
|
3418
3423
|
init_sqlite();
|
|
3419
3424
|
});
|
|
@@ -3719,7 +3724,7 @@ var init_commands = __esm(() => {
|
|
|
3719
3724
|
console.error(formatNotASpecPlatform(err.platformDir));
|
|
3720
3725
|
process.exit(EXIT.USAGE);
|
|
3721
3726
|
}
|
|
3722
|
-
handleInvalidDomainFiles(err, !!args.json);
|
|
3727
|
+
await handleInvalidDomainFiles(err, !!args.json);
|
|
3723
3728
|
console.error("spec index FAILED:", err);
|
|
3724
3729
|
process.exit(EXIT.FAILURE);
|
|
3725
3730
|
} finally {
|
|
@@ -5699,6 +5704,7 @@ var init_check2 = __esm(() => {
|
|
|
5699
5704
|
init_prompt();
|
|
5700
5705
|
init__index();
|
|
5701
5706
|
init_check();
|
|
5707
|
+
init_stdout();
|
|
5702
5708
|
init__args();
|
|
5703
5709
|
init__shared();
|
|
5704
5710
|
checkCommand = defineCommand3({
|
|
@@ -5772,7 +5778,7 @@ var init_check2 = __esm(() => {
|
|
|
5772
5778
|
return result;
|
|
5773
5779
|
});
|
|
5774
5780
|
} catch (e) {
|
|
5775
|
-
handleInvalidDomainFiles(e, jsonMode);
|
|
5781
|
+
await handleInvalidDomainFiles(e, jsonMode);
|
|
5776
5782
|
exitAfterCrash(e);
|
|
5777
5783
|
}
|
|
5778
5784
|
if (outcome === undefined) {
|
|
@@ -5790,7 +5796,7 @@ var init_check2 = __esm(() => {
|
|
|
5790
5796
|
console.log(renderDiagnostics(diagnostics2, jsonMode ? "json" : "text"));
|
|
5791
5797
|
if (!jsonMode)
|
|
5792
5798
|
console.log(`build_id: ${outcome.buildId}`);
|
|
5793
|
-
|
|
5799
|
+
await exit(outcome.failing ? EXIT.FAILURE : EXIT.OK);
|
|
5794
5800
|
}
|
|
5795
5801
|
});
|
|
5796
5802
|
});
|
|
@@ -7431,8 +7437,8 @@ async function confirmTermCommand(opts) {
|
|
|
7431
7437
|
exitOnFailure("spec term confirm", result);
|
|
7432
7438
|
await withIndex({ platformDir, build: "fresh" }, () => {
|
|
7433
7439
|
return;
|
|
7434
|
-
}).catch((e) => {
|
|
7435
|
-
handleInvalidDomainFiles(e, false, EXIT.USAGE);
|
|
7440
|
+
}).catch(async (e) => {
|
|
7441
|
+
await handleInvalidDomainFiles(e, false, EXIT.USAGE);
|
|
7436
7442
|
throw e;
|
|
7437
7443
|
});
|
|
7438
7444
|
const { pinned, file } = result;
|
|
@@ -7639,7 +7645,7 @@ async function generate(platformDir, json) {
|
|
|
7639
7645
|
else
|
|
7640
7646
|
console.log(`generated GLOSSARY.md from ${result.generated} terms`);
|
|
7641
7647
|
}
|
|
7642
|
-
function check2(platformDir, json) {
|
|
7648
|
+
async function check2(platformDir, json) {
|
|
7643
7649
|
if (checkGlossary(platformDir).clean) {
|
|
7644
7650
|
if (json)
|
|
7645
7651
|
console.log(JSON.stringify({ ok: true }));
|
|
@@ -7651,13 +7657,14 @@ function check2(platformDir, json) {
|
|
|
7651
7657
|
console.error("run `spec glossary .` to regenerate the human view from the store");
|
|
7652
7658
|
if (json)
|
|
7653
7659
|
console.log(JSON.stringify({ ok: false }));
|
|
7654
|
-
|
|
7660
|
+
await exit(EXIT.FAILURE);
|
|
7655
7661
|
}
|
|
7656
7662
|
var glossaryCommand;
|
|
7657
7663
|
var init_glossary2 = __esm(() => {
|
|
7658
7664
|
init_constants();
|
|
7659
7665
|
init_discover();
|
|
7660
7666
|
init_glossary();
|
|
7667
|
+
init_stdout();
|
|
7661
7668
|
init__args();
|
|
7662
7669
|
init__shared();
|
|
7663
7670
|
glossaryCommand = defineCommand14({
|
|
@@ -7683,7 +7690,7 @@ var init_glossary2 = __esm(() => {
|
|
|
7683
7690
|
if (args.migrate)
|
|
7684
7691
|
await migrate(platformDir, json);
|
|
7685
7692
|
else if (args.check)
|
|
7686
|
-
check2(platformDir, json);
|
|
7693
|
+
await check2(platformDir, json);
|
|
7687
7694
|
else
|
|
7688
7695
|
await generate(platformDir, json);
|
|
7689
7696
|
}
|
|
@@ -9395,7 +9402,7 @@ __export(exports_gate, {
|
|
|
9395
9402
|
import { existsSync as existsSync13 } from "fs";
|
|
9396
9403
|
import { join as join15 } from "path";
|
|
9397
9404
|
import { defineCommand as defineCommand22 } from "citty";
|
|
9398
|
-
function
|
|
9405
|
+
function isEpipe2(e) {
|
|
9399
9406
|
if (e === null || typeof e !== "object" || !("code" in e))
|
|
9400
9407
|
return false;
|
|
9401
9408
|
const code = e.code;
|
|
@@ -9405,7 +9412,7 @@ function writeStdoutTolerant(line) {
|
|
|
9405
9412
|
try {
|
|
9406
9413
|
console.log(line);
|
|
9407
9414
|
} catch (writeErr) {
|
|
9408
|
-
if (!
|
|
9415
|
+
if (!isEpipe2(writeErr))
|
|
9409
9416
|
throw writeErr;
|
|
9410
9417
|
}
|
|
9411
9418
|
}
|
|
@@ -9430,6 +9437,7 @@ var init_gate2 = __esm(() => {
|
|
|
9430
9437
|
init_prompt();
|
|
9431
9438
|
init__index();
|
|
9432
9439
|
init_gate();
|
|
9440
|
+
init_stdout();
|
|
9433
9441
|
init__args();
|
|
9434
9442
|
init__shared();
|
|
9435
9443
|
gateArgs = {
|
|
@@ -9490,7 +9498,7 @@ var init_gate2 = __esm(() => {
|
|
|
9490
9498
|
writeStdoutTolerant(`build_id: ${gated.buildId}`);
|
|
9491
9499
|
}
|
|
9492
9500
|
} catch (e) {
|
|
9493
|
-
handleInvalidDomainFiles(e, Boolean(args.json));
|
|
9501
|
+
await handleInvalidDomainFiles(e, Boolean(args.json));
|
|
9494
9502
|
const msg = e instanceof Error ? e.message : String(e);
|
|
9495
9503
|
console.error(`spec gate: crashed: ${msg}`);
|
|
9496
9504
|
process.exit(EXIT.USAGE);
|
|
@@ -9500,7 +9508,7 @@ var init_gate2 = __esm(() => {
|
|
|
9500
9508
|
process.exit(EXIT.USAGE);
|
|
9501
9509
|
return;
|
|
9502
9510
|
}
|
|
9503
|
-
|
|
9511
|
+
await exit(gated.outcome.pass ? EXIT.OK : EXIT.FAILURE);
|
|
9504
9512
|
}
|
|
9505
9513
|
});
|
|
9506
9514
|
});
|
|
@@ -9586,6 +9594,7 @@ var guardCommand;
|
|
|
9586
9594
|
var init_guard2 = __esm(() => {
|
|
9587
9595
|
init_constants();
|
|
9588
9596
|
init_guard();
|
|
9597
|
+
init_stdout();
|
|
9589
9598
|
init__args();
|
|
9590
9599
|
init__shared();
|
|
9591
9600
|
guardCommand = defineCommand23({
|
|
@@ -9611,14 +9620,14 @@ var init_guard2 = __esm(() => {
|
|
|
9611
9620
|
if (!gitRefResolves(platformDir, ref)) {
|
|
9612
9621
|
console.error(`spec guard: NOT_A_GIT_REPO \u2014 ref '${ref}' does not resolve in ${platformDir} ` + "(not a git repo, a fresh repo with no commit, or an unfetched/misspelled ref); " + "skipping loss detection");
|
|
9613
9622
|
console.log(jsonMode ? "[]" : `\u2713 spec guard: no requirements about to be lost (non-git context)`);
|
|
9614
|
-
|
|
9623
|
+
await exit(EXIT.OK);
|
|
9615
9624
|
}
|
|
9616
9625
|
let losses = [];
|
|
9617
9626
|
await withReadStorage({ platformDir, dbPath: defaultIndexPath(platformDir), fresh: true, json: jsonMode }, async (storage2) => {
|
|
9618
9627
|
losses = (await guard(storage2, platformDir, ref)).losses;
|
|
9619
9628
|
});
|
|
9620
9629
|
console.log(renderGuard(losses, jsonMode ? "json" : "text", ref));
|
|
9621
|
-
|
|
9630
|
+
await exit(losses.length > 0 ? EXIT.FAILURE : EXIT.OK);
|
|
9622
9631
|
}
|
|
9623
9632
|
});
|
|
9624
9633
|
});
|
|
@@ -12901,12 +12910,12 @@ function mountApi(app, storage2, platformDir = process.cwd(), bindHost = DEFAULT
|
|
|
12901
12910
|
if (!featureEnabled("relations")) {
|
|
12902
12911
|
return c.json({ error: featureDisabledMessage("relations") }, 404);
|
|
12903
12912
|
}
|
|
12904
|
-
const
|
|
12905
|
-
if (
|
|
12913
|
+
const format2 = c.req.query("format");
|
|
12914
|
+
if (format2 !== undefined && format2 !== "mermaid") {
|
|
12906
12915
|
return c.json({ error: 'format must be "mermaid" when provided' }, 400);
|
|
12907
12916
|
}
|
|
12908
12917
|
const rows = relations(storage2).rows;
|
|
12909
|
-
if (
|
|
12918
|
+
if (format2 === "mermaid") {
|
|
12910
12919
|
return c.text(renderRelations(rows, "mermaid"));
|
|
12911
12920
|
}
|
|
12912
12921
|
return c.json(sortRelations(rows));
|
|
@@ -13161,7 +13170,7 @@ async function runProbe() {
|
|
|
13161
13170
|
}
|
|
13162
13171
|
console.log("serve --probe OK");
|
|
13163
13172
|
server.stop();
|
|
13164
|
-
|
|
13173
|
+
await exit(EXIT.OK);
|
|
13165
13174
|
}
|
|
13166
13175
|
var serveCommand;
|
|
13167
13176
|
var init_serve = __esm(() => {
|
|
@@ -13173,6 +13182,7 @@ var init_serve = __esm(() => {
|
|
|
13173
13182
|
init_prompt();
|
|
13174
13183
|
init_api();
|
|
13175
13184
|
init_lan();
|
|
13185
|
+
init_stdout();
|
|
13176
13186
|
init_sqlite();
|
|
13177
13187
|
init__args();
|
|
13178
13188
|
init__shared();
|
|
@@ -13270,7 +13280,7 @@ var init_serve = __esm(() => {
|
|
|
13270
13280
|
});
|
|
13271
13281
|
} catch (err) {
|
|
13272
13282
|
storage2.close();
|
|
13273
|
-
handleInvalidDomainFiles(err, false);
|
|
13283
|
+
await handleInvalidDomainFiles(err, false);
|
|
13274
13284
|
handleStorageUnavailable(err, dbPath);
|
|
13275
13285
|
console.error(`spec serve: failed to start on ${urlHost(host, port)}:`, err);
|
|
13276
13286
|
process.exit(EXIT.FAILURE);
|
|
@@ -13369,7 +13379,7 @@ async function runProbe2(root) {
|
|
|
13369
13379
|
}
|
|
13370
13380
|
console.log("docs --probe OK");
|
|
13371
13381
|
server.stop();
|
|
13372
|
-
|
|
13382
|
+
await exit(EXIT.OK);
|
|
13373
13383
|
}
|
|
13374
13384
|
function exitNoDocsRoot() {
|
|
13375
13385
|
console.error("spec docs: no built documentation found. From a checkout run `bun run build:site` " + "(writes packages/site/dist); the published npm package ships it at dist/docs.");
|
|
@@ -13378,6 +13388,7 @@ function exitNoDocsRoot() {
|
|
|
13378
13388
|
var docsCommand;
|
|
13379
13389
|
var init_docs2 = __esm(() => {
|
|
13380
13390
|
init_constants();
|
|
13391
|
+
init_stdout();
|
|
13381
13392
|
docsCommand = defineCommand25({
|
|
13382
13393
|
meta: {
|
|
13383
13394
|
name: "docs",
|
|
@@ -13511,7 +13522,9 @@ var init___smoke = __esm(() => {
|
|
|
13511
13522
|
|
|
13512
13523
|
// src/cli.ts
|
|
13513
13524
|
init_package();
|
|
13525
|
+
init_stdout();
|
|
13514
13526
|
import { defineCommand as defineCommand27, runMain, showUsage } from "citty";
|
|
13527
|
+
routeStdout();
|
|
13515
13528
|
var main = defineCommand27({
|
|
13516
13529
|
meta: {
|
|
13517
13530
|
name: "spec",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spec-engine/spec-engine",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Cross-repo spec engine — durable requirements with permanent IDs, bound to code via @spec tags, checked in CI. Ships the spec CLI, the local coverage webapp (spec serve), and offline docs (spec docs).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|