@orkestrel/scaffold 0.0.21 → 0.0.23
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/bin/scaffold.js +371 -140
- package/dist/bin/scaffold.js.map +1 -1
- package/dist/host/AGENTS.md +61 -42
- package/dist/host/CLAUDE.md +39 -408
- package/dist/host/agents/orchestration.md +454 -0
- package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +25 -7
- package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-build-application/SKILL.md +42 -31
- package/dist/host/agents/skills/orkestrel-build-application/references/application.md +129 -0
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +3 -3
- package/dist/host/agents/skills/orkestrel-debrief/references/field-testing.md +2 -2
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +167 -0
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +98 -0
- package/dist/host/agents/skills/orkestrel-falsify/references/reconcile.md +148 -0
- package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +4 -2
- package/dist/host/agents/skills/orkestrel-harden-package/references/centralization.md +5 -5
- package/dist/host/agents/skills/orkestrel-harden-package/references/research.md +2 -0
- package/dist/host/agents/skills/orkestrel-polish-surface/SKILL.md +11 -6
- package/dist/host/claude/agents/analyst.md +59 -0
- package/dist/host/claude/agents/application.md +1 -1
- package/dist/host/claude/agents/builder.md +1 -1
- package/dist/host/claude/agents/checker.md +5 -1
- package/dist/host/claude/agents/codex.md +120 -94
- package/dist/host/claude/agents/grok.md +44 -32
- package/dist/host/claude/agents/implementer.md +1 -1
- package/dist/host/claude/agents/orkestrel.md +5 -5
- package/dist/host/claude/agents/planner.md +9 -3
- package/dist/host/claude/agents/researcher.md +6 -5
- package/dist/host/claude/agents/reviewer.md +12 -6
- package/dist/host/claude/agents/scout.md +7 -4
- package/dist/host/claude/agents/verifier.md +1 -1
- package/dist/host/claude/rules/application.md +17 -16
- package/dist/host/claude/rules/architecture.md +41 -22
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/names.md +7 -6
- package/dist/host/claude/rules/quality.md +65 -18
- package/dist/host/claude/rules/styles.md +1 -1
- package/dist/host/claude/rules/tests.md +12 -6
- package/dist/host/claude/rules/typescript.md +1 -1
- package/dist/host/claude/rules/workspace.md +6 -3
- package/dist/host/claude/settings.json +2 -0
- package/dist/host/claude/skills/orkestrel-falsify/SKILL.md +10 -0
- package/dist/host/codex/agents/analyst.toml +13 -4
- package/dist/host/codex/agents/checker.toml +1 -1
- package/dist/host/codex/agents/grok.toml +2 -1
- package/dist/host/codex/agents/opus.toml +1 -1
- package/dist/host/codex/agents/planner.toml +1 -1
- package/dist/host/codex/agents/researcher.toml +2 -2
- package/dist/host/codex/agents/reviewer.toml +1 -1
- package/dist/host/codex/agents/scout.toml +2 -2
- package/dist/host/codex/config.toml +23 -70
- package/dist/host/cursor/rules/orchestration.mdc +33 -0
- package/dist/host/guides/src/scaffold.md +339 -125
- package/dist/host/manifest.json +47 -1
- package/dist/host/tests/setupPolicy.ts +210 -3
- package/dist/src/core/index.cjs +477 -69
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +132 -43
- package/dist/src/core/index.d.ts +132 -43
- package/dist/src/core/index.js +474 -70
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +83 -33
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +43 -27
- package/dist/src/server/index.d.ts +43 -27
- package/dist/src/server/index.js +84 -35
- package/dist/src/server/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -256,7 +256,7 @@ function isManifestEntry(value) {
|
|
|
256
256
|
* Narrow a value to one exact complete vendored-host manifest.
|
|
257
257
|
*
|
|
258
258
|
* @param value - The candidate manifest value.
|
|
259
|
-
* @returns `true` only for an exact `{ entries, roots }` record with safe paths.
|
|
259
|
+
* @returns `true` only for an exact `{ entries, roots, digest }` record with safe paths.
|
|
260
260
|
*/
|
|
261
261
|
function isHostManifest(value) {
|
|
262
262
|
const result = (0, _orkestrel_contract.attempt)(() => {
|
|
@@ -264,7 +264,8 @@ function isHostManifest(value) {
|
|
|
264
264
|
const keys = Reflect.ownKeys(value);
|
|
265
265
|
const entries = Reflect.getOwnPropertyDescriptor(value, "entries");
|
|
266
266
|
const roots = Reflect.getOwnPropertyDescriptor(value, "roots");
|
|
267
|
-
|
|
267
|
+
const digest = Reflect.getOwnPropertyDescriptor(value, "digest");
|
|
268
|
+
return keys.length === 3 && keys.every((key) => key === "entries" || key === "roots" || key === "digest") && entries !== void 0 && Reflect.has(entries, "value") && roots !== void 0 && Reflect.has(roots, "value") && digest !== void 0 && Reflect.has(digest, "value") && (0, _src_core.isDenseDataArray)(entries.value, 4096, isManifestEntry) && (0, _src_core.isDenseDataArray)(roots.value, 4096, isPortablePath) && typeof digest.value === "string" && WRITE_DIGEST_PATTERN.test(digest.value);
|
|
268
269
|
});
|
|
269
270
|
return result.success && result.value;
|
|
270
271
|
}
|
|
@@ -939,6 +940,19 @@ function digestText(value) {
|
|
|
939
940
|
return (0, node_crypto.createHash)("sha256").update(value, "utf8").digest("hex");
|
|
940
941
|
}
|
|
941
942
|
/**
|
|
943
|
+
* Digest the exact declared membership of a vendored host manifest.
|
|
944
|
+
*
|
|
945
|
+
* @param entries - The ordered file membership declarations.
|
|
946
|
+
* @param roots - The ordered directory membership declarations.
|
|
947
|
+
* @returns A SHA-256 digest independent of the manifest's stored digest field.
|
|
948
|
+
*/
|
|
949
|
+
function digestHostManifest(entries, roots) {
|
|
950
|
+
return digestText((0, _src_core.stableStringify)({
|
|
951
|
+
entries,
|
|
952
|
+
roots
|
|
953
|
+
}));
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
942
956
|
* Render the local pointer written when an upstream dependency guide is not vendored yet.
|
|
943
957
|
*
|
|
944
958
|
* @param source - The canonical `guides/src/<name>.md` source path.
|
|
@@ -1772,9 +1786,10 @@ function selectOrkestrelEntries(value) {
|
|
|
1772
1786
|
* and the name satisfies `isWorkspaceName`; every other name is a coded
|
|
1773
1787
|
* `TARGET` failure. `src` is derived from `src/<environment>/` and `app` from
|
|
1774
1788
|
* `app/<environment>/`; a target with no environment on either axis is also a coded
|
|
1775
|
-
* `TARGET` failure. The `bin
|
|
1776
|
-
* directories at `src/bin
|
|
1777
|
-
*
|
|
1789
|
+
* `TARGET` failure. The `bin` and `integration` facts probe physical
|
|
1790
|
+
* directories at `src/bin` and `tests/integration`. `services` is the sorted
|
|
1791
|
+
* set of direct vendor directories under `tests/service` that contain a test
|
|
1792
|
+
* at any depth, while `global` probes the physical exact-case `tests/setupGlobal.ts` file and `showcase`
|
|
1778
1793
|
* probes the physical exact-case `configs/app/vite.showcase.config.ts` regular file; none is
|
|
1779
1794
|
* inferred from the workspace name. `dependencies` /
|
|
1780
1795
|
* `peers` are the `@orkestrel/`-prefixed entries of `manifest.dependencies` /
|
|
@@ -1794,8 +1809,8 @@ function selectOrkestrelEntries(value) {
|
|
|
1794
1809
|
* @throws `ScaffoldError('TARGET', …)` when `target`'s manifest is unreadable
|
|
1795
1810
|
* (via `readManifest`), is not valid JSON, its name is unsafe for its
|
|
1796
1811
|
* publication mode, or `target` carries no source or application environment.
|
|
1797
|
-
* @throws `ScaffoldError('
|
|
1798
|
-
*
|
|
1812
|
+
* @throws `ScaffoldError('INVALID', …)` when service tests use the retired flat
|
|
1813
|
+
* layout, a vendor directory has no test, or a service companion is missing.
|
|
1799
1814
|
*
|
|
1800
1815
|
* @example
|
|
1801
1816
|
* ```ts
|
|
@@ -1835,22 +1850,46 @@ function deriveBlueprint(target) {
|
|
|
1835
1850
|
const engines = typeof rawNode === "string" ? rawNode : _src_core.DEFAULT_ENGINES;
|
|
1836
1851
|
const bin = isRealDirectory((0, node_path.join)(target, "src", "bin"));
|
|
1837
1852
|
const integration = isRealDirectory((0, node_path.join)(target, "tests", "integration"));
|
|
1838
|
-
const
|
|
1853
|
+
const serviceRoot = (0, node_path.join)(target, "tests", "service");
|
|
1854
|
+
const services = [];
|
|
1855
|
+
if ((0, node_fs.existsSync)(serviceRoot)) {
|
|
1856
|
+
if (!isRealDirectory(serviceRoot)) throw new _src_core.ScaffoldError("INVALID", `Service root at ${serviceRoot} must be a physical directory`, {
|
|
1857
|
+
target,
|
|
1858
|
+
path: "tests/service"
|
|
1859
|
+
});
|
|
1860
|
+
const serviceEntries = (0, node_fs.readdirSync)(serviceRoot, { withFileTypes: true });
|
|
1861
|
+
const flat = serviceEntries.filter((entry) => entry.name.endsWith(".test.ts") && !entry.isDirectory()).map((entry) => entry.name).sort();
|
|
1862
|
+
if (flat.length > 0) throw new _src_core.ScaffoldError("INVALID", `Flat service tests are not supported; move ${flat.join(", ")} into tests/service/<vendor>/`, {
|
|
1863
|
+
target,
|
|
1864
|
+
paths: flat.map((path) => `tests/service/${path}`)
|
|
1865
|
+
});
|
|
1866
|
+
for (const entry of serviceEntries) {
|
|
1867
|
+
const vendor = (0, node_path.join)(serviceRoot, entry.name);
|
|
1868
|
+
if (!isRealDirectory(vendor)) continue;
|
|
1869
|
+
if (!(0, _src_core.isWorkspaceName)(entry.name)) throw new _src_core.ScaffoldError("INVALID", `Service vendor directory "${entry.name}" must use a bounded lowercase name`, {
|
|
1870
|
+
target,
|
|
1871
|
+
path: `tests/service/${entry.name}`
|
|
1872
|
+
});
|
|
1873
|
+
if (listFiles(vendor).filter((path) => path.endsWith(".test.ts")).length === 0) throw new _src_core.ScaffoldError("INVALID", `Service vendor "${entry.name}" contains no test; add tests/service/${entry.name}/**/*.test.ts or remove the directory`, {
|
|
1874
|
+
target,
|
|
1875
|
+
service: entry.name
|
|
1876
|
+
});
|
|
1877
|
+
const setup = `tests/service/${entry.name}/setup.ts`;
|
|
1878
|
+
if (!isRealFile((0, node_path.join)(target, setup))) throw new _src_core.ScaffoldError("INVALID", `Service vendor "${entry.name}" is missing ${setup}; add a readiness module that probes and warms the vendor and throws when unavailable`, {
|
|
1879
|
+
target,
|
|
1880
|
+
service: entry.name,
|
|
1881
|
+
missing: setup
|
|
1882
|
+
});
|
|
1883
|
+
services.push(entry.name);
|
|
1884
|
+
}
|
|
1885
|
+
services.sort();
|
|
1886
|
+
}
|
|
1839
1887
|
const showcaseRoot = (0, node_path.join)(target, (0, node_path.dirname)(_src_core.SHOWCASE_CONFIG_PATH));
|
|
1840
1888
|
const showcaseEntries = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readdirSync)(showcaseRoot));
|
|
1841
1889
|
const showcase = showcaseEntries.success && showcaseEntries.value.includes((0, node_path.basename)(_src_core.SHOWCASE_CONFIG_PATH)) && isRealFile((0, node_path.join)(target, _src_core.SHOWCASE_CONFIG_PATH));
|
|
1842
1890
|
const tests = (0, node_path.join)(target, (0, node_path.dirname)(_src_core.GLOBAL_SETUP_PATH));
|
|
1843
1891
|
const entries = (0, _orkestrel_contract.attempt)(() => (0, node_fs.readdirSync)(tests));
|
|
1844
1892
|
const global = entries.success && entries.value.includes((0, node_path.basename)(_src_core.GLOBAL_SETUP_PATH)) && isRealFile((0, node_path.join)(target, _src_core.GLOBAL_SETUP_PATH));
|
|
1845
|
-
if (service) {
|
|
1846
|
-
const missing = [];
|
|
1847
|
-
if (!isRealFile((0, node_path.join)(target, "tests", "setupService.ts"))) missing.push("tests/setupService.ts");
|
|
1848
|
-
if (!isRealFile((0, node_path.join)(target, _src_core.SERVICE_SCRIPT_PATH))) missing.push(_src_core.SERVICE_SCRIPT_PATH);
|
|
1849
|
-
if (missing.length > 0) throw new _src_core.ScaffoldError("TARGET", `Service tests under ${target} are missing ${missing.join(" and ")}`, {
|
|
1850
|
-
target,
|
|
1851
|
-
missing
|
|
1852
|
-
});
|
|
1853
|
-
}
|
|
1854
1893
|
const rawDependencies = (0, _src_core.ownDataValue)(parsed, "dependencies");
|
|
1855
1894
|
const rawPeerDependencies = (0, _src_core.ownDataValue)(parsed, "peerDependencies");
|
|
1856
1895
|
const dependencies = selectOrkestrelEntries(rawDependencies).map(([depName, range]) => ({
|
|
@@ -1879,7 +1918,7 @@ function deriveBlueprint(target) {
|
|
|
1879
1918
|
extras: [],
|
|
1880
1919
|
bin,
|
|
1881
1920
|
integration,
|
|
1882
|
-
|
|
1921
|
+
services,
|
|
1883
1922
|
global,
|
|
1884
1923
|
showcase
|
|
1885
1924
|
}))));
|
|
@@ -1902,7 +1941,7 @@ function deriveBlueprint(target) {
|
|
|
1902
1941
|
overrides: [],
|
|
1903
1942
|
bin,
|
|
1904
1943
|
integration,
|
|
1905
|
-
|
|
1944
|
+
services,
|
|
1906
1945
|
global,
|
|
1907
1946
|
showcase
|
|
1908
1947
|
});
|
|
@@ -2026,8 +2065,9 @@ function readManifest(target) {
|
|
|
2026
2065
|
* `manifest.json` — the raw-repo-root fallback (`Materializer` then maps
|
|
2027
2066
|
* an artifact's `source` to `host` 1:1, no vendored staging indirection).
|
|
2028
2067
|
* @throws `ScaffoldError('TARGET', …)` when `manifest.json` exists but is
|
|
2029
|
-
* unreadable, malformed,
|
|
2030
|
-
* bijectively and case-exactly onto real
|
|
2068
|
+
* unreadable, malformed, membership-corrupted, collision-prone,
|
|
2069
|
+
* root-incomplete, or does not map bijectively and case-exactly onto real
|
|
2070
|
+
* contained storage files.
|
|
2031
2071
|
*
|
|
2032
2072
|
* @example
|
|
2033
2073
|
* ```ts
|
|
@@ -2051,6 +2091,10 @@ function readHostManifest(host) {
|
|
|
2051
2091
|
host,
|
|
2052
2092
|
full
|
|
2053
2093
|
});
|
|
2094
|
+
if (manifest.digest !== digestHostManifest(manifest.entries, manifest.roots)) throw new _src_core.ScaffoldError("TARGET", `Host manifest membership at ${full} is corrupted`, {
|
|
2095
|
+
host,
|
|
2096
|
+
full
|
|
2097
|
+
});
|
|
2054
2098
|
const destinationConflict = (0, _src_core.findFileConflict)(manifest.entries.map((entry) => entry.destination));
|
|
2055
2099
|
if (destinationConflict !== void 0) throw new _src_core.ScaffoldError("TARGET", `Host manifest destination collision between "${destinationConflict[0]}" and "${destinationConflict[1]}"`, {
|
|
2056
2100
|
host,
|
|
@@ -2527,7 +2571,8 @@ function stageHost(root, out, paths = _src_core.HOST_PATHS) {
|
|
|
2527
2571
|
if (rootConflict !== void 0) throw new _src_core.ScaffoldError("TARGET", `Directory collision between "${rootConflict[0]}" and "${rootConflict[1]}"`, { paths: rootConflict });
|
|
2528
2572
|
const manifest = {
|
|
2529
2573
|
entries,
|
|
2530
|
-
roots: uniqueRoots
|
|
2574
|
+
roots: uniqueRoots,
|
|
2575
|
+
digest: digestHostManifest(entries, uniqueRoots)
|
|
2531
2576
|
};
|
|
2532
2577
|
const parent = (0, node_path.dirname)((0, node_path.resolve)(out));
|
|
2533
2578
|
const name = (0, node_path.basename)((0, node_path.resolve)(out));
|
|
@@ -2626,6 +2671,7 @@ function stageHost(root, out, paths = _src_core.HOST_PATHS) {
|
|
|
2626
2671
|
* {
|
|
2627
2672
|
* entries: [{ storage: 'pkg.tmpl', destination: 'package.json', executable: false }],
|
|
2628
2673
|
* roots: [],
|
|
2674
|
+
* digest: '3b52f19450237ea4cfb39bc7a77b1e5094b52a8ff1fc9c02fd68b13ad088aa0f',
|
|
2629
2675
|
* },
|
|
2630
2676
|
* 'package.json',
|
|
2631
2677
|
* './dist/host',
|
|
@@ -2738,7 +2784,8 @@ function hydratePlan(plan, host) {
|
|
|
2738
2784
|
});
|
|
2739
2785
|
if (entries.length === 0) {
|
|
2740
2786
|
if (source.startsWith("guides/src/") && source.endsWith(".md")) {
|
|
2741
|
-
|
|
2787
|
+
const { hex: _hex, ...presenceOwned } = artifact;
|
|
2788
|
+
artifacts.push(presenceOwned);
|
|
2742
2789
|
continue;
|
|
2743
2790
|
}
|
|
2744
2791
|
throw new _src_core.ScaffoldError("TARGET", `Host manifest does not declare ${source}`, {
|
|
@@ -3081,9 +3128,10 @@ function catalogPackages(roots, limit = MAX_HOST_ENTRIES) {
|
|
|
3081
3128
|
* (`ScaffoldError('TARGET', …)`), then byte-copies each `host` artifact from
|
|
3082
3129
|
* the `host` root and writes each `template` / `computed` artifact's rendered
|
|
3083
3130
|
* `content`, failing fast on any write error (`ScaffoldError('WRITE', …)`).
|
|
3084
|
-
* `repair` is into-existing: it skips the vacancy check and writes
|
|
3085
|
-
* `
|
|
3086
|
-
*
|
|
3131
|
+
* `repair` is into-existing: it skips the vacancy check and writes `missing`
|
|
3132
|
+
* artifacts an `Audit` names. `stale` artifacts are report-only unless its
|
|
3133
|
+
* `replace` switch is true, because byte replacement discards local changes.
|
|
3134
|
+
* Hydrated directory-shaped host entries are expanded into
|
|
3087
3135
|
* file-shaped artifacts, so canonical skills and agent configuration are
|
|
3088
3136
|
* audited and repaired file by file. `prune` deletes stale files under
|
|
3089
3137
|
* `target/.claude/agents/`, `target/.codex/agents/`, and `target/scripts/`
|
|
@@ -3114,9 +3162,10 @@ function catalogPackages(roots, limit = MAX_HOST_ENTRIES) {
|
|
|
3114
3162
|
* source is always staged by `stageHost`, so a non-guide zero-match means a
|
|
3115
3163
|
* corrupted or truncated `manifest.json`, not an intentionally-unvendored
|
|
3116
3164
|
* artifact. For a guide pointer, a short stub file is written at the
|
|
3117
|
-
* destination and reported exactly like a successful copy
|
|
3118
|
-
*
|
|
3119
|
-
*
|
|
3165
|
+
* destination and reported exactly like a successful copy. The READ path
|
|
3166
|
+
* leaves that intentional pointer without canonical bytes, so `diffPlan`
|
|
3167
|
+
* treats it as presence-owned rather than inventing a byte match.
|
|
3168
|
+
* For every OTHER zero-match, the
|
|
3120
3169
|
* fail-closed `ScaffoldError('TARGET', …)` is thrown — degrading an
|
|
3121
3170
|
* unscoped zero-match would otherwise let a corrupted manifest silently stub
|
|
3122
3171
|
* an unrecoverable artifact (e.g. `AGENTS.md` — `pull` only ever fetches
|
|
@@ -3190,16 +3239,16 @@ var Materializer = class {
|
|
|
3190
3239
|
this.#emitter.emit("done", result);
|
|
3191
3240
|
return result;
|
|
3192
3241
|
}
|
|
3193
|
-
repair(plan, audit, target) {
|
|
3242
|
+
repair(plan, audit, target, replace = false) {
|
|
3194
3243
|
this.#ensureAlive();
|
|
3195
3244
|
const context = this.#prepare(plan, target, plan, false);
|
|
3196
3245
|
if (!(0, _src_core.hasOnlyDataProperties)(audit) || !(0, _src_core.hasValidAuditBytes)(audit)) throw new _src_core.ScaffoldError("INVALID", "repair requires a bounded audit snapshot");
|
|
3197
3246
|
const preview = (0, _orkestrel_contract.attempt)(() => structuredClone(audit));
|
|
3198
3247
|
if (!preview.success || !Array.isArray(preview.value.findings)) throw new _src_core.ScaffoldError("INVALID", "repair requires a structurally valid audit", { ...preview.success ? {} : { error: preview.error } });
|
|
3199
|
-
const
|
|
3248
|
+
const selectedPaths = new Set(preview.value.findings.filter((finding) => finding.drift === "missing" || replace === true && finding.drift === "stale").map((finding) => finding.path));
|
|
3200
3249
|
const selected = {
|
|
3201
3250
|
...context,
|
|
3202
|
-
artifacts: context.artifacts.filter((artifact) =>
|
|
3251
|
+
artifacts: context.artifacts.filter((artifact) => selectedPaths.has(artifact.path))
|
|
3203
3252
|
};
|
|
3204
3253
|
const prepared = this.#prepare(selected, target, context);
|
|
3205
3254
|
const preparedByPath = new Map(prepared.artifacts.map((artifact) => [artifact.path, artifact]));
|
|
@@ -3223,7 +3272,7 @@ var Materializer = class {
|
|
|
3223
3272
|
throw new _src_core.ScaffoldError("INVALID", `Repair precondition is missing at ${artifact.path}`, { path: artifact.path });
|
|
3224
3273
|
});
|
|
3225
3274
|
const skipped = [];
|
|
3226
|
-
for (const artifact of context.artifacts) if (!
|
|
3275
|
+
for (const artifact of context.artifacts) if (!selectedPaths.has(artifact.path)) skipped.push(artifact.path);
|
|
3227
3276
|
const { written, copied } = this.#apply(prepared, target, preconditions);
|
|
3228
3277
|
const result = {
|
|
3229
3278
|
target,
|
|
@@ -4190,6 +4239,7 @@ exports.createWriteDirectory = createWriteDirectory;
|
|
|
4190
4239
|
exports.deriveBlueprint = deriveBlueprint;
|
|
4191
4240
|
exports.digestFile = digestFile;
|
|
4192
4241
|
exports.digestHex = digestHex;
|
|
4242
|
+
exports.digestHostManifest = digestHostManifest;
|
|
4193
4243
|
exports.digestText = digestText;
|
|
4194
4244
|
exports.discardWriteTransaction = discardWriteTransaction;
|
|
4195
4245
|
exports.discoverPackages = discoverPackages;
|