@orkestrel/scaffold 0.0.81 → 0.0.82
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/main.js +167 -13
- package/dist/bin/main.js.map +1 -1
- package/dist/host/AGENTS.md +5 -3
- package/dist/host/agents/skills/orkestrel-harden/references/centralization.md +2 -2
- package/dist/host/agents/skills/orkestrel-journey/SKILL.md +41 -38
- package/dist/host/agents/skills/orkestrel-journey/references/captures.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/decide.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/layer.md +5 -5
- package/dist/host/agents/skills/orkestrel-journey/references/statechart.md +3 -3
- package/dist/host/agents/skills/orkestrel-journey/references/styles.md +9 -9
- package/dist/host/claude/rules/application.md +20 -6
- package/dist/host/claude/rules/architecture.md +2 -2
- package/dist/host/claude/rules/browser.md +9 -0
- package/dist/host/claude/rules/documentation.md +2 -1
- package/dist/host/claude/rules/styles.md +35 -12
- package/dist/host/claude/rules/tests.md +15 -10
- package/dist/host/claude/rules/workspace.md +128 -98
- package/dist/host/claude/skills/orkestrel-journey/SKILL.md +1 -1
- package/dist/host/configs/helpers.ts +157 -9
- package/dist/host/configs/policy.ts +64 -61
- package/dist/host/dotfiles/oxlintrc.json +132 -16
- package/dist/host/dotfiles/prettierignore +1 -1
- package/dist/host/guides/README.md +9 -5
- package/dist/host/guides/scaffold.md +475 -115
- package/dist/host/manifest.json +26 -26
- package/dist/host/tests/config.test.ts +996 -39
- package/dist/host/tests/policy.test.ts +11 -0
- package/dist/host/tests/setupPolicy.ts +396 -22
- package/dist/src/core/index.cjs +1261 -159
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +297 -35
- package/dist/src/core/index.d.ts +297 -35
- package/dist/src/core/index.js +1241 -160
- package/dist/src/core/index.js.map +1 -1
- package/package.json +1 -1
package/dist/src/core/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type { EmitterInterface } from '@orkestrel/emitter';
|
|
|
4
4
|
import type { Guard } from '@orkestrel/contract';
|
|
5
5
|
import type { JSONValue } from '@orkestrel/contract';
|
|
6
6
|
|
|
7
|
-
/** Lists the development dependencies a private
|
|
7
|
+
/** Lists the development dependencies a private browser application adds. */
|
|
8
8
|
export declare const APP_BROWSER_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
9
9
|
|
|
10
10
|
/** Names the development dependency every private `app` environment adds. */
|
|
@@ -92,12 +92,43 @@ export declare type Artifact = HostArtifact | HydratedArtifact | ContentArtifact
|
|
|
92
92
|
*/
|
|
93
93
|
export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
94
94
|
source: Readonly<{
|
|
95
|
+
sheet: Readonly<{
|
|
96
|
+
'index.scss': "@use 'tokens';\n@use 'elements';\n@use 'components';\n@use 'utilities';\n";
|
|
97
|
+
'_tokens.scss': "@layer theme, reset, base, elements, components, utilities;\n";
|
|
98
|
+
'_mixins.scss': "";
|
|
99
|
+
'elements/_index.scss': "";
|
|
100
|
+
'components/_index.scss': "";
|
|
101
|
+
'utilities/_index.scss': "";
|
|
102
|
+
'sheet.ts': "import './index.scss'\n";
|
|
103
|
+
'index.ts': "export * from './sheet.js'\n";
|
|
104
|
+
}>;
|
|
105
|
+
themes: Readonly<{
|
|
106
|
+
'index.scss': "@use '../tokens';\n@use 'default';\n";
|
|
107
|
+
'_default.scss': "";
|
|
108
|
+
'sheet.ts': "import './index.scss'\n";
|
|
109
|
+
}>;
|
|
95
110
|
empty: "";
|
|
111
|
+
barrel: "// TODO: [Feature] Export the browser extension API.\n";
|
|
112
|
+
main: "document.body\n\t.appendChild(document.createElement('main'))\n\t.appendChild(document.createElement('h1')).textContent ={{heading}}\n";
|
|
113
|
+
vue: Readonly<{
|
|
114
|
+
'main.ts': "import { createApp } from 'vue'\nimport App from './App.vue'\n\ncreateApp(App).mount(document.body.appendChild(document.createElement('main')))\n";
|
|
115
|
+
'App.vue': "<template>\n\t<h1>{{heading}}</h1>\n</template>\n";
|
|
116
|
+
}>;
|
|
96
117
|
browser: "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n\t\t<title>Application</title>\n\t</head>\n\t<body>\n\t\t<script type=\"module\" src=\"/main.ts\"></script>\n\t</body>\n</html>\n";
|
|
97
118
|
}>;
|
|
98
119
|
tests: Readonly<{
|
|
120
|
+
journey: "import {\n\tACCESSIBLE_ROLES,\n\tcreatePortfolio,\n\texpandCaptures,\n\tisRendered,\n\treadRefusal,\n\treadStyle,\n} from '@orkestrel/test/browser'\n{{imports}}import { page } from 'vitest/browser'\nimport { describe, expect, inject, it } from 'vitest'\n\nconst VARIANT = inject('variant')\nconst VARIANTS = inject('variants')\nconst CAPTURE = inject('capture')\n\ndescribe('{{application}} arrival journey', () => {\n\tit('proves the declared arrival families', async () => {\n\t\tconst families = new Set(['Journey', 'Refusal', 'Matrix', ...(CAPTURE ? ['Capture'] : [])])\n\t\tconst proven = new Set<string>()\n\t\tconst states = ['{{application}}-arrival']\n\t\tconst placed = new Set<string>()\n\t\tconst portfolio = createPortfolio({\n\t\t\tstates,\n\t\t\tvariants: VARIANTS,\n\t\t\tvariant: VARIANT,\n\t\t\tdirectory: '../../../tmp/captures/states',\n\t\t\tenabled: CAPTURE,\n\t\t})\n{{mount}}\t\ttry {\n{{arrival}}\t\t\tconst heading = page\n\t\t\t\t.getByRole('heading', {\n\t\t\t\t\tname: {{heading}},\n\t\t\t\t\texact: true,\n\t\t\t\t\tlevel: 1,\n\t\t\t\t})\n\t\t\t\t.element()\n\t\t\texpect(isRendered(heading)).toBe(true)\n\t\t\tproven.add('Journey')\n\t\t\tawait portfolio.place('{{application}}-arrival')\n\t\t\tplaced.add('{{application}}-arrival')\n\n\t\t\tfor (const role of ACCESSIBLE_ROLES) expect(page.getByRole(role).elements()).toEqual([])\n\t\t\texpect(readRefusal('Continue')).toBe(\n\t\t\t\t'No interactive element has the accessible name \"Continue\"',\n\t\t\t)\n\t\t\tproven.add('Refusal')\n\n\t\t\tconst measured = new Set<string>()\n\t\t\tfor (const variant of VARIANTS) {\n\t\t\t\tawait page.viewport(variant.width, variant.height)\n\t\t\t\texpect(readStyle(heading, 'display')).toBe('block')\n\t\t\t\texpect(window.innerWidth).toBe(variant.width)\n\t\t\t\tmeasured.add(variant.name)\n\t\t\t}\n\t\t\texpect(measured).toEqual(new Set(VARIANTS.map(({ name }) => name)))\n\t\t\tproven.add('Matrix')\n\n\t\t\tconst files = expandCaptures(states, VARIANTS)\n\t\t\texpect(portfolio.files).toEqual(files)\n\t\t\texpect(new Set(files).size).toBe(states.length * VARIANTS.length)\n\t\t\texpect(placed).toEqual(new Set(states))\n\t\t\tconst expected = CAPTURE\n\t\t\t\t? expandCaptures(\n\t\t\t\t\t\tstates,\n\t\t\t\t\t\tVARIANTS.filter(({ name }) => name === VARIANT),\n\t\t\t\t\t)\n\t\t\t\t: []\n\t\t\texpect(portfolio.paths.map((path) => path.replaceAll('\\\\', '/').split('/').at(-1))).toEqual(\n\t\t\t\texpected,\n\t\t\t)\n\t\t\tif (CAPTURE) proven.add('Capture')\n\t\t\texpect(proven).toEqual(families)\n\t\t} finally {\n{{cleanup}}\t\t\tconst variant = VARIANTS.find(({ name }) => name === VARIANT)\n\t\t\tif (variant !== undefined) await page.viewport(variant.width, variant.height)\n\t\t}\n\t})\n})\n";
|
|
121
|
+
browser: "import type { JourneyVariant } from '@orkestrel/test'\n\ndeclare module 'vitest' {\n\texport interface ProvidedContext {\n\t\treadonly variant: string\n\t\treadonly variants: readonly JourneyVariant[]\n\t\treadonly capture: boolean\n\t}\n}\n";
|
|
122
|
+
sheet: "import sheet from '/dist/src/{{name}}/index.css?raw'\nimport { describe, expect, it } from 'vitest'\nimport { adoptSheet, readLayerNames } from '{{setup}}'\n\ndescribe('{{name}} entry', () => {\n\tit('opens with the declared cascade order', () => {\n\t\tconst adopted = adoptSheet(sheet)\n\t\ttry {\n\t\t\texpect(adopted.sheet.cssRules[0]?.cssText).toBe(\n\t\t\t\t'@layer theme, reset, base, elements, components, utilities;',\n\t\t\t)\n\t\t\texpect(readLayerNames(adopted.sheet).slice(0, 6)).toEqual([\n\t\t\t\t'theme',\n\t\t\t\t'reset',\n\t\t\t\t'base',\n\t\t\t\t'elements',\n\t\t\t\t'components',\n\t\t\t\t'utilities',\n\t\t\t])\n\t\t} finally {\n\t\t\tadopted.release()\n\t\t}\n\t})\n})\n";
|
|
123
|
+
styles: Readonly<{
|
|
124
|
+
module: "/** Carries a CSSOM rule and its enclosing layer. */\nexport interface SheetEntry {\n\treadonly rule: CSSRule\n\treadonly layer: string | undefined\n}\n\n/** Describes an adopted stylesheet and its idempotent release operation. */\nexport interface SheetAdoption {\n\treadonly sheet: CSSStyleSheet\n\trelease(): void\n}\n\n/**\n * Adopts CSS text into the document with an idempotent release operation.\n * @param text - The compiled sheet text.\n * @returns The adopted sheet and its release operation.\n * @example\n * ```ts\n * const adopted = adoptSheet('.sample { color: red }')\n * adopted.release()\n * ```\n */\nexport function adoptSheet(text: string): SheetAdoption {\n\tconst sheet = new CSSStyleSheet()\n\tsheet.replaceSync(text)\n\tdocument.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]\n\treturn {\n\t\tsheet,\n\t\trelease: () => {\n\t\t\tdocument.adoptedStyleSheets = document.adoptedStyleSheets.filter(\n\t\t\t\t(candidate) => candidate !== sheet,\n\t\t\t)\n\t\t},\n\t}\n}\n\n/**\n * Reads layer statements and blocks in declaration order, including repeated names.\n * @param sheet - The parsed sheet.\n * @returns Qualified layer names, with an empty name for an anonymous layer.\n * @example\n * ```ts\n * readLayerNames(new CSSStyleSheet()) // []\n * ```\n */\nexport function readLayerNames(sheet: CSSStyleSheet): readonly string[] {\n\tconst pending: SheetEntry[] = Array.from(sheet.cssRules, (rule) => ({\n\t\trule,\n\t\tlayer: undefined,\n\t})).reverse()\n\tconst names: string[] = []\n\twhile (pending.length > 0) {\n\t\tconst entry = pending.pop()\n\t\tif (entry === undefined) break\n\t\tconst { rule, layer } = entry\n\t\tconst declared =\n\t\t\trule instanceof CSSLayerStatementRule\n\t\t\t\t? rule.nameList\n\t\t\t\t: rule instanceof CSSLayerBlockRule\n\t\t\t\t\t? [rule.name]\n\t\t\t\t\t: []\n\t\tfor (const name of declared) names.push(layer === undefined ? name : layer + '.' + name)\n\t\tif (!(rule instanceof CSSGroupingRule)) continue\n\t\tconst parent =\n\t\t\trule instanceof CSSLayerBlockRule\n\t\t\t\t? layer === undefined\n\t\t\t\t\t? rule.name\n\t\t\t\t\t: layer + '.' + rule.name\n\t\t\t\t: layer\n\t\tfor (const child of Array.from(rule.cssRules).reverse()) {\n\t\t\tpending.push({ rule: child, layer: parent })\n\t\t}\n\t}\n\treturn names\n}\n";
|
|
125
|
+
proof: "import type { SheetAdoption } from './setupStyles.js'\nimport { describe, expect, it } from 'vitest'\nimport { adoptSheet, readLayerNames } from './setupStyles.js'\n\ndescribe('CSSOM instruments', () => {\n\tit('adopts and releases only its own sheet, including repeated release', () => {\n\t\tconst previous = [...document.adoptedStyleSheets]\n\t\tconst first: SheetAdoption = adoptSheet('.sample { color: red }')\n\t\ttry {\n\t\t\tconst second = adoptSheet('.other { display: block }')\n\t\t\ttry {\n\t\t\t\texpect(document.adoptedStyleSheets).toEqual([...previous, first.sheet, second.sheet])\n\t\t\t\texpect(first.sheet.cssRules.length).toBe(1)\n\t\t\t\tfirst.release()\n\t\t\t\tfirst.release()\n\t\t\t\texpect(document.adoptedStyleSheets).toEqual([...previous, second.sheet])\n\t\t\t} finally {\n\t\t\t\tsecond.release()\n\t\t\t}\n\t\t} finally {\n\t\t\tfirst.release()\n\t\t}\n\t\texpect(document.adoptedStyleSheets).toEqual(previous)\n\t})\n\n\tit('reads statements, blocks, nested conditions, and anonymous layers in order', () => {\n\t\tconst adopted = adoptSheet(\n\t\t\t'@layer first, second; @layer first { @media all { @layer nested {} } } @layer {}',\n\t\t)\n\t\ttry {\n\t\t\texpect(readLayerNames(adopted.sheet)).toEqual([\n\t\t\t\t'first',\n\t\t\t\t'second',\n\t\t\t\t'first',\n\t\t\t\t'first.nested',\n\t\t\t\t'',\n\t\t\t])\n\t\t} finally {\n\t\t\tadopted.release()\n\t\t}\n\t})\n\n\tit('returns no layer names for an empty sheet or an unlayered rule', () => {\n\t\tconst sheet = new CSSStyleSheet()\n\t\texpect(readLayerNames(sheet)).toEqual([])\n\t\tsheet.replaceSync('.sample { color: red }')\n\t\texpect(readLayerNames(sheet)).toEqual([])\n\t})\n})\n";
|
|
126
|
+
}>;
|
|
99
127
|
setup: "";
|
|
100
|
-
global:
|
|
128
|
+
global: Readonly<{
|
|
129
|
+
module: "export function setup(): void {}\n";
|
|
130
|
+
proof: "import { describe, expect, it } from 'vitest'\nimport { setup } from './setupGlobal.js'\n\ndescribe('global setup', () => {\n\tit('runs without producing a teardown', () => {\n\t\texpect(setup()).toBeUndefined()\n\t\texpect(setup()).toBeUndefined()\n\t})\n})\n";
|
|
131
|
+
}>;
|
|
101
132
|
entry: "import * as entry from {{specifier}}\nimport { describe, expect, it } from 'vitest'\n\ndescribe({{label}}, () => {\n\tit('has no starter exports', () => {\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
102
133
|
bin: "import { describe, expect, it } from 'vitest'\n\ndescribe('bin entry', () => {\n\tit('has no starter exports', async () => {\n{{import}}\n\t\texpect(Object.keys(entry)).toStrictEqual([])\n\t})\n})\n";
|
|
103
134
|
distribution: Readonly<{
|
|
@@ -233,6 +264,12 @@ export declare interface Audit {
|
|
|
233
264
|
readonly questions: readonly Question[];
|
|
234
265
|
}
|
|
235
266
|
|
|
267
|
+
/** Lists the axes a browser extension may occupy, frozen. */
|
|
268
|
+
export declare const AXES: readonly Axis[];
|
|
269
|
+
|
|
270
|
+
/** Names the workspace axis an extension occupies. */
|
|
271
|
+
export declare type Axis = 'src' | 'app';
|
|
272
|
+
|
|
236
273
|
/** Holds the tooling versions scaffold and every generated workspace share. */
|
|
237
274
|
export declare const BASE_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
238
275
|
|
|
@@ -253,12 +290,12 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
253
290
|
* fleet pin; every other peer is a floor. `extras` are package-specific
|
|
254
291
|
* development dependencies and may carry any valid npm name.
|
|
255
292
|
* `bin`, `setup`, `guides`, `integration`, `conformance`, `service`,
|
|
256
|
-
* `vendors`, `global`, `showcase`, `journey`, and `skills` are structural facts: each is
|
|
293
|
+
* `vendors`, `global`, `showcase`, `journey`, `styles`, `themes`, and `skills` are structural facts: each is
|
|
257
294
|
* set only when the workspace physically ships the directory or exact-case file
|
|
258
295
|
* that defines it, never because of the workspace's name and never because a
|
|
259
296
|
* sibling fact is set.
|
|
260
297
|
* `setup` lists the runtimes required by root setup proofs: `node` for generic
|
|
261
|
-
* and server proofs, and `browser` for `tests/setupBrowser.test.ts`.
|
|
298
|
+
* and server proofs, and `browser` for `tests/setupBrowser.test.ts` and `tests/setupStyles.test.ts`.
|
|
262
299
|
* `journey` selects the birth-owned variant wrapper for a browser application.
|
|
263
300
|
* `skills` registers the `skills` Vitest project over the mirrored proofs of the skill
|
|
264
301
|
* scripts a workspace ships under each `.agents/skills/<skill>/scripts/` directory, and adds their
|
|
@@ -280,6 +317,12 @@ export declare interface Blueprint {
|
|
|
280
317
|
readonly keywords: readonly string[];
|
|
281
318
|
readonly src: readonly Environment[];
|
|
282
319
|
readonly app: readonly Environment[];
|
|
320
|
+
/** Lists browser faces by their physical axes and sheets by their marker pair. */
|
|
321
|
+
readonly extensions: readonly Extension[];
|
|
322
|
+
/** Selects the exact-case `src/styles/index.scss` marker. */
|
|
323
|
+
readonly styles: boolean;
|
|
324
|
+
/** Selects `src/styles/themes/index.scss` beside `src/styles/themes/sheet.ts`. */
|
|
325
|
+
readonly themes: boolean;
|
|
283
326
|
readonly dependencies: readonly Dependency[];
|
|
284
327
|
readonly peers: readonly Dependency[];
|
|
285
328
|
readonly extras: readonly Dependency[];
|
|
@@ -388,6 +431,33 @@ export declare function blueprintToDevDependencies(blueprint: Blueprint): Readon
|
|
|
388
431
|
*/
|
|
389
432
|
export declare function blueprintToDocumentArtifacts(blueprint: Blueprint): readonly ContentArtifact[];
|
|
390
433
|
|
|
434
|
+
/**
|
|
435
|
+
* Projects published environments and sheets into the manifest export map.
|
|
436
|
+
* @param blueprint - The workspace specification.
|
|
437
|
+
* @returns JavaScript conditions and CSS and SCSS subpaths, without an invented JavaScript root.
|
|
438
|
+
* @example
|
|
439
|
+
* ```ts
|
|
440
|
+
* import { blueprintToExports, createBlueprint } from '@orkestrel/scaffold'
|
|
441
|
+
*
|
|
442
|
+
* blueprintToExports(createBlueprint('paper', { styles: true }))['./styles']
|
|
443
|
+
* // './dist/src/styles/index.css'
|
|
444
|
+
* ```
|
|
445
|
+
*/
|
|
446
|
+
export declare function blueprintToExports(blueprint: Blueprint): Readonly<Record<string, unknown>>;
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Projects a blueprint into browser extensions restricted to occupied browser axes.
|
|
450
|
+
* @param blueprint - The workspace specification.
|
|
451
|
+
* @returns Browser extensions with their occupied axes, omitting unplaced extensions.
|
|
452
|
+
* @example
|
|
453
|
+
* ```ts
|
|
454
|
+
* import { blueprintToFaces, createBlueprint } from '@orkestrel/scaffold'
|
|
455
|
+
*
|
|
456
|
+
* blueprintToFaces(createBlueprint('desk', { app: ['core'] })).length // 0
|
|
457
|
+
* ```
|
|
458
|
+
*/
|
|
459
|
+
export declare function blueprintToFaces(blueprint: Blueprint): readonly BrowserExtension[];
|
|
460
|
+
|
|
391
461
|
/**
|
|
392
462
|
* Compiles the generated workspace's guide index.
|
|
393
463
|
*
|
|
@@ -481,7 +551,7 @@ export declare function blueprintToHostArtifacts(blueprint: Blueprint): readonly
|
|
|
481
551
|
*
|
|
482
552
|
* const blueprint = createBlueprint('router', { app: ['browser'] })
|
|
483
553
|
*
|
|
484
|
-
* blueprintToMachinery(blueprint).
|
|
554
|
+
* blueprintToMachinery(blueprint).frameworks // []
|
|
485
555
|
* ```
|
|
486
556
|
*/
|
|
487
557
|
export declare function blueprintToMachinery(blueprint: Blueprint): ViteMachinery;
|
|
@@ -547,6 +617,21 @@ export declare function blueprintToManifest(blueprint: Blueprint): string;
|
|
|
547
617
|
*/
|
|
548
618
|
export declare function blueprintToOrchestrationArtifacts(blueprint: Blueprint): readonly ContentArtifact[];
|
|
549
619
|
|
|
620
|
+
/**
|
|
621
|
+
* Projects a blueprint into the project labels its root Vitest configuration registers.
|
|
622
|
+
*
|
|
623
|
+
* @param blueprint - The workspace specification.
|
|
624
|
+
* @returns Project labels in registration order, including wrapper-registered sheet faces.
|
|
625
|
+
*
|
|
626
|
+
* @example
|
|
627
|
+
* ```ts
|
|
628
|
+
* import { blueprintToProjects, createBlueprint } from '@orkestrel/scaffold'
|
|
629
|
+
*
|
|
630
|
+
* blueprintToProjects(createBlueprint('desk')).includes('policy') // true
|
|
631
|
+
* ```
|
|
632
|
+
*/
|
|
633
|
+
export declare function blueprintToProjects(blueprint: Blueprint): readonly string[];
|
|
634
|
+
|
|
550
635
|
/**
|
|
551
636
|
* Measures a blueprint against every law its own fields decide.
|
|
552
637
|
*
|
|
@@ -567,7 +652,8 @@ export declare function blueprintToOrchestrationArtifacts(blueprint: Blueprint):
|
|
|
567
652
|
* These do not, because each describes a workspace it can describe honestly but
|
|
568
653
|
* will not create: a published axis of several environments without core,
|
|
569
654
|
* whose manifest names a core build the workspace never runs; a showcase flag
|
|
570
|
-
* whose required browser axis is absent, which emits nothing;
|
|
655
|
+
* or journey flag whose required browser axis is absent, which emits nothing; an unplaced browser
|
|
656
|
+
* extension or a styles extension without the styles surface; and an
|
|
571
657
|
* integration flag over fewer than two environments, whose seed does emit and
|
|
572
658
|
* has nothing to compose across. Blocking any of them closed the gate for every
|
|
573
659
|
* verb. The verbs that read an existing workspace need the plan the gate
|
|
@@ -685,19 +771,28 @@ export declare function blueprintToRootVite(blueprint: Blueprint): string;
|
|
|
685
771
|
*/
|
|
686
772
|
export declare function blueprintToScripts(blueprint: Blueprint): Readonly<Record<string, string>>;
|
|
687
773
|
|
|
774
|
+
/**
|
|
775
|
+
* Projects a blueprint into its validated sheet-face names in stable order.
|
|
776
|
+
* @param blueprint - The workspace specification.
|
|
777
|
+
* @returns The base face followed by named styles extensions; themes remain a separate target.
|
|
778
|
+
* @example
|
|
779
|
+
* ```ts
|
|
780
|
+
* import { blueprintToSheets, createBlueprint } from '@orkestrel/scaffold'
|
|
781
|
+
*
|
|
782
|
+
* blueprintToSheets(createBlueprint('paper', { styles: true })) // ['styles']
|
|
783
|
+
* ```
|
|
784
|
+
*/
|
|
785
|
+
export declare function blueprintToSheets(blueprint: Blueprint): readonly string[];
|
|
786
|
+
|
|
688
787
|
/**
|
|
689
788
|
* Compiles every artifact in the `source` group.
|
|
690
789
|
*
|
|
691
790
|
* @param blueprint - The workspace specification.
|
|
692
|
-
* @returns
|
|
791
|
+
* @returns Published barrels, sheet seeds, selected application entries, and the optional bin entry.
|
|
693
792
|
*
|
|
694
793
|
* @remarks
|
|
695
|
-
*
|
|
696
|
-
*
|
|
697
|
-
* scaffold establishes only the selected environment boundaries. An application
|
|
698
|
-
* entry is empty for the same reason the bin entry is, and because the vendored
|
|
699
|
-
* lint config refuses an unassigned import outside a stylesheet, so the entry
|
|
700
|
-
* cannot start by importing its barrel for effect either.
|
|
794
|
+
* Barrels, server entries, and bin entries hold no starter implementation. Browser entries
|
|
795
|
+
* render the workspace name as a level-one heading; the Vue face mounts its arrival component.
|
|
701
796
|
*
|
|
702
797
|
* @example
|
|
703
798
|
* ```ts
|
|
@@ -714,7 +809,7 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
|
|
|
714
809
|
* Compiles every artifact in the `tests` group that is not vendored from the host.
|
|
715
810
|
*
|
|
716
811
|
* @param blueprint - The workspace specification.
|
|
717
|
-
* @returns Shared setup modules, axis tests, and the optional integration seed.
|
|
812
|
+
* @returns Shared setup modules and proofs, axis and sheet tests, journey suites, and the optional integration seed.
|
|
718
813
|
*
|
|
719
814
|
* @remarks
|
|
720
815
|
* `tests/setupPolicy.ts`, `tests/policy.test.ts`, and `tests/config.test.ts` are
|
|
@@ -758,6 +853,8 @@ export declare function blueprintToTestArtifacts(blueprint: Blueprint): readonly
|
|
|
758
853
|
* benchmark workbench scripts. A workspace carrying guides adds `test:guides`,
|
|
759
854
|
* whose package-owned entry runs the guides project and handles explicit parity
|
|
760
855
|
* rewrites, and one carrying skills adds `test:skills`. Publishing adds the pack and publication lifecycle scripts.
|
|
856
|
+
* Sheet and framework faces add their check and build scripts, application frameworks add dev scripts,
|
|
857
|
+
* and selected showcases and journeys add their mode scripts.
|
|
761
858
|
* Aggregate test scripts and
|
|
762
859
|
* maintainer-owned gate chains stay outside the region.
|
|
763
860
|
*
|
|
@@ -781,6 +878,13 @@ export declare function blueprintToTestArtifacts(blueprint: Blueprint): readonly
|
|
|
781
878
|
*/
|
|
782
879
|
export declare function blueprintToWritableScripts(blueprint: Blueprint): readonly ManifestScript[];
|
|
783
880
|
|
|
881
|
+
/** Represents a browser framework and its physically occupied axes. */
|
|
882
|
+
export declare interface BrowserExtension {
|
|
883
|
+
readonly surface: 'browser';
|
|
884
|
+
readonly name: Framework;
|
|
885
|
+
readonly axes: readonly Axis[];
|
|
886
|
+
}
|
|
887
|
+
|
|
784
888
|
/** Names one module format a published library environment builds. */
|
|
785
889
|
export declare type BuildFormat = 'es' | 'cjs';
|
|
786
890
|
|
|
@@ -1290,36 +1394,47 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1290
1394
|
*/
|
|
1291
1395
|
export declare const CONFIG_TEMPLATES: Readonly<{
|
|
1292
1396
|
root: Readonly<{
|
|
1293
|
-
tsconfig: "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"allowImportingTsExtensions\": true,\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"node\", \"vite/client\", \"vitest/globals\"],\n\t\t\"moduleDetection\": \"force\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"strict\": true,\n\t\t\"verbatimModuleSyntax\": true,\n\t\t\"noUncheckedIndexedAccess\": true,\n\t\t\"noUncheckedSideEffectImports\": true,\n\t\t\"exactOptionalPropertyTypes\": true,\n\t\t\"noUnusedLocals\": true,\n\t\t\"noUnusedParameters\": true,\n\t\t\"noImplicitOverride\": true,\n\t\t\"noFallthroughCasesInSwitch\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"noEmit\": true,\n
|
|
1397
|
+
tsconfig: "{\n\t\"compilerOptions\": {\n\t\t\"target\": \"ESNext\",\n\t\t\"module\": \"ESNext\",\n\t\t\"moduleResolution\": \"bundler\",\n\t\t\"allowImportingTsExtensions\": true,\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"node\", \"vite/client\", \"vitest/globals\"],\n\t\t\"moduleDetection\": \"force\",\n\t\t\"resolveJsonModule\": true,\n\t\t\"strict\": true,\n\t\t\"verbatimModuleSyntax\": true,\n\t\t\"noUncheckedIndexedAccess\": true,\n\t\t\"noUncheckedSideEffectImports\": true,\n\t\t\"exactOptionalPropertyTypes\": true,\n\t\t\"noUnusedLocals\": true,\n\t\t\"noUnusedParameters\": true,\n\t\t\"noImplicitOverride\": true,\n\t\t\"noFallthroughCasesInSwitch\": true,\n\t\t\"forceConsistentCasingInFileNames\": true,\n\t\t\"skipLibCheck\": true,\n\t\t\"noEmit\": true,\n{{paths}}\n\t},\n\t\"exclude\": [\"node_modules\", \"dist\", \"tmp\"]\n}\n";
|
|
1294
1398
|
vite: "{{journey}}import type { PluginOption, UserConfig } from 'vite'\nimport { mergeConfig } from 'vite'\n{{imports}}import { defineConfig } from 'vitest/config'\nimport manifest from './package.json' with { type: 'json' }\nimport tsconfig from './tsconfig.json' with { type: 'json' }\n{{helpers}}{{browsers}}import { fileURLToPath, URL } from 'node:url'\n\n{{options}}export function resolveWorkspacePath(relativePath: string): string {\n\treturn fileURLToPath(new URL(relativePath, import.meta.url))\n}\n\nconst peerDependencies = 'peerDependencies' in manifest ? manifest.peerDependencies : undefined\nif (\n\tpeerDependencies !== undefined &&\n\t(typeof peerDependencies !== 'object' ||\n\t\tpeerDependencies === null ||\n\t\tArray.isArray(peerDependencies))\n) {\n\tthrow new Error('package peerDependencies must be an object')\n}\nexport const peers: readonly string[] =\n\tpeerDependencies === undefined ? [] : Object.keys(peerDependencies)\n\nconst resolve = {\n\talias: Object.entries(tsconfig.compilerOptions.paths).reduce((aliases, [key, values]) => {\n\t\tconst [path] = values\n\t\tif (path === undefined) throw new Error('tsconfig path alias ' + key + ' has no target')\n\t\treturn Object.assign(aliases, { [key]: resolveWorkspacePath(path) })\n\t}, {}),\n}\n\n// Merges a caller's override onto the configuration a factory declares, so a\n// package's own configuration reaches the factory through its parameter instead of\n// wrapping the call from outside.\n//\n// Vitest calls every registered project factory with its own invocation record —\n// `command`, `mode`, `isSsrBuild`, `isPreview` — so a factory that also takes an\n// override receives that record in the same position. A `UserConfig` declares `mode`\n// but not `command`, and the invocation record always carries both, so a value\n// carrying the pair is that record rather than an override. The merge returns the\n// base in the record's `mode` and carries none of the record's other fields. Vitest\n// runs a project that declares no `mode` in its own run mode, `test`, rather than in\n// the `--mode` value it was invoked with, so a distribution proof run with\n// `--mode release` would read `test` and skip where it must fail. A record whose\n// `mode` is not a string throws. The `tests/config.test.ts` file drives every\n// registered factory through it.\n//\n// `mergeConfig` concatenates arrays, so an override carrying `plugins` would otherwise\n// add a second copy of a plugin the base already declares. Only named top-level\n// objects replace a base plugin of the same name, in the base's position, and one\n// override entry is taken at most once. An entry no base position took appends in its\n// written order; the caller's own entries never merge with each other. Nested arrays,\n// promises, falsy entries, and anonymous objects pass through unchanged. An override\n// cannot remove a base plugin. Every key other than `plugins` merges as `mergeConfig`\n// merges it, so an override's arrays elsewhere concatenate with the base's rather than\n// replacing them.\nexport function mergeOverride(base: UserConfig, override?: UserConfig): UserConfig {\n\tif (override === undefined) return base\n\tif ('command' in override && 'mode' in override) {\n\t\tif (typeof override.mode !== 'string') {\n\t\t\tthrow new Error('The project invocation carries no string mode')\n\t\t}\n\t\treturn { ...base, mode: override.mode }\n\t}\n\tconst merged: UserConfig = mergeConfig(base, override)\n\tif (merged.plugins === undefined) return merged\n\tconst candidates = override.plugins ?? []\n\tconst taken = new Set<number>()\n\tconst selected: PluginOption[] = []\n\tfor (const plugin of base.plugins ?? []) {\n\t\tif (!isNamedPlugin(plugin)) {\n\t\t\tselected.push(plugin)\n\t\t\tcontinue\n\t\t}\n\t\tconst index = candidates.findIndex(\n\t\t\t(candidate, position) =>\n\t\t\t\t!taken.has(position) && isNamedPlugin(candidate) && candidate.name === plugin.name,\n\t\t)\n\t\tconst replacement = candidates[index]\n\t\tif (replacement === undefined) {\n\t\t\tselected.push(plugin)\n\t\t} else {\n\t\t\tselected.push(replacement)\n\t\t\ttaken.add(index)\n\t\t}\n\t}\n\tfor (const [index, plugin] of candidates.entries()) {\n\t\tif (!taken.has(index)) selected.push(plugin)\n\t}\n\treturn { ...merged, plugins: selected }\n}\n\nfunction isNamedPlugin(plugin: PluginOption): plugin is { name: string } {\n\treturn (\n\t\ttypeof plugin === 'object' &&\n\t\tplugin !== null &&\n\t\t!Array.isArray(plugin) &&\n\t\t!('then' in plugin && typeof plugin.then === 'function') &&\n\t\t'name' in plugin &&\n\t\ttypeof plugin.name === 'string'\n\t)\n}\n\n{{factories}}export default defineConfig({\n\tresolve,\n\ttest: {\n{{projects}}\n\t},\n})\n";
|
|
1295
1399
|
}>;
|
|
1296
1400
|
factories: Readonly<{
|
|
1401
|
+
sheet: "export function sheetProject(name: string, override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\ttest: {\n\t\t\tname: { label: name, color: 'magenta' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tisolate: false,\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts', './tests/setupStyles.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1297
1402
|
src: Readonly<{
|
|
1298
1403
|
core: "export function srcCore(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\trolldownOptions: { onLog: enforceBuildLog },\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:core', color: 'magenta' },\n\t\t\tinclude: ['tests/src/core/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1404
|
+
vue: "function resolveVueFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcVue(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps: { include: [...optimizeDeps.include, 'vue'] },\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/vue'), environmentBoundary('src/vue'), vue()],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/vue/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveVueFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/vue',\n\t\t\trolldownOptions: { onLog: enforceBuildLog },\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:vue', color: 'green' },\n\t\t\tinclude: ['tests/src/vue/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1405
|
+
browser: "function resolveBrowserFilename(): string {\n\treturn 'index.js'\n}\n\nexport function srcBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/browser'), environmentBoundary('src/browser')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/browser/index.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveBrowserFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/browser',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\t{{external}}\n{{output}}\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:browser', color: 'yellow' },\n\t\t\tinclude: ['tests/src/browser/**/*.test.ts'],\n{{exclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1406
|
+
server: "function resolveServerFilename(format: string): string {\n\treturn format === 'es' ? 'index.js' : 'index.cjs'\n}\n\nexport function srcServer(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/src/server'), environmentBoundary('src/server')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/server/index.ts'),\n\t\t\t\tformats: ['es', 'cjs'],\n\t\t\t\tfileName: resolveServerFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/src/server',\n\t\t\ttarget: 'node22',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tplatform: 'node',\n\t\t\t\t{{external}}\n{{output}}\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:server', color: 'red' },\n\t\t\tinclude: ['tests/src/server/**/*.test.ts'],\n{{exclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1407
|
+
bin: "function resolveBinFilename(): string {\n\treturn 'main.js'\n}\n\nfunction resolveBinExternal(id: string): boolean {\n\treturn id.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] })\n}\n\nexport function srcBin(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/bin')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tsourcemap: true,\n\t\t\tminify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/bin/main.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: resolveBinFilename,\n\t\t\t},\n\t\t\toutDir: 'dist/bin',\n\t\t\ttarget: 'node22',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\texternal: resolveBinExternal,\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'src:bin', color: 'yellow' },\n\t\t\tinclude: ['tests/src/bin/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// A bin test drives the real executable over a real temporary repository, so it\n\t\t\t// spends seconds in process startup and filesystem work rather than milliseconds.\n\t\t\t// Vitest's five-second default clears one alone and times out under a full suite.\n\t\t\ttestTimeout: 15_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1302
1408
|
}>;
|
|
1303
1409
|
app: Readonly<{
|
|
1304
1410
|
core: "export function appCore(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [environmentBoundary('app/core')],\n\t\ttest: {\n\t\t\tname: { label: 'app:core', color: 'cyan' },\n\t\t\tinclude: ['tests/app/core/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1305
|
-
browser: "export function appBrowser(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/browser'\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/browser')
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1411
|
+
browser: "export function appBrowser(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/browser'\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\toptimizeDeps,\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/browser')],\n\t\troot: resolveWorkspacePath('app/browser'),\n\t\tpublicDir: false,\n\t\tbuild: {\n\t\t\tassetsInlineLimit: 0,\n\t\t\temptyOutDir: true,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\tinput: resolveWorkspacePath('app/browser/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:browser', color: 'blue' },\n\t\t\troot: resolveWorkspacePath('.'),\n\t\t\tdir: resolveWorkspacePath('.'),\n\t\t\tinclude: ['tests/app/browser/**/*.test.ts'],\n{{journeyExclude}}\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n{{showcaseFactory}}{{journeyFactory}}";
|
|
1412
|
+
vue: "export function appVue(override?: UserConfig): UserConfig {\n\tconst output = 'dist/app/vue'\n\tconst browser = appBrowser()\n\tconst project: UserConfig = {\n\t\t...browser,\n\t\toptimizeDeps: { include: [...optimizeDeps.include, 'vue'] },\n\t\tplugins: [outputBoundary(output), environmentBoundary('app/vue'), vue()],\n\t\troot: resolveWorkspacePath('app/vue'),\n\t\tbuild: {\n\t\t\t...browser.build,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\trolldownOptions: {\n\t\t\t\t...browser.build?.rolldownOptions,\n\t\t\t\tinput: resolveWorkspacePath('app/vue/index.html'),\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\t...browser.test,\n\t\t\tname: { label: 'app:vue', color: 'magenta' },\n\t\t\tinclude: ['tests/app/vue/**/*.test.ts'],\n{{journeyExclude}}\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1413
|
+
journey: "\n// Replace the journey fields directly: merging would concatenate the ordinary include\n// and retain the exclusion of the journey suite.\nexport function appJourney(\n\tvariant: JourneyVariant,\n\tvariants: readonly JourneyVariant[],\n\tmode?: string,\n): UserConfig {\n\tconst application = resolveApplication(mode, applications)\n\tconst browser = applications[application]()\n\treturn {\n\t\t...browser,\n\t\ttest: {\n\t\t\t...browser.test,\n\t\t\tname: { label: `journey:${variant.name}`, color: 'green' },\n\t\t\tinclude: [`tests/app/${application}/integration.test.ts`],\n\t\t\texclude: [],\n\t\t\tprovide: { variant: variant.name, variants, capture },\n\t\t\tbrowser: {\n\t\t\t\t...browser.test?.browser,\n\t\t\t\tenabled: true,\n\t\t\t\tviewport: { width: variant.width, height: variant.height },\n\t\t\t},\n\t\t},\n\t}\n}\n";
|
|
1414
|
+
showcase: "\nconst showcaseStamp: PluginOption = {\n\tname: 'orkestrel-showcase-html',\n\tenforce: 'post',\n\tgenerateBundle(_, bundle) {\n\t\tfor (const file of Object.values(bundle)) {\n\t\t\tif (\n\t\t\t\tfile.type === 'asset' &&\n\t\t\t\ttypeof file.source === 'string' &&\n\t\t\t\tfile.fileName.endsWith('.html')\n\t\t\t) {\n\t\t\t\tfile.source = stampPage(file.source)\n\t\t\t}\n\t\t}\n\t},\n}\n\nfunction createShowcaseNaming(application: string): PluginOption {\n\treturn {\n\t\tname: 'orkestrel-showcase-name',\n\t\tenforce: 'post',\n\t\twriteBundle(options) {\n\t\t\tif (options.dir === undefined) throw new Error('The showcase output is absent.')\n\t\t\trenameSync(\n\t\t\t\tresolvePath(options.dir, 'index.html'),\n\t\t\t\tresolvePath(options.dir, application + '.html'),\n\t\t\t)\n\t\t},\n\t}\n}\n\nexport function appShowcase(mode: string, override?: UserConfig): UserConfig {\n\tconst application = resolveApplication(mode, applications)\n\tconst output = 'showcase'\n\tconst showcase: UserConfig = {\n\t\tplugins: [\n\t\t\toutputBoundary(output),\n\t\t\tviteSingleFile({\n\t\t\t\tremoveViteModuleLoader: true,\n\t\t\t\tuseRecommendedBuildConfig: true,\n\t\t\t}),\n\t\t\tshowcaseStamp,\n\t\t\tcreateShowcaseNaming(application),\n\t\t],\n\t\tbuild: {\n\t\t\t// The `appBrowser` factory sets `assetsInlineLimit` to 0, so every asset becomes\n\t\t\t// its own file, and 4096 is Vite's own default put back. The `viteSingleFile`\n\t\t\t// plugin overwrites the value while the `useRecommendedBuildConfig` option stays\n\t\t\t// true, so this line takes effect only in a workspace that turns that option off.\n\t\t\tassetsInlineLimit: 4096,\n\t\t\tcssMinify: 'lightningcss',\n\t\t\temptyOutDir: false,\n\t\t\tminify: 'oxc',\n\t\t\tmodulePreload: false,\n\t\t\toutDir: resolveWorkspacePath(output),\n\t\t\treportCompressedSize: false,\n\t\t\tsourcemap: false,\n\t\t\ttarget: 'esnext',\n\t\t},\n\t}\n\treturn applications[application](mergeOverride(showcase, override))\n}\n";
|
|
1415
|
+
server: "function resolveAppFilename(): string {\n\treturn 'main.cjs'\n}\n\nfunction resolveAppExternal(id: string): boolean {\n\treturn id.startsWith('node:')\n}\n\nexport function appServer(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\tpublicDir: false,\n\t\tplugins: [outputBoundary('dist/app/server'), environmentBoundary('app/server')],\n\t\tbuild: {\n\t\t\temptyOutDir: true,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('app/server/main.ts'),\n\t\t\t\tformats: ['cjs'],\n\t\t\t\tfileName: resolveAppFilename,\n\t\t\t},\n\t\t\toutDir: resolveWorkspacePath('dist/app/server'),\n\t\t\ttarget: 'node22',\n\t\t\trolldownOptions: {\n\t\t\t\tonLog: enforceBuildLog,\n\t\t\t\texternal: resolveAppExternal,\n\t\t\t},\n\t\t},\n\t\ttest: {\n\t\t\tname: { label: 'app:server', color: 'green' },\n\t\t\tinclude: ['tests/app/server/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1309
1416
|
}>;
|
|
1310
1417
|
policy: "export function policy(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'policy', color: 'white' },\n\t\t\tinclude: ['tests/policy.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1311
1418
|
config: "export function config(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'config', color: 'yellow' },\n\t\t\tinclude: ['tests/config.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// A config test validates every target wrapper, spawns the real linter twice under\n\t\t\t// 15-second child caps, and rolls one face up through the compiler and the extractor it\n\t\t\t// spawns, so this budget clears the capped pair with room for a contended host.\n\t\t\ttestTimeout: 60_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1312
|
-
setup: "export function setup(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'setup', color: 'white' },\n\t\t\tinclude: ['tests/setup*.test.ts'],\n\t\t\texclude: ['tests/setupBrowser.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1313
|
-
browser: "export function setupBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n{{plugins}}\t\ttest: {\n\t\t\tname: { label: 'setup:browser', color: 'blue' },\n\t\t\tinclude: ['tests/setupBrowser.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1419
|
+
setup: "export function setup(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'setup', color: 'white' },\n\t\t\tinclude: ['tests/setup*.test.ts'],\n\t\t\texclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tpool: 'threads',\n\t\t\tisolate: false,\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1420
|
+
browser: "export function setupBrowser(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\t{{optimization}},\n{{plugins}}\t\ttest: {\n\t\t\tname: { label: 'setup:browser', color: 'blue' },\n\t\t\tinclude: ['tests/setupBrowser.test.ts', 'tests/setupStyles.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupBrowser.ts'],\n{{global}}\t\t\tbrowser: {\n\t\t\t\tenabled: true,\n\t\t\t\tprovider: playwright(browserOptions),\n\t\t\t\tinstances: [{ browser: 'chromium', headless: true }],\n\t\t\t},\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1314
1421
|
guides: "export function guides(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'guides', color: 'green' },\n\t\t\tinclude: ['tests/guides.test.ts'],\n\t\t\texclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1315
1422
|
skills: "// The skill scripts this package ships as canon, each driven as a child process against a\n// scratch fixture from its mirrored proof under `tests/agents/skills/<skill>/scripts/`. The\n// `configs/agents/tsconfig.skills.json` wrapper selects the project.\nexport function skills(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'skills', color: 'blue' },\n\t\t\tinclude: ['tests/agents/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\t// Each case spawns node on a script; a census case runs `vitest list` over this checkout.\n\t\t\ttestTimeout: 60_000,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1316
|
-
conformance: "// Where this package drifts from the official tooling it stays compatible with.\n// The subject is this package, so the proof is hermetic and stays in `npm test`.\nexport function conformance(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1423
|
+
conformance: "// Where this package drifts from the official tooling it stays compatible with.\n// The subject is this package, so the proof is hermetic and stays in `npm test`.\nexport function conformance(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupServer.ts'],\n\t\t\tpool: 'threads',\n\t\t\tisolate: false,\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1317
1424
|
service: "// The caller prepares the live external services before this project.\n// `tests/setupService.ts` verifies readiness, and the project stays out of `npm test`\n// because a real service answers it.\nexport function service(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'service', color: 'red' },\n\t\t\tinclude: ['tests/service/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupService.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1318
1425
|
distribution: "export function distribution(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'distribution', color: 'cyan' },\n\t\t\tinclude: ['tests/distribution.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\ttestTimeout: 120_000,\n\t\t\thookTimeout: 120_000,\n\t\t\tfileParallelism: false,\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1319
1426
|
probe: "// A workbench, not a proof. No gate selects this project. Run in test mode by the\n// `test:probe` script, it collects `tmp/probes/**/*.test.ts`. Run in benchmark mode by the\n// `test:bench` script, the same workbench also collects `tests/**/*.test.ts` for a `bench` block,\n// so a suite may carry a bench beside its ordinary tests without a second project. The mode\n// guard around each `bench` call keeps it out of test mode, so it never executes there.\nexport function probe(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'probe', color: 'black' },\n\t\t\tinclude: ['tmp/probes/**/*.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\tenvironment: 'node',\n\t\t\tbrowser: { enabled: false },\n\t\t\tfileParallelism: false,\n\t\t\tpool: 'threads',\n\t\t\tbenchmark: { include: ['tmp/probes/**/*.test.ts', 'tests/**/*.test.ts'] },\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1320
|
-
integration:
|
|
1427
|
+
integration: Readonly<{
|
|
1428
|
+
sheet: "export function integration(override?: UserConfig): UserConfig {\n\tconst project = sheetProject('integration', {\n\t\ttest: {\n\t\t\tinclude: ['tests/integration.test.ts'],\n{{global}}\t\t},\n\t})\n\treturn mergeOverride(project, override)\n}\n";
|
|
1429
|
+
module: "export function integration(override?: UserConfig): UserConfig {\n\tconst project: UserConfig = {\n\t\tresolve,\n\t\ttest: {\n\t\t\tname: { label: 'integration', color: 'blue' },\n\t\t\tinclude: ['tests/integration.test.ts'],\n\t\t\tsetupFiles: ['./tests/setup.ts'],\n{{global}}\t\t\tenvironment: 'node',\n\t\t},\n\t}\n\treturn mergeOverride(project, override)\n}\n";
|
|
1430
|
+
}>;
|
|
1321
1431
|
}>;
|
|
1322
1432
|
tsconfigs: Readonly<{
|
|
1433
|
+
vue: Readonly<{
|
|
1434
|
+
src: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"vite/client\"],\n\t\t\"noEmit\": false,\n\t\t\"declaration\": true,\n\t\t\"emitDeclarationOnly\": true,\n\t\t\"rootDir\": \"../../src\",\n\t\t\"outDir\": \"../../dist/src\"\n\t},\n\t\"include\": [\n\t\t\"../../src/vue/**/*.cts\",\n\t\t\"../../src/vue/**/*.mts\",\n\t\t\"../../src/vue/**/*.ts\",\n\t\t\"../../src/vue/**/*.tsx\"\n\t]\n}\n";
|
|
1435
|
+
app: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"vite/client\", \"vue\"]\n\t},\n\t\"include\": [\n{{include}}\n\t]\n}\n";
|
|
1436
|
+
}>;
|
|
1437
|
+
sheet: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"vite/client\"],\n\t\t\"noEmit\": true\n\t},\n\t\"include\": [\"../../src/{{name}}/**/*.ts\"]\n}\n";
|
|
1323
1438
|
src: Readonly<{
|
|
1324
1439
|
core: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"WebWorker\"],\n\t\t\"types\": [],\n\t\t\"noEmit\": false,\n\t\t\"declaration\": true,\n\t\t\"emitDeclarationOnly\": true,\n\t\t\"rootDir\": \"../../src/core\",\n\t\t\"outDir\": \"../../dist/src/core\"\n\t},\n\t\"include\": [\n\t\t\"../../src/core/**/*.cts\",\n\t\t\"../../src/core/**/*.mts\",\n\t\t\"../../src/core/**/*.ts\",\n\t\t\"../../src/core/**/*.tsx\"\n\t]\n}\n";
|
|
1325
1440
|
browser: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"vite/client\"],\n\t\t\"noEmit\": false,\n\t\t\"declaration\": true,\n\t\t\"emitDeclarationOnly\": true,\n\t\t\"rootDir\": \"../../src\",\n\t\t\"outDir\": \"../../dist/src\"\n\t},\n\t\"include\": [\n\t\t\"../../src/browser/**/*.cts\",\n\t\t\"../../src/browser/**/*.mts\",\n\t\t\"../../src/browser/**/*.ts\",\n\t\t\"../../src/browser/**/*.tsx\"\n\t]\n}\n";
|
|
@@ -1327,24 +1442,27 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1327
1442
|
}>;
|
|
1328
1443
|
app: Readonly<{
|
|
1329
1444
|
core: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"WebWorker\"],\n\t\t\"types\": []\n\t},\n\t\"include\": [\n\t\t\"../../app/core/**/*.cts\",\n\t\t\"../../app/core/**/*.mts\",\n\t\t\"../../app/core/**/*.ts\",\n\t\t\"../../app/core/**/*.tsx\",\n\t\t\"../../tests/app/core/**/*.cts\",\n\t\t\"../../tests/app/core/**/*.mts\",\n\t\t\"../../tests/app/core/**/*.ts\",\n\t\t\"../../tests/app/core/**/*.tsx\",\n\t\t\"../../tests/setup.ts\"\n\t]\n}\n";
|
|
1330
|
-
browser: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"vite/client\"
|
|
1445
|
+
browser: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\", \"DOM\", \"DOM.Iterable\"],\n\t\t\"types\": [\"vite/client\"]\n\t},\n\t\"include\": [\n{{include}}\n\t]\n}\n";
|
|
1331
1446
|
server: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"]\n\t},\n\t\"include\": [\n{{include}}\n\t]\n}\n";
|
|
1332
1447
|
}>;
|
|
1333
1448
|
bin: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"],\n\t\t\"noEmit\": false,\n\t\t\"declaration\": true,\n\t\t\"emitDeclarationOnly\": true,\n\t\t\"rootDir\": \"../../src\",\n\t\t\"outDir\": \"../../dist/bin\"\n\t},\n\t\"include\": [\n\t\t\"../../src/bin/**/*.cts\",\n\t\t\"../../src/bin/**/*.mts\",\n\t\t\"../../src/bin/**/*.ts\",\n\t\t\"../../src/bin/**/*.tsx\"\n\t]\n}\n";
|
|
1334
1449
|
skills: "{\n\t\"extends\": \"../../tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"lib\": [\"ESNext\"],\n\t\t\"types\": [\"node\"]\n\t},\n\t\"include\": [\"../../.agents/skills/*/scripts/*.ts\"],\n\t\"exclude\": [\"../../node_modules\"]\n}\n";
|
|
1335
1450
|
}>;
|
|
1336
1451
|
vites: Readonly<{
|
|
1452
|
+
sheet: "import { defineConfig } from 'vitest/config'\nimport { outputBoundary } from '../helpers.js'\nimport { resolveWorkspacePath, sheetProject } from '../../vite.config.ts'\n\nexport default defineConfig((invocation) => {\n\tconst project = sheetProject('src:{{label}}', {\n\t\tplugins: [outputBoundary('dist/src/{{name}}')],\n\t\tbuild: {\n\t\t\toutDir: 'dist/src/{{name}}',\n\t\t\temptyOutDir: true,\n\t\t\t// Preserve the authored layer-order statement in the published sheet.\n\t\t\tcssMinify: false,\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/{{name}}/sheet.ts'),\n\t\t\t\tformats: ['es'],\n\t\t\t\tfileName: 'index',\n\t\t\t\tcssFileName: 'index',\n\t\t\t},\n\t\t},\n\t\ttest: { include: ['tests/src/{{name}}/**/*.test.ts'] },\n\t})\n\treturn { ...project, mode: invocation.mode }\n})\n";
|
|
1337
1453
|
src: Readonly<{
|
|
1338
|
-
core: "import { defineConfig } from 'vite'\nimport {
|
|
1454
|
+
core: "import { defineConfig } from 'vite'\nimport {\n\tdeclarationRollup,\n\tenvironmentBoundary,\n\toutputBoundary,\n\tresolveExternal,\n} from '../helpers.js'\nimport { peers, srcCore, resolveWorkspacePath } from '../../vite.config.ts'\n\nexport default defineConfig(\n\tsrcCore({\n\t\tpublicDir: false,\n\t\tplugins: [\n\t\t\toutputBoundary('dist/src/core'),\n\t\t\tenvironmentBoundary('src/core'),\n\t\t\tdeclarationRollup({\n\t\t\t\tproject: resolveWorkspacePath('configs/src/tsconfig.core.json'),\n\t\t\t\ttypes: ['node'],\n\t\t\t}),\n\t\t],\n\t\tbuild: {\n\t\t\tlib: {\n\t\t\t\tentry: resolveWorkspacePath('src/core/index.ts'),\n\t\t\t\tformats: ['es', 'cjs'],\n\t\t\t\tfileName: (format: string) => (format === 'es' ? 'index.js' : 'index.cjs'),\n\t\t\t},\n\t\t\toutDir: 'dist/src/core',\n\t\t\trolldownOptions: {\n\t\t\t\texternal: (id: string) => resolveExternal(id, { peers, refused: [], siblings: [] }),\n\t\t\t},\n\t\t},\n\t}),\n)\n";
|
|
1455
|
+
vue: "import { defineConfig } from 'vite'\nimport {\n\tdeclarationRollup,\n\tresolveExternal,\n\trewriteBrowserSpecifier,\n\trewriteCoreSpecifier,\n} from '../helpers.js'\nimport { peers, srcVue, resolveWorkspacePath } from '../../vite.config.ts'\n\nconst siblings = {\n{{siblings}}\n}\n\nexport default defineConfig(\n\tsrcVue({\n\t\tplugins: [\n\t\t\tdeclarationRollup({\n\t\t\t\tproject: resolveWorkspacePath('configs/src/tsconfig.vue.json'),\n\t\t\t\trewrite: (content) => rewriteBrowserSpecifier(rewriteCoreSpecifier(content)),\n\t\t\t}),\n\t\t],\n\t\tbuild: {\n\t\t\trolldownOptions: {\n\t\t\t\texternal: (id: string) =>\n\t\t\t\t\tresolveExternal(id, {\n\t\t\t\t\t\tpeers,\n\t\t\t\t\t\trefused: {{refused}},\n\t\t\t\t\t\tsiblings: Object.keys(siblings),\n\t\t\t\t\t}),\n\t\t\t\toutput: { paths: siblings },\n\t\t\t},\n\t\t},\n\t}),\n)\n";
|
|
1339
1456
|
browser: "import { defineConfig } from 'vite'\nimport { declarationRollup, rewriteCoreSpecifier } from '../helpers.js'\nimport { srcBrowser, resolveWorkspacePath } from '../../vite.config.ts'\n\n// The roll-up reaches src/core through a specifier the tarball does not carry, so the rewrite\n// externalizes core through the package's own published root export, on the final roll-up alone.\nexport default defineConfig(\n\tsrcBrowser({\n\t\tplugins: [\n\t\t\tdeclarationRollup({\n\t\t\t\tproject: resolveWorkspacePath('configs/src/tsconfig.browser.json'),\n\t\t\t\trewrite: rewriteCoreSpecifier,\n\t\t\t}),\n\t\t],\n\t}),\n)\n";
|
|
1340
1457
|
server: "import { defineConfig } from 'vite'\nimport { declarationRollup, rewriteCoreSpecifier } from '../helpers.js'\nimport { srcServer, resolveWorkspacePath } from '../../vite.config.ts'\n\n// The roll-up reaches src/core through a specifier the tarball does not carry, so the rewrite\n// externalizes core through the package's own published root export, on the final roll-up alone.\nexport default defineConfig(\n\tsrcServer({\n\t\tplugins: [\n\t\t\tdeclarationRollup({\n\t\t\t\tproject: resolveWorkspacePath('configs/src/tsconfig.server.json'),\n\t\t\t\trewrite: rewriteCoreSpecifier,\n\t\t\t}),\n\t\t],\n\t}),\n)\n";
|
|
1341
1458
|
}>;
|
|
1342
|
-
bin: "import { defineConfig } from 'vite'\nimport { srcBin } from '../../vite.config.ts'\n\n// The `scaffold` executable build — a single ESM lib file, no declarations (an\n// executable ships no types), with the `#!/usr/bin/env node` shebang re-emitted through\n// `output.banner` (rolldown strips shebangs from source during bundling), and\n// `output.paths` rewriting the externalized `@src/*` specifiers to the built sibling\n// src environments (relative to `dist/bin/`), so the emitted bin resolves at runtime.\nexport default defineConfig(\n\tsrcBin({\n\t\tbuild: {\n\t\t\trolldownOptions: {\n\t\t\t\toutput: {\n\t\t\t\t\tbanner: '#!/usr/bin/env node',\n{{paths}}\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}),\n)\n";
|
|
1459
|
+
bin: "import { defineConfig } from 'vite'\nimport { resolveExternal } from '../helpers.js'\nimport { peers, srcBin } from '../../vite.config.ts'\n\n// The `scaffold` executable build — a single ESM lib file, no declarations (an\n// executable ships no types), with the `#!/usr/bin/env node` shebang re-emitted through\n// `output.banner` (rolldown strips shebangs from source during bundling), and\n// `output.paths` rewriting the externalized `@src/*` specifiers to the built sibling\n// src environments (relative to `dist/bin/`), so the emitted bin resolves at runtime.\nexport default defineConfig(\n\tsrcBin({\n\t\tbuild: {\n\t\t\trolldownOptions: {\n\t\t\t\texternal: (id: string) =>\n\t\t\t\t\tid.startsWith('@src/') || resolveExternal(id, { peers, refused: [], siblings: [] }),\n\t\t\t\toutput: {\n\t\t\t\t\tbanner: '#!/usr/bin/env node',\n{{paths}}\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t}),\n)\n";
|
|
1343
1460
|
app: Readonly<{
|
|
1461
|
+
vue: "import { defineConfig } from 'vite'\nimport { appVue } from '../../vite.config.ts'\n\nexport default defineConfig(appVue())\n";
|
|
1344
1462
|
browser: "import { defineConfig } from 'vite'\nimport { appBrowser } from '../../vite.config.ts'\n\nexport default defineConfig(appBrowser())\n";
|
|
1345
1463
|
server: "import { defineConfig } from 'vite'\nimport { appServer } from '../../vite.config.ts'\n\nexport default defineConfig(appServer())\n";
|
|
1346
|
-
showcase: "import { defineConfig } from 'vite'\nimport { appShowcase } from '../../vite.config.ts'\n\nexport default defineConfig(appShowcase())\n";
|
|
1347
|
-
journey: "import type { JourneyVariant } from '@orkestrel/test'\nimport { defineConfig } from 'vitest/config'\nimport { appJourney } from '../../vite.config.ts'\n\n// Rename and extend these viewports for the application. Apply themes through its interface.\nconst VARIANTS: readonly JourneyVariant[] = Object.freeze([\n\t{ name: 'desktop', width: 1280, height: 800 },\n\t{ name: 'compact', width: 390, height: 844 },\n])\n\nexport default defineConfig({\n\ttest: {\n\t\tprojects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS)),\n\t},\n})\n";
|
|
1464
|
+
showcase: "import { defineConfig } from 'vite'\nimport { appShowcase } from '../../vite.config.ts'\n\nexport default defineConfig(({ mode }) => appShowcase(mode))\n";
|
|
1465
|
+
journey: "import type { JourneyVariant } from '@orkestrel/test'\nimport { defineConfig } from 'vitest/config'\nimport { appJourney } from '../../vite.config.ts'\n\n// Rename and extend these viewports for the application. Apply themes through its interface.\nconst VARIANTS: readonly JourneyVariant[] = Object.freeze([\n\t{ name: 'desktop', width: 1280, height: 800 },\n\t{ name: 'compact', width: 390, height: 844 },\n])\n\nexport default defineConfig(({ mode }) => ({\n\ttest: {\n\t\tprojects: VARIANTS.map((variant) => () => appJourney(variant, VARIANTS, mode)),\n\t},\n}))\n";
|
|
1348
1466
|
}>;
|
|
1349
1467
|
}>;
|
|
1350
1468
|
browsers: "// A generated browser workspace resolves its own Chromium here rather than in\n// `configs/helpers.ts`, because that leaf is vendored byte-identical to every\n// workspace and most of them declare no `playwright` to import.\n\nimport type { PlaywrightProviderOptions } from '@vitest/browser-playwright'\nimport { chromium } from 'playwright'\nimport { accessSync, constants as FS_CONSTANTS, globSync, readdirSync, statSync } from 'node:fs'\nimport { basename, dirname, join, resolve as resolvePath } from 'node:path'\n\n/**\n * Lists the Chromium executable layouts inside a `chromium-<revision>` browsers-directory\n * entry, per platform.\n *\n * @remarks\n * The current Playwright build ships Chrome for Testing on macOS. The trailing `Chromium.app`\n * layouts are what earlier builds shipped, so the list spans Playwright versions instead of\n * pinning to the installed one.\n */\nexport const CHROMIUM_LAYOUTS = Object.freeze([\n\t'chrome-linux/chrome',\n\t'chrome-linux64/chrome',\n\t'chrome-win/chrome.exe',\n\t'chrome-win64/chrome.exe',\n\t'chrome-mac-x64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac-arm64/Google Chrome for Testing.app/Contents/MacOS/Google Chrome for Testing',\n\t'chrome-mac/Chromium.app/Contents/MacOS/Chromium',\n\t'chrome-mac-arm64/Chromium.app/Contents/MacOS/Chromium',\n])\n\n/** Matches the `chromium-<revision>` entry name Playwright installs one managed build into. */\nexport const CHROMIUM_ENTRY_PATTERN = /^chromium-\\d+$/\n\n/** Matches the revision number carried by any path containing a `chromium-<revision>` segment. */\nexport const CHROMIUM_REVISION_PATTERN = /chromium-(\\d+)/\n\n/** Names the directory a managed Linux container installs its bundled Playwright browsers into. */\nexport const BUNDLED_BROWSERS_ROOT = '/opt/pw-browsers'\n\n/**\n * Lists the bundled Chromium layouts under the managed-container browsers root, as glob patterns.\n *\n * @remarks\n * The revision directory and its inner layout both drift across Playwright builds, and the\n * container also carries a top-level `chromium` alias, so every known shape is globbed.\n */\nexport const BUNDLED_CHROMIUM_LAYOUTS = Object.freeze([\n\t'chromium',\n\t'chromium-*/chrome-linux64/chrome',\n\t'chromium-*/chrome-linux/chrome',\n])\n\n/** Lists the stable Playwright Chromium channels and their standard executable layouts. */\nexport const SYSTEM_BROWSER_CHANNELS = Object.freeze([\n\tObject.freeze({\n\t\tchannel: 'chrome',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/google/chrome/chrome',\n\t\t\tdarwin: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',\n\t\t\twin32: Object.freeze(['Google', 'Chrome', 'Application', 'chrome.exe']),\n\t\t}),\n\t}),\n\tObject.freeze({\n\t\tchannel: 'msedge',\n\t\tlayouts: Object.freeze({\n\t\t\tlinux: '/opt/microsoft/msedge/msedge',\n\t\t\tdarwin: '/Applications/Microsoft Edge.app/Contents/MacOS/Microsoft Edge',\n\t\t\twin32: Object.freeze(['Microsoft', 'Edge', 'Application', 'msedge.exe']),\n\t\t}),\n\t}),\n])\n\n/**\n * Determines whether a path identifies an executable regular file.\n *\n * @param path - The filesystem path to inspect.\n * @returns True if the path is a regular file with execute access; false otherwise.\n *\n * @example\n * ```ts\n * isBrowserExecutable('/opt/google/chrome/chrome')\n * ```\n */\nexport function isBrowserExecutable(path: string): boolean {\n\ttry {\n\t\tif (!statSync(path).isFile()) return false\n\t\taccessSync(path, FS_CONSTANTS.X_OK)\n\t\treturn true\n\t} catch {\n\t\treturn false\n\t}\n}\n\n/**\n * Orders two Chromium paths so the highest revision sorts first.\n *\n * @param left - The first path or directory entry to compare.\n * @param right - The second path or directory entry to compare.\n * @returns A negative number when `left` sorts first, positive when `right` does.\n *\n * @remarks\n * Revisions are numbers, so `chromium-1200` outranks `chromium-999` despite sorting below it\n * lexically. A path carrying no revision falls back to descending name order.\n *\n * @example\n * ```ts\n * ['chromium-999', 'chromium-1200'].sort(compareRevisions)\n * ```\n */\nexport function compareRevisions(left: string, right: string): number {\n\tconst leftRevision = CHROMIUM_REVISION_PATTERN.exec(left)?.[1]\n\tconst rightRevision = CHROMIUM_REVISION_PATTERN.exec(right)?.[1]\n\tif (leftRevision === undefined || rightRevision === undefined) return right.localeCompare(left)\n\treturn Number(rightRevision) - Number(leftRevision)\n}\n\n/**\n * Reads the executable path of Playwright's pinned Chromium revision.\n *\n * @returns The pinned executable path, or `undefined` when this platform has none.\n *\n * @remarks\n * Playwright throws rather than returning a path when the current platform carries no initialized\n * executable, and an unguarded call would fail configuration evaluation for every project.\n *\n * @example\n * ```ts\n * resolvePinnedBrowser()\n * ```\n */\nexport function resolvePinnedBrowser(): string | undefined {\n\ttry {\n\t\tconst pinned = chromium.executablePath()\n\t\treturn pinned.length === 0 ? undefined : pinned\n\t} catch {\n\t\treturn undefined\n\t}\n}\n\n/**\n * Resolves a launchable Playwright-managed Chromium executable: the pinned revision when installed,\n * otherwise a `chromium` / `chromium.exe` alias or any other `chromium-*` revision under the same\n * Playwright browsers directory. A pinned-revision miss is not Chromium absence — managed\n * containers ship one usable build, often behind a revision-agnostic alias, for many Playwright\n * versions.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision.\n * @returns The managed executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveManagedBrowser('/root/.cache/ms-playwright/chromium-1234/chrome-linux64/chrome')\n * ```\n */\nexport function resolveManagedBrowser(pinned: string): string | undefined {\n\tif (isBrowserExecutable(pinned)) return pinned\n\tlet revisionRoot = dirname(pinned)\n\tfor (;;) {\n\t\tif (CHROMIUM_ENTRY_PATTERN.test(basename(revisionRoot))) break\n\t\tconst parent = dirname(revisionRoot)\n\t\tif (parent === revisionRoot) return undefined\n\t\trevisionRoot = parent\n\t}\n\tconst browsersRoot = dirname(revisionRoot)\n\tfor (const alias of ['chromium', 'chromium.exe']) {\n\t\tconst candidate = resolvePath(browsersRoot, alias)\n\t\tif (isBrowserExecutable(candidate)) return candidate\n\t}\n\tlet entries: readonly string[]\n\ttry {\n\t\tentries = readdirSync(browsersRoot)\n\t} catch {\n\t\treturn undefined\n\t}\n\tconst revisions = entries\n\t\t.filter((entry) => CHROMIUM_ENTRY_PATTERN.test(entry))\n\t\t.sort(compareRevisions)\n\tfor (const revision of revisions) {\n\t\tfor (const layout of CHROMIUM_LAYOUTS) {\n\t\t\tconst candidate = resolvePath(browsersRoot, revision, layout)\n\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves the Chromium a managed Linux container bundles outside the Playwright cache.\n *\n * @param platform - The Node platform the container runs on.\n * @param root - The bundled browsers directory to search.\n * @returns The highest matching executable path, or `undefined` when none is executable.\n *\n * @example\n * ```ts\n * resolveBundledBrowser('linux', BUNDLED_BROWSERS_ROOT)\n * ```\n */\nexport function resolveBundledBrowser(platform: NodeJS.Platform, root: string): string | undefined {\n\tif (platform !== 'linux') return undefined\n\tfor (const layout of BUNDLED_CHROMIUM_LAYOUTS) {\n\t\tlet matches: readonly string[]\n\t\ttry {\n\t\t\tmatches = globSync(layout, { cwd: root })\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t\tfor (const match of [...matches].sort(compareRevisions)) {\n\t\t\tconst candidate = resolvePath(root, match)\n\t\t\tif (isBrowserExecutable(candidate)) return candidate\n\t\t}\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves the first installed stable system Chromium channel.\n *\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying Windows installation roots.\n * @returns `chrome`, then `msedge`, or `undefined` when neither is executable.\n *\n * @example\n * ```ts\n * resolveSystemBrowser(process.platform, process.env)\n * ```\n */\nexport function resolveSystemBrowser(\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n): string | undefined {\n\tif (platform !== 'linux' && platform !== 'darwin' && platform !== 'win32') return undefined\n\tconst roots = new Set<string>()\n\tif (platform === 'win32') {\n\t\tfor (const root of [\n\t\t\tenvironment.LOCALAPPDATA,\n\t\t\tenvironment.PROGRAMFILES,\n\t\t\tenvironment['PROGRAMFILES(X86)'],\n\t\t]) {\n\t\t\tif (root !== undefined && root.length > 0) roots.add(root)\n\t\t}\n\t\tconst homeDrive = environment.HOMEDRIVE\n\t\tif (homeDrive !== undefined && homeDrive.length > 0) {\n\t\t\troots.add(join(homeDrive, 'Program Files'))\n\t\t\troots.add(join(homeDrive, 'Program Files (x86)'))\n\t\t}\n\t}\n\tfor (const browser of SYSTEM_BROWSER_CHANNELS) {\n\t\tif (platform === 'win32') {\n\t\t\tfor (const root of roots) {\n\t\t\t\tif (isBrowserExecutable(join(root, ...browser.layouts.win32))) return browser.channel\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif (isBrowserExecutable(browser.layouts[platform])) return browser.channel\n\t}\n\treturn undefined\n}\n\n/**\n * Resolves Playwright provider options for Chromium on this host.\n *\n * @param pinned - The executable path for Playwright's pinned Chromium revision, when it has one.\n * @param platform - The Node platform whose standard layouts this call probes.\n * @param environment - The process environment supplying operator overrides and Windows roots.\n * @param root - The managed-container bundled browsers directory to search.\n * @returns Provider options naming an executable, a WebSocket endpoint, or a channel.\n *\n * @remarks\n * Precedence, most important first: `PLAYWRIGHT_EXECUTABLE_PATH`, `PLAYWRIGHT_WS_ENDPOINT`,\n * `PLAYWRIGHT_CHANNEL`, the managed Playwright Chromium, the container's bundled Chromium, a\n * verified system channel, then the platform default channel. An operator override outranks\n * discovery and is returned exactly as given: none of those environment values is checked\n * against the filesystem, because verifying an override would defeat the override. The pinned\n * managed revision outranks anything found on the host because it is deterministic. The installed\n * pinned revision returns empty options so Playwright keeps its own default launch semantics. Only\n * a discovered system channel is verified before it is named. The platform default is unverified\n * as well and exists only as a last resort: Windows takes `msedge`, which ships with the OS and\n * never collides with a foreground Chrome.\n *\n * The resolver and the gate cover Chromium alone. Reopen engine selection when another\n * Playwright engine is installed and launches on the host with a `captureFrame` reading\n * back at its declared size, or when a journey or style divergence is recorded.\n *\n * @example\n * ```ts\n * resolveBrowser(resolvePinnedBrowser(), process.platform, process.env)\n * ```\n */\nexport function resolveBrowser(\n\tpinned: string | undefined,\n\tplatform: NodeJS.Platform,\n\tenvironment: NodeJS.ProcessEnv,\n\troot: string = BUNDLED_BROWSERS_ROOT,\n): PlaywrightProviderOptions {\n\tconst executable = environment.PLAYWRIGHT_EXECUTABLE_PATH\n\tif (executable !== undefined && executable.length > 0) {\n\t\treturn { launchOptions: { executablePath: executable } }\n\t}\n\tconst endpoint = environment.PLAYWRIGHT_WS_ENDPOINT\n\tif (endpoint !== undefined && endpoint.length > 0) {\n\t\treturn { connectOptions: { wsEndpoint: endpoint } }\n\t}\n\tconst requested = environment.PLAYWRIGHT_CHANNEL\n\tif (requested !== undefined && requested.length > 0) {\n\t\treturn { launchOptions: { channel: requested } }\n\t}\n\tconst managed = pinned === undefined ? undefined : resolveManagedBrowser(pinned)\n\tif (managed !== undefined) {\n\t\treturn managed === pinned ? {} : { launchOptions: { executablePath: managed } }\n\t}\n\tconst bundled = resolveBundledBrowser(platform, root)\n\tif (bundled !== undefined) return { launchOptions: { executablePath: bundled } }\n\tconst fallback = platform === 'win32' ? 'msedge' : 'chrome'\n\treturn { launchOptions: { channel: resolveSystemBrowser(platform, environment) ?? fallback } }\n}\n";
|
|
@@ -1559,6 +1677,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1559
1677
|
*/
|
|
1560
1678
|
export declare const EXECUTABLE_PATHS: readonly string[];
|
|
1561
1679
|
|
|
1680
|
+
/** Represents an extension discriminated by its surface. */
|
|
1681
|
+
export declare type Extension = BrowserExtension | StylesExtension;
|
|
1682
|
+
|
|
1562
1683
|
/** Matches the registry-only semver subset accepted for a development extra's range. */
|
|
1563
1684
|
export declare const EXTRA_RANGE_PATTERN: RegExp;
|
|
1564
1685
|
|
|
@@ -1684,6 +1805,29 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1684
1805
|
*/
|
|
1685
1806
|
export declare const FOREIGN_NAME_PATTERN: RegExp;
|
|
1686
1807
|
|
|
1808
|
+
/** Names a supported browser framework. */
|
|
1809
|
+
export declare type Framework = 'vue';
|
|
1810
|
+
|
|
1811
|
+
/** Describes the tooling and package boundaries of each browser framework, frozen. */
|
|
1812
|
+
export declare const FRAMEWORK_MATRIX: Readonly<Record<Framework, FrameworkDefinition>>;
|
|
1813
|
+
|
|
1814
|
+
/** Describes the tooling and package boundaries a browser framework contributes. */
|
|
1815
|
+
export declare interface FrameworkDefinition {
|
|
1816
|
+
/** Names the Vite plugin package. */
|
|
1817
|
+
readonly plugin: string;
|
|
1818
|
+
/** Names the application typechecker executable. */
|
|
1819
|
+
readonly checker: string;
|
|
1820
|
+
/** Lists source file suffixes without their leading dot. */
|
|
1821
|
+
readonly suffixes: readonly string[];
|
|
1822
|
+
/** Lists refused package names and implementation scope prefixes. */
|
|
1823
|
+
readonly refused: readonly string[];
|
|
1824
|
+
/** Maps development package names to their version ranges. */
|
|
1825
|
+
readonly dependencies: Readonly<Record<string, string>>;
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
/** Lists the supported browser frameworks, frozen. */
|
|
1829
|
+
export declare const FRAMEWORKS: readonly Framework[];
|
|
1830
|
+
|
|
1687
1831
|
/** Names the shared Vitest global-setup module whose presence makes a workspace `global`. */
|
|
1688
1832
|
export declare const GLOBAL_SETUP_PATH = "tests/setupGlobal.ts";
|
|
1689
1833
|
|
|
@@ -1925,6 +2069,20 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1925
2069
|
*/
|
|
1926
2070
|
export declare const isBlueprint: Guard<Blueprint>;
|
|
1927
2071
|
|
|
2072
|
+
/**
|
|
2073
|
+
* Narrows a value to a supported browser framework with distinct occupied axes.
|
|
2074
|
+
* @param value - The candidate extension.
|
|
2075
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
2076
|
+
* @example
|
|
2077
|
+
* ```ts
|
|
2078
|
+
* import { isBrowserExtension } from '@orkestrel/scaffold'
|
|
2079
|
+
*
|
|
2080
|
+
* isBrowserExtension({ surface: 'browser', name: 'vue', axes: ['app'] }) // true
|
|
2081
|
+
* isBrowserExtension(undefined) // false
|
|
2082
|
+
* ```
|
|
2083
|
+
*/
|
|
2084
|
+
export declare const isBrowserExtension: Guard<BrowserExtension>;
|
|
2085
|
+
|
|
1928
2086
|
/**
|
|
1929
2087
|
* Checks whether a path belongs to the instruction canon a target reads rather than holds.
|
|
1930
2088
|
*
|
|
@@ -2093,6 +2251,20 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2093
2251
|
*/
|
|
2094
2252
|
export declare const isEnvironment: Guard<Environment>;
|
|
2095
2253
|
|
|
2254
|
+
/**
|
|
2255
|
+
* Narrows a value to an extension of a supported surface.
|
|
2256
|
+
* @param value - The candidate extension.
|
|
2257
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
2258
|
+
* @example
|
|
2259
|
+
* ```ts
|
|
2260
|
+
* import { isExtension } from '@orkestrel/scaffold'
|
|
2261
|
+
*
|
|
2262
|
+
* isExtension({ surface: 'styles', name: 'print' }) // true
|
|
2263
|
+
* isExtension(undefined) // false
|
|
2264
|
+
* ```
|
|
2265
|
+
*/
|
|
2266
|
+
export declare const isExtension: Guard<Extension>;
|
|
2267
|
+
|
|
2096
2268
|
/**
|
|
2097
2269
|
* Narrows a value to a {@link Finding}.
|
|
2098
2270
|
*
|
|
@@ -2302,6 +2474,20 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2302
2474
|
*/
|
|
2303
2475
|
export declare function isScaffoldError(value: unknown): value is ScaffoldError;
|
|
2304
2476
|
|
|
2477
|
+
/**
|
|
2478
|
+
* Narrows a value to a non-reserved sheet face name.
|
|
2479
|
+
* @param value - The candidate name.
|
|
2480
|
+
* @returns True if the name matches the workspace pattern and is not reserved; false otherwise.
|
|
2481
|
+
* @example
|
|
2482
|
+
* ```ts
|
|
2483
|
+
* import { isSheetName } from '@orkestrel/scaffold'
|
|
2484
|
+
*
|
|
2485
|
+
* isSheetName('print') // true
|
|
2486
|
+
* isSheetName('styles') // false
|
|
2487
|
+
* ```
|
|
2488
|
+
*/
|
|
2489
|
+
export declare function isSheetName(value: unknown): value is string;
|
|
2490
|
+
|
|
2305
2491
|
/**
|
|
2306
2492
|
* Narrows a value to a {@link Snapshot}.
|
|
2307
2493
|
*
|
|
@@ -2325,6 +2511,34 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2325
2511
|
*/
|
|
2326
2512
|
export declare function isSnapshot(value: unknown): value is Snapshot;
|
|
2327
2513
|
|
|
2514
|
+
/**
|
|
2515
|
+
* Narrows a value to a named non-reserved stylesheet face.
|
|
2516
|
+
* @param value - The candidate extension.
|
|
2517
|
+
* @returns True if the value is an admitted extension; false otherwise.
|
|
2518
|
+
* @example
|
|
2519
|
+
* ```ts
|
|
2520
|
+
* import { isStylesExtension } from '@orkestrel/scaffold'
|
|
2521
|
+
*
|
|
2522
|
+
* isStylesExtension({ surface: 'styles', name: 'print' }) // true
|
|
2523
|
+
* isStylesExtension(undefined) // false
|
|
2524
|
+
* ```
|
|
2525
|
+
*/
|
|
2526
|
+
export declare const isStylesExtension: Guard<StylesExtension>;
|
|
2527
|
+
|
|
2528
|
+
/**
|
|
2529
|
+
* Narrows a value to a surface an extension can extend.
|
|
2530
|
+
* @param value - The candidate surface.
|
|
2531
|
+
* @returns True if the value is a supported surface; false otherwise.
|
|
2532
|
+
* @example
|
|
2533
|
+
* ```ts
|
|
2534
|
+
* import { isSurface } from '@orkestrel/scaffold'
|
|
2535
|
+
*
|
|
2536
|
+
* isSurface('styles') // true
|
|
2537
|
+
* isSurface('themes') // false
|
|
2538
|
+
* ```
|
|
2539
|
+
*/
|
|
2540
|
+
export declare const isSurface: Guard<Surface>;
|
|
2541
|
+
|
|
2328
2542
|
/** Names the Vite wrapper whose presence makes a workspace `journey`. */
|
|
2329
2543
|
export declare const JOURNEY_CONFIG_PATH = "configs/app/vite.journey.config.ts";
|
|
2330
2544
|
|
|
@@ -2845,6 +3059,21 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2845
3059
|
*/
|
|
2846
3060
|
export declare function parseCompilerOptions(value: unknown): CompilerOptions | undefined;
|
|
2847
3061
|
|
|
3062
|
+
/**
|
|
3063
|
+
* Coerces an extension value or a `surface:name` selection into an extension.
|
|
3064
|
+
* @param value - An extension record or its selection text.
|
|
3065
|
+
* @returns The extension, or `undefined` for a malformed or unsupported selection.
|
|
3066
|
+
* @remarks Browser text has empty axes; the creating command supplies its selected browser axes.
|
|
3067
|
+
* @example
|
|
3068
|
+
* ```ts
|
|
3069
|
+
* import { parseExtension } from '@orkestrel/scaffold'
|
|
3070
|
+
*
|
|
3071
|
+
* parseExtension('browser:vue') // { surface: 'browser', name: 'vue', axes: [] }
|
|
3072
|
+
* parseExtension('styles:print') // { surface: 'styles', name: 'print' }
|
|
3073
|
+
* ```
|
|
3074
|
+
*/
|
|
3075
|
+
export declare function parseExtension(value: unknown): Extension | undefined;
|
|
3076
|
+
|
|
2848
3077
|
/**
|
|
2849
3078
|
* Coerces an untrusted value to a group selection.
|
|
2850
3079
|
*
|
|
@@ -3198,6 +3427,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3198
3427
|
*/
|
|
3199
3428
|
export declare function replacePlanRanges(plan: Plan, pins: DependencyPinSet): Plan | undefined;
|
|
3200
3429
|
|
|
3430
|
+
/** Lists the names a styles extension cannot occupy, frozen. */
|
|
3431
|
+
export declare const RESERVED_SHEET_NAMES: readonly string[];
|
|
3432
|
+
|
|
3201
3433
|
/**
|
|
3202
3434
|
* Represents the one error this package throws, carrying the coded reason it was raised.
|
|
3203
3435
|
*
|
|
@@ -3354,6 +3586,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3354
3586
|
/** Names the runtime a root setup proof requires. */
|
|
3355
3587
|
export declare type SetupRuntime = 'node' | 'browser';
|
|
3356
3588
|
|
|
3589
|
+
/** Names the build entry beside each stylesheet marker. */
|
|
3590
|
+
export declare const SHEET_ENTRY_NAME = "sheet.ts";
|
|
3591
|
+
|
|
3357
3592
|
/** Names the Vite wrapper whose presence makes a workspace `showcase`. */
|
|
3358
3593
|
export declare const SHOWCASE_CONFIG_PATH = "configs/app/vite.showcase.config.ts";
|
|
3359
3594
|
|
|
@@ -3369,6 +3604,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3369
3604
|
*/
|
|
3370
3605
|
export declare const SHOWCASE_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
3371
3606
|
|
|
3607
|
+
/** Names the physical showcase output directory. */
|
|
3608
|
+
export declare const SHOWCASE_PAGES_PATH = "showcase";
|
|
3609
|
+
|
|
3372
3610
|
/** Names the TypeScript wrapper whose presence makes a workspace `skills`. */
|
|
3373
3611
|
export declare const SKILLS_CONFIG_PATH = "configs/agents/tsconfig.skills.json";
|
|
3374
3612
|
|
|
@@ -3476,6 +3714,24 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3476
3714
|
*/
|
|
3477
3715
|
export declare function srcToRoot(src: readonly Environment[]): Environment | undefined;
|
|
3478
3716
|
|
|
3717
|
+
/** Lists the development dependencies the styles surface adds, frozen. */
|
|
3718
|
+
export declare const STYLES_DEV_DEPENDENCIES: Readonly<Record<string, string>>;
|
|
3719
|
+
|
|
3720
|
+
/** Names the base stylesheet marker. */
|
|
3721
|
+
export declare const STYLES_ENTRY_PATH = "src/styles/index.scss";
|
|
3722
|
+
|
|
3723
|
+
/** Represents a named sheet face under `src/<name>`. */
|
|
3724
|
+
export declare interface StylesExtension {
|
|
3725
|
+
readonly surface: 'styles';
|
|
3726
|
+
readonly name: string;
|
|
3727
|
+
}
|
|
3728
|
+
|
|
3729
|
+
/** Names the surface an extension extends. */
|
|
3730
|
+
export declare type Surface = 'browser' | 'styles';
|
|
3731
|
+
|
|
3732
|
+
/** Lists the surfaces an extension may extend, frozen. */
|
|
3733
|
+
export declare const SURFACES: readonly Surface[];
|
|
3734
|
+
|
|
3479
3735
|
/** Sets the columns one tab occupies when the formatter measures a line, matching `tabWidth`. */
|
|
3480
3736
|
export declare const TAB_WIDTH = 2;
|
|
3481
3737
|
|
|
@@ -3492,6 +3748,12 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3492
3748
|
*/
|
|
3493
3749
|
export declare const TARGET_SKILL_NAMES: readonly string[];
|
|
3494
3750
|
|
|
3751
|
+
/** Names the themes stylesheet marker. */
|
|
3752
|
+
export declare const THEMES_BARREL_PATH = "src/styles/themes/index.scss";
|
|
3753
|
+
|
|
3754
|
+
/** Names the themes build entry marker. */
|
|
3755
|
+
export declare const THEMES_ENTRY_PATH = "src/styles/themes/sheet.ts";
|
|
3756
|
+
|
|
3495
3757
|
/** Matches the exact `major.minor.patch` version syntax a blueprint declares. */
|
|
3496
3758
|
export declare const VERSION_PATTERN: RegExp;
|
|
3497
3759
|
|
|
@@ -3502,14 +3764,14 @@ export declare class Compiler implements CompilerInterface {
|
|
|
3502
3764
|
* Boundary guarantees never vary by blueprint, so they are not selected here:
|
|
3503
3765
|
* every generated configuration emits the environment-boundary plugin, its
|
|
3504
3766
|
* module-graph audit, and stylesheet rejection. `browser` selects the shared
|
|
3505
|
-
* root CSS analysis and real-browser test machinery. `
|
|
3506
|
-
*
|
|
3507
|
-
*
|
|
3767
|
+
* root CSS analysis and real-browser test machinery. `frameworks` selects the
|
|
3768
|
+
* browser extension tooling.
|
|
3769
|
+
* `output` selects build-output containment.
|
|
3508
3770
|
* `showcase` selects the optional single-file application-browser projection.
|
|
3509
3771
|
*/
|
|
3510
3772
|
export declare interface ViteMachinery {
|
|
3511
3773
|
readonly browser: boolean;
|
|
3512
|
-
readonly
|
|
3774
|
+
readonly frameworks: readonly Framework[];
|
|
3513
3775
|
readonly output: boolean;
|
|
3514
3776
|
readonly showcase: boolean;
|
|
3515
3777
|
}
|