@orkestrel/scaffold 0.0.60 → 0.0.62
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 +13 -10
- package/dist/bin/main.js +632 -320
- package/dist/bin/main.js.map +1 -1
- package/dist/host/CLAUDE.md +5 -1
- package/dist/host/agents/orchestration.md +44 -19
- package/dist/host/agents/skills/enterprise-bootstrap/references/components.md +5 -5
- package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +2 -2
- package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +10 -9
- package/dist/host/agents/skills/orkestrel-falsify/SKILL.md +21 -11
- package/dist/host/agents/skills/orkestrel-falsify/references/brief.md +20 -2
- package/dist/host/agents/skills/orkestrel-harden-package/SKILL.md +1 -1
- package/dist/host/agents/skills/orkestrel-harden-package/references/hardening.md +1 -1
- package/dist/host/agents/skills/orkestrel-harden-package/references/research.md +1 -1
- package/dist/host/agents/templates/brief.md +16 -7
- package/dist/host/agents/transports/claude.md +4 -2
- package/dist/host/agents/transports/codex.md +4 -1
- package/dist/host/claude/agents/analyst.md +3 -1
- package/dist/host/claude/agents/application.md +1 -1
- package/dist/host/claude/agents/builder.md +3 -3
- package/dist/host/claude/agents/checker.md +5 -0
- package/dist/host/claude/agents/grok.md +15 -5
- package/dist/host/claude/agents/implementer.md +1 -1
- package/dist/host/claude/agents/orkestrel.md +2 -2
- package/dist/host/claude/agents/planner.md +10 -0
- package/dist/host/claude/agents/reviewer.md +14 -8
- package/dist/host/claude/agents/sol.md +3 -1
- package/dist/host/claude/agents/verifier.md +2 -4
- package/dist/host/claude/rules/architecture.md +7 -5
- package/dist/host/claude/rules/documentation.md +1 -0
- package/dist/host/claude/rules/names.md +23 -5
- package/dist/host/claude/rules/patterns.md +1 -0
- package/dist/host/claude/rules/quality.md +1 -1
- package/dist/host/claude/rules/tests.md +3 -3
- package/dist/host/claude/rules/typescript.md +4 -1
- package/dist/host/claude/rules/writing.md +2 -2
- package/dist/host/codex/agents/builder.toml +6 -6
- package/dist/host/codex/agents/checker.toml +2 -1
- package/dist/host/codex/agents/grok.toml +12 -5
- package/dist/host/codex/agents/implementer.toml +2 -2
- package/dist/host/codex/agents/opus.toml +6 -1
- package/dist/host/codex/agents/planner.toml +11 -6
- package/dist/host/codex/agents/reviewer.toml +8 -6
- package/dist/host/guides/scaffold.md +39 -14
- package/dist/host/manifest.json +41 -41
- package/dist/host/scripts/codex.sh +0 -0
- package/dist/host/scripts/cursor.sh +0 -0
- package/dist/host/scripts/deps.sh +0 -0
- package/dist/host/scripts/ollama.sh +0 -0
- package/dist/src/core/index.cjs +429 -287
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +361 -220
- package/dist/src/core/index.d.ts +361 -220
- package/dist/src/core/index.js +426 -288
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +208 -170
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +276 -152
- package/dist/src/server/index.d.ts +276 -152
- package/dist/src/server/index.js +200 -172
- package/dist/src/server/index.js.map +1 -1
- package/package.json +13 -12
package/dist/src/core/index.cjs
CHANGED
|
@@ -4,7 +4,7 @@ let _orkestrel_template = require("@orkestrel/template");
|
|
|
4
4
|
let _orkestrel_emitter = require("@orkestrel/emitter");
|
|
5
5
|
var package_default = {
|
|
6
6
|
name: "@orkestrel/scaffold",
|
|
7
|
-
version: "0.0.
|
|
7
|
+
version: "0.0.62",
|
|
8
8
|
description: "Scaffold workspaces with five commands: new, audit, repair, catalog, and overwrite.",
|
|
9
9
|
keywords: [
|
|
10
10
|
"audit",
|
|
@@ -59,7 +59,7 @@ var package_default = {
|
|
|
59
59
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
60
60
|
"copy": "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
61
61
|
"scaffold": "node ./dist/bin/main.js",
|
|
62
|
-
"lint": "oxlint --config .oxlintrc.json --fix
|
|
62
|
+
"lint": "oxlint --config .oxlintrc.json --fix .",
|
|
63
63
|
"check": "tsc --noEmit --project tsconfig.json && npm run check:src",
|
|
64
64
|
"check:src": "npm run check:src:core && npm run check:src:server && npm run check:src:bin",
|
|
65
65
|
"check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
|
|
@@ -68,7 +68,7 @@ var package_default = {
|
|
|
68
68
|
"format": "oxfmt --config .oxfmtrc.json --write .",
|
|
69
69
|
"format:check": "oxfmt --config .oxfmtrc.json --check .",
|
|
70
70
|
"lint:check": "oxlint --config .oxlintrc.json --deny-warnings .",
|
|
71
|
-
"test": "npm run test:src:core && npm run test:src:server && npm run test:src:bin && npm run test:policy && npm run test:config && npm run test:guides",
|
|
71
|
+
"test": "npm run test:src:core && npm run test:src:server && npm run test:src:bin && npm run test:policy && npm run test:config && npm run test:setup && npm run test:guides",
|
|
72
72
|
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
73
73
|
"test:src:server": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:server",
|
|
74
74
|
"test:src:bin": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:bin",
|
|
@@ -78,6 +78,7 @@ var package_default = {
|
|
|
78
78
|
"test:distribution": "vitest run --config vite.config.ts --no-cache --reporter=dot --project distribution",
|
|
79
79
|
"test:probe": "vitest run --config vite.config.ts --no-cache --reporter=verbose --project probe",
|
|
80
80
|
"test:bench": "vitest bench --config vite.config.ts --no-cache --project probe",
|
|
81
|
+
"test:setup": "vitest run --config vite.config.ts --no-cache --reporter=dot --project setup",
|
|
81
82
|
"build": "npm run clean && npm run build:src && npm run build:host && npm run build:inventory",
|
|
82
83
|
"build:src": "npm run build:src:core && npm run build:src:server && npm run build:src:bin",
|
|
83
84
|
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
@@ -89,19 +90,19 @@ var package_default = {
|
|
|
89
90
|
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test && npm run test:distribution -- --mode release"
|
|
90
91
|
},
|
|
91
92
|
dependencies: {
|
|
92
|
-
"@orkestrel/console": "^0.0.
|
|
93
|
-
"@orkestrel/contract": "^0.0.
|
|
94
|
-
"@orkestrel/emitter": "^0.0.
|
|
95
|
-
"@orkestrel/markdown": "^0.0.
|
|
96
|
-
"@orkestrel/process": "^0.0.
|
|
97
|
-
"@orkestrel/template": "^0.0.
|
|
93
|
+
"@orkestrel/console": "^0.0.12",
|
|
94
|
+
"@orkestrel/contract": "^0.0.16",
|
|
95
|
+
"@orkestrel/emitter": "^0.0.9",
|
|
96
|
+
"@orkestrel/markdown": "^0.0.13",
|
|
97
|
+
"@orkestrel/process": "^0.0.10",
|
|
98
|
+
"@orkestrel/template": "^0.0.6"
|
|
98
99
|
},
|
|
99
100
|
devDependencies: {
|
|
100
101
|
"@microsoft/api-extractor": "^7.59.0",
|
|
101
|
-
"@orkestrel/guide": "^0.0.
|
|
102
|
-
"@orkestrel/html": "^0.0.
|
|
102
|
+
"@orkestrel/guide": "^0.0.16",
|
|
103
|
+
"@orkestrel/html": "^0.0.8",
|
|
103
104
|
"@orkestrel/probe": "^0.0.11",
|
|
104
|
-
"@orkestrel/test": "^0.0.
|
|
105
|
+
"@orkestrel/test": "^0.0.13",
|
|
105
106
|
"@types/node": "^26.4.0",
|
|
106
107
|
"@vitest/browser-playwright": "^4.1.11",
|
|
107
108
|
"oxfmt": "^0.65.0",
|
|
@@ -117,7 +118,7 @@ var package_default = {
|
|
|
117
118
|
//#endregion
|
|
118
119
|
//#region src/core/constants.ts
|
|
119
120
|
/**
|
|
120
|
-
*
|
|
121
|
+
* Lists the `Environment` values, frozen.
|
|
121
122
|
*
|
|
122
123
|
* @remarks
|
|
123
124
|
* A blueprint's `src` and `app` axes are caller-supplied, so the gate measures
|
|
@@ -131,7 +132,7 @@ var ENVIRONMENTS = Object.freeze([
|
|
|
131
132
|
"server"
|
|
132
133
|
]);
|
|
133
134
|
/**
|
|
134
|
-
*
|
|
135
|
+
* Lists the `Group` values in plan order, frozen.
|
|
135
136
|
*
|
|
136
137
|
* @remarks
|
|
137
138
|
* A compile that names no groups covers every one of them, so this list is the
|
|
@@ -148,7 +149,7 @@ var GROUPS = Object.freeze([
|
|
|
148
149
|
"orchestration"
|
|
149
150
|
]);
|
|
150
151
|
/**
|
|
151
|
-
*
|
|
152
|
+
* Holds the build and export settings each published `src` environment contributes, frozen.
|
|
152
153
|
*
|
|
153
154
|
* @remarks
|
|
154
155
|
* Per environment: the thin configuration files it adds under `configs/src`,
|
|
@@ -178,7 +179,8 @@ var SRC_MATRIX = Object.freeze({
|
|
|
178
179
|
})
|
|
179
180
|
});
|
|
180
181
|
/**
|
|
181
|
-
*
|
|
182
|
+
* Holds the configuration and runtime-entry settings each private `app` environment
|
|
183
|
+
* contributes, frozen.
|
|
182
184
|
*
|
|
183
185
|
* @remarks
|
|
184
186
|
* An application environment declares no exports, so it carries a runtime
|
|
@@ -201,24 +203,25 @@ var APP_MATRIX = Object.freeze({
|
|
|
201
203
|
entry: "app/server/main.ts"
|
|
202
204
|
})
|
|
203
205
|
});
|
|
204
|
-
/**
|
|
206
|
+
/** Lists the configuration files a workspace that ships its own executable adds, frozen. */
|
|
205
207
|
var BIN_CONFIGS = Object.freeze(["configs/src/vite.bin.config.ts", "configs/src/tsconfig.bin.json"]);
|
|
206
|
-
/**
|
|
208
|
+
/** Names the executable entry whose presence makes a workspace `bin`. */
|
|
207
209
|
var BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
208
210
|
/**
|
|
209
|
-
*
|
|
211
|
+
* Lists the paths a target receives from the vendored data root, frozen.
|
|
210
212
|
*
|
|
211
213
|
* @remarks
|
|
212
|
-
* These are the files the fleet shares verbatim and
|
|
213
|
-
* of: the licence, the harness permission file, the
|
|
214
|
-
* shared policy register, the
|
|
215
|
-
*
|
|
216
|
-
*
|
|
214
|
+
* These are the files the fleet shares verbatim, and each target holds a copy
|
|
215
|
+
* of the paths it selects: the licence, the harness permission file, the
|
|
216
|
+
* session-start hooks, the shared policy register, the shared policy proof,
|
|
217
|
+
* the shared policy plugin, the shared configuration leaf and its proof, the
|
|
218
|
+
* byte-identical root dotfiles, and the guide mirrors a generated workspace
|
|
219
|
+
* starts from. A directory entry vendors everything beneath it.
|
|
217
220
|
*
|
|
218
221
|
* A plan carries the subset its target selects, which is why the list is a
|
|
219
222
|
* candidate set rather than a plan: a workspace never mirrors its own guide.
|
|
220
223
|
*
|
|
221
|
-
* Neither the instruction canon nor the
|
|
224
|
+
* Neither the instruction canon nor the bench and MCP wiring is here. A target reads
|
|
222
225
|
* its rules, its skills, its agent roles, its bench configuration, and its MCP
|
|
223
226
|
* registrations from {@link CANON_PATHS} inside the installed package, so no
|
|
224
227
|
* file scaffold leaves in a target names a path the target does not hold.
|
|
@@ -248,7 +251,7 @@ var HOST_PATHS = Object.freeze([
|
|
|
248
251
|
"guides/scaffold.md"
|
|
249
252
|
]);
|
|
250
253
|
/**
|
|
251
|
-
*
|
|
254
|
+
* Lists the instruction-canon paths staged for reading rather than for a target, frozen.
|
|
252
255
|
*
|
|
253
256
|
* @remarks
|
|
254
257
|
* The root instruction documents, the orchestration contract every harness
|
|
@@ -294,10 +297,10 @@ var CANON_PATHS = Object.freeze([
|
|
|
294
297
|
".cursor/mcp.json",
|
|
295
298
|
".cursor/rules"
|
|
296
299
|
]);
|
|
297
|
-
/**
|
|
300
|
+
/** Names the repository-relative path where the committed vendored-file inventory is served. */
|
|
298
301
|
var HOST_INVENTORY_PATH = "host.json";
|
|
299
302
|
/**
|
|
300
|
-
*
|
|
303
|
+
* Lists the vendored paths whose present bytes belong to each workspace, frozen.
|
|
301
304
|
*
|
|
302
305
|
* @remarks
|
|
303
306
|
* These paths are copied into a workspace when absent and are never compared
|
|
@@ -307,7 +310,7 @@ var HOST_INVENTORY_PATH = "host.json";
|
|
|
307
310
|
*/
|
|
308
311
|
var WORKSPACE_OWNED_PATHS = Object.freeze([".gitignore"]);
|
|
309
312
|
/**
|
|
310
|
-
*
|
|
313
|
+
* Lists the vendored paths a target receives with its executable bit set, frozen.
|
|
311
314
|
*
|
|
312
315
|
* @remarks
|
|
313
316
|
* Declared rather than read from the staging host's filesystem, because that
|
|
@@ -326,7 +329,7 @@ var EXECUTABLE_PATHS = Object.freeze([
|
|
|
326
329
|
"scripts/ollama.sh"
|
|
327
330
|
]);
|
|
328
331
|
/**
|
|
329
|
-
*
|
|
332
|
+
* Lists the path prefixes whose contents instruct or wire an agent, frozen.
|
|
330
333
|
*
|
|
331
334
|
* @remarks
|
|
332
335
|
* A path is grouped by what it governs rather than by where it sits: anything
|
|
@@ -344,7 +347,7 @@ var ORCHESTRATION_PATH_PREFIXES = Object.freeze([
|
|
|
344
347
|
"scripts/"
|
|
345
348
|
]);
|
|
346
349
|
/**
|
|
347
|
-
*
|
|
350
|
+
* Lists the exact root filenames that wire an agent bench rather than the toolchain, frozen.
|
|
348
351
|
*
|
|
349
352
|
* @remarks
|
|
350
353
|
* `.mcp.json` registers MCP servers for the harness. It sits among the root
|
|
@@ -352,7 +355,7 @@ var ORCHESTRATION_PATH_PREFIXES = Object.freeze([
|
|
|
352
355
|
*/
|
|
353
356
|
var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json"]);
|
|
354
357
|
/**
|
|
355
|
-
*
|
|
358
|
+
* Names the agent file whose marker-bounded package table the catalog verb alone owns.
|
|
356
359
|
*
|
|
357
360
|
* @remarks
|
|
358
361
|
* A plan claims it at a canon path, because the catalog verb refuses a target
|
|
@@ -366,16 +369,34 @@ var ORCHESTRATION_PATH_NAMES = Object.freeze([".mcp.json"]);
|
|
|
366
369
|
* inside the markers.
|
|
367
370
|
*/
|
|
368
371
|
var CATALOG_AGENT_PATH = ".claude/agents/orkestrel.md";
|
|
369
|
-
/**
|
|
372
|
+
/**
|
|
373
|
+
* Names the marker opening the package table inside {@link CATALOG_AGENT_PATH}.
|
|
374
|
+
*
|
|
375
|
+
* @remarks
|
|
376
|
+
* The catalog verb rewrites the region between this marker and
|
|
377
|
+
* {@link CATALOG_CLOSING_MARKER} and leaves every other byte of the file alone,
|
|
378
|
+
* so the writer and every proof that reads the rendered file read the pair from
|
|
379
|
+
* here rather than repeating a literal that only agrees by inspection.
|
|
380
|
+
*/
|
|
381
|
+
var CATALOG_OPENING_MARKER = "<!-- orkestrel:catalog -->";
|
|
382
|
+
/**
|
|
383
|
+
* Names the marker closing the package table inside {@link CATALOG_AGENT_PATH}.
|
|
384
|
+
*
|
|
385
|
+
* @remarks
|
|
386
|
+
* It pairs with {@link CATALOG_OPENING_MARKER}; a file missing either marker is
|
|
387
|
+
* refused rather than rewritten.
|
|
388
|
+
*/
|
|
389
|
+
var CATALOG_CLOSING_MARKER = "<!-- /orkestrel:catalog -->";
|
|
390
|
+
/** Names the provisioner skeleton a workspace with declared service vendors is given once. */
|
|
370
391
|
var SERVICE_SCRIPT_PATH = "scripts/service.sh";
|
|
371
|
-
/**
|
|
392
|
+
/** Names the shared Vitest global-setup module whose presence makes a workspace `global`. */
|
|
372
393
|
var GLOBAL_SETUP_PATH = "tests/setupGlobal.ts";
|
|
373
|
-
/**
|
|
394
|
+
/** Names the guide-parity proof whose presence selects the planned `guides` project. */
|
|
374
395
|
var GUIDES_TEST_PATH = "tests/guides.test.ts";
|
|
375
|
-
/**
|
|
396
|
+
/** Names the generated packed-package proof every publishing workspace is planned at. */
|
|
376
397
|
var DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
|
|
377
398
|
/**
|
|
378
|
-
*
|
|
399
|
+
* Names the `prepublishOnly` row that runs the packed-package proof against a real registry.
|
|
379
400
|
*
|
|
380
401
|
* @remarks
|
|
381
402
|
* The proof reads `import.meta.env.MODE`, so without `--mode release` it passes
|
|
@@ -383,22 +404,28 @@ var DISTRIBUTION_TEST_PATH = "tests/distribution.test.ts";
|
|
|
383
404
|
* and both the script compiler and the manifest region writer read it from here.
|
|
384
405
|
*/
|
|
385
406
|
var RELEASE_PROOF_COMMAND = "npm run test:distribution -- --mode release";
|
|
386
|
-
/**
|
|
407
|
+
/**
|
|
408
|
+
* Names the cross-environment composition proof whose presence makes a workspace
|
|
409
|
+
* `integration`.
|
|
410
|
+
*/
|
|
387
411
|
var INTEGRATION_TEST_PATH = "tests/integration.test.ts";
|
|
388
|
-
/**
|
|
412
|
+
/** Names the manifest path every compiler plan emits with birth ownership. */
|
|
389
413
|
var MANIFEST_PATH = "package.json";
|
|
390
|
-
/**
|
|
414
|
+
/** Names the official-tooling drift proof whose presence makes a workspace `conformance`. */
|
|
391
415
|
var CONFORMANCE_TEST_PATH = "tests/conformance.test.ts";
|
|
392
|
-
/**
|
|
416
|
+
/** Names the live-service readiness module whose presence makes a workspace `service`. */
|
|
393
417
|
var SERVICE_SETUP_PATH = "tests/setupService.ts";
|
|
394
|
-
/**
|
|
418
|
+
/**
|
|
419
|
+
* Names the include the live-service project covers, which is a directory rather than
|
|
420
|
+
* one proof.
|
|
421
|
+
*/
|
|
395
422
|
var SERVICE_TEST_INCLUDE = "tests/service/**/*.test.ts";
|
|
396
|
-
/**
|
|
423
|
+
/** Names the Vite wrapper whose presence makes a workspace `showcase`. */
|
|
397
424
|
var SHOWCASE_CONFIG_PATH = "configs/app/vite.showcase.config.ts";
|
|
398
|
-
/**
|
|
425
|
+
/** Matches the bare workspace name syntax: lowercase alphanumeric with hyphens, letter first. */
|
|
399
426
|
var NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
400
427
|
/**
|
|
401
|
-
*
|
|
428
|
+
* Matches the runtime dependency name syntax: the `@orkestrel` scope and a bare name.
|
|
402
429
|
*
|
|
403
430
|
* @remarks
|
|
404
431
|
* A dependency name reaches a path, because a workspace's guide mirror is
|
|
@@ -408,7 +435,7 @@ var NAME_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
|
408
435
|
*/
|
|
409
436
|
var DEPENDENCY_NAME_PATTERN = /^@orkestrel\/[a-z][a-z0-9-]*$/;
|
|
410
437
|
/**
|
|
411
|
-
*
|
|
438
|
+
* Matches the package name syntax for a dependency this package does not publish.
|
|
412
439
|
*
|
|
413
440
|
* @remarks
|
|
414
441
|
* A foreign package is one this package does not publish, so its name reaches
|
|
@@ -418,10 +445,10 @@ var DEPENDENCY_NAME_PATTERN = /^@orkestrel\/[a-z][a-z0-9-]*$/;
|
|
|
418
445
|
* is admitted, so the shape cannot express a traversal.
|
|
419
446
|
*/
|
|
420
447
|
var FOREIGN_NAME_PATTERN = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
|
|
421
|
-
/**
|
|
448
|
+
/** Matches the exact `major.minor.patch` version syntax a blueprint declares. */
|
|
422
449
|
var VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
423
450
|
/**
|
|
424
|
-
*
|
|
451
|
+
* Matches the exact caret-pinned pre-1.0 range accepted for an `@orkestrel/*` runtime dependency.
|
|
425
452
|
*
|
|
426
453
|
* @remarks
|
|
427
454
|
* Pre-1.0 means any `0.x`, not `0.0.x`. The narrower form would refuse the first
|
|
@@ -430,10 +457,10 @@ var VERSION_PATTERN = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
|
430
457
|
* workspace that had already been pinned to it.
|
|
431
458
|
*/
|
|
432
459
|
var ORKESTREL_RANGE_PATTERN = /^\^0\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
433
|
-
/**
|
|
460
|
+
/** Matches the registry-only semver subset accepted for a development extra's range. */
|
|
434
461
|
var EXTRA_RANGE_PATTERN = /^(?:\^|~)?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?$/;
|
|
435
462
|
/**
|
|
436
|
-
*
|
|
463
|
+
* Matches the exact `major.minor.patch` floor accepted for a foreign peer's range.
|
|
437
464
|
*
|
|
438
465
|
* @remarks
|
|
439
466
|
* This is independent from {@link ENGINES_PATTERN}. An engine floors the Node
|
|
@@ -441,44 +468,47 @@ var EXTRA_RANGE_PATTERN = /^(?:\^|~)?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\
|
|
|
441
468
|
* supplies. Either obligation may change without changing the other.
|
|
442
469
|
*/
|
|
443
470
|
var FLOOR_RANGE_PATTERN = /^>=(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
444
|
-
/**
|
|
471
|
+
/** Matches the minimum-Node engine syntax a blueprint declares. */
|
|
445
472
|
var ENGINES_PATTERN = /^>=(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)$/;
|
|
446
|
-
/**
|
|
473
|
+
/** Matches exact lowercase hexadecimal bytes: two digits per byte, and empty content is valid. */
|
|
447
474
|
var HEX_PATTERN = /^(?:[0-9a-f]{2})*$/;
|
|
448
|
-
/**
|
|
475
|
+
/**
|
|
476
|
+
* Matches the Unicode controls, formatting controls, and line and paragraph separators
|
|
477
|
+
* rejected in text.
|
|
478
|
+
*/
|
|
449
479
|
var CONTROL_CHARACTER_PATTERN = /[\p{Cc}\p{Cf}\p{Zl}\p{Zp}]/u;
|
|
450
|
-
/**
|
|
480
|
+
/** Matches the visible characters a target-relative path and a Markdown path cell both forbid. */
|
|
451
481
|
var INVALID_PATH_CHARACTER_PATTERN = /[<>:"|?*\\]/;
|
|
452
482
|
/**
|
|
453
|
-
*
|
|
483
|
+
* Caps the bare workspace name length.
|
|
454
484
|
*
|
|
455
485
|
* @remarks
|
|
456
486
|
* The registry caps a whole package name at 214 characters and the generated
|
|
457
487
|
* scope `@orkestrel/` spends 11 of them.
|
|
458
488
|
*/
|
|
459
489
|
var MAX_NAME_LENGTH = 203;
|
|
460
|
-
/**
|
|
490
|
+
/** Sets the maximum dependency package name length, scope included, as the registry caps it. */
|
|
461
491
|
var MAX_DEPENDENCY_NAME_LENGTH = 214;
|
|
462
|
-
/**
|
|
492
|
+
/** Caps the length of one declared package range. */
|
|
463
493
|
var MAX_RANGE_LENGTH = 2048;
|
|
464
|
-
/**
|
|
494
|
+
/** Caps the length of one manifest script name or command. */
|
|
465
495
|
var MAX_SCRIPT_LENGTH = 4096;
|
|
466
|
-
/**
|
|
496
|
+
/** Caps the length of one path, matching the longest a supported filesystem accepts. */
|
|
467
497
|
var MAX_PATH_LENGTH = 32767;
|
|
468
|
-
/**
|
|
498
|
+
/** Caps the items accepted in one public collection. */
|
|
469
499
|
var MAX_COLLECTION_ITEMS = 1e3;
|
|
470
|
-
/**
|
|
500
|
+
/** Caps the columns one emitted line may occupy, matching `printWidth` in `.oxfmtrc.json`. */
|
|
471
501
|
var PRINT_WIDTH = 100;
|
|
472
|
-
/**
|
|
502
|
+
/** Sets the columns one tab occupies when the formatter measures a line, matching `tabWidth`. */
|
|
473
503
|
var TAB_WIDTH = 2;
|
|
474
|
-
/**
|
|
504
|
+
/** Caps the findings one audit can produce from a bounded plan and snapshot. */
|
|
475
505
|
var MAX_AUDIT_FINDINGS = MAX_COLLECTION_ITEMS * 2;
|
|
476
|
-
/**
|
|
506
|
+
/** Caps the bytes accepted for one artifact. */
|
|
477
507
|
var MAX_ARTIFACT_BYTES = 5242880;
|
|
478
|
-
/**
|
|
508
|
+
/** Caps the length of the hexadecimal string carrying one artifact's bytes. */
|
|
479
509
|
var MAX_ARTIFACT_HEX_LENGTH = MAX_ARTIFACT_BYTES * 2;
|
|
480
510
|
/**
|
|
481
|
-
*
|
|
511
|
+
* Caps the decoded bytes accepted from one registry response.
|
|
482
512
|
*
|
|
483
513
|
* @remarks
|
|
484
514
|
* The 2026-08-21 abbreviated-packument measurements were 8,647,138 bytes for
|
|
@@ -488,24 +518,24 @@ var MAX_ARTIFACT_HEX_LENGTH = MAX_ARTIFACT_BYTES * 2;
|
|
|
488
518
|
*/
|
|
489
519
|
var MAX_REGISTRY_BYTES = 33554432;
|
|
490
520
|
/**
|
|
491
|
-
*
|
|
521
|
+
* Caps the decoded bytes accepted across one registry-reading call.
|
|
492
522
|
*
|
|
493
523
|
* @remarks
|
|
494
524
|
* The 2026-08-21 browser-workspace registry set measured about 24 MiB. The
|
|
495
525
|
* bound leaves headroom for that set to grow without making a call unbounded.
|
|
496
526
|
*/
|
|
497
527
|
var MAX_TOTAL_REGISTRY_BYTES = 100663296;
|
|
498
|
-
/**
|
|
528
|
+
/** Caps the bytes accepted for one package or vendored-host manifest. */
|
|
499
529
|
var MAX_MANIFEST_BYTES = 1048576;
|
|
500
|
-
/**
|
|
530
|
+
/** Caps the bytes retained across one whole plan or audit. */
|
|
501
531
|
var MAX_TOTAL_ARTIFACT_BYTES = 104857600;
|
|
502
|
-
/**
|
|
532
|
+
/** Names the oldest Node version the generated toolchain supports. */
|
|
503
533
|
var MINIMUM_NODE_VERSION = "22.12.0";
|
|
504
|
-
/**
|
|
534
|
+
/** Names the version a workspace starts at. */
|
|
505
535
|
var DEFAULT_VERSION = "0.0.1";
|
|
506
|
-
/**
|
|
536
|
+
/** Names the `engines.node` range a workspace starts with. */
|
|
507
537
|
var DEFAULT_ENGINES = `>=${MINIMUM_NODE_VERSION}`;
|
|
508
|
-
/**
|
|
538
|
+
/** Holds the tooling versions scaffold and every generated workspace share. */
|
|
509
539
|
var BASE_DEV_DEPENDENCIES = Object.freeze({
|
|
510
540
|
"@orkestrel/guide": package_default.devDependencies["@orkestrel/guide"],
|
|
511
541
|
"@orkestrel/probe": package_default.devDependencies["@orkestrel/probe"],
|
|
@@ -518,19 +548,22 @@ var BASE_DEV_DEPENDENCIES = Object.freeze({
|
|
|
518
548
|
vite: package_default.devDependencies.vite,
|
|
519
549
|
vitest: package_default.devDependencies.vitest
|
|
520
550
|
});
|
|
521
|
-
/**
|
|
551
|
+
/**
|
|
552
|
+
* Lists the development dependencies that emit declarations for published source or an
|
|
553
|
+
* executable.
|
|
554
|
+
*/
|
|
522
555
|
var DECLARATION_DEV_DEPENDENCIES = Object.freeze({
|
|
523
556
|
"@microsoft/api-extractor": package_default.devDependencies["@microsoft/api-extractor"],
|
|
524
557
|
"vite-plugin-dts": package_default.devDependencies["vite-plugin-dts"]
|
|
525
558
|
});
|
|
526
|
-
/**
|
|
559
|
+
/** Lists the development dependencies a published browser `src` environment adds. */
|
|
527
560
|
var SOURCE_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
528
561
|
"@vitest/browser-playwright": package_default.devDependencies["@vitest/browser-playwright"],
|
|
529
562
|
playwright: package_default.devDependencies.playwright
|
|
530
563
|
});
|
|
531
|
-
/**
|
|
564
|
+
/** Names the development dependency every private `app` environment adds. */
|
|
532
565
|
var APP_DEV_DEPENDENCIES = Object.freeze({ "@orkestrel/contract": package_default.dependencies["@orkestrel/contract"] });
|
|
533
|
-
/**
|
|
566
|
+
/** Lists the development dependencies a private Vue browser application adds. */
|
|
534
567
|
var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
535
568
|
...SOURCE_BROWSER_DEV_DEPENDENCIES,
|
|
536
569
|
"@orkestrel/html": package_default.devDependencies["@orkestrel/html"],
|
|
@@ -539,7 +572,7 @@ var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
539
572
|
"vue-tsc": "^3.3.7"
|
|
540
573
|
});
|
|
541
574
|
/**
|
|
542
|
-
*
|
|
575
|
+
* Names the development dependency used only by the optional single-file showcase build.
|
|
543
576
|
*
|
|
544
577
|
* @example
|
|
545
578
|
* ```ts
|
|
@@ -549,7 +582,7 @@ var APP_BROWSER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
549
582
|
* ```
|
|
550
583
|
*/
|
|
551
584
|
var SHOWCASE_DEV_DEPENDENCIES = Object.freeze({ "vite-plugin-singlefile": "^2.3.3" });
|
|
552
|
-
/**
|
|
585
|
+
/** Lists the development dependencies a private server application adds. */
|
|
553
586
|
var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
|
|
554
587
|
"@orkestrel/emitter": package_default.dependencies["@orkestrel/emitter"],
|
|
555
588
|
"@orkestrel/middleware": "^0.0.16",
|
|
@@ -559,7 +592,7 @@ var APP_SERVER_DEV_DEPENDENCIES = Object.freeze({
|
|
|
559
592
|
//#endregion
|
|
560
593
|
//#region src/core/templates.ts
|
|
561
594
|
/**
|
|
562
|
-
*
|
|
595
|
+
* Holds formatter-stable template text for every configuration artifact.
|
|
563
596
|
*
|
|
564
597
|
* @remarks
|
|
565
598
|
* Builders in `compilers.ts` fill these definitions through
|
|
@@ -1230,8 +1263,8 @@ import { accessSync, constants as FS_CONSTANTS, globSync, readdirSync, statSync
|
|
|
1230
1263
|
import { basename, dirname, join, resolve as resolvePath } from 'node:path'
|
|
1231
1264
|
|
|
1232
1265
|
/**
|
|
1233
|
-
* Chromium executable layouts inside a \`chromium-<revision>\` browsers-directory
|
|
1234
|
-
* platform.
|
|
1266
|
+
* Lists the Chromium executable layouts inside a \`chromium-<revision>\` browsers-directory
|
|
1267
|
+
* entry, per platform.
|
|
1235
1268
|
*
|
|
1236
1269
|
* @remarks
|
|
1237
1270
|
* The current Playwright build ships Chrome for Testing on macOS. The trailing \`Chromium.app\`
|
|
@@ -1249,17 +1282,17 @@ export const CHROMIUM_LAYOUTS = Object.freeze([
|
|
|
1249
1282
|
'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',
|
|
1250
1283
|
])
|
|
1251
1284
|
|
|
1252
|
-
/**
|
|
1285
|
+
/** Matches the \`chromium-<revision>\` entry name Playwright installs one managed build into. */
|
|
1253
1286
|
export const CHROMIUM_ENTRY_PATTERN = /^chromium-\\d+$/
|
|
1254
1287
|
|
|
1255
|
-
/**
|
|
1288
|
+
/** Matches the revision number carried by any path containing a \`chromium-<revision>\` segment. */
|
|
1256
1289
|
export const CHROMIUM_REVISION_PATTERN = /chromium-(\\d+)/
|
|
1257
1290
|
|
|
1258
|
-
/**
|
|
1291
|
+
/** Names the directory a managed Linux container installs its bundled Playwright browsers into. */
|
|
1259
1292
|
export const BUNDLED_BROWSERS_ROOT = '/opt/pw-browsers'
|
|
1260
1293
|
|
|
1261
1294
|
/**
|
|
1262
|
-
*
|
|
1295
|
+
* Lists the bundled Chromium layouts under the managed-container browsers root, as glob patterns.
|
|
1263
1296
|
*
|
|
1264
1297
|
* @remarks
|
|
1265
1298
|
* The revision directory and its inner layout both drift across Playwright builds, and the
|
|
@@ -1271,7 +1304,7 @@ export const BUNDLED_CHROMIUM_LAYOUTS = Object.freeze([
|
|
|
1271
1304
|
'chromium-*/chrome-linux/chrome',
|
|
1272
1305
|
])
|
|
1273
1306
|
|
|
1274
|
-
/**
|
|
1307
|
+
/** Lists the stable Playwright Chromium channels and their standard executable layouts. */
|
|
1275
1308
|
export const SYSTEM_BROWSER_CHANNELS = Object.freeze([
|
|
1276
1309
|
Object.freeze({
|
|
1277
1310
|
channel: 'chrome',
|
|
@@ -1292,10 +1325,10 @@ export const SYSTEM_BROWSER_CHANNELS = Object.freeze([
|
|
|
1292
1325
|
])
|
|
1293
1326
|
|
|
1294
1327
|
/**
|
|
1295
|
-
*
|
|
1328
|
+
* Determines whether a path identifies an executable regular file.
|
|
1296
1329
|
*
|
|
1297
1330
|
* @param path - The filesystem path to inspect.
|
|
1298
|
-
* @returns
|
|
1331
|
+
* @returns True if the path is a regular file with execute access; false otherwise.
|
|
1299
1332
|
*
|
|
1300
1333
|
* @example
|
|
1301
1334
|
* \`\`\`ts
|
|
@@ -1313,7 +1346,7 @@ export function isBrowserExecutable(path: string): boolean {
|
|
|
1313
1346
|
}
|
|
1314
1347
|
|
|
1315
1348
|
/**
|
|
1316
|
-
*
|
|
1349
|
+
* Orders two Chromium paths so the highest revision sorts first.
|
|
1317
1350
|
*
|
|
1318
1351
|
* @param left - The first path or directory entry to compare.
|
|
1319
1352
|
* @param right - The second path or directory entry to compare.
|
|
@@ -1336,7 +1369,7 @@ export function compareRevisions(left: string, right: string): number {
|
|
|
1336
1369
|
}
|
|
1337
1370
|
|
|
1338
1371
|
/**
|
|
1339
|
-
*
|
|
1372
|
+
* Reads the executable path of Playwright's pinned Chromium revision.
|
|
1340
1373
|
*
|
|
1341
1374
|
* @returns The pinned executable path, or \`undefined\` when this platform has none.
|
|
1342
1375
|
*
|
|
@@ -1359,7 +1392,7 @@ export function resolvePinnedBrowser(): string | undefined {
|
|
|
1359
1392
|
}
|
|
1360
1393
|
|
|
1361
1394
|
/**
|
|
1362
|
-
*
|
|
1395
|
+
* Resolves a launchable Playwright-managed Chromium executable: the pinned revision when installed,
|
|
1363
1396
|
* otherwise a \`chromium\` / \`chromium.exe\` alias or any other \`chromium-*\` revision under the same
|
|
1364
1397
|
* Playwright browsers directory. A pinned-revision miss is not Chromium absence — managed
|
|
1365
1398
|
* containers ship one usable build, often behind a revision-agnostic alias, for many Playwright
|
|
@@ -1406,7 +1439,7 @@ export function resolveManagedBrowser(pinned: string): string | undefined {
|
|
|
1406
1439
|
}
|
|
1407
1440
|
|
|
1408
1441
|
/**
|
|
1409
|
-
*
|
|
1442
|
+
* Resolves the Chromium a managed Linux container bundles outside the Playwright cache.
|
|
1410
1443
|
*
|
|
1411
1444
|
* @param platform - The Node platform the container runs on.
|
|
1412
1445
|
* @param root - The bundled browsers directory to search.
|
|
@@ -1435,7 +1468,7 @@ export function resolveBundledBrowser(platform: NodeJS.Platform, root: string):
|
|
|
1435
1468
|
}
|
|
1436
1469
|
|
|
1437
1470
|
/**
|
|
1438
|
-
*
|
|
1471
|
+
* Resolves the first installed stable system Chromium channel.
|
|
1439
1472
|
*
|
|
1440
1473
|
* @param platform - The Node platform whose standard layouts this call probes.
|
|
1441
1474
|
* @param environment - The process environment supplying Windows installation roots.
|
|
@@ -1479,7 +1512,7 @@ export function resolveSystemBrowser(
|
|
|
1479
1512
|
}
|
|
1480
1513
|
|
|
1481
1514
|
/**
|
|
1482
|
-
*
|
|
1515
|
+
* Resolves Playwright provider options for whatever browser this host can actually launch.
|
|
1483
1516
|
*
|
|
1484
1517
|
* @param pinned - The executable path for Playwright's pinned Chromium revision, when it has one.
|
|
1485
1518
|
* @param platform - The Node platform whose standard layouts this call probes.
|
|
@@ -1534,7 +1567,7 @@ export function resolveBrowser(
|
|
|
1534
1567
|
`
|
|
1535
1568
|
});
|
|
1536
1569
|
/**
|
|
1537
|
-
*
|
|
1570
|
+
* Holds formatter-stable template text for source, test, document, guide, and service artifacts.
|
|
1538
1571
|
*
|
|
1539
1572
|
* @remarks
|
|
1540
1573
|
* Builders in `compilers.ts` fill every varying span through
|
|
@@ -2628,7 +2661,7 @@ printf '%s\\n' \\
|
|
|
2628
2661
|
//#endregion
|
|
2629
2662
|
//#region src/core/errors.ts
|
|
2630
2663
|
/**
|
|
2631
|
-
*
|
|
2664
|
+
* Represents the one error this package throws, carrying the coded reason it was raised.
|
|
2632
2665
|
*
|
|
2633
2666
|
* @remarks
|
|
2634
2667
|
* Each code names one cause: `INVALID` for off-contract input, `DESTROYED` for
|
|
@@ -2665,7 +2698,7 @@ var ScaffoldError = class extends Error {
|
|
|
2665
2698
|
code;
|
|
2666
2699
|
context;
|
|
2667
2700
|
/**
|
|
2668
|
-
*
|
|
2701
|
+
* Constructs a coded scaffold error.
|
|
2669
2702
|
*
|
|
2670
2703
|
* @param code - The coded reason the error is raised.
|
|
2671
2704
|
* @param message - What went wrong, in one sentence.
|
|
@@ -2679,10 +2712,10 @@ var ScaffoldError = class extends Error {
|
|
|
2679
2712
|
}
|
|
2680
2713
|
};
|
|
2681
2714
|
/**
|
|
2682
|
-
*
|
|
2715
|
+
* Narrows a caught value to a {@link ScaffoldError}.
|
|
2683
2716
|
*
|
|
2684
2717
|
* @param value - The caught value to narrow.
|
|
2685
|
-
* @returns
|
|
2718
|
+
* @returns True if `value` is a {@link ScaffoldError}; false otherwise.
|
|
2686
2719
|
*
|
|
2687
2720
|
* @example
|
|
2688
2721
|
* ```ts
|
|
@@ -2698,11 +2731,11 @@ function isScaffoldError(value) {
|
|
|
2698
2731
|
//#endregion
|
|
2699
2732
|
//#region src/core/validators.ts
|
|
2700
2733
|
/**
|
|
2701
|
-
*
|
|
2734
|
+
* Narrows a value to a logical target-relative path.
|
|
2702
2735
|
*
|
|
2703
2736
|
* @param value - The candidate path.
|
|
2704
|
-
* @returns
|
|
2705
|
-
* control character, or reserved syntax character.
|
|
2737
|
+
* @returns True if the value is a bounded relative path with no traversal, empty
|
|
2738
|
+
* segment, control character, or reserved syntax character; false otherwise.
|
|
2706
2739
|
*
|
|
2707
2740
|
* @remarks
|
|
2708
2741
|
* Every path this package reads or writes passes here, so one law covers a
|
|
@@ -2731,7 +2764,7 @@ function isPath(value) {
|
|
|
2731
2764
|
});
|
|
2732
2765
|
}
|
|
2733
2766
|
/**
|
|
2734
|
-
*
|
|
2767
|
+
* Narrows a value to exact lowercase hexadecimal bytes within one artifact's limit.
|
|
2735
2768
|
*
|
|
2736
2769
|
* @remarks
|
|
2737
2770
|
* Two digits per byte, so an odd length is refused and empty content is valid.
|
|
@@ -2751,7 +2784,7 @@ var isHex = (0, _orkestrel_contract.stringOf)({
|
|
|
2751
2784
|
pattern: HEX_PATTERN
|
|
2752
2785
|
});
|
|
2753
2786
|
/**
|
|
2754
|
-
*
|
|
2787
|
+
* Narrows a value to text this package will accept as one artifact's content.
|
|
2755
2788
|
*
|
|
2756
2789
|
* @remarks
|
|
2757
2790
|
* The bound is a code-unit ceiling rather than a byte count, because a string
|
|
@@ -2762,10 +2795,11 @@ var isHex = (0, _orkestrel_contract.stringOf)({
|
|
|
2762
2795
|
*/
|
|
2763
2796
|
var isContent = (0, _orkestrel_contract.stringOf)({ max: MAX_ARTIFACT_BYTES });
|
|
2764
2797
|
/**
|
|
2765
|
-
*
|
|
2798
|
+
* Narrows a value to an array within the limit one public collection accepts.
|
|
2766
2799
|
*
|
|
2767
2800
|
* @param value - The candidate collection.
|
|
2768
|
-
* @returns
|
|
2801
|
+
* @returns True if the value is an array of no more than
|
|
2802
|
+
* `MAX_COLLECTION_ITEMS` items; false otherwise.
|
|
2769
2803
|
*
|
|
2770
2804
|
* @remarks
|
|
2771
2805
|
* Compose this ahead of an element guard so the item count is settled before
|
|
@@ -2784,7 +2818,7 @@ function isCollection(value) {
|
|
|
2784
2818
|
return (0, _orkestrel_contract.holds)(() => (0, _orkestrel_contract.isArray)(value) && value.length <= 1e3);
|
|
2785
2819
|
}
|
|
2786
2820
|
/**
|
|
2787
|
-
*
|
|
2821
|
+
* Narrows a value to one {@link Environment} a workspace may select.
|
|
2788
2822
|
*
|
|
2789
2823
|
* @example
|
|
2790
2824
|
* ```ts
|
|
@@ -2796,7 +2830,7 @@ function isCollection(value) {
|
|
|
2796
2830
|
*/
|
|
2797
2831
|
var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
|
|
2798
2832
|
/**
|
|
2799
|
-
*
|
|
2833
|
+
* Narrows a value to one {@link Group} a plan selects over.
|
|
2800
2834
|
*
|
|
2801
2835
|
* @example
|
|
2802
2836
|
* ```ts
|
|
@@ -2807,10 +2841,10 @@ var isEnvironment = (0, _orkestrel_contract.literalOf)(ENVIRONMENTS);
|
|
|
2807
2841
|
* ```
|
|
2808
2842
|
*/
|
|
2809
2843
|
var isGroup = (0, _orkestrel_contract.literalOf)(GROUPS);
|
|
2810
|
-
/**
|
|
2844
|
+
/** Narrows a value to a bounded group selection. */
|
|
2811
2845
|
var isGroups = (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isGroup));
|
|
2812
2846
|
/**
|
|
2813
|
-
*
|
|
2847
|
+
* Narrows a value to the scoped package name a runtime dependency carries.
|
|
2814
2848
|
*
|
|
2815
2849
|
* @remarks
|
|
2816
2850
|
* A dependency name reaches a path, because a workspace's guide mirror is
|
|
@@ -2832,7 +2866,7 @@ var isDependencyName = (0, _orkestrel_contract.stringOf)({
|
|
|
2832
2866
|
pattern: DEPENDENCY_NAME_PATTERN
|
|
2833
2867
|
});
|
|
2834
2868
|
/**
|
|
2835
|
-
*
|
|
2869
|
+
* Narrows a value to a {@link Dependency}.
|
|
2836
2870
|
*
|
|
2837
2871
|
* @remarks
|
|
2838
2872
|
* Structural and bounded: which names and ranges a blueprint may declare is a
|
|
@@ -2859,7 +2893,7 @@ var isDependency = (0, _orkestrel_contract.recordOf)({
|
|
|
2859
2893
|
optional: _orkestrel_contract.isBoolean
|
|
2860
2894
|
}, ["optional"]);
|
|
2861
2895
|
/**
|
|
2862
|
-
*
|
|
2896
|
+
* Narrows a value to a {@link ManifestScript}.
|
|
2863
2897
|
*
|
|
2864
2898
|
* @remarks
|
|
2865
2899
|
* Structural and bounded, exactly as {@link isDependency} is: a script name
|
|
@@ -2890,7 +2924,7 @@ var isManifestScript = (0, _orkestrel_contract.recordOf)({
|
|
|
2890
2924
|
})))
|
|
2891
2925
|
});
|
|
2892
2926
|
/**
|
|
2893
|
-
*
|
|
2927
|
+
* Narrows a value to an {@link Override}.
|
|
2894
2928
|
*
|
|
2895
2929
|
* @remarks
|
|
2896
2930
|
* Whether the path names a planned artifact is a gate law; whether it names a
|
|
@@ -2908,7 +2942,7 @@ var isOverride = (0, _orkestrel_contract.recordOf)({
|
|
|
2908
2942
|
content: isContent
|
|
2909
2943
|
});
|
|
2910
2944
|
/**
|
|
2911
|
-
*
|
|
2945
|
+
* Narrows a value to a {@link Blueprint}.
|
|
2912
2946
|
*
|
|
2913
2947
|
* @remarks
|
|
2914
2948
|
* The whole closed record, its literal axes, and the count and length bounds
|
|
@@ -2949,7 +2983,7 @@ var isBlueprint = (0, _orkestrel_contract.recordOf)({
|
|
|
2949
2983
|
showcase: _orkestrel_contract.isBoolean
|
|
2950
2984
|
}, ["description"]);
|
|
2951
2985
|
/**
|
|
2952
|
-
*
|
|
2986
|
+
* Narrows a value to an {@link Artifact}.
|
|
2953
2987
|
*
|
|
2954
2988
|
* @remarks
|
|
2955
2989
|
* One branch per way content is produced, discriminated by `origin` and
|
|
@@ -2989,7 +3023,7 @@ var isArtifact = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.record
|
|
|
2989
3023
|
content: isContent
|
|
2990
3024
|
}, ["environment"]));
|
|
2991
3025
|
/**
|
|
2992
|
-
*
|
|
3026
|
+
* Narrows a value to a {@link Plan}.
|
|
2993
3027
|
*
|
|
2994
3028
|
* @remarks
|
|
2995
3029
|
* A plan reaches the writer, and the writer has no question channel, so this
|
|
@@ -3005,7 +3039,7 @@ var isPlan = (0, _orkestrel_contract.andOf)((0, _orkestrel_contract.recordOf)({
|
|
|
3005
3039
|
hash: isHex
|
|
3006
3040
|
}, ["hash"]), (plan) => plan.artifacts.every((artifact) => artifact.path !== "package.json" || artifact.ownership === "birth"));
|
|
3007
3041
|
/**
|
|
3008
|
-
*
|
|
3042
|
+
* Narrows a value to a {@link Question}.
|
|
3009
3043
|
*
|
|
3010
3044
|
* @example
|
|
3011
3045
|
* ```ts
|
|
@@ -3021,7 +3055,7 @@ var isQuestion = (0, _orkestrel_contract.recordOf)({
|
|
|
3021
3055
|
candidates: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(_orkestrel_contract.isString))
|
|
3022
3056
|
}, ["candidates"]);
|
|
3023
3057
|
/**
|
|
3024
|
-
*
|
|
3058
|
+
* Narrows a value to a {@link Finding}.
|
|
3025
3059
|
*
|
|
3026
3060
|
* @remarks
|
|
3027
3061
|
* `observed` is required exactly where the mutation it precedes is held to it,
|
|
@@ -3058,7 +3092,7 @@ var isFinding = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.recordO
|
|
|
3058
3092
|
observed: isHex
|
|
3059
3093
|
}, ["observed"]));
|
|
3060
3094
|
/**
|
|
3061
|
-
*
|
|
3095
|
+
* Narrows a value to an {@link Audit}.
|
|
3062
3096
|
*
|
|
3063
3097
|
* @remarks
|
|
3064
3098
|
* An audit reaches the writer and the destructive verb, so it is guarded as
|
|
@@ -3070,7 +3104,7 @@ var isAudit = (0, _orkestrel_contract.recordOf)({
|
|
|
3070
3104
|
questions: (0, _orkestrel_contract.andOf)(isCollection, (0, _orkestrel_contract.arrayOf)(isQuestion))
|
|
3071
3105
|
});
|
|
3072
3106
|
/**
|
|
3073
|
-
*
|
|
3107
|
+
* Narrows a value to a {@link Mirror}.
|
|
3074
3108
|
*
|
|
3075
3109
|
* @remarks
|
|
3076
3110
|
* `content` is the fetched guide text and `observed` is the local mirror's
|
|
@@ -3091,7 +3125,7 @@ var isMirror = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.recordOf
|
|
|
3091
3125
|
observed: isHex
|
|
3092
3126
|
}, ["observed"]));
|
|
3093
3127
|
/**
|
|
3094
|
-
*
|
|
3128
|
+
* Narrows a value to a {@link CatalogEntry}.
|
|
3095
3129
|
*
|
|
3096
3130
|
* @remarks
|
|
3097
3131
|
* A row that found no version carries the cause instead, and neither branch may
|
|
@@ -3108,11 +3142,11 @@ var isCatalogEntry = (0, _orkestrel_contract.unionOf)((0, _orkestrel_contract.re
|
|
|
3108
3142
|
note: _orkestrel_contract.isString
|
|
3109
3143
|
}));
|
|
3110
3144
|
/**
|
|
3111
|
-
*
|
|
3145
|
+
* Narrows a value to a {@link Snapshot}.
|
|
3112
3146
|
*
|
|
3113
3147
|
* @param value - The candidate target snapshot.
|
|
3114
|
-
* @returns
|
|
3115
|
-
* whose every value is exact lowercase hexadecimal bytes.
|
|
3148
|
+
* @returns True if the value is a bounded plain record whose every key is a path and
|
|
3149
|
+
* whose every value is exact lowercase hexadecimal bytes; false otherwise.
|
|
3116
3150
|
*
|
|
3117
3151
|
* @remarks
|
|
3118
3152
|
* Read through the shared total key lens, so a hostile `ownKeys` trap and a
|
|
@@ -3138,7 +3172,7 @@ function isSnapshot(value) {
|
|
|
3138
3172
|
});
|
|
3139
3173
|
}
|
|
3140
3174
|
/**
|
|
3141
|
-
*
|
|
3175
|
+
* Narrows a value to the compiler's initial listener record.
|
|
3142
3176
|
*
|
|
3143
3177
|
* @remarks
|
|
3144
3178
|
* Every event is optional and every declared value is a function. A key outside
|
|
@@ -3153,7 +3187,7 @@ var isCompilerHooks = (0, _orkestrel_contract.recordOf)({
|
|
|
3153
3187
|
destroy: _orkestrel_contract.isFunction
|
|
3154
3188
|
}, true);
|
|
3155
3189
|
/**
|
|
3156
|
-
*
|
|
3190
|
+
* Narrows a value to {@link CompilerOptions}.
|
|
3157
3191
|
*
|
|
3158
3192
|
* @example
|
|
3159
3193
|
* ```ts
|
|
@@ -3170,7 +3204,7 @@ var isCompilerOptions = (0, _orkestrel_contract.recordOf)({
|
|
|
3170
3204
|
//#endregion
|
|
3171
3205
|
//#region src/core/cloners.ts
|
|
3172
3206
|
/**
|
|
3173
|
-
*
|
|
3207
|
+
* Snapshots an untrusted value into exact JSON data the caller owns.
|
|
3174
3208
|
*
|
|
3175
3209
|
* @param value - The untrusted value to take ownership of.
|
|
3176
3210
|
* @returns A deeply frozen copy sharing nothing with `value`, or `undefined`
|
|
@@ -3218,7 +3252,7 @@ function cloneValue(value) {
|
|
|
3218
3252
|
//#endregion
|
|
3219
3253
|
//#region src/core/parsers.ts
|
|
3220
3254
|
/**
|
|
3221
|
-
*
|
|
3255
|
+
* Coerces an untrusted value to a {@link Blueprint}.
|
|
3222
3256
|
*
|
|
3223
3257
|
* @param value - The value to parse.
|
|
3224
3258
|
* @returns The blueprint, or `undefined` when the value is not one.
|
|
@@ -3240,7 +3274,7 @@ function parseBlueprint(value) {
|
|
|
3240
3274
|
return isBlueprint(value) ? value : void 0;
|
|
3241
3275
|
}
|
|
3242
3276
|
/**
|
|
3243
|
-
*
|
|
3277
|
+
* Coerces an untrusted value to a group selection.
|
|
3244
3278
|
*
|
|
3245
3279
|
* @param value - The value to parse.
|
|
3246
3280
|
* @returns The selection, or `undefined` when the value is not one.
|
|
@@ -3262,7 +3296,7 @@ function parseGroups(value) {
|
|
|
3262
3296
|
return isGroups(value) ? value : void 0;
|
|
3263
3297
|
}
|
|
3264
3298
|
/**
|
|
3265
|
-
*
|
|
3299
|
+
* Coerces an untrusted value to a {@link Snapshot}.
|
|
3266
3300
|
*
|
|
3267
3301
|
* @param value - The value to parse.
|
|
3268
3302
|
* @returns The snapshot, or `undefined` when the value is not one.
|
|
@@ -3282,7 +3316,7 @@ function parseSnapshot(value) {
|
|
|
3282
3316
|
return isSnapshot(value) ? value : void 0;
|
|
3283
3317
|
}
|
|
3284
3318
|
/**
|
|
3285
|
-
*
|
|
3319
|
+
* Coerces an untrusted value to {@link CompilerOptions}.
|
|
3286
3320
|
*
|
|
3287
3321
|
* @param value - The value to parse.
|
|
3288
3322
|
* @returns The options, or `undefined` when the value is not an option bag.
|
|
@@ -3306,7 +3340,7 @@ function parseCompilerOptions(value) {
|
|
|
3306
3340
|
//#endregion
|
|
3307
3341
|
//#region src/core/helpers.ts
|
|
3308
3342
|
/**
|
|
3309
|
-
*
|
|
3343
|
+
* Encodes bytes as exact lowercase hexadecimal text.
|
|
3310
3344
|
*
|
|
3311
3345
|
* @param bytes - The bytes to encode.
|
|
3312
3346
|
* @returns Two lowercase hexadecimal digits per input byte, and `''` for no bytes.
|
|
@@ -3330,7 +3364,7 @@ function bytesToHex(bytes) {
|
|
|
3330
3364
|
return hex;
|
|
3331
3365
|
}
|
|
3332
3366
|
/**
|
|
3333
|
-
*
|
|
3367
|
+
* Encodes text as the exact lowercase hexadecimal form of its UTF-8 bytes.
|
|
3334
3368
|
*
|
|
3335
3369
|
* @param content - The text to encode.
|
|
3336
3370
|
* @returns The hexadecimal form of the text's exact UTF-8 bytes.
|
|
@@ -3352,7 +3386,7 @@ function contentToHex(content) {
|
|
|
3352
3386
|
return bytesToHex(new TextEncoder().encode(content));
|
|
3353
3387
|
}
|
|
3354
3388
|
/**
|
|
3355
|
-
*
|
|
3389
|
+
* Counts the UTF-8 bytes text encodes to.
|
|
3356
3390
|
*
|
|
3357
3391
|
* @param content - The text to measure.
|
|
3358
3392
|
* @returns The exact number of UTF-8 bytes.
|
|
@@ -3380,7 +3414,7 @@ function computeBytes(content) {
|
|
|
3380
3414
|
return bytes;
|
|
3381
3415
|
}
|
|
3382
3416
|
/**
|
|
3383
|
-
*
|
|
3417
|
+
* Computes the deterministic content identity of text.
|
|
3384
3418
|
*
|
|
3385
3419
|
* @param text - The text to digest.
|
|
3386
3420
|
* @returns Sixteen lowercase hexadecimal digits.
|
|
@@ -3409,11 +3443,11 @@ function computeHash(text) {
|
|
|
3409
3443
|
return hash.toString(16).padStart(16, "0");
|
|
3410
3444
|
}
|
|
3411
3445
|
/**
|
|
3412
|
-
*
|
|
3446
|
+
* Tests whether a path instructs or wires an agent rather than the toolchain.
|
|
3413
3447
|
*
|
|
3414
3448
|
* @param path - The target-relative path to test.
|
|
3415
|
-
* @returns
|
|
3416
|
-
*
|
|
3449
|
+
* @returns True if the path is beneath a harness directory or is one of the exact
|
|
3450
|
+
* root filenames that wires an agent bench; false otherwise.
|
|
3417
3451
|
*
|
|
3418
3452
|
* @remarks
|
|
3419
3453
|
* The one home of the orchestration membership rule. A vendored path and a
|
|
@@ -3438,8 +3472,8 @@ function matchesOrchestrationPath(path) {
|
|
|
3438
3472
|
* Checks whether another surface owns the vendored bytes at a path.
|
|
3439
3473
|
*
|
|
3440
3474
|
* @param path - The target-relative vendored path to test.
|
|
3441
|
-
* @returns
|
|
3442
|
-
*
|
|
3475
|
+
* @returns True if the path is the catalog agent file or a Markdown guide
|
|
3476
|
+
* mirror; false otherwise.
|
|
3443
3477
|
*
|
|
3444
3478
|
* @remarks
|
|
3445
3479
|
* The materializer keeps these paths presence-owned because the catalog or
|
|
@@ -3461,8 +3495,8 @@ function isDeferredPath(path) {
|
|
|
3461
3495
|
* Checks whether a path belongs to the instruction canon a target reads rather than holds.
|
|
3462
3496
|
*
|
|
3463
3497
|
* @param path - The target-relative path to test.
|
|
3464
|
-
* @returns
|
|
3465
|
-
* member that is a directory;
|
|
3498
|
+
* @returns True if the path is a {@link CANON_PATHS} member or sits beneath a
|
|
3499
|
+
* member that is a directory; false otherwise.
|
|
3466
3500
|
*
|
|
3467
3501
|
* @remarks
|
|
3468
3502
|
* The one reading of canon membership, so the live overlay and the executable's
|
|
@@ -3487,7 +3521,57 @@ function isCanonPath(path) {
|
|
|
3487
3521
|
return CANON_PATHS.some((canon) => path === canon || path.startsWith(`${canon}/`));
|
|
3488
3522
|
}
|
|
3489
3523
|
/**
|
|
3490
|
-
*
|
|
3524
|
+
* Checks whether a target's present bytes at a path are owned by another surface.
|
|
3525
|
+
*
|
|
3526
|
+
* @param path - The target-relative path to test.
|
|
3527
|
+
* @returns True if the path is a {@link WORKSPACE_OWNED_PATHS} member or a
|
|
3528
|
+
* deferred path; false otherwise.
|
|
3529
|
+
*
|
|
3530
|
+
* @remarks
|
|
3531
|
+
* The one reading of presence ownership. A workspace-owned path carries bytes
|
|
3532
|
+
* the consumer's own workspace writes, and a deferred path carries bytes the
|
|
3533
|
+
* catalog or mirror surface writes, so a vendored expansion plans either by
|
|
3534
|
+
* presence rather than reading and claiming its content.
|
|
3535
|
+
*
|
|
3536
|
+
* @example
|
|
3537
|
+
* ```ts
|
|
3538
|
+
* import { isRetainedPath } from '@orkestrel/scaffold'
|
|
3539
|
+
*
|
|
3540
|
+
* isRetainedPath('.gitignore') // true
|
|
3541
|
+
* isRetainedPath('LICENSE') // false
|
|
3542
|
+
* ```
|
|
3543
|
+
*/
|
|
3544
|
+
function isRetainedPath(path) {
|
|
3545
|
+
return WORKSPACE_OWNED_PATHS.includes(path) || isDeferredPath(path);
|
|
3546
|
+
}
|
|
3547
|
+
/**
|
|
3548
|
+
* Checks whether a destination's floor bytes survive a live overlay.
|
|
3549
|
+
*
|
|
3550
|
+
* @param path - The target-relative destination to test.
|
|
3551
|
+
* @returns True if the path is deferred or belongs to the instruction
|
|
3552
|
+
* canon; false otherwise.
|
|
3553
|
+
*
|
|
3554
|
+
* @remarks
|
|
3555
|
+
* The one reading of what a live fill does not replace, so the overlay assembler
|
|
3556
|
+
* and the executable's fetch list never disagree about a destination. A deferred
|
|
3557
|
+
* path's bytes belong to the catalog or mirror verb, and a canon destination is
|
|
3558
|
+
* staged for reading rather than for a target, so the installed floor's bytes
|
|
3559
|
+
* stand for both. A reader that requested either would spend a round trip on
|
|
3560
|
+
* bytes the overlay would not take.
|
|
3561
|
+
*
|
|
3562
|
+
* @example
|
|
3563
|
+
* ```ts
|
|
3564
|
+
* import { isFloorPath } from '@orkestrel/scaffold'
|
|
3565
|
+
*
|
|
3566
|
+
* isFloorPath('AGENTS.md') // true
|
|
3567
|
+
* isFloorPath('scripts/codex.sh') // false
|
|
3568
|
+
* ```
|
|
3569
|
+
*/
|
|
3570
|
+
function isFloorPath(path) {
|
|
3571
|
+
return isDeferredPath(path) || isCanonPath(path);
|
|
3572
|
+
}
|
|
3573
|
+
/**
|
|
3574
|
+
* Infers the {@link Group} a path belongs to.
|
|
3491
3575
|
*
|
|
3492
3576
|
* @param path - The target-relative path to classify.
|
|
3493
3577
|
* @returns The group that owns the path.
|
|
@@ -3522,7 +3606,7 @@ function inferGroup(path) {
|
|
|
3522
3606
|
return "configs";
|
|
3523
3607
|
}
|
|
3524
3608
|
/**
|
|
3525
|
-
*
|
|
3609
|
+
* Serializes one string as a single-quoted TypeScript literal.
|
|
3526
3610
|
*
|
|
3527
3611
|
* @param value - The string to serialize.
|
|
3528
3612
|
* @returns A complete single-quoted literal with line-breaking and delimiter
|
|
@@ -3565,7 +3649,7 @@ function serializeTypeScriptString(value) {
|
|
|
3565
3649
|
return `${serialized}'`;
|
|
3566
3650
|
}
|
|
3567
3651
|
/**
|
|
3568
|
-
*
|
|
3652
|
+
* Derives the guide mirror path a package name answers for.
|
|
3569
3653
|
*
|
|
3570
3654
|
* @param name - A bare or `@orkestrel`-scoped package name.
|
|
3571
3655
|
* @returns The mirror path, `guides/<bare name>.md`.
|
|
@@ -3590,10 +3674,10 @@ function nameToGuide(name) {
|
|
|
3590
3674
|
return `guides/${name.slice(name.lastIndexOf("/") + 1)}.md`;
|
|
3591
3675
|
}
|
|
3592
3676
|
/**
|
|
3593
|
-
*
|
|
3677
|
+
* Tests whether one emitted line fits the vendored formatter width.
|
|
3594
3678
|
*
|
|
3595
3679
|
* @param line - One emitted line, leading tabs included.
|
|
3596
|
-
* @returns
|
|
3680
|
+
* @returns True if the expanded line fits; false otherwise.
|
|
3597
3681
|
*
|
|
3598
3682
|
* @remarks
|
|
3599
3683
|
* A generator writes source the formatter then reads back, so a line packed
|
|
@@ -3614,7 +3698,7 @@ function matchesPrintWidth(line) {
|
|
|
3614
3698
|
return line.replaceAll(" ", " ".repeat(2)).length <= 100;
|
|
3615
3699
|
}
|
|
3616
3700
|
/**
|
|
3617
|
-
*
|
|
3701
|
+
* Derives the declaration rewrite a published face's `beforeWriteFile` applies.
|
|
3618
3702
|
*
|
|
3619
3703
|
* @param name - The workspace's own bare package name.
|
|
3620
3704
|
* @returns The ternary consequent an emitted `vite.{browser,server}.config.ts`
|
|
@@ -3654,7 +3738,34 @@ function nameToRewrite(name) {
|
|
|
3654
3738
|
].join("\n");
|
|
3655
3739
|
}
|
|
3656
3740
|
/**
|
|
3657
|
-
*
|
|
3741
|
+
* Selects the single published environment a package root points at.
|
|
3742
|
+
*
|
|
3743
|
+
* @param src - The declared published environments.
|
|
3744
|
+
* @returns That environment, or `undefined` when the selection declares none or
|
|
3745
|
+
* several.
|
|
3746
|
+
*
|
|
3747
|
+
* @remarks
|
|
3748
|
+
* A workspace publishing exactly one environment puts it at the package root,
|
|
3749
|
+
* so its entry fields and its `'.'` export condition both name that
|
|
3750
|
+
* environment's build. A workspace publishing several puts core at the root and
|
|
3751
|
+
* gives every other environment a subpath, so there is no single root to name.
|
|
3752
|
+
* Both callers read the same answer, which is why the branch is decided once
|
|
3753
|
+
* here rather than twice.
|
|
3754
|
+
*
|
|
3755
|
+
* @example
|
|
3756
|
+
* ```ts
|
|
3757
|
+
* import { srcToRoot } from '@orkestrel/scaffold'
|
|
3758
|
+
*
|
|
3759
|
+
* srcToRoot(['browser']) // 'browser'
|
|
3760
|
+
* srcToRoot(['core', 'server']) // undefined
|
|
3761
|
+
* ```
|
|
3762
|
+
*/
|
|
3763
|
+
function srcToRoot(src) {
|
|
3764
|
+
if (src.length !== 1) return void 0;
|
|
3765
|
+
return src[0];
|
|
3766
|
+
}
|
|
3767
|
+
/**
|
|
3768
|
+
* Selects the host paths a named workspace vendors.
|
|
3658
3769
|
*
|
|
3659
3770
|
* @param paths - The candidate host paths, in their declared order.
|
|
3660
3771
|
* @param name - The target workspace's own bare package name.
|
|
@@ -3677,7 +3788,7 @@ function selectHostPaths(paths, name) {
|
|
|
3677
3788
|
return paths.filter((path) => path !== guide);
|
|
3678
3789
|
}
|
|
3679
3790
|
/**
|
|
3680
|
-
*
|
|
3791
|
+
* Selects the groups a compile covers, in plan order.
|
|
3681
3792
|
*
|
|
3682
3793
|
* @param groups - The requested selection; every group when absent.
|
|
3683
3794
|
* @returns The requested groups in `GROUPS` order, without repeats.
|
|
@@ -3702,7 +3813,7 @@ function selectGroups(groups) {
|
|
|
3702
3813
|
return GROUPS.filter((group) => selection.includes(group));
|
|
3703
3814
|
}
|
|
3704
3815
|
/**
|
|
3705
|
-
*
|
|
3816
|
+
* Projects an artifact to the exact bytes it claims, as hexadecimal.
|
|
3706
3817
|
*
|
|
3707
3818
|
* @param artifact - The planned artifact to read.
|
|
3708
3819
|
* @returns The claimed bytes, or `undefined` when the artifact claims none.
|
|
@@ -3731,7 +3842,7 @@ function artifactToHex(artifact) {
|
|
|
3731
3842
|
return artifact.hex;
|
|
3732
3843
|
}
|
|
3733
3844
|
/**
|
|
3734
|
-
*
|
|
3845
|
+
* Infers how one target path compares to the artifact planned for it.
|
|
3735
3846
|
*
|
|
3736
3847
|
* @param artifact - The planned artifact.
|
|
3737
3848
|
* @param observed - The destination's exact bytes as hexadecimal; absent when
|
|
@@ -3773,16 +3884,99 @@ function inferDrift(artifact, observed) {
|
|
|
3773
3884
|
return observed === artifactToHex(artifact) ? "aligned" : "stale";
|
|
3774
3885
|
}
|
|
3775
3886
|
/**
|
|
3776
|
-
*
|
|
3887
|
+
* Projects one planned artifact and the bytes found at its path into a verdict.
|
|
3888
|
+
*
|
|
3889
|
+
* @param artifact - The planned artifact.
|
|
3890
|
+
* @param observed - The destination's exact bytes as hexadecimal; absent when
|
|
3891
|
+
* the destination holds no file.
|
|
3892
|
+
* @returns The finding, carrying the artifact's ownership and `observed`
|
|
3893
|
+
* exactly where bytes were read.
|
|
3894
|
+
*
|
|
3895
|
+
* @remarks
|
|
3896
|
+
* The comparison itself is {@link inferDrift}'s, so ownership decides it here
|
|
3897
|
+
* exactly as it does everywhere else. This adds only the shape: a missing
|
|
3898
|
+
* destination has no bytes to record, and every other verdict records the bytes
|
|
3899
|
+
* it was given, which is the precondition the mutation that follows is held to.
|
|
3900
|
+
* Ownership is copied rather than inferred from drift because aligned findings
|
|
3901
|
+
* span every ownership tier.
|
|
3902
|
+
*
|
|
3903
|
+
* `foreign` is not answerable here, because it describes a path no artifact was
|
|
3904
|
+
* planned for.
|
|
3905
|
+
*
|
|
3906
|
+
* @example
|
|
3907
|
+
* ```ts
|
|
3908
|
+
* import { artifactToFinding } from '@orkestrel/scaffold'
|
|
3909
|
+
*
|
|
3910
|
+
* artifactToFinding(
|
|
3911
|
+
* { path: 'README.md', group: 'docs', ownership: 'content', origin: 'computed', content: 'hi\n' },
|
|
3912
|
+
* '6279650a',
|
|
3913
|
+
* ) // { path: 'README.md', group: 'docs', ownership: 'content', drift: 'stale', observed: '6279650a' }
|
|
3914
|
+
* ```
|
|
3915
|
+
*/
|
|
3916
|
+
function artifactToFinding(artifact, observed) {
|
|
3917
|
+
const path = artifact.path;
|
|
3918
|
+
const group = artifact.group;
|
|
3919
|
+
const ownership = artifact.ownership;
|
|
3920
|
+
if (observed === void 0) return inferDrift(artifact) === "aligned" ? {
|
|
3921
|
+
path,
|
|
3922
|
+
group,
|
|
3923
|
+
ownership,
|
|
3924
|
+
drift: "aligned"
|
|
3925
|
+
} : {
|
|
3926
|
+
path,
|
|
3927
|
+
group,
|
|
3928
|
+
ownership,
|
|
3929
|
+
drift: "missing"
|
|
3930
|
+
};
|
|
3931
|
+
return inferDrift(artifact, observed) === "stale" ? {
|
|
3932
|
+
path,
|
|
3933
|
+
group,
|
|
3934
|
+
ownership,
|
|
3935
|
+
drift: "stale",
|
|
3936
|
+
observed
|
|
3937
|
+
} : {
|
|
3938
|
+
path,
|
|
3939
|
+
group,
|
|
3940
|
+
ownership,
|
|
3941
|
+
drift: "aligned",
|
|
3942
|
+
observed
|
|
3943
|
+
};
|
|
3944
|
+
}
|
|
3945
|
+
/**
|
|
3946
|
+
* Tests whether {@link inferDrift} could have produced a finding for an ownership.
|
|
3777
3947
|
*
|
|
3778
3948
|
* @param ownership - What scaffold claims at the planned path.
|
|
3779
3949
|
* @param finding - The audit verdict to test.
|
|
3780
|
-
* @returns
|
|
3950
|
+
* @returns True if the ownership and verdict are reachable through
|
|
3951
|
+
* {@link inferDrift}; false otherwise.
|
|
3781
3952
|
*
|
|
3782
3953
|
* @remarks
|
|
3783
3954
|
* This predicate keeps the comparison law beside the reachability law it
|
|
3784
3955
|
* restates. A mutation uses it so a refusal can distinguish an impossible
|
|
3785
3956
|
* verdict from a target that genuinely moved after its audit.
|
|
3957
|
+
*
|
|
3958
|
+
* @example
|
|
3959
|
+
* ```ts
|
|
3960
|
+
* import type { Finding } from '@orkestrel/scaffold'
|
|
3961
|
+
* import { matchesDriftReachability } from '@orkestrel/scaffold'
|
|
3962
|
+
*
|
|
3963
|
+
* const aligned: Finding = {
|
|
3964
|
+
* path: 'README.md',
|
|
3965
|
+
* group: 'docs',
|
|
3966
|
+
* ownership: 'birth',
|
|
3967
|
+
* drift: 'aligned',
|
|
3968
|
+
* }
|
|
3969
|
+
* const stale: Finding = {
|
|
3970
|
+
* path: 'README.md',
|
|
3971
|
+
* group: 'docs',
|
|
3972
|
+
* ownership: 'birth',
|
|
3973
|
+
* drift: 'stale',
|
|
3974
|
+
* observed: '6279650a',
|
|
3975
|
+
* }
|
|
3976
|
+
*
|
|
3977
|
+
* matchesDriftReachability('birth', aligned) // true
|
|
3978
|
+
* matchesDriftReachability('birth', stale) // false
|
|
3979
|
+
* ```
|
|
3786
3980
|
*/
|
|
3787
3981
|
function matchesDriftReachability(ownership, finding) {
|
|
3788
3982
|
if (finding.drift === "aligned") return ownership === "birth" || finding.observed !== void 0;
|
|
@@ -3790,7 +3984,7 @@ function matchesDriftReachability(ownership, finding) {
|
|
|
3790
3984
|
return finding.drift === "stale" && ownership === "content";
|
|
3791
3985
|
}
|
|
3792
3986
|
/**
|
|
3793
|
-
*
|
|
3987
|
+
* Projects a catalog into the layers it publishes in.
|
|
3794
3988
|
*
|
|
3795
3989
|
* @param entries - The catalog rows to order.
|
|
3796
3990
|
* @returns One layer per round, each holding the names publishable together,
|
|
@@ -3838,7 +4032,7 @@ function catalogToLayers(entries) {
|
|
|
3838
4032
|
return layers;
|
|
3839
4033
|
}
|
|
3840
4034
|
/**
|
|
3841
|
-
*
|
|
4035
|
+
* Projects a plan into its tally by artifact origin.
|
|
3842
4036
|
*
|
|
3843
4037
|
* @param plan - The plan to summarize.
|
|
3844
4038
|
* @returns The workspace's name, both environment axes, the covered groups, and
|
|
@@ -3875,7 +4069,7 @@ function planToSummary(plan) {
|
|
|
3875
4069
|
};
|
|
3876
4070
|
}
|
|
3877
4071
|
/**
|
|
3878
|
-
*
|
|
4072
|
+
* Extracts the major, minor, and patch components of an exact version.
|
|
3879
4073
|
*
|
|
3880
4074
|
* @param version - The candidate version text.
|
|
3881
4075
|
* @returns The major, minor, and patch numbers, or `undefined` when the text is
|
|
@@ -3905,7 +4099,7 @@ function extractVersion(version) {
|
|
|
3905
4099
|
];
|
|
3906
4100
|
}
|
|
3907
4101
|
/**
|
|
3908
|
-
*
|
|
4102
|
+
* Extracts the major component of an admitted dependency range.
|
|
3909
4103
|
*
|
|
3910
4104
|
* @param range - The candidate range text.
|
|
3911
4105
|
* @returns The major number, or `undefined` when the text is not a canonical
|
|
@@ -3931,7 +4125,7 @@ function extractRangeMajor(range) {
|
|
|
3931
4125
|
return major === void 0 ? void 0 : Number(major);
|
|
3932
4126
|
}
|
|
3933
4127
|
/**
|
|
3934
|
-
*
|
|
4128
|
+
* Compares two versions by their numeric components.
|
|
3935
4129
|
*
|
|
3936
4130
|
* @param left - The version ordered first when it compares lower.
|
|
3937
4131
|
* @param right - The version compared against.
|
|
@@ -3966,11 +4160,11 @@ function compareVersions(left, right) {
|
|
|
3966
4160
|
return 0;
|
|
3967
4161
|
}
|
|
3968
4162
|
/**
|
|
3969
|
-
*
|
|
4163
|
+
* Tests whether a declared range already admits a published version.
|
|
3970
4164
|
*
|
|
3971
4165
|
* @param range - The declared dependency range.
|
|
3972
4166
|
* @param latest - The version the registry reported as latest.
|
|
3973
|
-
* @returns
|
|
4167
|
+
* @returns True if the range admits that version; false otherwise.
|
|
3974
4168
|
*
|
|
3975
4169
|
* @remarks
|
|
3976
4170
|
* The one place this comparison is made. A `Release` records the declared range
|
|
@@ -4023,11 +4217,11 @@ function matchesRange(range, latest) {
|
|
|
4023
4217
|
return compareVersions(latest, declared) >= 0;
|
|
4024
4218
|
}
|
|
4025
4219
|
/**
|
|
4026
|
-
*
|
|
4220
|
+
* Tests whether a declared engines floor is at or above the supported minimum.
|
|
4027
4221
|
*
|
|
4028
4222
|
* @param engines - The declared `engines.node` range.
|
|
4029
|
-
* @returns
|
|
4030
|
-
*
|
|
4223
|
+
* @returns True if the range is the accepted syntax and its floor is at or above
|
|
4224
|
+
* `MINIMUM_NODE_VERSION`; false otherwise.
|
|
4031
4225
|
*
|
|
4032
4226
|
* @remarks
|
|
4033
4227
|
* The declaration states a floor, so the comparison is against the oldest Node
|
|
@@ -4048,7 +4242,7 @@ function matchesEngines(engines) {
|
|
|
4048
4242
|
return compareVersions(engines.slice(2), MINIMUM_NODE_VERSION) >= 0;
|
|
4049
4243
|
}
|
|
4050
4244
|
/**
|
|
4051
|
-
*
|
|
4245
|
+
* Projects a package manifest's text to its own name.
|
|
4052
4246
|
*
|
|
4053
4247
|
* @param manifest - The `package.json` text.
|
|
4054
4248
|
* @returns The declared name, or `undefined` when the text is oversized,
|
|
@@ -4076,7 +4270,8 @@ function manifestToName(manifest) {
|
|
|
4076
4270
|
return name;
|
|
4077
4271
|
}
|
|
4078
4272
|
/**
|
|
4079
|
-
*
|
|
4273
|
+
* Projects a package manifest's text to the `@orkestrel/*` packages each dependency
|
|
4274
|
+
* section declares.
|
|
4080
4275
|
*
|
|
4081
4276
|
* @param manifest - The `package.json` text.
|
|
4082
4277
|
* @returns The runtime, development, and peer declarations as separate lists.
|
|
@@ -4148,34 +4343,7 @@ function manifestToDependencies(manifest) {
|
|
|
4148
4343
|
//#endregion
|
|
4149
4344
|
//#region src/core/compilers.ts
|
|
4150
4345
|
/**
|
|
4151
|
-
*
|
|
4152
|
-
*
|
|
4153
|
-
* @param src - The declared published environments.
|
|
4154
|
-
* @returns That environment, or `undefined` when the selection declares none or
|
|
4155
|
-
* several.
|
|
4156
|
-
*
|
|
4157
|
-
* @remarks
|
|
4158
|
-
* A workspace publishing exactly one environment puts it at the package root,
|
|
4159
|
-
* so its entry fields and its `'.'` export condition both name that
|
|
4160
|
-
* environment's build. A workspace publishing several puts core at the root and
|
|
4161
|
-
* gives every other environment a subpath, so there is no single root to name.
|
|
4162
|
-
* Both callers read the same answer, which is why the branch is decided once
|
|
4163
|
-
* here rather than twice.
|
|
4164
|
-
*
|
|
4165
|
-
* @example
|
|
4166
|
-
* ```ts
|
|
4167
|
-
* import { srcToRoot } from '@orkestrel/scaffold'
|
|
4168
|
-
*
|
|
4169
|
-
* srcToRoot(['browser']) // 'browser'
|
|
4170
|
-
* srcToRoot(['core', 'server']) // undefined
|
|
4171
|
-
* ```
|
|
4172
|
-
*/
|
|
4173
|
-
function srcToRoot(src) {
|
|
4174
|
-
if (src.length !== 1) return void 0;
|
|
4175
|
-
return src[0];
|
|
4176
|
-
}
|
|
4177
|
-
/**
|
|
4178
|
-
* Build one `exports` condition block for a built environment.
|
|
4346
|
+
* Builds one `exports` condition block for a built environment.
|
|
4179
4347
|
*
|
|
4180
4348
|
* @param path - The extensionless `dist` path both conditions point at.
|
|
4181
4349
|
* @param formats - The module formats that environment builds.
|
|
@@ -4211,7 +4379,7 @@ function pathToCondition(path, formats) {
|
|
|
4211
4379
|
};
|
|
4212
4380
|
}
|
|
4213
4381
|
/**
|
|
4214
|
-
*
|
|
4382
|
+
* Projects a published selection into the manifest's entry fields.
|
|
4215
4383
|
*
|
|
4216
4384
|
* @param src - The declared published environments.
|
|
4217
4385
|
* @returns The `main` and `module` fields, plus `types` when one environment
|
|
@@ -4248,7 +4416,7 @@ function srcToEntry(src) {
|
|
|
4248
4416
|
};
|
|
4249
4417
|
}
|
|
4250
4418
|
/**
|
|
4251
|
-
*
|
|
4419
|
+
* Projects a published selection into the manifest's `exports` map.
|
|
4252
4420
|
*
|
|
4253
4421
|
* @param src - The declared published environments.
|
|
4254
4422
|
* @returns The map, keyed by subpath in `ENVIRONMENTS` order.
|
|
@@ -4285,7 +4453,7 @@ function srcToExports(src) {
|
|
|
4285
4453
|
return map;
|
|
4286
4454
|
}
|
|
4287
4455
|
/**
|
|
4288
|
-
*
|
|
4456
|
+
* Projects a blueprint into the development dependencies its manifest declares.
|
|
4289
4457
|
*
|
|
4290
4458
|
* @param blueprint - The workspace specification.
|
|
4291
4459
|
* @returns The merged set, sorted by package name.
|
|
@@ -4337,7 +4505,7 @@ function blueprintToDevDependencies(blueprint) {
|
|
|
4337
4505
|
return Object.fromEntries(Object.entries(merged).filter(([name]) => name !== own && !runtime.has(name)).sort(([left], [right]) => (0, _orkestrel_contract.compareValues)(left, right)));
|
|
4338
4506
|
}
|
|
4339
4507
|
/**
|
|
4340
|
-
*
|
|
4508
|
+
* Projects a blueprint into the scripts its manifest declares.
|
|
4341
4509
|
*
|
|
4342
4510
|
* @param blueprint - The workspace specification.
|
|
4343
4511
|
* @returns The scripts, in the order the manifest lists them.
|
|
@@ -4474,7 +4642,7 @@ function blueprintToScripts(blueprint) {
|
|
|
4474
4642
|
return scripts;
|
|
4475
4643
|
}
|
|
4476
4644
|
/**
|
|
4477
|
-
*
|
|
4645
|
+
* Projects a blueprint into the manifest scripts a region write may replace.
|
|
4478
4646
|
*
|
|
4479
4647
|
* @param blueprint - The workspace specification.
|
|
4480
4648
|
* @returns One entry per writable script.
|
|
@@ -4531,7 +4699,7 @@ function blueprintToWritableScripts(blueprint) {
|
|
|
4531
4699
|
return writable;
|
|
4532
4700
|
}
|
|
4533
4701
|
/**
|
|
4534
|
-
*
|
|
4702
|
+
* Compiles a blueprint into its `package.json` content.
|
|
4535
4703
|
*
|
|
4536
4704
|
* @param blueprint - The workspace specification.
|
|
4537
4705
|
* @returns The manifest text, newline-terminated.
|
|
@@ -4617,7 +4785,7 @@ function blueprintToManifest(blueprint) {
|
|
|
4617
4785
|
return `${JSON.stringify(manifest, void 0, " ")}\n`;
|
|
4618
4786
|
}
|
|
4619
4787
|
/**
|
|
4620
|
-
*
|
|
4788
|
+
* Derives the host-specific machinery a generated root Vite configuration carries.
|
|
4621
4789
|
*
|
|
4622
4790
|
* @param blueprint - The workspace specification.
|
|
4623
4791
|
* @returns The pipelines the generated configuration selects.
|
|
@@ -4653,7 +4821,7 @@ function blueprintToMachinery(blueprint) {
|
|
|
4653
4821
|
};
|
|
4654
4822
|
}
|
|
4655
4823
|
/**
|
|
4656
|
-
*
|
|
4824
|
+
* Compiles the root TypeScript configuration for a blueprint.
|
|
4657
4825
|
*
|
|
4658
4826
|
* @param blueprint - The workspace specification.
|
|
4659
4827
|
* @returns Formatter-stable `tsconfig.json` text.
|
|
@@ -4675,7 +4843,7 @@ function blueprintToRootTsconfig(blueprint) {
|
|
|
4675
4843
|
return (0, _orkestrel_template.fillTemplate)(CONFIG_TEMPLATES.root.tsconfig, { paths });
|
|
4676
4844
|
}
|
|
4677
4845
|
/**
|
|
4678
|
-
*
|
|
4846
|
+
* Compiles the root Vite and Vitest configuration for a blueprint.
|
|
4679
4847
|
*
|
|
4680
4848
|
* @param blueprint - The workspace specification.
|
|
4681
4849
|
* @returns Formatter-stable `vite.config.ts` text.
|
|
@@ -4866,7 +5034,7 @@ ${projects.map((project) => `\t\t\t${project},`).join("\n")}
|
|
|
4866
5034
|
});
|
|
4867
5035
|
}
|
|
4868
5036
|
/**
|
|
4869
|
-
*
|
|
5037
|
+
* Compiles every artifact in the `configs` group.
|
|
4870
5038
|
*
|
|
4871
5039
|
* @param blueprint - The workspace specification.
|
|
4872
5040
|
* @returns Root and selected wrapper artifacts in matrix order.
|
|
@@ -4976,7 +5144,7 @@ ${paths.join("\n")}
|
|
|
4976
5144
|
return artifacts;
|
|
4977
5145
|
}
|
|
4978
5146
|
/**
|
|
4979
|
-
*
|
|
5147
|
+
* Compiles every artifact in the `source` group.
|
|
4980
5148
|
*
|
|
4981
5149
|
* @param blueprint - The workspace specification.
|
|
4982
5150
|
* @returns Empty published barrels, selected application entries, and the optional bin entry.
|
|
@@ -5051,7 +5219,7 @@ function blueprintToSourceArtifacts(blueprint) {
|
|
|
5051
5219
|
return artifacts;
|
|
5052
5220
|
}
|
|
5053
5221
|
/**
|
|
5054
|
-
*
|
|
5222
|
+
* Compiles every artifact in the `tests` group that is not vendored from the host.
|
|
5055
5223
|
*
|
|
5056
5224
|
* @param blueprint - The workspace specification.
|
|
5057
5225
|
* @returns Shared setup modules, axis tests, and the optional integration seed.
|
|
@@ -5207,10 +5375,19 @@ function blueprintToTestArtifacts(blueprint) {
|
|
|
5207
5375
|
return artifacts;
|
|
5208
5376
|
}
|
|
5209
5377
|
/**
|
|
5210
|
-
*
|
|
5378
|
+
* Compiles the generated workspace's guide index.
|
|
5211
5379
|
*
|
|
5212
5380
|
* @param blueprint - The workspace specification.
|
|
5213
5381
|
* @returns One birth-owned guide index carrying the concept and directory views.
|
|
5382
|
+
*
|
|
5383
|
+
* @example
|
|
5384
|
+
* ```ts
|
|
5385
|
+
* import { blueprintToGuideArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
5386
|
+
*
|
|
5387
|
+
* const blueprint = createBlueprint('router', { src: ['core'] })
|
|
5388
|
+
*
|
|
5389
|
+
* blueprintToGuideArtifacts(blueprint)[0]?.path // 'guides/README.md'
|
|
5390
|
+
* ```
|
|
5214
5391
|
*/
|
|
5215
5392
|
function blueprintToGuideArtifacts(blueprint) {
|
|
5216
5393
|
const source = [];
|
|
@@ -5246,7 +5423,7 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5246
5423
|
}];
|
|
5247
5424
|
}
|
|
5248
5425
|
/**
|
|
5249
|
-
*
|
|
5426
|
+
* Compiles the generated workspace's root documentation.
|
|
5250
5427
|
*
|
|
5251
5428
|
* @param blueprint - The workspace specification.
|
|
5252
5429
|
* @returns The birth-owned package front page and the content-owned `AGENTS.md`
|
|
@@ -5265,6 +5442,15 @@ function blueprintToGuideArtifacts(blueprint) {
|
|
|
5265
5442
|
* Neither pointer carries a varying span, so neither is filled: a workspace's
|
|
5266
5443
|
* name never reaches the text, and the paths a reader follows are the same in
|
|
5267
5444
|
* every target.
|
|
5445
|
+
*
|
|
5446
|
+
* @example
|
|
5447
|
+
* ```ts
|
|
5448
|
+
* import { blueprintToDocumentArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
5449
|
+
*
|
|
5450
|
+
* const blueprint = createBlueprint('router', { src: ['core'] })
|
|
5451
|
+
*
|
|
5452
|
+
* blueprintToDocumentArtifacts(blueprint).map((artifact) => artifact.path) // ['README.md', 'AGENTS.md', 'CLAUDE.md']
|
|
5453
|
+
* ```
|
|
5268
5454
|
*/
|
|
5269
5455
|
function blueprintToDocumentArtifacts(blueprint) {
|
|
5270
5456
|
const publishes = blueprint.src.length > 0;
|
|
@@ -5298,7 +5484,7 @@ function blueprintToDocumentArtifacts(blueprint) {
|
|
|
5298
5484
|
];
|
|
5299
5485
|
}
|
|
5300
5486
|
/**
|
|
5301
|
-
*
|
|
5487
|
+
* Compiles the blueprint-dependent orchestration artifacts.
|
|
5302
5488
|
*
|
|
5303
5489
|
* @param blueprint - The workspace specification.
|
|
5304
5490
|
* @returns A vendor inventory script when vendors are declared, otherwise none.
|
|
@@ -5307,6 +5493,17 @@ function blueprintToDocumentArtifacts(blueprint) {
|
|
|
5307
5493
|
* A vendor name does not describe startup, readiness, or cleanup. The script
|
|
5308
5494
|
* therefore records only the declared inventory and does not invent a service
|
|
5309
5495
|
* runner or test project.
|
|
5496
|
+
*
|
|
5497
|
+
* @example
|
|
5498
|
+
* ```ts
|
|
5499
|
+
* import { blueprintToOrchestrationArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
5500
|
+
*
|
|
5501
|
+
* const plain = createBlueprint('router', { src: ['core'] })
|
|
5502
|
+
* const served = createBlueprint('router', { src: ['core'], vendors: ['ollama'] })
|
|
5503
|
+
*
|
|
5504
|
+
* blueprintToOrchestrationArtifacts(plain) // []
|
|
5505
|
+
* blueprintToOrchestrationArtifacts(served)[0]?.path // 'scripts/service.sh'
|
|
5506
|
+
* ```
|
|
5310
5507
|
*/
|
|
5311
5508
|
function blueprintToOrchestrationArtifacts(blueprint) {
|
|
5312
5509
|
if (blueprint.vendors.length === 0) return [];
|
|
@@ -5320,7 +5517,7 @@ function blueprintToOrchestrationArtifacts(blueprint) {
|
|
|
5320
5517
|
}];
|
|
5321
5518
|
}
|
|
5322
5519
|
/**
|
|
5323
|
-
*
|
|
5520
|
+
* Compiles the vendored host artifacts a named workspace plans.
|
|
5324
5521
|
*
|
|
5325
5522
|
* @param name - The target workspace's own bare package name.
|
|
5326
5523
|
* @returns One artifact per vendored path in `HOST_PATHS` order, then the
|
|
@@ -5365,7 +5562,7 @@ function nameToHostArtifacts(name) {
|
|
|
5365
5562
|
}));
|
|
5366
5563
|
}
|
|
5367
5564
|
/**
|
|
5368
|
-
*
|
|
5565
|
+
* Replaces the content of every drafted artifact an override names.
|
|
5369
5566
|
*
|
|
5370
5567
|
* @param artifacts - The drafted artifacts.
|
|
5371
5568
|
* @param overrides - The blueprint's overrides.
|
|
@@ -5400,7 +5597,7 @@ function applyOverrides(artifacts, overrides) {
|
|
|
5400
5597
|
});
|
|
5401
5598
|
}
|
|
5402
5599
|
/**
|
|
5403
|
-
*
|
|
5600
|
+
* Replaces declared dependency ranges in package manifest text.
|
|
5404
5601
|
*
|
|
5405
5602
|
* @param manifest - The manifest text to compile.
|
|
5406
5603
|
* @param pins - The runtime and development names and replacement ranges.
|
|
@@ -5581,7 +5778,7 @@ function replaceManifestRanges(manifest, pins) {
|
|
|
5581
5778
|
return declaredRuntime && declaredDevelopment ? compiled : void 0;
|
|
5582
5779
|
}
|
|
5583
5780
|
/**
|
|
5584
|
-
*
|
|
5781
|
+
* Replaces named script values in package manifest text.
|
|
5585
5782
|
*
|
|
5586
5783
|
* @param manifest - The manifest text to compile.
|
|
5587
5784
|
* @param scripts - The scripts to write, each with the predecessors it accepts.
|
|
@@ -5809,7 +6006,7 @@ function replaceManifestScripts(manifest, scripts) {
|
|
|
5809
6006
|
return compiled;
|
|
5810
6007
|
}
|
|
5811
6008
|
/**
|
|
5812
|
-
*
|
|
6009
|
+
* Replaces dependency ranges in a plan's manifest and recomputes its identity.
|
|
5813
6010
|
*
|
|
5814
6011
|
* @param plan - The plan carrying the manifest artifact to compile.
|
|
5815
6012
|
* @param pins - The runtime and development names and replacement ranges.
|
|
@@ -5857,7 +6054,7 @@ function replacePlanRanges(plan, pins) {
|
|
|
5857
6054
|
};
|
|
5858
6055
|
}
|
|
5859
6056
|
/**
|
|
5860
|
-
*
|
|
6057
|
+
* Computes a plan's content identity.
|
|
5861
6058
|
*
|
|
5862
6059
|
* @param plan - The plan to identify.
|
|
5863
6060
|
* @returns Sixteen lowercase hexadecimal digits, or `undefined` when the plan
|
|
@@ -5894,66 +6091,7 @@ function planToHash(plan) {
|
|
|
5894
6091
|
return computeHash(outcome.value);
|
|
5895
6092
|
}
|
|
5896
6093
|
/**
|
|
5897
|
-
*
|
|
5898
|
-
*
|
|
5899
|
-
* @param artifact - The planned artifact.
|
|
5900
|
-
* @param observed - The destination's exact bytes as hexadecimal; absent when
|
|
5901
|
-
* the destination holds no file.
|
|
5902
|
-
* @returns The finding, carrying the artifact's ownership and `observed`
|
|
5903
|
-
* exactly where bytes were read.
|
|
5904
|
-
*
|
|
5905
|
-
* @remarks
|
|
5906
|
-
* The comparison itself is {@link inferDrift}'s, so ownership decides it here
|
|
5907
|
-
* exactly as it does everywhere else. This adds only the shape: a missing
|
|
5908
|
-
* destination has no bytes to record, and every other verdict records the bytes
|
|
5909
|
-
* it was given, which is the precondition the mutation that follows is held to.
|
|
5910
|
-
* Ownership is copied rather than inferred from drift because aligned findings
|
|
5911
|
-
* span every ownership tier.
|
|
5912
|
-
*
|
|
5913
|
-
* `foreign` is not answerable here, because it describes a path no artifact was
|
|
5914
|
-
* planned for.
|
|
5915
|
-
*
|
|
5916
|
-
* @example
|
|
5917
|
-
* ```ts
|
|
5918
|
-
* import { artifactToFinding } from '@orkestrel/scaffold'
|
|
5919
|
-
*
|
|
5920
|
-
* artifactToFinding(
|
|
5921
|
-
* { path: 'README.md', group: 'docs', ownership: 'content', origin: 'computed', content: 'hi\n' },
|
|
5922
|
-
* '6279650a',
|
|
5923
|
-
* ) // { path: 'README.md', group: 'docs', ownership: 'content', drift: 'stale', observed: '6279650a' }
|
|
5924
|
-
* ```
|
|
5925
|
-
*/
|
|
5926
|
-
function artifactToFinding(artifact, observed) {
|
|
5927
|
-
const path = artifact.path;
|
|
5928
|
-
const group = artifact.group;
|
|
5929
|
-
const ownership = artifact.ownership;
|
|
5930
|
-
if (observed === void 0) return inferDrift(artifact) === "aligned" ? {
|
|
5931
|
-
path,
|
|
5932
|
-
group,
|
|
5933
|
-
ownership,
|
|
5934
|
-
drift: "aligned"
|
|
5935
|
-
} : {
|
|
5936
|
-
path,
|
|
5937
|
-
group,
|
|
5938
|
-
ownership,
|
|
5939
|
-
drift: "missing"
|
|
5940
|
-
};
|
|
5941
|
-
return inferDrift(artifact, observed) === "stale" ? {
|
|
5942
|
-
path,
|
|
5943
|
-
group,
|
|
5944
|
-
ownership,
|
|
5945
|
-
drift: "stale",
|
|
5946
|
-
observed
|
|
5947
|
-
} : {
|
|
5948
|
-
path,
|
|
5949
|
-
group,
|
|
5950
|
-
ownership,
|
|
5951
|
-
drift: "aligned",
|
|
5952
|
-
observed
|
|
5953
|
-
};
|
|
5954
|
-
}
|
|
5955
|
-
/**
|
|
5956
|
-
* Compare a plan against a target's current content.
|
|
6094
|
+
* Compares a plan against a target's current content.
|
|
5957
6095
|
*
|
|
5958
6096
|
* @param plan - The compiled plan.
|
|
5959
6097
|
* @param current - The target's exact bytes, keyed by artifact-relative path.
|
|
@@ -5999,7 +6137,7 @@ function planToFindings(plan, current) {
|
|
|
5999
6137
|
return findings;
|
|
6000
6138
|
}
|
|
6001
6139
|
/**
|
|
6002
|
-
*
|
|
6140
|
+
* Measures one declared package list against the name and range syntax it accepts.
|
|
6003
6141
|
*
|
|
6004
6142
|
* @param dependencies - The declared list.
|
|
6005
6143
|
* @param field - The blueprint field the list came from, reported on each question.
|
|
@@ -6056,7 +6194,7 @@ function dependenciesToQuestions(dependencies, field, name, range) {
|
|
|
6056
6194
|
return questions;
|
|
6057
6195
|
}
|
|
6058
6196
|
/**
|
|
6059
|
-
*
|
|
6197
|
+
* Measures a blueprint against every law its own fields decide.
|
|
6060
6198
|
*
|
|
6061
6199
|
* @param blueprint - The workspace specification.
|
|
6062
6200
|
* @returns One question per rejected field, in blueprint field order, with the
|
|
@@ -6196,7 +6334,7 @@ function blueprintToQuestions(blueprint) {
|
|
|
6196
6334
|
return questions;
|
|
6197
6335
|
}
|
|
6198
6336
|
/**
|
|
6199
|
-
*
|
|
6337
|
+
* Measures a drafted artifact list against the laws a whole plan decides.
|
|
6200
6338
|
*
|
|
6201
6339
|
* @param artifacts - The drafted artifacts.
|
|
6202
6340
|
* @returns One blocking question per colliding path and per exceeded ceiling.
|
|
@@ -6253,7 +6391,7 @@ function artifactsToQuestions(artifacts) {
|
|
|
6253
6391
|
return questions;
|
|
6254
6392
|
}
|
|
6255
6393
|
/**
|
|
6256
|
-
*
|
|
6394
|
+
* Measures a blueprint's overrides against the artifacts drafted for it.
|
|
6257
6395
|
*
|
|
6258
6396
|
* @param overrides - The blueprint's overrides.
|
|
6259
6397
|
* @param artifacts - The drafted artifacts, before overrides are applied.
|
|
@@ -6317,7 +6455,7 @@ function overridesToQuestions(overrides, artifacts) {
|
|
|
6317
6455
|
//#endregion
|
|
6318
6456
|
//#region src/core/factories.ts
|
|
6319
6457
|
/**
|
|
6320
|
-
*
|
|
6458
|
+
* Constructs a {@link Blueprint} from a name and the fields that differ from the defaults.
|
|
6321
6459
|
*
|
|
6322
6460
|
* @param name - The bare workspace name.
|
|
6323
6461
|
* @param input - The fields to set; every omitted field takes its default.
|
|
@@ -6382,7 +6520,7 @@ function createBlueprint(name, input) {
|
|
|
6382
6520
|
//#endregion
|
|
6383
6521
|
//#region src/core/Compiler.ts
|
|
6384
6522
|
/**
|
|
6385
|
-
*
|
|
6523
|
+
* Represents the compile spine: draft, gate, pin, run in that order over a blueprint.
|
|
6386
6524
|
*
|
|
6387
6525
|
* @remarks
|
|
6388
6526
|
* The draft stage assembles the artifacts the selected groups cover. The gate
|
|
@@ -6426,7 +6564,7 @@ var Compiler = class {
|
|
|
6426
6564
|
#emitter;
|
|
6427
6565
|
#destroyed = false;
|
|
6428
6566
|
/**
|
|
6429
|
-
*
|
|
6567
|
+
* Constructs a compiler.
|
|
6430
6568
|
*
|
|
6431
6569
|
* @param options - The initial listeners and the listener-error handler.
|
|
6432
6570
|
* @throws {@link ScaffoldError} coded `INVALID` when `options` is present but
|
|
@@ -6446,12 +6584,12 @@ var Compiler = class {
|
|
|
6446
6584
|
...accepted?.error === void 0 ? {} : { error: accepted.error }
|
|
6447
6585
|
});
|
|
6448
6586
|
}
|
|
6449
|
-
/**
|
|
6587
|
+
/** Exposes the compiler's observation channel. */
|
|
6450
6588
|
get emitter() {
|
|
6451
6589
|
return this.#emitter;
|
|
6452
6590
|
}
|
|
6453
6591
|
/**
|
|
6454
|
-
*
|
|
6592
|
+
* Compiles a blueprint into a plan through the draft, gate, and pin stages.
|
|
6455
6593
|
*
|
|
6456
6594
|
* @param blueprint - The workspace specification to compile.
|
|
6457
6595
|
* @param groups - The artifact groups to cover; every group when absent.
|
|
@@ -6490,7 +6628,7 @@ var Compiler = class {
|
|
|
6490
6628
|
return scaffolding;
|
|
6491
6629
|
}
|
|
6492
6630
|
/**
|
|
6493
|
-
*
|
|
6631
|
+
* Compiles a blueprint and compares its plan to a target's current content.
|
|
6494
6632
|
*
|
|
6495
6633
|
* @param blueprint - The workspace specification to compile.
|
|
6496
6634
|
* @param current - The target's exact bytes, keyed by artifact-relative path.
|
|
@@ -6533,7 +6671,7 @@ var Compiler = class {
|
|
|
6533
6671
|
return result;
|
|
6534
6672
|
}
|
|
6535
6673
|
/**
|
|
6536
|
-
*
|
|
6674
|
+
* Tears the compiler down. Every later call throws, and teardown is idempotent.
|
|
6537
6675
|
*
|
|
6538
6676
|
* @returns Nothing.
|
|
6539
6677
|
*
|
|
@@ -6691,6 +6829,8 @@ exports.BIN_CONFIGS = BIN_CONFIGS;
|
|
|
6691
6829
|
exports.BIN_ENTRY_PATH = BIN_ENTRY_PATH;
|
|
6692
6830
|
exports.CANON_PATHS = CANON_PATHS;
|
|
6693
6831
|
exports.CATALOG_AGENT_PATH = CATALOG_AGENT_PATH;
|
|
6832
|
+
exports.CATALOG_CLOSING_MARKER = CATALOG_CLOSING_MARKER;
|
|
6833
|
+
exports.CATALOG_OPENING_MARKER = CATALOG_OPENING_MARKER;
|
|
6694
6834
|
exports.CONFIG_TEMPLATES = CONFIG_TEMPLATES;
|
|
6695
6835
|
exports.CONFORMANCE_TEST_PATH = CONFORMANCE_TEST_PATH;
|
|
6696
6836
|
exports.CONTROL_CHARACTER_PATTERN = CONTROL_CHARACTER_PATTERN;
|
|
@@ -6791,6 +6931,7 @@ exports.isDependency = isDependency;
|
|
|
6791
6931
|
exports.isDependencyName = isDependencyName;
|
|
6792
6932
|
exports.isEnvironment = isEnvironment;
|
|
6793
6933
|
exports.isFinding = isFinding;
|
|
6934
|
+
exports.isFloorPath = isFloorPath;
|
|
6794
6935
|
exports.isGroup = isGroup;
|
|
6795
6936
|
exports.isGroups = isGroups;
|
|
6796
6937
|
exports.isHex = isHex;
|
|
@@ -6800,6 +6941,7 @@ exports.isOverride = isOverride;
|
|
|
6800
6941
|
exports.isPath = isPath;
|
|
6801
6942
|
exports.isPlan = isPlan;
|
|
6802
6943
|
exports.isQuestion = isQuestion;
|
|
6944
|
+
exports.isRetainedPath = isRetainedPath;
|
|
6803
6945
|
exports.isScaffoldError = isScaffoldError;
|
|
6804
6946
|
exports.isSnapshot = isSnapshot;
|
|
6805
6947
|
exports.manifestToDependencies = manifestToDependencies;
|