@orkestrel/scaffold 0.0.26 → 0.0.28
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 +5 -1
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/orchestration.md +183 -54
- package/dist/host/claude/agents/orkestrel.md +65 -48
- package/dist/host/claude/agents/researcher.md +1 -0
- package/dist/host/claude/agents/scout.md +1 -0
- package/dist/host/claude/rules/architecture.md +19 -0
- package/dist/host/claude/rules/documentation.md +2 -0
- package/dist/host/claude/rules/quality.md +3 -0
- package/dist/host/claude/rules/tests.md +25 -8
- package/dist/host/claude/rules/workspace.md +20 -9
- package/dist/host/guides/scaffold.md +98 -14
- 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/host/tests/config.test.ts +56 -1
- package/dist/src/core/index.cjs +167 -32
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +91 -16
- package/dist/src/core/index.d.ts +91 -16
- package/dist/src/core/index.js +164 -33
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +35 -4
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.js +36 -5
- package/dist/src/server/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -104,7 +104,7 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
104
104
|
readme: "# Guides\n\n## By concept\n\n- Package\n - Spec: Not created. Create this file when the workspace has a public surface:\n `guides/{{guide}}.md`\n - Source:\n{{source}}\n - Tests:\n{{tests}}\n\n## By directory\n\n{{directories}}\n";
|
|
105
105
|
}>;
|
|
106
106
|
orchestration: Readonly<{
|
|
107
|
-
service: "#!/usr/bin/env sh\nset -eu\n\nprintf '%s\\n' \\\n{{
|
|
107
|
+
service: "#!/usr/bin/env sh\nset -eu\n\nprintf '%s\\n' \\\n{{vendors}}\n";
|
|
108
108
|
}>;
|
|
109
109
|
}>;
|
|
110
110
|
|
|
@@ -235,14 +235,22 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
235
235
|
* application-only, and mixed workspaces are all first class. `dependencies`
|
|
236
236
|
* and `peers` are runtime `@orkestrel/*` packages; `extras` are
|
|
237
237
|
* package-specific development dependencies and may carry any valid npm name.
|
|
238
|
-
* `bin`, `integration`, `
|
|
239
|
-
* facts: each is set only when the workspace
|
|
240
|
-
* exact-case file that defines it, never
|
|
241
|
-
* never because a sibling fact is set. An
|
|
242
|
-
* when its required axis is absent:
|
|
243
|
-
* `
|
|
244
|
-
* with a non-blocking question, so a
|
|
245
|
-
* nothing and the compile still
|
|
238
|
+
* `bin`, `integration`, `conformance`, `service`, `vendors`, `global`, and
|
|
239
|
+
* `showcase` are structural facts: each is set only when the workspace
|
|
240
|
+
* physically ships the directory or exact-case file that defines it, never
|
|
241
|
+
* because of the workspace's name and never because a sibling fact is set. An
|
|
242
|
+
* axis-dependent fact projects nothing when its required axis is absent:
|
|
243
|
+
* `integration` projects only a published `src`, and `showcase` projects only a
|
|
244
|
+
* browser `app`. The gate answers that case with a non-blocking question, so a
|
|
245
|
+
* caller that set the flag learns it emitted nothing and the compile still
|
|
246
|
+
* completes.
|
|
247
|
+
*
|
|
248
|
+
* `service` says the workspace runs a live-service Vitest project over
|
|
249
|
+
* `tests/service`, and it alone registers that project. `vendors` names each
|
|
250
|
+
* external service the workspace drives and emits the provisioner skeleton that
|
|
251
|
+
* starts them. Neither is derivable from the other: a workspace may declare
|
|
252
|
+
* vendors before it writes a suite, and a suite may drive a service the skeleton
|
|
253
|
+
* does not start.
|
|
246
254
|
*/
|
|
247
255
|
export declare interface Blueprint {
|
|
248
256
|
readonly name: string;
|
|
@@ -258,7 +266,9 @@ export declare interface Blueprint {
|
|
|
258
266
|
readonly overrides: readonly Override[];
|
|
259
267
|
readonly bin: boolean;
|
|
260
268
|
readonly integration: boolean;
|
|
261
|
-
readonly
|
|
269
|
+
readonly conformance: boolean;
|
|
270
|
+
readonly service: boolean;
|
|
271
|
+
readonly vendors: readonly string[];
|
|
262
272
|
readonly global: boolean;
|
|
263
273
|
readonly showcase: boolean;
|
|
264
274
|
}
|
|
@@ -401,10 +411,10 @@ export declare function blueprintToManifest(blueprint: Blueprint): string;
|
|
|
401
411
|
* Compile the blueprint-dependent orchestration artifacts.
|
|
402
412
|
*
|
|
403
413
|
* @param blueprint - The workspace specification.
|
|
404
|
-
* @returns A
|
|
414
|
+
* @returns A vendor inventory script when vendors are declared, otherwise none.
|
|
405
415
|
*
|
|
406
416
|
* @remarks
|
|
407
|
-
* A
|
|
417
|
+
* A vendor name does not describe startup, readiness, or cleanup. The script
|
|
408
418
|
* therefore records only the declared inventory and does not invent a service
|
|
409
419
|
* runner or test project.
|
|
410
420
|
*/
|
|
@@ -499,8 +509,14 @@ export declare function blueprintToRootVite(blueprint: Blueprint): string;
|
|
|
499
509
|
* to the axes the blueprint declares: a check and a test script per declared
|
|
500
510
|
* environment, an aggregate over each axis, the policy and configuration
|
|
501
511
|
* proofs every workspace can pass before it has a public API, and one build per
|
|
502
|
-
* target that actually builds.
|
|
503
|
-
*
|
|
512
|
+
* target that actually builds.
|
|
513
|
+
*
|
|
514
|
+
* A proof leaves `test` when a real service or a real install answers it. The
|
|
515
|
+
* installed-package integration proof and the live-service proof therefore run
|
|
516
|
+
* from `prepublishOnly` instead. The conformance proof stays in `test`, because
|
|
517
|
+
* it measures this package against official tooling and drives nothing external:
|
|
518
|
+
* a conformance run may start a server, but it starts its own and reaches it
|
|
519
|
+
* over loopback, so the run stays hermetic.
|
|
504
520
|
*
|
|
505
521
|
* The configuration paths interpolated here are the same ones `SRC_MATRIX` and
|
|
506
522
|
* `APP_MATRIX` list as each environment's configuration files, so a rename in
|
|
@@ -556,6 +572,12 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
|
|
|
556
572
|
* workspace and therefore follows the `src` axis as well as its structural
|
|
557
573
|
* flag.
|
|
558
574
|
*
|
|
575
|
+
* The conformance proof is not emitted either, for the reason the guide proof
|
|
576
|
+
* is not: it names an official artifact only the package knows, so a generated
|
|
577
|
+
* placeholder would read as a proof while measuring nothing. `service` emits its
|
|
578
|
+
* readiness setup alone, because the root configuration names that module by
|
|
579
|
+
* path.
|
|
580
|
+
*
|
|
559
581
|
* @example
|
|
560
582
|
* ```ts
|
|
561
583
|
* import { blueprintToTestArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
@@ -609,19 +631,61 @@ export declare const CATALOG_AGENT_PATH = ".claude/agents/orkestrel.md";
|
|
|
609
631
|
* still a row: dropping it would hide a package the organization publishes
|
|
610
632
|
* behind one failed request, and inventing a version would state something
|
|
611
633
|
* upstream never said.
|
|
634
|
+
*
|
|
635
|
+
* `dependencies` are the RUNTIME edges the published version declares, which is
|
|
636
|
+
* what a publish order is computed over: a runtime bump obliges every dependent
|
|
637
|
+
* to re-pin and republish, while a development bump obliges nothing beyond the
|
|
638
|
+
* repository that declares it. No layer is recorded here, because a layer is a
|
|
639
|
+
* deterministic function of these edges across the whole catalog — a stored one
|
|
640
|
+
* could only disagree with the rows it was derived from. Read it through
|
|
641
|
+
* {@link catalogToLayers}.
|
|
612
642
|
*/
|
|
613
643
|
export declare type CatalogEntry = {
|
|
614
644
|
readonly name: string;
|
|
615
645
|
readonly lookup: 'found';
|
|
616
646
|
readonly version: string;
|
|
647
|
+
readonly dependencies: readonly Dependency[];
|
|
617
648
|
readonly note?: never;
|
|
618
649
|
} | {
|
|
619
650
|
readonly name: string;
|
|
620
651
|
readonly lookup: 'missing' | 'failed';
|
|
621
652
|
readonly note: string;
|
|
622
653
|
readonly version?: never;
|
|
654
|
+
readonly dependencies?: never;
|
|
623
655
|
};
|
|
624
656
|
|
|
657
|
+
/**
|
|
658
|
+
* Project a catalog into the layers it publishes in.
|
|
659
|
+
*
|
|
660
|
+
* @param entries - The catalog rows to order.
|
|
661
|
+
* @returns One layer per round, each holding the names publishable together,
|
|
662
|
+
* sorted within the layer; a name whose edges never resolve is omitted.
|
|
663
|
+
*
|
|
664
|
+
* @remarks
|
|
665
|
+
* A layer is a deterministic function of the catalog's own edges, so it is
|
|
666
|
+
* computed here rather than stored on a row that could disagree with them.
|
|
667
|
+
* Only RUNTIME edges between catalogued packages count: a development
|
|
668
|
+
* dependency reaches no consumer, so it constrains nothing about publish order,
|
|
669
|
+
* and an edge leaving the fleet is a package this catalog does not publish.
|
|
670
|
+
*
|
|
671
|
+
* The order matters because these packages are `0.0.x`, where a caret pins one
|
|
672
|
+
* exact release. Publishing a dependent before its dependency leaves the
|
|
673
|
+
* dependent pinned to the older release, and two ranges that disagree install
|
|
674
|
+
* two copies of one package that the compiler reads as two distinct types.
|
|
675
|
+
*
|
|
676
|
+
* A cycle cannot be published in rounds, so its members are omitted rather than
|
|
677
|
+
* placed in an order that would be wrong. An absent name is the report: compare
|
|
678
|
+
* the returned names against the catalog to find one.
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```ts
|
|
682
|
+
* import { catalogToLayers } from '@orkestrel/scaffold'
|
|
683
|
+
*
|
|
684
|
+
* catalogToLayers(entries)[0] // the names that depend on nothing in the fleet
|
|
685
|
+
* ```
|
|
686
|
+
*/
|
|
687
|
+
export declare function catalogToLayers(entries: readonly CatalogEntry[]): ReadonlyArray<readonly string[]>;
|
|
688
|
+
|
|
625
689
|
/**
|
|
626
690
|
* Snapshot an untrusted value into exact JSON data the caller owns.
|
|
627
691
|
*
|
|
@@ -979,6 +1043,8 @@ export declare class Compiler implements CompilerInterface {
|
|
|
979
1043
|
policy: "export const policy = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'policy', color: 'white' },\n\t\t\t\tinclude: ['tests/policy.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
980
1044
|
config: "export const config = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'config', color: 'yellow' },\n\t\t\t\tinclude: ['tests/config.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
981
1045
|
guides: "export const guides = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'guides', color: 'green' },\n\t\t\t\tinclude: ['tests/guides.test.ts'],\n\t\t\t\texclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
1046
|
+
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 const conformance = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
1047
|
+
service: "// The live external services this package drives. It starts nothing itself:\n// `scripts/service.sh` provisions, `tests/setupService.ts` proves readiness, and\n// the project stays out of `npm test` because a real service answers it.\nexport const service = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'service', color: 'red' },\n\t\t\t\tinclude: ['tests/service/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupService.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t\ttestTimeout: 120_000,\n\t\t\t\thookTimeout: 120_000,\n\t\t\t\tfileParallelism: false,\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
982
1048
|
probe: "// A workbench, not a proof. No gate selects this project.\nexport const probe = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'probe', color: 'gray' },\n\t\t\t\tinclude: ['tmp/probe/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
983
1049
|
integration: "export const integration = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'integration', color: 'blue' },\n\t\t\t\tinclude: ['tests/integration.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n{{global}}\t\t\t\tenvironment: 'node',\n\t\t\t\ttestTimeout: 120_000,\n\t\t\t\thookTimeout: 120_000,\n\t\t\t\tfileParallelism: false,\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
984
1050
|
}>;
|
|
@@ -1010,6 +1076,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1010
1076
|
}>;
|
|
1011
1077
|
}>;
|
|
1012
1078
|
|
|
1079
|
+
/** The official-tooling drift proof whose presence makes a workspace `conformance`. */
|
|
1080
|
+
export declare const CONFORMANCE_TEST_PATH = "tests/conformance.test.ts";
|
|
1081
|
+
|
|
1013
1082
|
/** A text file produced by the template or computed compilation path. */
|
|
1014
1083
|
export declare interface ContentArtifact extends ArtifactBase {
|
|
1015
1084
|
readonly origin: 'template' | 'computed';
|
|
@@ -1052,8 +1121,8 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1052
1121
|
* blueprint.
|
|
1053
1122
|
*
|
|
1054
1123
|
* @remarks
|
|
1055
|
-
* A blueprint is a closed record
|
|
1056
|
-
*
|
|
1124
|
+
* A blueprint is a closed record, and most of its fields have one sensible
|
|
1125
|
+
* starting value: an empty list, a cleared flag, `DEFAULT_VERSION`, and
|
|
1057
1126
|
* `DEFAULT_ENGINES`. Filling them here is what lets a caller state only what its
|
|
1058
1127
|
* workspace actually declares.
|
|
1059
1128
|
*
|
|
@@ -2546,6 +2615,12 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2546
2615
|
/** The provisioner skeleton a workspace with declared service vendors is given once. */
|
|
2547
2616
|
export declare const SERVICE_SCRIPT_PATH = "scripts/service.sh";
|
|
2548
2617
|
|
|
2618
|
+
/** The live-service readiness module whose presence makes a workspace `service`. */
|
|
2619
|
+
export declare const SERVICE_SETUP_PATH = "tests/setupService.ts";
|
|
2620
|
+
|
|
2621
|
+
/** The include the live-service project covers, which is a directory rather than one proof. */
|
|
2622
|
+
export declare const SERVICE_TEST_INCLUDE = "tests/service/**/*.test.ts";
|
|
2623
|
+
|
|
2549
2624
|
/** The Vite wrapper whose presence makes a workspace `showcase`. */
|
|
2550
2625
|
export declare const SHOWCASE_CONFIG_PATH = "configs/app/vite.showcase.config.ts";
|
|
2551
2626
|
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -104,7 +104,7 @@ export declare const ARTIFACT_TEMPLATES: Readonly<{
|
|
|
104
104
|
readme: "# Guides\n\n## By concept\n\n- Package\n - Spec: Not created. Create this file when the workspace has a public surface:\n `guides/{{guide}}.md`\n - Source:\n{{source}}\n - Tests:\n{{tests}}\n\n## By directory\n\n{{directories}}\n";
|
|
105
105
|
}>;
|
|
106
106
|
orchestration: Readonly<{
|
|
107
|
-
service: "#!/usr/bin/env sh\nset -eu\n\nprintf '%s\\n' \\\n{{
|
|
107
|
+
service: "#!/usr/bin/env sh\nset -eu\n\nprintf '%s\\n' \\\n{{vendors}}\n";
|
|
108
108
|
}>;
|
|
109
109
|
}>;
|
|
110
110
|
|
|
@@ -235,14 +235,22 @@ export declare const BIN_ENTRY_PATH = "src/bin/main.ts";
|
|
|
235
235
|
* application-only, and mixed workspaces are all first class. `dependencies`
|
|
236
236
|
* and `peers` are runtime `@orkestrel/*` packages; `extras` are
|
|
237
237
|
* package-specific development dependencies and may carry any valid npm name.
|
|
238
|
-
* `bin`, `integration`, `
|
|
239
|
-
* facts: each is set only when the workspace
|
|
240
|
-
* exact-case file that defines it, never
|
|
241
|
-
* never because a sibling fact is set. An
|
|
242
|
-
* when its required axis is absent:
|
|
243
|
-
* `
|
|
244
|
-
* with a non-blocking question, so a
|
|
245
|
-
* nothing and the compile still
|
|
238
|
+
* `bin`, `integration`, `conformance`, `service`, `vendors`, `global`, and
|
|
239
|
+
* `showcase` are structural facts: each is set only when the workspace
|
|
240
|
+
* physically ships the directory or exact-case file that defines it, never
|
|
241
|
+
* because of the workspace's name and never because a sibling fact is set. An
|
|
242
|
+
* axis-dependent fact projects nothing when its required axis is absent:
|
|
243
|
+
* `integration` projects only a published `src`, and `showcase` projects only a
|
|
244
|
+
* browser `app`. The gate answers that case with a non-blocking question, so a
|
|
245
|
+
* caller that set the flag learns it emitted nothing and the compile still
|
|
246
|
+
* completes.
|
|
247
|
+
*
|
|
248
|
+
* `service` says the workspace runs a live-service Vitest project over
|
|
249
|
+
* `tests/service`, and it alone registers that project. `vendors` names each
|
|
250
|
+
* external service the workspace drives and emits the provisioner skeleton that
|
|
251
|
+
* starts them. Neither is derivable from the other: a workspace may declare
|
|
252
|
+
* vendors before it writes a suite, and a suite may drive a service the skeleton
|
|
253
|
+
* does not start.
|
|
246
254
|
*/
|
|
247
255
|
export declare interface Blueprint {
|
|
248
256
|
readonly name: string;
|
|
@@ -258,7 +266,9 @@ export declare interface Blueprint {
|
|
|
258
266
|
readonly overrides: readonly Override[];
|
|
259
267
|
readonly bin: boolean;
|
|
260
268
|
readonly integration: boolean;
|
|
261
|
-
readonly
|
|
269
|
+
readonly conformance: boolean;
|
|
270
|
+
readonly service: boolean;
|
|
271
|
+
readonly vendors: readonly string[];
|
|
262
272
|
readonly global: boolean;
|
|
263
273
|
readonly showcase: boolean;
|
|
264
274
|
}
|
|
@@ -401,10 +411,10 @@ export declare function blueprintToManifest(blueprint: Blueprint): string;
|
|
|
401
411
|
* Compile the blueprint-dependent orchestration artifacts.
|
|
402
412
|
*
|
|
403
413
|
* @param blueprint - The workspace specification.
|
|
404
|
-
* @returns A
|
|
414
|
+
* @returns A vendor inventory script when vendors are declared, otherwise none.
|
|
405
415
|
*
|
|
406
416
|
* @remarks
|
|
407
|
-
* A
|
|
417
|
+
* A vendor name does not describe startup, readiness, or cleanup. The script
|
|
408
418
|
* therefore records only the declared inventory and does not invent a service
|
|
409
419
|
* runner or test project.
|
|
410
420
|
*/
|
|
@@ -499,8 +509,14 @@ export declare function blueprintToRootVite(blueprint: Blueprint): string;
|
|
|
499
509
|
* to the axes the blueprint declares: a check and a test script per declared
|
|
500
510
|
* environment, an aggregate over each axis, the policy and configuration
|
|
501
511
|
* proofs every workspace can pass before it has a public API, and one build per
|
|
502
|
-
* target that actually builds.
|
|
503
|
-
*
|
|
512
|
+
* target that actually builds.
|
|
513
|
+
*
|
|
514
|
+
* A proof leaves `test` when a real service or a real install answers it. The
|
|
515
|
+
* installed-package integration proof and the live-service proof therefore run
|
|
516
|
+
* from `prepublishOnly` instead. The conformance proof stays in `test`, because
|
|
517
|
+
* it measures this package against official tooling and drives nothing external:
|
|
518
|
+
* a conformance run may start a server, but it starts its own and reaches it
|
|
519
|
+
* over loopback, so the run stays hermetic.
|
|
504
520
|
*
|
|
505
521
|
* The configuration paths interpolated here are the same ones `SRC_MATRIX` and
|
|
506
522
|
* `APP_MATRIX` list as each environment's configuration files, so a rename in
|
|
@@ -556,6 +572,12 @@ export declare function blueprintToSourceArtifacts(blueprint: Blueprint): readon
|
|
|
556
572
|
* workspace and therefore follows the `src` axis as well as its structural
|
|
557
573
|
* flag.
|
|
558
574
|
*
|
|
575
|
+
* The conformance proof is not emitted either, for the reason the guide proof
|
|
576
|
+
* is not: it names an official artifact only the package knows, so a generated
|
|
577
|
+
* placeholder would read as a proof while measuring nothing. `service` emits its
|
|
578
|
+
* readiness setup alone, because the root configuration names that module by
|
|
579
|
+
* path.
|
|
580
|
+
*
|
|
559
581
|
* @example
|
|
560
582
|
* ```ts
|
|
561
583
|
* import { blueprintToTestArtifacts, createBlueprint } from '@orkestrel/scaffold'
|
|
@@ -609,19 +631,61 @@ export declare const CATALOG_AGENT_PATH = ".claude/agents/orkestrel.md";
|
|
|
609
631
|
* still a row: dropping it would hide a package the organization publishes
|
|
610
632
|
* behind one failed request, and inventing a version would state something
|
|
611
633
|
* upstream never said.
|
|
634
|
+
*
|
|
635
|
+
* `dependencies` are the RUNTIME edges the published version declares, which is
|
|
636
|
+
* what a publish order is computed over: a runtime bump obliges every dependent
|
|
637
|
+
* to re-pin and republish, while a development bump obliges nothing beyond the
|
|
638
|
+
* repository that declares it. No layer is recorded here, because a layer is a
|
|
639
|
+
* deterministic function of these edges across the whole catalog — a stored one
|
|
640
|
+
* could only disagree with the rows it was derived from. Read it through
|
|
641
|
+
* {@link catalogToLayers}.
|
|
612
642
|
*/
|
|
613
643
|
export declare type CatalogEntry = {
|
|
614
644
|
readonly name: string;
|
|
615
645
|
readonly lookup: 'found';
|
|
616
646
|
readonly version: string;
|
|
647
|
+
readonly dependencies: readonly Dependency[];
|
|
617
648
|
readonly note?: never;
|
|
618
649
|
} | {
|
|
619
650
|
readonly name: string;
|
|
620
651
|
readonly lookup: 'missing' | 'failed';
|
|
621
652
|
readonly note: string;
|
|
622
653
|
readonly version?: never;
|
|
654
|
+
readonly dependencies?: never;
|
|
623
655
|
};
|
|
624
656
|
|
|
657
|
+
/**
|
|
658
|
+
* Project a catalog into the layers it publishes in.
|
|
659
|
+
*
|
|
660
|
+
* @param entries - The catalog rows to order.
|
|
661
|
+
* @returns One layer per round, each holding the names publishable together,
|
|
662
|
+
* sorted within the layer; a name whose edges never resolve is omitted.
|
|
663
|
+
*
|
|
664
|
+
* @remarks
|
|
665
|
+
* A layer is a deterministic function of the catalog's own edges, so it is
|
|
666
|
+
* computed here rather than stored on a row that could disagree with them.
|
|
667
|
+
* Only RUNTIME edges between catalogued packages count: a development
|
|
668
|
+
* dependency reaches no consumer, so it constrains nothing about publish order,
|
|
669
|
+
* and an edge leaving the fleet is a package this catalog does not publish.
|
|
670
|
+
*
|
|
671
|
+
* The order matters because these packages are `0.0.x`, where a caret pins one
|
|
672
|
+
* exact release. Publishing a dependent before its dependency leaves the
|
|
673
|
+
* dependent pinned to the older release, and two ranges that disagree install
|
|
674
|
+
* two copies of one package that the compiler reads as two distinct types.
|
|
675
|
+
*
|
|
676
|
+
* A cycle cannot be published in rounds, so its members are omitted rather than
|
|
677
|
+
* placed in an order that would be wrong. An absent name is the report: compare
|
|
678
|
+
* the returned names against the catalog to find one.
|
|
679
|
+
*
|
|
680
|
+
* @example
|
|
681
|
+
* ```ts
|
|
682
|
+
* import { catalogToLayers } from '@orkestrel/scaffold'
|
|
683
|
+
*
|
|
684
|
+
* catalogToLayers(entries)[0] // the names that depend on nothing in the fleet
|
|
685
|
+
* ```
|
|
686
|
+
*/
|
|
687
|
+
export declare function catalogToLayers(entries: readonly CatalogEntry[]): ReadonlyArray<readonly string[]>;
|
|
688
|
+
|
|
625
689
|
/**
|
|
626
690
|
* Snapshot an untrusted value into exact JSON data the caller owns.
|
|
627
691
|
*
|
|
@@ -979,6 +1043,8 @@ export declare class Compiler implements CompilerInterface {
|
|
|
979
1043
|
policy: "export const policy = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'policy', color: 'white' },\n\t\t\t\tinclude: ['tests/policy.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
980
1044
|
config: "export const config = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'config', color: 'yellow' },\n\t\t\t\tinclude: ['tests/config.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
981
1045
|
guides: "export const guides = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'guides', color: 'green' },\n\t\t\t\tinclude: ['tests/guides.test.ts'],\n\t\t\t\texclude: ['tests/src/**/*.test.ts', 'tests/app/**/*.test.ts', 'tests/setup.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
1046
|
+
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 const conformance = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'conformance', color: 'magenta' },\n\t\t\t\tinclude: ['tests/conformance.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
1047
|
+
service: "// The live external services this package drives. It starts nothing itself:\n// `scripts/service.sh` provisions, `tests/setupService.ts` proves readiness, and\n// the project stays out of `npm test` because a real service answers it.\nexport const service = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'service', color: 'red' },\n\t\t\t\tinclude: ['tests/service/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts', './tests/setupService.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t\ttestTimeout: 120_000,\n\t\t\t\thookTimeout: 120_000,\n\t\t\t\tfileParallelism: false,\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
982
1048
|
probe: "// A workbench, not a proof. No gate selects this project.\nexport const probe = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'probe', color: 'gray' },\n\t\t\t\tinclude: ['tmp/probe/**/*.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n\t\t\t\tenvironment: 'node',\n\t\t\t\tbrowser: { enabled: false },\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
983
1049
|
integration: "export const integration = (options?: UserConfig): UserConfig =>\n\tmergeConfig(\n\t\t{\n\t\t\tresolve,\n\t\t\ttest: {\n\t\t\t\tname: { label: 'integration', color: 'blue' },\n\t\t\t\tinclude: ['tests/integration.test.ts'],\n\t\t\t\tsetupFiles: ['./tests/setup.ts'],\n{{global}}\t\t\t\tenvironment: 'node',\n\t\t\t\ttestTimeout: 120_000,\n\t\t\t\thookTimeout: 120_000,\n\t\t\t\tfileParallelism: false,\n\t\t\t},\n\t\t},\n\t\toptions ?? {},\n\t)\n";
|
|
984
1050
|
}>;
|
|
@@ -1010,6 +1076,9 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1010
1076
|
}>;
|
|
1011
1077
|
}>;
|
|
1012
1078
|
|
|
1079
|
+
/** The official-tooling drift proof whose presence makes a workspace `conformance`. */
|
|
1080
|
+
export declare const CONFORMANCE_TEST_PATH = "tests/conformance.test.ts";
|
|
1081
|
+
|
|
1013
1082
|
/** A text file produced by the template or computed compilation path. */
|
|
1014
1083
|
export declare interface ContentArtifact extends ArtifactBase {
|
|
1015
1084
|
readonly origin: 'template' | 'computed';
|
|
@@ -1052,8 +1121,8 @@ export declare class Compiler implements CompilerInterface {
|
|
|
1052
1121
|
* blueprint.
|
|
1053
1122
|
*
|
|
1054
1123
|
* @remarks
|
|
1055
|
-
* A blueprint is a closed record
|
|
1056
|
-
*
|
|
1124
|
+
* A blueprint is a closed record, and most of its fields have one sensible
|
|
1125
|
+
* starting value: an empty list, a cleared flag, `DEFAULT_VERSION`, and
|
|
1057
1126
|
* `DEFAULT_ENGINES`. Filling them here is what lets a caller state only what its
|
|
1058
1127
|
* workspace actually declares.
|
|
1059
1128
|
*
|
|
@@ -2546,6 +2615,12 @@ export declare class Compiler implements CompilerInterface {
|
|
|
2546
2615
|
/** The provisioner skeleton a workspace with declared service vendors is given once. */
|
|
2547
2616
|
export declare const SERVICE_SCRIPT_PATH = "scripts/service.sh";
|
|
2548
2617
|
|
|
2618
|
+
/** The live-service readiness module whose presence makes a workspace `service`. */
|
|
2619
|
+
export declare const SERVICE_SETUP_PATH = "tests/setupService.ts";
|
|
2620
|
+
|
|
2621
|
+
/** The include the live-service project covers, which is a directory rather than one proof. */
|
|
2622
|
+
export declare const SERVICE_TEST_INCLUDE = "tests/service/**/*.test.ts";
|
|
2623
|
+
|
|
2549
2624
|
/** The Vite wrapper whose presence makes a workspace `showcase`. */
|
|
2550
2625
|
export declare const SHOWCASE_CONFIG_PATH = "configs/app/vite.showcase.config.ts";
|
|
2551
2626
|
|