@orkestrel/scaffold 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -5
- package/dist/host/claude/agents/orkestrel.md +1 -0
- package/dist/host/guides/src/scaffold.md +53 -15
- package/dist/src/core/index.cjs +169 -16
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +123 -8
- package/dist/src/core/index.d.ts +123 -8
- package/dist/src/core/index.js +163 -17
- package/dist/src/core/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -440,6 +440,23 @@ export declare interface CompilerOptions {
|
|
|
440
440
|
/** The three fixed pipeline phases, in order. */
|
|
441
441
|
export declare type CompileStage = 'draft' | 'gate' | 'pin';
|
|
442
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Measure a rendered fragment's column width, counting each literal tab as
|
|
445
|
+
* `JSON_TAB_WIDTH` columns (matching `.oxfmtrc.json`'s `tabWidth`) and every
|
|
446
|
+
* other character as one.
|
|
447
|
+
*
|
|
448
|
+
* @param text - The rendered fragment to measure.
|
|
449
|
+
* @returns The fragment's column width against `JSON_PRINT_WIDTH`.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```ts
|
|
453
|
+
* import { computeColumnWidth } from '@orkestrel/scaffold'
|
|
454
|
+
*
|
|
455
|
+
* computeColumnWidth('\t"a"') // 3 — one tab counted as JSON_TAB_WIDTH, plus two characters
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
export declare function computeColumnWidth(text: string): number;
|
|
459
|
+
|
|
443
460
|
/**
|
|
444
461
|
* Compute a canonical FNV-1a digest of a text string.
|
|
445
462
|
*
|
|
@@ -660,14 +677,25 @@ export declare function coreViteConfig(): string;
|
|
|
660
677
|
* @param plan - The plan whose artifacts are the source of truth.
|
|
661
678
|
* @param current - The target's current content, keyed by artifact-relative path.
|
|
662
679
|
* @remarks
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
* with its real host bytes (`hydratePlan`'s `content`), in which case it is
|
|
668
|
-
* content-compared exactly like a `template` / `computed` artifact and CAN be
|
|
680
|
+
* Audit semantics are per-origin. A `host`-origin artifact is audited by
|
|
681
|
+
* PRESENCE only — `missing` or `aligned`, never `stale` — UNLESS it has been
|
|
682
|
+
* hydrated with its real host bytes (`hydratePlan`'s `content`), in which case
|
|
683
|
+
* it is content-compared exactly like a `computed` artifact and CAN be
|
|
669
684
|
* `stale`. A degrade-path or directory-shaped host artifact (never hydrated)
|
|
670
|
-
* stays presence-only.
|
|
685
|
+
* stays presence-only. A `computed` artifact is content-aware canon —
|
|
686
|
+
* `missing` / `aligned` / `stale` — and gates the audit like any drifted
|
|
687
|
+
* finding. A `template`-origin artifact is BIRTH-ONLY and AUDIT-EXEMPT: it is
|
|
688
|
+
* always reported `aligned`, regardless of whether the target has it at all
|
|
689
|
+
* or what its bytes are. Starter files (source stubs, test stubs, starter
|
|
690
|
+
* guides, README) are written ONCE by `materialize` and are legitimately
|
|
691
|
+
* outgrown — real code replaces the stub, a hand-authored guide replaces the
|
|
692
|
+
* scaffold prose, an entity gets renamed. Content- or presence-comparing a
|
|
693
|
+
* mature package against its birth stub is a category error (the build and
|
|
694
|
+
* parity gates already police the package's substance) AND makes any
|
|
695
|
+
* unscoped repair a data-loss footgun — a stub overwrite would clobber real,
|
|
696
|
+
* hand-authored code. `template` findings therefore never contribute to
|
|
697
|
+
* `drifted` / `missing` / `clean`. A target file the plan does not own is
|
|
698
|
+
* `foreign`.
|
|
671
699
|
* @returns The `Audit` of drift findings — pure, no I/O.
|
|
672
700
|
*
|
|
673
701
|
* @example
|
|
@@ -767,6 +795,31 @@ export declare function coreViteConfig(): string;
|
|
|
767
795
|
readonly drift: Drift;
|
|
768
796
|
}
|
|
769
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Serialize a value to newline-terminated JSON that matches the fleet's own
|
|
800
|
+
* `oxfmt` output byte-for-byte — objects one key per line, arrays collapsed
|
|
801
|
+
* onto one line when they fit `JSON_PRINT_WIDTH`, one item per line
|
|
802
|
+
* otherwise.
|
|
803
|
+
*
|
|
804
|
+
* @param value - The value to serialize (config JSON — objects/arrays/primitives).
|
|
805
|
+
* @remarks
|
|
806
|
+
* `JSON.stringify(value, undefined, '\t')` always breaks arrays one item per
|
|
807
|
+
* line; `oxfmt` collapses short ones. Emitting through `formatJson` keeps
|
|
808
|
+
* computed config JSON format-stable by construction — `oxfmt --check` never
|
|
809
|
+
* has anything left to rewrite. The rendering itself is delegated to
|
|
810
|
+
* `renderValue` / `renderArray` / `renderObject` / `computeColumnWidth`, so
|
|
811
|
+
* `formatJson` is a thin orchestrator around them.
|
|
812
|
+
* @returns The rendered value, newline-terminated.
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```ts
|
|
816
|
+
* import { formatJson } from '@orkestrel/scaffold'
|
|
817
|
+
*
|
|
818
|
+
* formatJson({ lib: ['ESNext', 'DOM'] }) // '{\n\t"lib": ["ESNext", "DOM"]\n}\n'
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
export declare function formatJson(value: unknown): string;
|
|
822
|
+
|
|
770
823
|
/** The four `Freshness` values, frozen — the currency axis `Sync` reports on. */
|
|
771
824
|
export declare const FRESHNESS: readonly ["current", "behind", "missing", "failed"];
|
|
772
825
|
|
|
@@ -1001,6 +1054,12 @@ export declare function coreViteConfig(): string;
|
|
|
1001
1054
|
*/
|
|
1002
1055
|
export declare const isSyncReport: Guard<SyncReport>;
|
|
1003
1056
|
|
|
1057
|
+
/** The fleet's `.oxfmtrc.json` `printWidth` — `formatJson`'s array-collapse threshold. */
|
|
1058
|
+
export declare const JSON_PRINT_WIDTH = 100;
|
|
1059
|
+
|
|
1060
|
+
/** The fleet's `.oxfmtrc.json` `tabWidth` — the column width `formatJson` counts each tab as. */
|
|
1061
|
+
export declare const JSON_TAB_WIDTH = 2;
|
|
1062
|
+
|
|
1004
1063
|
/**
|
|
1005
1064
|
* Parse a `package.json` text into its declared `@orkestrel/*` dependencies.
|
|
1006
1065
|
*
|
|
@@ -1501,6 +1560,62 @@ export declare function coreViteConfig(): string;
|
|
|
1501
1560
|
*/
|
|
1502
1561
|
export declare function rangeToFreshness(range: string, latest: string): Freshness;
|
|
1503
1562
|
|
|
1563
|
+
/**
|
|
1564
|
+
* Render a JSON array through `formatJson`'s inline-or-broken rule — inline
|
|
1565
|
+
* when the rendered width (via `computeColumnWidth`) fits `JSON_PRINT_WIDTH`, one
|
|
1566
|
+
* item per line otherwise.
|
|
1567
|
+
*
|
|
1568
|
+
* @param entries - The array's elements, in order.
|
|
1569
|
+
* @param indent - The current indentation prefix.
|
|
1570
|
+
* @param prefix - The text already emitted on this line before the array.
|
|
1571
|
+
* @param suffix - The text that will follow the array on this line.
|
|
1572
|
+
* @returns The rendered array fragment (no trailing newline).
|
|
1573
|
+
*
|
|
1574
|
+
* @example
|
|
1575
|
+
* ```ts
|
|
1576
|
+
* import { renderArray } from '@orkestrel/scaffold'
|
|
1577
|
+
*
|
|
1578
|
+
* renderArray(['ESNext', 'DOM'], '', '', '') // '["ESNext", "DOM"]'
|
|
1579
|
+
* ```
|
|
1580
|
+
*/
|
|
1581
|
+
export declare function renderArray(entries: readonly unknown[], indent: string, prefix: string, suffix: string): string;
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* Render a JSON object through `formatJson`'s one-key-per-line rule.
|
|
1585
|
+
*
|
|
1586
|
+
* @param entry - The object to render.
|
|
1587
|
+
* @param indent - The current indentation prefix.
|
|
1588
|
+
* @returns The rendered object fragment (no trailing newline).
|
|
1589
|
+
*
|
|
1590
|
+
* @example
|
|
1591
|
+
* ```ts
|
|
1592
|
+
* import { renderObject } from '@orkestrel/scaffold'
|
|
1593
|
+
*
|
|
1594
|
+
* renderObject({ lib: ['ESNext'] }, '') // '{\n\t"lib": ["ESNext"]\n}'
|
|
1595
|
+
* ```
|
|
1596
|
+
*/
|
|
1597
|
+
export declare function renderObject(entry: Readonly<Record<string, unknown>>, indent: string): string;
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Render one JSON value through `formatJson`'s dispatch — arrays via
|
|
1601
|
+
* `renderArray`, objects via `renderObject`, everything else via
|
|
1602
|
+
* `JSON.stringify`.
|
|
1603
|
+
*
|
|
1604
|
+
* @param entry - The value to render.
|
|
1605
|
+
* @param indent - The current indentation prefix.
|
|
1606
|
+
* @param prefix - The text already emitted on this line before `entry`.
|
|
1607
|
+
* @param suffix - The text that will follow `entry` on this line.
|
|
1608
|
+
* @returns The rendered fragment (no trailing newline).
|
|
1609
|
+
*
|
|
1610
|
+
* @example
|
|
1611
|
+
* ```ts
|
|
1612
|
+
* import { renderValue } from '@orkestrel/scaffold'
|
|
1613
|
+
*
|
|
1614
|
+
* renderValue('ESNext', '', '', '') // '"ESNext"'
|
|
1615
|
+
* ```
|
|
1616
|
+
*/
|
|
1617
|
+
export declare function renderValue(entry: unknown, indent: string, prefix: string, suffix: string): string;
|
|
1618
|
+
|
|
1504
1619
|
/**
|
|
1505
1620
|
* The root `tsconfig.json` — one `@src/<surface>` path alias per declared
|
|
1506
1621
|
* surface, in declared order.
|
|
@@ -1543,7 +1658,7 @@ export declare function coreViteConfig(): string;
|
|
|
1543
1658
|
export declare function rootViteConfig(surfaces: readonly Surface[]): string;
|
|
1544
1659
|
|
|
1545
1660
|
/** The devDependency range generated packages pin `@orkestrel/scaffold` at. */
|
|
1546
|
-
export declare const SCAFFOLD_RANGE = "^0.0.
|
|
1661
|
+
export declare const SCAFFOLD_RANGE = "^0.0.2";
|
|
1547
1662
|
|
|
1548
1663
|
/**
|
|
1549
1664
|
* Carries a `ScaffoldErrorCode` + optional `context` (AGENTS §12).
|
package/dist/src/core/index.d.ts
CHANGED
|
@@ -440,6 +440,23 @@ export declare interface CompilerOptions {
|
|
|
440
440
|
/** The three fixed pipeline phases, in order. */
|
|
441
441
|
export declare type CompileStage = 'draft' | 'gate' | 'pin';
|
|
442
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Measure a rendered fragment's column width, counting each literal tab as
|
|
445
|
+
* `JSON_TAB_WIDTH` columns (matching `.oxfmtrc.json`'s `tabWidth`) and every
|
|
446
|
+
* other character as one.
|
|
447
|
+
*
|
|
448
|
+
* @param text - The rendered fragment to measure.
|
|
449
|
+
* @returns The fragment's column width against `JSON_PRINT_WIDTH`.
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```ts
|
|
453
|
+
* import { computeColumnWidth } from '@orkestrel/scaffold'
|
|
454
|
+
*
|
|
455
|
+
* computeColumnWidth('\t"a"') // 3 — one tab counted as JSON_TAB_WIDTH, plus two characters
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
export declare function computeColumnWidth(text: string): number;
|
|
459
|
+
|
|
443
460
|
/**
|
|
444
461
|
* Compute a canonical FNV-1a digest of a text string.
|
|
445
462
|
*
|
|
@@ -660,14 +677,25 @@ export declare function coreViteConfig(): string;
|
|
|
660
677
|
* @param plan - The plan whose artifacts are the source of truth.
|
|
661
678
|
* @param current - The target's current content, keyed by artifact-relative path.
|
|
662
679
|
* @remarks
|
|
663
|
-
*
|
|
664
|
-
*
|
|
665
|
-
*
|
|
666
|
-
*
|
|
667
|
-
* with its real host bytes (`hydratePlan`'s `content`), in which case it is
|
|
668
|
-
* content-compared exactly like a `template` / `computed` artifact and CAN be
|
|
680
|
+
* Audit semantics are per-origin. A `host`-origin artifact is audited by
|
|
681
|
+
* PRESENCE only — `missing` or `aligned`, never `stale` — UNLESS it has been
|
|
682
|
+
* hydrated with its real host bytes (`hydratePlan`'s `content`), in which case
|
|
683
|
+
* it is content-compared exactly like a `computed` artifact and CAN be
|
|
669
684
|
* `stale`. A degrade-path or directory-shaped host artifact (never hydrated)
|
|
670
|
-
* stays presence-only.
|
|
685
|
+
* stays presence-only. A `computed` artifact is content-aware canon —
|
|
686
|
+
* `missing` / `aligned` / `stale` — and gates the audit like any drifted
|
|
687
|
+
* finding. A `template`-origin artifact is BIRTH-ONLY and AUDIT-EXEMPT: it is
|
|
688
|
+
* always reported `aligned`, regardless of whether the target has it at all
|
|
689
|
+
* or what its bytes are. Starter files (source stubs, test stubs, starter
|
|
690
|
+
* guides, README) are written ONCE by `materialize` and are legitimately
|
|
691
|
+
* outgrown — real code replaces the stub, a hand-authored guide replaces the
|
|
692
|
+
* scaffold prose, an entity gets renamed. Content- or presence-comparing a
|
|
693
|
+
* mature package against its birth stub is a category error (the build and
|
|
694
|
+
* parity gates already police the package's substance) AND makes any
|
|
695
|
+
* unscoped repair a data-loss footgun — a stub overwrite would clobber real,
|
|
696
|
+
* hand-authored code. `template` findings therefore never contribute to
|
|
697
|
+
* `drifted` / `missing` / `clean`. A target file the plan does not own is
|
|
698
|
+
* `foreign`.
|
|
671
699
|
* @returns The `Audit` of drift findings — pure, no I/O.
|
|
672
700
|
*
|
|
673
701
|
* @example
|
|
@@ -767,6 +795,31 @@ export declare function coreViteConfig(): string;
|
|
|
767
795
|
readonly drift: Drift;
|
|
768
796
|
}
|
|
769
797
|
|
|
798
|
+
/**
|
|
799
|
+
* Serialize a value to newline-terminated JSON that matches the fleet's own
|
|
800
|
+
* `oxfmt` output byte-for-byte — objects one key per line, arrays collapsed
|
|
801
|
+
* onto one line when they fit `JSON_PRINT_WIDTH`, one item per line
|
|
802
|
+
* otherwise.
|
|
803
|
+
*
|
|
804
|
+
* @param value - The value to serialize (config JSON — objects/arrays/primitives).
|
|
805
|
+
* @remarks
|
|
806
|
+
* `JSON.stringify(value, undefined, '\t')` always breaks arrays one item per
|
|
807
|
+
* line; `oxfmt` collapses short ones. Emitting through `formatJson` keeps
|
|
808
|
+
* computed config JSON format-stable by construction — `oxfmt --check` never
|
|
809
|
+
* has anything left to rewrite. The rendering itself is delegated to
|
|
810
|
+
* `renderValue` / `renderArray` / `renderObject` / `computeColumnWidth`, so
|
|
811
|
+
* `formatJson` is a thin orchestrator around them.
|
|
812
|
+
* @returns The rendered value, newline-terminated.
|
|
813
|
+
*
|
|
814
|
+
* @example
|
|
815
|
+
* ```ts
|
|
816
|
+
* import { formatJson } from '@orkestrel/scaffold'
|
|
817
|
+
*
|
|
818
|
+
* formatJson({ lib: ['ESNext', 'DOM'] }) // '{\n\t"lib": ["ESNext", "DOM"]\n}\n'
|
|
819
|
+
* ```
|
|
820
|
+
*/
|
|
821
|
+
export declare function formatJson(value: unknown): string;
|
|
822
|
+
|
|
770
823
|
/** The four `Freshness` values, frozen — the currency axis `Sync` reports on. */
|
|
771
824
|
export declare const FRESHNESS: readonly ["current", "behind", "missing", "failed"];
|
|
772
825
|
|
|
@@ -1001,6 +1054,12 @@ export declare function coreViteConfig(): string;
|
|
|
1001
1054
|
*/
|
|
1002
1055
|
export declare const isSyncReport: Guard<SyncReport>;
|
|
1003
1056
|
|
|
1057
|
+
/** The fleet's `.oxfmtrc.json` `printWidth` — `formatJson`'s array-collapse threshold. */
|
|
1058
|
+
export declare const JSON_PRINT_WIDTH = 100;
|
|
1059
|
+
|
|
1060
|
+
/** The fleet's `.oxfmtrc.json` `tabWidth` — the column width `formatJson` counts each tab as. */
|
|
1061
|
+
export declare const JSON_TAB_WIDTH = 2;
|
|
1062
|
+
|
|
1004
1063
|
/**
|
|
1005
1064
|
* Parse a `package.json` text into its declared `@orkestrel/*` dependencies.
|
|
1006
1065
|
*
|
|
@@ -1501,6 +1560,62 @@ export declare function coreViteConfig(): string;
|
|
|
1501
1560
|
*/
|
|
1502
1561
|
export declare function rangeToFreshness(range: string, latest: string): Freshness;
|
|
1503
1562
|
|
|
1563
|
+
/**
|
|
1564
|
+
* Render a JSON array through `formatJson`'s inline-or-broken rule — inline
|
|
1565
|
+
* when the rendered width (via `computeColumnWidth`) fits `JSON_PRINT_WIDTH`, one
|
|
1566
|
+
* item per line otherwise.
|
|
1567
|
+
*
|
|
1568
|
+
* @param entries - The array's elements, in order.
|
|
1569
|
+
* @param indent - The current indentation prefix.
|
|
1570
|
+
* @param prefix - The text already emitted on this line before the array.
|
|
1571
|
+
* @param suffix - The text that will follow the array on this line.
|
|
1572
|
+
* @returns The rendered array fragment (no trailing newline).
|
|
1573
|
+
*
|
|
1574
|
+
* @example
|
|
1575
|
+
* ```ts
|
|
1576
|
+
* import { renderArray } from '@orkestrel/scaffold'
|
|
1577
|
+
*
|
|
1578
|
+
* renderArray(['ESNext', 'DOM'], '', '', '') // '["ESNext", "DOM"]'
|
|
1579
|
+
* ```
|
|
1580
|
+
*/
|
|
1581
|
+
export declare function renderArray(entries: readonly unknown[], indent: string, prefix: string, suffix: string): string;
|
|
1582
|
+
|
|
1583
|
+
/**
|
|
1584
|
+
* Render a JSON object through `formatJson`'s one-key-per-line rule.
|
|
1585
|
+
*
|
|
1586
|
+
* @param entry - The object to render.
|
|
1587
|
+
* @param indent - The current indentation prefix.
|
|
1588
|
+
* @returns The rendered object fragment (no trailing newline).
|
|
1589
|
+
*
|
|
1590
|
+
* @example
|
|
1591
|
+
* ```ts
|
|
1592
|
+
* import { renderObject } from '@orkestrel/scaffold'
|
|
1593
|
+
*
|
|
1594
|
+
* renderObject({ lib: ['ESNext'] }, '') // '{\n\t"lib": ["ESNext"]\n}'
|
|
1595
|
+
* ```
|
|
1596
|
+
*/
|
|
1597
|
+
export declare function renderObject(entry: Readonly<Record<string, unknown>>, indent: string): string;
|
|
1598
|
+
|
|
1599
|
+
/**
|
|
1600
|
+
* Render one JSON value through `formatJson`'s dispatch — arrays via
|
|
1601
|
+
* `renderArray`, objects via `renderObject`, everything else via
|
|
1602
|
+
* `JSON.stringify`.
|
|
1603
|
+
*
|
|
1604
|
+
* @param entry - The value to render.
|
|
1605
|
+
* @param indent - The current indentation prefix.
|
|
1606
|
+
* @param prefix - The text already emitted on this line before `entry`.
|
|
1607
|
+
* @param suffix - The text that will follow `entry` on this line.
|
|
1608
|
+
* @returns The rendered fragment (no trailing newline).
|
|
1609
|
+
*
|
|
1610
|
+
* @example
|
|
1611
|
+
* ```ts
|
|
1612
|
+
* import { renderValue } from '@orkestrel/scaffold'
|
|
1613
|
+
*
|
|
1614
|
+
* renderValue('ESNext', '', '', '') // '"ESNext"'
|
|
1615
|
+
* ```
|
|
1616
|
+
*/
|
|
1617
|
+
export declare function renderValue(entry: unknown, indent: string, prefix: string, suffix: string): string;
|
|
1618
|
+
|
|
1504
1619
|
/**
|
|
1505
1620
|
* The root `tsconfig.json` — one `@src/<surface>` path alias per declared
|
|
1506
1621
|
* surface, in declared order.
|
|
@@ -1543,7 +1658,7 @@ export declare function coreViteConfig(): string;
|
|
|
1543
1658
|
export declare function rootViteConfig(surfaces: readonly Surface[]): string;
|
|
1544
1659
|
|
|
1545
1660
|
/** The devDependency range generated packages pin `@orkestrel/scaffold` at. */
|
|
1546
|
-
export declare const SCAFFOLD_RANGE = "^0.0.
|
|
1661
|
+
export declare const SCAFFOLD_RANGE = "^0.0.2";
|
|
1547
1662
|
|
|
1548
1663
|
/**
|
|
1549
1664
|
* Carries a `ScaffoldErrorCode` + optional `context` (AGENTS §12).
|
package/dist/src/core/index.js
CHANGED
|
@@ -128,9 +128,13 @@ var DEFAULT_VERSION = "0.0.1";
|
|
|
128
128
|
/** The `engines.node` range the `blueprint` builder fills. */
|
|
129
129
|
var DEFAULT_ENGINES = ">=22";
|
|
130
130
|
/** The devDependency range generated packages pin `@orkestrel/scaffold` at. */
|
|
131
|
-
var SCAFFOLD_RANGE = "^0.0.
|
|
131
|
+
var SCAFFOLD_RANGE = "^0.0.2";
|
|
132
132
|
/** The default id for a `Compiler` orchestrator. */
|
|
133
133
|
var COMPILER_ID = "compiler";
|
|
134
|
+
/** The fleet's `.oxfmtrc.json` `printWidth` — `formatJson`'s array-collapse threshold. */
|
|
135
|
+
var JSON_PRINT_WIDTH = 100;
|
|
136
|
+
/** The fleet's `.oxfmtrc.json` `tabWidth` — the column width `formatJson` counts each tab as. */
|
|
137
|
+
var JSON_TAB_WIDTH = 2;
|
|
134
138
|
//#endregion
|
|
135
139
|
//#region src/core/errors.ts
|
|
136
140
|
/**
|
|
@@ -984,14 +988,25 @@ function inferGroup(path) {
|
|
|
984
988
|
* @param plan - The plan whose artifacts are the source of truth.
|
|
985
989
|
* @param current - The target's current content, keyed by artifact-relative path.
|
|
986
990
|
* @remarks
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
* with its real host bytes (`hydratePlan`'s `content`), in which case it is
|
|
992
|
-
* content-compared exactly like a `template` / `computed` artifact and CAN be
|
|
991
|
+
* Audit semantics are per-origin. A `host`-origin artifact is audited by
|
|
992
|
+
* PRESENCE only — `missing` or `aligned`, never `stale` — UNLESS it has been
|
|
993
|
+
* hydrated with its real host bytes (`hydratePlan`'s `content`), in which case
|
|
994
|
+
* it is content-compared exactly like a `computed` artifact and CAN be
|
|
993
995
|
* `stale`. A degrade-path or directory-shaped host artifact (never hydrated)
|
|
994
|
-
* stays presence-only.
|
|
996
|
+
* stays presence-only. A `computed` artifact is content-aware canon —
|
|
997
|
+
* `missing` / `aligned` / `stale` — and gates the audit like any drifted
|
|
998
|
+
* finding. A `template`-origin artifact is BIRTH-ONLY and AUDIT-EXEMPT: it is
|
|
999
|
+
* always reported `aligned`, regardless of whether the target has it at all
|
|
1000
|
+
* or what its bytes are. Starter files (source stubs, test stubs, starter
|
|
1001
|
+
* guides, README) are written ONCE by `materialize` and are legitimately
|
|
1002
|
+
* outgrown — real code replaces the stub, a hand-authored guide replaces the
|
|
1003
|
+
* scaffold prose, an entity gets renamed. Content- or presence-comparing a
|
|
1004
|
+
* mature package against its birth stub is a category error (the build and
|
|
1005
|
+
* parity gates already police the package's substance) AND makes any
|
|
1006
|
+
* unscoped repair a data-loss footgun — a stub overwrite would clobber real,
|
|
1007
|
+
* hand-authored code. `template` findings therefore never contribute to
|
|
1008
|
+
* `drifted` / `missing` / `clean`. A target file the plan does not own is
|
|
1009
|
+
* `foreign`.
|
|
995
1010
|
* @returns The `Audit` of drift findings — pure, no I/O.
|
|
996
1011
|
*
|
|
997
1012
|
* @example
|
|
@@ -1007,6 +1022,14 @@ function diffPlan(plan, current) {
|
|
|
1007
1022
|
for (const artifact of plan.artifacts) {
|
|
1008
1023
|
owned.add(artifact.path);
|
|
1009
1024
|
const seen = current[artifact.path];
|
|
1025
|
+
if (artifact.origin === "template") {
|
|
1026
|
+
findings.push({
|
|
1027
|
+
path: artifact.path,
|
|
1028
|
+
group: artifact.group,
|
|
1029
|
+
drift: "aligned"
|
|
1030
|
+
});
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
1010
1033
|
if (artifact.origin === "host") {
|
|
1011
1034
|
let drift;
|
|
1012
1035
|
if (seen === void 0) drift = "missing";
|
|
@@ -1379,6 +1402,125 @@ function stableStringify(value) {
|
|
|
1379
1402
|
return JSON.stringify(value);
|
|
1380
1403
|
}
|
|
1381
1404
|
/**
|
|
1405
|
+
* Measure a rendered fragment's column width, counting each literal tab as
|
|
1406
|
+
* `JSON_TAB_WIDTH` columns (matching `.oxfmtrc.json`'s `tabWidth`) and every
|
|
1407
|
+
* other character as one.
|
|
1408
|
+
*
|
|
1409
|
+
* @param text - The rendered fragment to measure.
|
|
1410
|
+
* @returns The fragment's column width against `JSON_PRINT_WIDTH`.
|
|
1411
|
+
*
|
|
1412
|
+
* @example
|
|
1413
|
+
* ```ts
|
|
1414
|
+
* import { computeColumnWidth } from '@orkestrel/scaffold'
|
|
1415
|
+
*
|
|
1416
|
+
* computeColumnWidth('\t"a"') // 3 — one tab counted as JSON_TAB_WIDTH, plus two characters
|
|
1417
|
+
* ```
|
|
1418
|
+
*/
|
|
1419
|
+
function computeColumnWidth(text) {
|
|
1420
|
+
let width = 0;
|
|
1421
|
+
for (const char of text) width += char === " " ? 2 : 1;
|
|
1422
|
+
return width;
|
|
1423
|
+
}
|
|
1424
|
+
/**
|
|
1425
|
+
* Render a JSON array through `formatJson`'s inline-or-broken rule — inline
|
|
1426
|
+
* when the rendered width (via `computeColumnWidth`) fits `JSON_PRINT_WIDTH`, one
|
|
1427
|
+
* item per line otherwise.
|
|
1428
|
+
*
|
|
1429
|
+
* @param entries - The array's elements, in order.
|
|
1430
|
+
* @param indent - The current indentation prefix.
|
|
1431
|
+
* @param prefix - The text already emitted on this line before the array.
|
|
1432
|
+
* @param suffix - The text that will follow the array on this line.
|
|
1433
|
+
* @returns The rendered array fragment (no trailing newline).
|
|
1434
|
+
*
|
|
1435
|
+
* @example
|
|
1436
|
+
* ```ts
|
|
1437
|
+
* import { renderArray } from '@orkestrel/scaffold'
|
|
1438
|
+
*
|
|
1439
|
+
* renderArray(['ESNext', 'DOM'], '', '', '') // '["ESNext", "DOM"]'
|
|
1440
|
+
* ```
|
|
1441
|
+
*/
|
|
1442
|
+
function renderArray(entries, indent, prefix, suffix) {
|
|
1443
|
+
if (entries.length === 0) return "[]";
|
|
1444
|
+
const items = entries.map((entry) => renderValue(entry, indent, "", ""));
|
|
1445
|
+
const inline = `[${items.join(", ")}]`;
|
|
1446
|
+
if (computeColumnWidth(`${prefix}${inline}${suffix}`) <= 100) return inline;
|
|
1447
|
+
const childIndent = `${indent}\t`;
|
|
1448
|
+
return `[\n${items.map((item) => `${childIndent}${item}`).join(",\n")}\n${indent}]`;
|
|
1449
|
+
}
|
|
1450
|
+
/**
|
|
1451
|
+
* Render a JSON object through `formatJson`'s one-key-per-line rule.
|
|
1452
|
+
*
|
|
1453
|
+
* @param entry - The object to render.
|
|
1454
|
+
* @param indent - The current indentation prefix.
|
|
1455
|
+
* @returns The rendered object fragment (no trailing newline).
|
|
1456
|
+
*
|
|
1457
|
+
* @example
|
|
1458
|
+
* ```ts
|
|
1459
|
+
* import { renderObject } from '@orkestrel/scaffold'
|
|
1460
|
+
*
|
|
1461
|
+
* renderObject({ lib: ['ESNext'] }, '') // '{\n\t"lib": ["ESNext"]\n}'
|
|
1462
|
+
* ```
|
|
1463
|
+
*/
|
|
1464
|
+
function renderObject(entry, indent) {
|
|
1465
|
+
const keys = Object.keys(entry);
|
|
1466
|
+
if (keys.length === 0) return "{}";
|
|
1467
|
+
const childIndent = `${indent}\t`;
|
|
1468
|
+
return `{\n${keys.map((key, index) => {
|
|
1469
|
+
const prefix = `${childIndent}${JSON.stringify(key)}: `;
|
|
1470
|
+
const suffix = index === keys.length - 1 ? "" : ",";
|
|
1471
|
+
return `${prefix}${renderValue(entry[key], childIndent, prefix, suffix)}${suffix}`;
|
|
1472
|
+
}).join("\n")}\n${indent}}`;
|
|
1473
|
+
}
|
|
1474
|
+
/**
|
|
1475
|
+
* Render one JSON value through `formatJson`'s dispatch — arrays via
|
|
1476
|
+
* `renderArray`, objects via `renderObject`, everything else via
|
|
1477
|
+
* `JSON.stringify`.
|
|
1478
|
+
*
|
|
1479
|
+
* @param entry - The value to render.
|
|
1480
|
+
* @param indent - The current indentation prefix.
|
|
1481
|
+
* @param prefix - The text already emitted on this line before `entry`.
|
|
1482
|
+
* @param suffix - The text that will follow `entry` on this line.
|
|
1483
|
+
* @returns The rendered fragment (no trailing newline).
|
|
1484
|
+
*
|
|
1485
|
+
* @example
|
|
1486
|
+
* ```ts
|
|
1487
|
+
* import { renderValue } from '@orkestrel/scaffold'
|
|
1488
|
+
*
|
|
1489
|
+
* renderValue('ESNext', '', '', '') // '"ESNext"'
|
|
1490
|
+
* ```
|
|
1491
|
+
*/
|
|
1492
|
+
function renderValue(entry, indent, prefix, suffix) {
|
|
1493
|
+
if (Array.isArray(entry)) return renderArray(entry, indent, prefix, suffix);
|
|
1494
|
+
if (isRecord(entry)) return renderObject(entry, indent);
|
|
1495
|
+
return JSON.stringify(entry);
|
|
1496
|
+
}
|
|
1497
|
+
/**
|
|
1498
|
+
* Serialize a value to newline-terminated JSON that matches the fleet's own
|
|
1499
|
+
* `oxfmt` output byte-for-byte — objects one key per line, arrays collapsed
|
|
1500
|
+
* onto one line when they fit `JSON_PRINT_WIDTH`, one item per line
|
|
1501
|
+
* otherwise.
|
|
1502
|
+
*
|
|
1503
|
+
* @param value - The value to serialize (config JSON — objects/arrays/primitives).
|
|
1504
|
+
* @remarks
|
|
1505
|
+
* `JSON.stringify(value, undefined, '\t')` always breaks arrays one item per
|
|
1506
|
+
* line; `oxfmt` collapses short ones. Emitting through `formatJson` keeps
|
|
1507
|
+
* computed config JSON format-stable by construction — `oxfmt --check` never
|
|
1508
|
+
* has anything left to rewrite. The rendering itself is delegated to
|
|
1509
|
+
* `renderValue` / `renderArray` / `renderObject` / `computeColumnWidth`, so
|
|
1510
|
+
* `formatJson` is a thin orchestrator around them.
|
|
1511
|
+
* @returns The rendered value, newline-terminated.
|
|
1512
|
+
*
|
|
1513
|
+
* @example
|
|
1514
|
+
* ```ts
|
|
1515
|
+
* import { formatJson } from '@orkestrel/scaffold'
|
|
1516
|
+
*
|
|
1517
|
+
* formatJson({ lib: ['ESNext', 'DOM'] }) // '{\n\t"lib": ["ESNext", "DOM"]\n}\n'
|
|
1518
|
+
* ```
|
|
1519
|
+
*/
|
|
1520
|
+
function formatJson(value) {
|
|
1521
|
+
return `${renderValue(value, "", "", "")}\n`;
|
|
1522
|
+
}
|
|
1523
|
+
/**
|
|
1382
1524
|
* Return a fresh `Plan` with `trace` and `hash` filled.
|
|
1383
1525
|
*
|
|
1384
1526
|
* @param plan - The plan to pin.
|
|
@@ -2251,6 +2393,8 @@ function packageManifest(spec) {
|
|
|
2251
2393
|
for (const peer of [...spec.peers].sort((a, b) => compareCodeUnit(a.name, b.name))) peerDependencies[peer.name] = peer.range;
|
|
2252
2394
|
const peerDependenciesMeta = {};
|
|
2253
2395
|
for (const peer of spec.peers) if (peer.optional === true) peerDependenciesMeta[peer.name] = { optional: true };
|
|
2396
|
+
const peerDevDependencies = {};
|
|
2397
|
+
for (const peer of [...spec.peers].sort((a, b) => compareCodeUnit(a.name, b.name))) peerDevDependencies[peer.name] = peer.range;
|
|
2254
2398
|
const scripts = {
|
|
2255
2399
|
clean: "node -e \"try{require('node:fs').rmSync('dist',{recursive:true,force:true})}catch{}\"",
|
|
2256
2400
|
copy: "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
@@ -2294,7 +2438,10 @@ function packageManifest(spec) {
|
|
|
2294
2438
|
publishConfig: { access: "public" },
|
|
2295
2439
|
scripts,
|
|
2296
2440
|
dependencies,
|
|
2297
|
-
devDependencies:
|
|
2441
|
+
devDependencies: Object.fromEntries(Object.entries({
|
|
2442
|
+
...devDependenciesFor(spec.extras),
|
|
2443
|
+
...peerDevDependencies
|
|
2444
|
+
}).sort(([a], [b]) => compareCodeUnit(a, b))),
|
|
2298
2445
|
...Object.keys(peerDependencies).length > 0 ? { peerDependencies } : {},
|
|
2299
2446
|
...Object.keys(peerDependenciesMeta).length > 0 ? { peerDependenciesMeta } : {},
|
|
2300
2447
|
engines: { node: spec.engines }
|
|
@@ -2316,7 +2463,7 @@ function packageManifest(spec) {
|
|
|
2316
2463
|
function rootTsconfig(surfaces) {
|
|
2317
2464
|
const paths = {};
|
|
2318
2465
|
for (const surface of surfaces) paths[`@src/${surface}`] = [`./src/${surface}/index.ts`];
|
|
2319
|
-
return
|
|
2466
|
+
return formatJson({
|
|
2320
2467
|
compilerOptions: {
|
|
2321
2468
|
target: "ESNext",
|
|
2322
2469
|
module: "ESNext",
|
|
@@ -2346,7 +2493,7 @@ function rootTsconfig(surfaces) {
|
|
|
2346
2493
|
"dist",
|
|
2347
2494
|
"tmp"
|
|
2348
2495
|
]
|
|
2349
|
-
}
|
|
2496
|
+
});
|
|
2350
2497
|
}
|
|
2351
2498
|
/**
|
|
2352
2499
|
* The rendered import / `resolve` header block every `rootViteConfig` shape
|
|
@@ -2701,7 +2848,7 @@ export default defineConfig({
|
|
|
2701
2848
|
* ```
|
|
2702
2849
|
*/
|
|
2703
2850
|
function coreTsconfig() {
|
|
2704
|
-
return
|
|
2851
|
+
return formatJson({
|
|
2705
2852
|
extends: "../../tsconfig.json",
|
|
2706
2853
|
compilerOptions: {
|
|
2707
2854
|
lib: ["ESNext"],
|
|
@@ -2712,7 +2859,7 @@ function coreTsconfig() {
|
|
|
2712
2859
|
outDir: "../../dist/src/core"
|
|
2713
2860
|
},
|
|
2714
2861
|
include: ["../../src/core/**/*.ts"]
|
|
2715
|
-
}
|
|
2862
|
+
});
|
|
2716
2863
|
}
|
|
2717
2864
|
/**
|
|
2718
2865
|
* `configs/src/vite.core.config.ts` — inlines its own `build.lib` /
|
|
@@ -2767,7 +2914,7 @@ export default defineConfig(
|
|
|
2767
2914
|
* ```
|
|
2768
2915
|
*/
|
|
2769
2916
|
function surfaceTsconfig(surface) {
|
|
2770
|
-
|
|
2917
|
+
return formatJson({
|
|
2771
2918
|
extends: "../../tsconfig.json",
|
|
2772
2919
|
compilerOptions: {
|
|
2773
2920
|
lib: surface === "browser" ? [
|
|
@@ -2783,8 +2930,7 @@ function surfaceTsconfig(surface) {
|
|
|
2783
2930
|
outDir: "../../dist/src"
|
|
2784
2931
|
},
|
|
2785
2932
|
include: [`../../src/${surface}/**/*.ts`]
|
|
2786
|
-
};
|
|
2787
|
-
return `${JSON.stringify(config, void 0, " ")}\n`;
|
|
2933
|
+
});
|
|
2788
2934
|
}
|
|
2789
2935
|
/**
|
|
2790
2936
|
* `configs/src/vite.<browser|server>.config.ts` — a thin `dts`-only wrapper;
|
|
@@ -3631,6 +3777,6 @@ function createBlueprint(data) {
|
|
|
3631
3777
|
return candidate;
|
|
3632
3778
|
}
|
|
3633
3779
|
//#endregion
|
|
3634
|
-
export { CATEGORIES, COMPILER_ID, COMPILE_STAGES, Compiler, DEFAULT_ENGINES, DEFAULT_VERSION, DEPENDENCY_NAME_PATTERN, EXTRA_NAME_PATTERN, FRESHNESS, GROUPS, HOST_PATHS, NAME_PATTERN, ORIGINS, PlanManager, SCAFFOLD_RANGE, SURFACES, SURFACE_MATRIX, ScaffoldError, TEMPLATES, alignTable, applyOverrides, artifactShape, auditToReview, blueprint, blueprintShape, blueprintToMembers, blueprintToPlan, catalogNames, catalogToBlock, compareCodeUnit, computeHash, configArtifacts, coreTsconfig, coreViteConfig, createBlueprint, createCompiler, createPlanManager, delimiterCell, dependency, dependencyShape, devDependenciesFor, diffPlan, dualCondition, entryFields, exportsMap, fillArtifact, guideArtifacts, guideMemberTable, hostGroup, inferGroup, isArtifact, isBehind, isBlueprint, isDependency, isMember, isOverride, isPlan, isRecord, isScaffoldError, isSyncReport, manifestToDependencies, member, memberShape, override, overrideShape, packageManifest, padCell, paritySpecifiers, parseBlueprint, parsePlan, parseSyncReport, pascalCase, pinPlan, planShape, planToReview, planToSummary, rangeToFreshness, rootTsconfig, rootViteConfig, singleSurfaceViteConfig, sourceArtifacts, splitTableRow, stableStringify, surfaceTsconfig, surfaceVariant, surfaceViteConfig, syncReportShape, syncToReview, testArtifacts, validateBlueprint, validateDependencyArray, viteHeader };
|
|
3780
|
+
export { CATEGORIES, COMPILER_ID, COMPILE_STAGES, Compiler, DEFAULT_ENGINES, DEFAULT_VERSION, DEPENDENCY_NAME_PATTERN, EXTRA_NAME_PATTERN, FRESHNESS, GROUPS, HOST_PATHS, JSON_PRINT_WIDTH, JSON_TAB_WIDTH, NAME_PATTERN, ORIGINS, PlanManager, SCAFFOLD_RANGE, SURFACES, SURFACE_MATRIX, ScaffoldError, TEMPLATES, alignTable, applyOverrides, artifactShape, auditToReview, blueprint, blueprintShape, blueprintToMembers, blueprintToPlan, catalogNames, catalogToBlock, compareCodeUnit, computeColumnWidth, computeHash, configArtifacts, coreTsconfig, coreViteConfig, createBlueprint, createCompiler, createPlanManager, delimiterCell, dependency, dependencyShape, devDependenciesFor, diffPlan, dualCondition, entryFields, exportsMap, fillArtifact, formatJson, guideArtifacts, guideMemberTable, hostGroup, inferGroup, isArtifact, isBehind, isBlueprint, isDependency, isMember, isOverride, isPlan, isRecord, isScaffoldError, isSyncReport, manifestToDependencies, member, memberShape, override, overrideShape, packageManifest, padCell, paritySpecifiers, parseBlueprint, parsePlan, parseSyncReport, pascalCase, pinPlan, planShape, planToReview, planToSummary, rangeToFreshness, renderArray, renderObject, renderValue, rootTsconfig, rootViteConfig, singleSurfaceViteConfig, sourceArtifacts, splitTableRow, stableStringify, surfaceTsconfig, surfaceVariant, surfaceViteConfig, syncReportShape, syncToReview, testArtifacts, validateBlueprint, validateDependencyArray, viteHeader };
|
|
3635
3781
|
|
|
3636
3782
|
//# sourceMappingURL=index.js.map
|