@orkestrel/scaffold 0.0.55 → 0.0.56
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 +21 -6
- package/dist/bin/main.js +2 -2
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/orchestration.md +6 -3
- package/dist/host/agents/skills/orkestrel-publish/references/wave.md +28 -2
- package/dist/host/claude/agents/orkestrel.md +6 -2
- package/dist/host/claude/rules/quality.md +1 -0
- package/dist/host/guides/scaffold.md +187 -68
- package/dist/host/manifest.json +7 -7
- 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/policy.test.ts +71 -4
- package/dist/src/core/index.cjs +196 -40
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +113 -12
- package/dist/src/core/index.d.ts +113 -12
- package/dist/src/core/index.js +195 -41
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +140 -12
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +108 -9
- package/dist/src/server/index.d.ts +108 -9
- package/dist/src/server/index.js +141 -15
- package/dist/src/server/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { Dependency } from '@orkestrel/scaffold';
|
|
|
4
4
|
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
5
5
|
import { EmitterHooks } from '@orkestrel/emitter';
|
|
6
6
|
import { EmitterInterface } from '@orkestrel/emitter';
|
|
7
|
+
import { Group } from '@orkestrel/scaffold';
|
|
7
8
|
import { Guard } from '@orkestrel/contract';
|
|
8
9
|
import { HostFile } from '@orkestrel/scaffold';
|
|
9
10
|
import { ManifestRegionSet } from '@orkestrel/scaffold';
|
|
@@ -130,8 +131,11 @@ export declare const DRIVE_PATTERN: RegExp;
|
|
|
130
131
|
* went missing, names an undeclared path, or leaves a host-owned path absent
|
|
131
132
|
* answers `undefined`. Deferred paths are presence-only and retain the installed
|
|
132
133
|
* floor bytes that their catalog or mirror surface owns; repair never writes
|
|
133
|
-
* those floor bytes.
|
|
134
|
-
*
|
|
134
|
+
* those floor bytes. A canon path is read the same way for a different reason:
|
|
135
|
+
* the canon is staged for reading rather than for a target, so every canon
|
|
136
|
+
* destination keeps its floor bytes here, claimed or not, and a fill that carries
|
|
137
|
+
* no row for one is complete rather than spoiled. One `Host` can therefore carry
|
|
138
|
+
* live host bytes beside floor bytes without mixing baselines within a surface.
|
|
135
139
|
*
|
|
136
140
|
* The emitted entries keep the release's own order and its storage and
|
|
137
141
|
* executable declarations, and carry digests recomputed over the bytes the fill
|
|
@@ -143,8 +147,12 @@ export declare const DRIVE_PATTERN: RegExp;
|
|
|
143
147
|
* ```ts
|
|
144
148
|
* import { filesToHost } from '@orkestrel/scaffold/server'
|
|
145
149
|
*
|
|
146
|
-
*
|
|
147
|
-
* //
|
|
150
|
+
* // A floor declaring the host-owned `scripts/codex.sh` path and the canon
|
|
151
|
+
* // `AGENTS.md` destination. The script's live bytes are taken; the canon
|
|
152
|
+
* // destination keeps the floor's.
|
|
153
|
+
* filesToHost([{ path: 'scripts/codex.sh', lookup: 'found', hex: '23212f62696e2f73680a' }], floor)
|
|
154
|
+
* // { manifest: { entries: [ … ], roots: [ … ], digest: '…' },
|
|
155
|
+
* // bytes: { 'scripts/codex.sh': '23212f62696e2f73680a', 'AGENTS.md': floor.bytes['AGENTS.md'] } }
|
|
148
156
|
* ```
|
|
149
157
|
*/
|
|
150
158
|
export declare function filesToHost(files: readonly HostFile[], floor: Host): Host | undefined;
|
|
@@ -624,6 +632,39 @@ export declare function isVacant(target: string): boolean;
|
|
|
624
632
|
*/
|
|
625
633
|
export declare const isWorktree: Guard<Worktree>;
|
|
626
634
|
|
|
635
|
+
/**
|
|
636
|
+
* Lists the canon paths a target holds, filtered to a plan's groups.
|
|
637
|
+
*
|
|
638
|
+
* @param target - The target directory to inspect.
|
|
639
|
+
* @param groups - The artifact groups the plan covers; a held path whose group
|
|
640
|
+
* is outside them is not listed.
|
|
641
|
+
* @returns Every held canon path as a `/`-separated target-relative path, a
|
|
642
|
+
* directory member expanded to the files beneath it, and `[]` when the target
|
|
643
|
+
* holds none or cannot be resolved.
|
|
644
|
+
* @throws `ScaffoldError('TARGET', …)` when a held canon directory cannot be
|
|
645
|
+
* inventoried; {@link listFiles} states each refusal.
|
|
646
|
+
*
|
|
647
|
+
* @remarks
|
|
648
|
+
* A release stages the canon for reading rather than for a target, so a copy
|
|
649
|
+
* sitting in one is an artifact of a release that vendored it, and reading it
|
|
650
|
+
* here is what lets the deletion verb take it.
|
|
651
|
+
*
|
|
652
|
+
* A directory member is read by file, which is what pairs the paths a plan
|
|
653
|
+
* claims inside the canon with their artifacts and leaves only the rest foreign,
|
|
654
|
+
* with no case for a planned file. The plan's own selection gates the reading,
|
|
655
|
+
* the same rule that decides a vendored path's group, so a scoped audit reports
|
|
656
|
+
* nothing outside its groups. A member that cannot resolve inside the target is
|
|
657
|
+
* not held by it.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```ts
|
|
661
|
+
* import { listCanonPaths } from '@orkestrel/scaffold/server'
|
|
662
|
+
*
|
|
663
|
+
* listCanonPaths('vacant', ['orchestration']) // []
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
export declare function listCanonPaths(target: string, groups: readonly Group[]): readonly string[];
|
|
667
|
+
|
|
627
668
|
/**
|
|
628
669
|
* List a directory's descendant directories as sorted root-relative paths.
|
|
629
670
|
*
|
|
@@ -988,7 +1029,8 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
988
1029
|
*
|
|
989
1030
|
* @param plan - The compiled plan to compare.
|
|
990
1031
|
* @param target - The directory to inspect.
|
|
991
|
-
* @returns One finding per hydrated planned path, plus foreign files
|
|
1032
|
+
* @returns One finding per hydrated planned path, plus the foreign files
|
|
1033
|
+
* beneath owned host roots and inside the instruction canon.
|
|
992
1034
|
* @throws {@link ScaffoldError} coded `INVALID` when an argument is not the
|
|
993
1035
|
* exact shape, `TARGET` when the host or target cannot be read within its
|
|
994
1036
|
* bounds, and `DESTROYED` after teardown.
|
|
@@ -996,8 +1038,16 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
996
1038
|
* @remarks
|
|
997
1039
|
* Host directories expand before the target is read, so this method and
|
|
998
1040
|
* {@link repair} compare the same paths with the same ownership. Foreign
|
|
999
|
-
* candidates are files beneath those expanded roots
|
|
1000
|
-
*
|
|
1041
|
+
* candidates are files beneath those expanded roots and files the target holds
|
|
1042
|
+
* at a `CANON_PATHS` member, each in a group the plan selects; a file outside
|
|
1043
|
+
* both populations never becomes a deletion candidate merely because its group
|
|
1044
|
+
* is selected.
|
|
1045
|
+
*
|
|
1046
|
+
* The canon is staged for reading rather than for a target, so a copy of one of
|
|
1047
|
+
* its paths sitting in a target is a superseded artifact and reports foreign. A
|
|
1048
|
+
* path the plan claims inside the canon — the root instruction pointers and the
|
|
1049
|
+
* catalog agent file — pairs with its artifact and is compared like any other
|
|
1050
|
+
* planned path.
|
|
1001
1051
|
*/
|
|
1002
1052
|
audit(plan: Plan, target: string): Audit;
|
|
1003
1053
|
/**
|
|
@@ -1124,9 +1174,20 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1124
1174
|
* recovery mechanism, so a path it cannot restore is not one this verb takes.
|
|
1125
1175
|
* A tree carrying uncommitted work is refused whole for the same reason.
|
|
1126
1176
|
*
|
|
1177
|
+
* One candidate list carries both foreign populations {@link audit} reports, so
|
|
1178
|
+
* a superseded instruction copy the target holds inside the canon is deleted in
|
|
1179
|
+
* the same transaction as a stray beneath an owned root. Membership decides it,
|
|
1180
|
+
* never byte identity: a copy a release behind no longer matches the bytes the
|
|
1181
|
+
* canon now stages, and matching bytes is exactly how such a copy would be
|
|
1182
|
+
* spared. An untracked leftover is left where it sits and stays a finding, which
|
|
1183
|
+
* is the seam a maintainer keeps a git-ignored file in.
|
|
1184
|
+
*
|
|
1127
1185
|
* The whole call refuses when the preview disagrees with the re-derivation on
|
|
1128
1186
|
* any foreign finding, including one the deletion itself would skip, because a
|
|
1129
1187
|
* preview stale anywhere is stale evidence.
|
|
1188
|
+
*
|
|
1189
|
+
* Every directory the deletions emptied is taken after the commit, so a swept
|
|
1190
|
+
* target does not keep the shape of the set it no longer holds.
|
|
1130
1191
|
*/
|
|
1131
1192
|
remove(plan: Plan, audit: Audit, worktree: Worktree, target: string): MaterializeResult;
|
|
1132
1193
|
/**
|
|
@@ -1384,6 +1445,38 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1384
1445
|
*/
|
|
1385
1446
|
export declare function pathToStorage(path: string): string;
|
|
1386
1447
|
|
|
1448
|
+
/**
|
|
1449
|
+
* Removes every directory one set of deletions emptied.
|
|
1450
|
+
*
|
|
1451
|
+
* @param target - The directory the deleted paths are relative to.
|
|
1452
|
+
* @param removed - The `/`-separated target-relative paths the deletion took.
|
|
1453
|
+
* @returns Every removed directory as a target-relative path, in the order they
|
|
1454
|
+
* were taken, and `[]` when the target is absent or nothing it holds was
|
|
1455
|
+
* emptied.
|
|
1456
|
+
*
|
|
1457
|
+
* @remarks
|
|
1458
|
+
* A deletion that takes the last file out of a directory leaves the directory
|
|
1459
|
+
* standing, and git records no directory, so a swept target keeps the shape of a
|
|
1460
|
+
* set it no longer holds while every reading of it reports clean. Only an
|
|
1461
|
+
* ancestor of a path this deletion took is a candidate, so nothing the deletion
|
|
1462
|
+
* did not reach is inspected, and the target itself is never a candidate.
|
|
1463
|
+
*
|
|
1464
|
+
* Candidates are taken deepest first, which is what lets a whole chain go: the
|
|
1465
|
+
* directory holding nothing but the emptied directory is empty in turn by the
|
|
1466
|
+
* time it is read. Each one is resolved through the containment law and left
|
|
1467
|
+
* standing when it escapes the target, is not a physical directory, still holds
|
|
1468
|
+
* an entry, or refuses removal, and a directory left standing is absent from the
|
|
1469
|
+
* answer.
|
|
1470
|
+
*
|
|
1471
|
+
* @example
|
|
1472
|
+
* ```ts
|
|
1473
|
+
* import { pruneEmptiedDirectories } from '@orkestrel/scaffold/server'
|
|
1474
|
+
*
|
|
1475
|
+
* pruneEmptiedDirectories('vacant', ['notes/entry.md']) // []
|
|
1476
|
+
* ```
|
|
1477
|
+
*/
|
|
1478
|
+
export declare function pruneEmptiedDirectories(target: string, removed: readonly string[]): readonly string[];
|
|
1479
|
+
|
|
1387
1480
|
/**
|
|
1388
1481
|
* Capture one directory's physical identity.
|
|
1389
1482
|
*
|
|
@@ -1779,9 +1872,15 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1779
1872
|
* once. A directory is the same case — declaring an absent directory as an empty
|
|
1780
1873
|
* root would create an empty directory in every generated workspace.
|
|
1781
1874
|
*
|
|
1782
|
-
* The
|
|
1875
|
+
* The walk covers `HOST_PATHS` and `CANON_PATHS` together, because a release
|
|
1876
|
+
* ships both: a target receives the first set, and reads the second one out of
|
|
1877
|
+
* the installed package. Everything downstream — the missing-path refusal, the
|
|
1878
|
+
* storage collision guard, the sort, the digests, and the root inventory — reads
|
|
1879
|
+
* the union, so a canon path is staged under exactly the law a vendored one is.
|
|
1880
|
+
*
|
|
1881
|
+
* The vendoring deny-list applies to what the walk discovers beneath a staged
|
|
1783
1882
|
* directory, where a maintainer's local credential can legitimately sit, and
|
|
1784
|
-
* such a path is skipped. A path
|
|
1883
|
+
* such a path is skipped. A path either list names itself is curated data
|
|
1785
1884
|
* rather than discovery, so it is staged or the stage is refused.
|
|
1786
1885
|
*
|
|
1787
1886
|
* @example
|
|
@@ -4,6 +4,7 @@ import { Dependency } from '@orkestrel/scaffold';
|
|
|
4
4
|
import { EmitterErrorHandler } from '@orkestrel/emitter';
|
|
5
5
|
import { EmitterHooks } from '@orkestrel/emitter';
|
|
6
6
|
import { EmitterInterface } from '@orkestrel/emitter';
|
|
7
|
+
import { Group } from '@orkestrel/scaffold';
|
|
7
8
|
import { Guard } from '@orkestrel/contract';
|
|
8
9
|
import { HostFile } from '@orkestrel/scaffold';
|
|
9
10
|
import { ManifestRegionSet } from '@orkestrel/scaffold';
|
|
@@ -130,8 +131,11 @@ export declare const DRIVE_PATTERN: RegExp;
|
|
|
130
131
|
* went missing, names an undeclared path, or leaves a host-owned path absent
|
|
131
132
|
* answers `undefined`. Deferred paths are presence-only and retain the installed
|
|
132
133
|
* floor bytes that their catalog or mirror surface owns; repair never writes
|
|
133
|
-
* those floor bytes.
|
|
134
|
-
*
|
|
134
|
+
* those floor bytes. A canon path is read the same way for a different reason:
|
|
135
|
+
* the canon is staged for reading rather than for a target, so every canon
|
|
136
|
+
* destination keeps its floor bytes here, claimed or not, and a fill that carries
|
|
137
|
+
* no row for one is complete rather than spoiled. One `Host` can therefore carry
|
|
138
|
+
* live host bytes beside floor bytes without mixing baselines within a surface.
|
|
135
139
|
*
|
|
136
140
|
* The emitted entries keep the release's own order and its storage and
|
|
137
141
|
* executable declarations, and carry digests recomputed over the bytes the fill
|
|
@@ -143,8 +147,12 @@ export declare const DRIVE_PATTERN: RegExp;
|
|
|
143
147
|
* ```ts
|
|
144
148
|
* import { filesToHost } from '@orkestrel/scaffold/server'
|
|
145
149
|
*
|
|
146
|
-
*
|
|
147
|
-
* //
|
|
150
|
+
* // A floor declaring the host-owned `scripts/codex.sh` path and the canon
|
|
151
|
+
* // `AGENTS.md` destination. The script's live bytes are taken; the canon
|
|
152
|
+
* // destination keeps the floor's.
|
|
153
|
+
* filesToHost([{ path: 'scripts/codex.sh', lookup: 'found', hex: '23212f62696e2f73680a' }], floor)
|
|
154
|
+
* // { manifest: { entries: [ … ], roots: [ … ], digest: '…' },
|
|
155
|
+
* // bytes: { 'scripts/codex.sh': '23212f62696e2f73680a', 'AGENTS.md': floor.bytes['AGENTS.md'] } }
|
|
148
156
|
* ```
|
|
149
157
|
*/
|
|
150
158
|
export declare function filesToHost(files: readonly HostFile[], floor: Host): Host | undefined;
|
|
@@ -624,6 +632,39 @@ export declare function isVacant(target: string): boolean;
|
|
|
624
632
|
*/
|
|
625
633
|
export declare const isWorktree: Guard<Worktree>;
|
|
626
634
|
|
|
635
|
+
/**
|
|
636
|
+
* Lists the canon paths a target holds, filtered to a plan's groups.
|
|
637
|
+
*
|
|
638
|
+
* @param target - The target directory to inspect.
|
|
639
|
+
* @param groups - The artifact groups the plan covers; a held path whose group
|
|
640
|
+
* is outside them is not listed.
|
|
641
|
+
* @returns Every held canon path as a `/`-separated target-relative path, a
|
|
642
|
+
* directory member expanded to the files beneath it, and `[]` when the target
|
|
643
|
+
* holds none or cannot be resolved.
|
|
644
|
+
* @throws `ScaffoldError('TARGET', …)` when a held canon directory cannot be
|
|
645
|
+
* inventoried; {@link listFiles} states each refusal.
|
|
646
|
+
*
|
|
647
|
+
* @remarks
|
|
648
|
+
* A release stages the canon for reading rather than for a target, so a copy
|
|
649
|
+
* sitting in one is an artifact of a release that vendored it, and reading it
|
|
650
|
+
* here is what lets the deletion verb take it.
|
|
651
|
+
*
|
|
652
|
+
* A directory member is read by file, which is what pairs the paths a plan
|
|
653
|
+
* claims inside the canon with their artifacts and leaves only the rest foreign,
|
|
654
|
+
* with no case for a planned file. The plan's own selection gates the reading,
|
|
655
|
+
* the same rule that decides a vendored path's group, so a scoped audit reports
|
|
656
|
+
* nothing outside its groups. A member that cannot resolve inside the target is
|
|
657
|
+
* not held by it.
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```ts
|
|
661
|
+
* import { listCanonPaths } from '@orkestrel/scaffold/server'
|
|
662
|
+
*
|
|
663
|
+
* listCanonPaths('vacant', ['orchestration']) // []
|
|
664
|
+
* ```
|
|
665
|
+
*/
|
|
666
|
+
export declare function listCanonPaths(target: string, groups: readonly Group[]): readonly string[];
|
|
667
|
+
|
|
627
668
|
/**
|
|
628
669
|
* List a directory's descendant directories as sorted root-relative paths.
|
|
629
670
|
*
|
|
@@ -988,7 +1029,8 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
988
1029
|
*
|
|
989
1030
|
* @param plan - The compiled plan to compare.
|
|
990
1031
|
* @param target - The directory to inspect.
|
|
991
|
-
* @returns One finding per hydrated planned path, plus foreign files
|
|
1032
|
+
* @returns One finding per hydrated planned path, plus the foreign files
|
|
1033
|
+
* beneath owned host roots and inside the instruction canon.
|
|
992
1034
|
* @throws {@link ScaffoldError} coded `INVALID` when an argument is not the
|
|
993
1035
|
* exact shape, `TARGET` when the host or target cannot be read within its
|
|
994
1036
|
* bounds, and `DESTROYED` after teardown.
|
|
@@ -996,8 +1038,16 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
996
1038
|
* @remarks
|
|
997
1039
|
* Host directories expand before the target is read, so this method and
|
|
998
1040
|
* {@link repair} compare the same paths with the same ownership. Foreign
|
|
999
|
-
* candidates are files beneath those expanded roots
|
|
1000
|
-
*
|
|
1041
|
+
* candidates are files beneath those expanded roots and files the target holds
|
|
1042
|
+
* at a `CANON_PATHS` member, each in a group the plan selects; a file outside
|
|
1043
|
+
* both populations never becomes a deletion candidate merely because its group
|
|
1044
|
+
* is selected.
|
|
1045
|
+
*
|
|
1046
|
+
* The canon is staged for reading rather than for a target, so a copy of one of
|
|
1047
|
+
* its paths sitting in a target is a superseded artifact and reports foreign. A
|
|
1048
|
+
* path the plan claims inside the canon — the root instruction pointers and the
|
|
1049
|
+
* catalog agent file — pairs with its artifact and is compared like any other
|
|
1050
|
+
* planned path.
|
|
1001
1051
|
*/
|
|
1002
1052
|
audit(plan: Plan, target: string): Audit;
|
|
1003
1053
|
/**
|
|
@@ -1124,9 +1174,20 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1124
1174
|
* recovery mechanism, so a path it cannot restore is not one this verb takes.
|
|
1125
1175
|
* A tree carrying uncommitted work is refused whole for the same reason.
|
|
1126
1176
|
*
|
|
1177
|
+
* One candidate list carries both foreign populations {@link audit} reports, so
|
|
1178
|
+
* a superseded instruction copy the target holds inside the canon is deleted in
|
|
1179
|
+
* the same transaction as a stray beneath an owned root. Membership decides it,
|
|
1180
|
+
* never byte identity: a copy a release behind no longer matches the bytes the
|
|
1181
|
+
* canon now stages, and matching bytes is exactly how such a copy would be
|
|
1182
|
+
* spared. An untracked leftover is left where it sits and stays a finding, which
|
|
1183
|
+
* is the seam a maintainer keeps a git-ignored file in.
|
|
1184
|
+
*
|
|
1127
1185
|
* The whole call refuses when the preview disagrees with the re-derivation on
|
|
1128
1186
|
* any foreign finding, including one the deletion itself would skip, because a
|
|
1129
1187
|
* preview stale anywhere is stale evidence.
|
|
1188
|
+
*
|
|
1189
|
+
* Every directory the deletions emptied is taken after the commit, so a swept
|
|
1190
|
+
* target does not keep the shape of the set it no longer holds.
|
|
1130
1191
|
*/
|
|
1131
1192
|
remove(plan: Plan, audit: Audit, worktree: Worktree, target: string): MaterializeResult;
|
|
1132
1193
|
/**
|
|
@@ -1384,6 +1445,38 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1384
1445
|
*/
|
|
1385
1446
|
export declare function pathToStorage(path: string): string;
|
|
1386
1447
|
|
|
1448
|
+
/**
|
|
1449
|
+
* Removes every directory one set of deletions emptied.
|
|
1450
|
+
*
|
|
1451
|
+
* @param target - The directory the deleted paths are relative to.
|
|
1452
|
+
* @param removed - The `/`-separated target-relative paths the deletion took.
|
|
1453
|
+
* @returns Every removed directory as a target-relative path, in the order they
|
|
1454
|
+
* were taken, and `[]` when the target is absent or nothing it holds was
|
|
1455
|
+
* emptied.
|
|
1456
|
+
*
|
|
1457
|
+
* @remarks
|
|
1458
|
+
* A deletion that takes the last file out of a directory leaves the directory
|
|
1459
|
+
* standing, and git records no directory, so a swept target keeps the shape of a
|
|
1460
|
+
* set it no longer holds while every reading of it reports clean. Only an
|
|
1461
|
+
* ancestor of a path this deletion took is a candidate, so nothing the deletion
|
|
1462
|
+
* did not reach is inspected, and the target itself is never a candidate.
|
|
1463
|
+
*
|
|
1464
|
+
* Candidates are taken deepest first, which is what lets a whole chain go: the
|
|
1465
|
+
* directory holding nothing but the emptied directory is empty in turn by the
|
|
1466
|
+
* time it is read. Each one is resolved through the containment law and left
|
|
1467
|
+
* standing when it escapes the target, is not a physical directory, still holds
|
|
1468
|
+
* an entry, or refuses removal, and a directory left standing is absent from the
|
|
1469
|
+
* answer.
|
|
1470
|
+
*
|
|
1471
|
+
* @example
|
|
1472
|
+
* ```ts
|
|
1473
|
+
* import { pruneEmptiedDirectories } from '@orkestrel/scaffold/server'
|
|
1474
|
+
*
|
|
1475
|
+
* pruneEmptiedDirectories('vacant', ['notes/entry.md']) // []
|
|
1476
|
+
* ```
|
|
1477
|
+
*/
|
|
1478
|
+
export declare function pruneEmptiedDirectories(target: string, removed: readonly string[]): readonly string[];
|
|
1479
|
+
|
|
1387
1480
|
/**
|
|
1388
1481
|
* Capture one directory's physical identity.
|
|
1389
1482
|
*
|
|
@@ -1779,9 +1872,15 @@ export declare class Materializer implements MaterializerInterface {
|
|
|
1779
1872
|
* once. A directory is the same case — declaring an absent directory as an empty
|
|
1780
1873
|
* root would create an empty directory in every generated workspace.
|
|
1781
1874
|
*
|
|
1782
|
-
* The
|
|
1875
|
+
* The walk covers `HOST_PATHS` and `CANON_PATHS` together, because a release
|
|
1876
|
+
* ships both: a target receives the first set, and reads the second one out of
|
|
1877
|
+
* the installed package. Everything downstream — the missing-path refusal, the
|
|
1878
|
+
* storage collision guard, the sort, the digests, and the root inventory — reads
|
|
1879
|
+
* the union, so a canon path is staged under exactly the law a vendored one is.
|
|
1880
|
+
*
|
|
1881
|
+
* The vendoring deny-list applies to what the walk discovers beneath a staged
|
|
1783
1882
|
* directory, where a maintainer's local credential can legitimately sit, and
|
|
1784
|
-
* such a path is skipped. A path
|
|
1883
|
+
* such a path is skipped. A path either list names itself is curated data
|
|
1785
1884
|
* rather than discovery, so it is staged or the stage is refused.
|
|
1786
1885
|
*
|
|
1787
1886
|
* @example
|
package/dist/src/server/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { andOf, arrayOf, attempt, boundsOf, holds, isArray, isBoolean, isError, isFunction, isInteger, isRecord, isString, parseJSON, parseJSONAs, parseStringField, recordOf, stringOf, unionOf } from "@orkestrel/contract";
|
|
2
|
-
import { CATALOG_AGENT_PATH, CONTROL_CHARACTER_PATTERN, EXECUTABLE_PATHS, HOST_INVENTORY_PATH, HOST_PATHS, MAX_ARTIFACT_BYTES, MAX_COLLECTION_ITEMS, MAX_DEPENDENCY_NAME_LENGTH, MAX_MANIFEST_BYTES, MAX_PATH_LENGTH, MAX_RANGE_LENGTH, MAX_REGISTRY_BYTES, MAX_TOTAL_ARTIFACT_BYTES, MAX_TOTAL_REGISTRY_BYTES, ScaffoldError, WORKSPACE_OWNED_PATHS, bytesToHex, catalogToLayers, cloneValue, compareVersions, computeBytes, contentToHex, extractRangeMajor, extractVersion, inferGroup, isAudit, isCatalogEntry, isCollection, isDeferredPath, isDependency, isDependencyName, isHex, isManifestScript, isMirror, isPath, isPlan, isSnapshot, matchesDriftReachability, matchesRange, nameToGuide, planToFindings, replaceManifestRanges, replaceManifestScripts } from "../core/index.js";
|
|
1
|
+
import { andOf, arrayOf, attempt, boundsOf, compareValues, holds, isArray, isBoolean, isError, isFunction, isInteger, isRecord, isString, parseJSON, parseJSONAs, parseStringField, recordOf, stringOf, unionOf } from "@orkestrel/contract";
|
|
2
|
+
import { CANON_PATHS, CATALOG_AGENT_PATH, CONTROL_CHARACTER_PATTERN, EXECUTABLE_PATHS, HOST_INVENTORY_PATH, HOST_PATHS, MAX_ARTIFACT_BYTES, MAX_COLLECTION_ITEMS, MAX_DEPENDENCY_NAME_LENGTH, MAX_MANIFEST_BYTES, MAX_PATH_LENGTH, MAX_RANGE_LENGTH, MAX_REGISTRY_BYTES, MAX_TOTAL_ARTIFACT_BYTES, MAX_TOTAL_REGISTRY_BYTES, ScaffoldError, WORKSPACE_OWNED_PATHS, bytesToHex, catalogToLayers, cloneValue, compareVersions, computeBytes, contentToHex, extractRangeMajor, extractVersion, inferGroup, isAudit, isCanonPath, isCatalogEntry, isCollection, isDeferredPath, isDependency, isDependencyName, isHex, isManifestScript, isMirror, isPath, isPlan, isSnapshot, matchesDriftReachability, matchesRange, nameToGuide, planToFindings, replaceManifestRanges, replaceManifestScripts } from "../core/index.js";
|
|
3
3
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
4
|
import { chmodSync, closeSync, constants, copyFileSync, fstatSync, linkSync, lstatSync, mkdirSync, mkdtempSync, openSync, opendirSync, readSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, rmdirSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
@@ -1210,6 +1210,97 @@ function listDirectories(root) {
|
|
|
1210
1210
|
return directories.sort();
|
|
1211
1211
|
}
|
|
1212
1212
|
/**
|
|
1213
|
+
* Lists the canon paths a target holds, filtered to a plan's groups.
|
|
1214
|
+
*
|
|
1215
|
+
* @param target - The target directory to inspect.
|
|
1216
|
+
* @param groups - The artifact groups the plan covers; a held path whose group
|
|
1217
|
+
* is outside them is not listed.
|
|
1218
|
+
* @returns Every held canon path as a `/`-separated target-relative path, a
|
|
1219
|
+
* directory member expanded to the files beneath it, and `[]` when the target
|
|
1220
|
+
* holds none or cannot be resolved.
|
|
1221
|
+
* @throws `ScaffoldError('TARGET', …)` when a held canon directory cannot be
|
|
1222
|
+
* inventoried; {@link listFiles} states each refusal.
|
|
1223
|
+
*
|
|
1224
|
+
* @remarks
|
|
1225
|
+
* A release stages the canon for reading rather than for a target, so a copy
|
|
1226
|
+
* sitting in one is an artifact of a release that vendored it, and reading it
|
|
1227
|
+
* here is what lets the deletion verb take it.
|
|
1228
|
+
*
|
|
1229
|
+
* A directory member is read by file, which is what pairs the paths a plan
|
|
1230
|
+
* claims inside the canon with their artifacts and leaves only the rest foreign,
|
|
1231
|
+
* with no case for a planned file. The plan's own selection gates the reading,
|
|
1232
|
+
* the same rule that decides a vendored path's group, so a scoped audit reports
|
|
1233
|
+
* nothing outside its groups. A member that cannot resolve inside the target is
|
|
1234
|
+
* not held by it.
|
|
1235
|
+
*
|
|
1236
|
+
* @example
|
|
1237
|
+
* ```ts
|
|
1238
|
+
* import { listCanonPaths } from '@orkestrel/scaffold/server'
|
|
1239
|
+
*
|
|
1240
|
+
* listCanonPaths('vacant', ['orchestration']) // []
|
|
1241
|
+
* ```
|
|
1242
|
+
*/
|
|
1243
|
+
function listCanonPaths(target, groups) {
|
|
1244
|
+
const held = [];
|
|
1245
|
+
for (const member of CANON_PATHS) {
|
|
1246
|
+
const full = resolveContainedPath(target, member);
|
|
1247
|
+
if (full === void 0) continue;
|
|
1248
|
+
if (isPhysicalFile(full)) held.push(member);
|
|
1249
|
+
else if (isPhysicalDirectory(full)) for (const name of listFiles(full)) held.push(`${member}/${name}`);
|
|
1250
|
+
}
|
|
1251
|
+
return held.filter((path) => groups.includes(inferGroup(path)));
|
|
1252
|
+
}
|
|
1253
|
+
/**
|
|
1254
|
+
* Removes every directory one set of deletions emptied.
|
|
1255
|
+
*
|
|
1256
|
+
* @param target - The directory the deleted paths are relative to.
|
|
1257
|
+
* @param removed - The `/`-separated target-relative paths the deletion took.
|
|
1258
|
+
* @returns Every removed directory as a target-relative path, in the order they
|
|
1259
|
+
* were taken, and `[]` when the target is absent or nothing it holds was
|
|
1260
|
+
* emptied.
|
|
1261
|
+
*
|
|
1262
|
+
* @remarks
|
|
1263
|
+
* A deletion that takes the last file out of a directory leaves the directory
|
|
1264
|
+
* standing, and git records no directory, so a swept target keeps the shape of a
|
|
1265
|
+
* set it no longer holds while every reading of it reports clean. Only an
|
|
1266
|
+
* ancestor of a path this deletion took is a candidate, so nothing the deletion
|
|
1267
|
+
* did not reach is inspected, and the target itself is never a candidate.
|
|
1268
|
+
*
|
|
1269
|
+
* Candidates are taken deepest first, which is what lets a whole chain go: the
|
|
1270
|
+
* directory holding nothing but the emptied directory is empty in turn by the
|
|
1271
|
+
* time it is read. Each one is resolved through the containment law and left
|
|
1272
|
+
* standing when it escapes the target, is not a physical directory, still holds
|
|
1273
|
+
* an entry, or refuses removal, and a directory left standing is absent from the
|
|
1274
|
+
* answer.
|
|
1275
|
+
*
|
|
1276
|
+
* @example
|
|
1277
|
+
* ```ts
|
|
1278
|
+
* import { pruneEmptiedDirectories } from '@orkestrel/scaffold/server'
|
|
1279
|
+
*
|
|
1280
|
+
* pruneEmptiedDirectories('vacant', ['notes/entry.md']) // []
|
|
1281
|
+
* ```
|
|
1282
|
+
*/
|
|
1283
|
+
function pruneEmptiedDirectories(target, removed) {
|
|
1284
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
1285
|
+
for (const path of removed) {
|
|
1286
|
+
let parent = dirname(path);
|
|
1287
|
+
while (parent !== "." && parent !== dirname(parent) && !candidates.has(parent)) {
|
|
1288
|
+
candidates.add(parent);
|
|
1289
|
+
parent = dirname(parent);
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
const ordered = [...candidates].sort((left, right) => compareValues(right.split("/").length, left.split("/").length) || compareValues(left, right));
|
|
1293
|
+
const pruned = [];
|
|
1294
|
+
for (const candidate of ordered) {
|
|
1295
|
+
const directory = resolveContainedPath(target, candidate);
|
|
1296
|
+
if (directory === void 0 || !isPhysicalDirectory(directory)) continue;
|
|
1297
|
+
const entries = attempt(() => readdirSync(directory));
|
|
1298
|
+
if (!entries.success || entries.value.length > 0) continue;
|
|
1299
|
+
if (attempt(() => rmdirSync(directory)).success) pruned.push(candidate);
|
|
1300
|
+
}
|
|
1301
|
+
return pruned;
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1213
1304
|
* Read one contained file as its exact bytes in lowercase hexadecimal.
|
|
1214
1305
|
*
|
|
1215
1306
|
* @param root - The containing host directory.
|
|
@@ -1518,8 +1609,11 @@ function readManifestEntry(destination, source) {
|
|
|
1518
1609
|
* went missing, names an undeclared path, or leaves a host-owned path absent
|
|
1519
1610
|
* answers `undefined`. Deferred paths are presence-only and retain the installed
|
|
1520
1611
|
* floor bytes that their catalog or mirror surface owns; repair never writes
|
|
1521
|
-
* those floor bytes.
|
|
1522
|
-
*
|
|
1612
|
+
* those floor bytes. A canon path is read the same way for a different reason:
|
|
1613
|
+
* the canon is staged for reading rather than for a target, so every canon
|
|
1614
|
+
* destination keeps its floor bytes here, claimed or not, and a fill that carries
|
|
1615
|
+
* no row for one is complete rather than spoiled. One `Host` can therefore carry
|
|
1616
|
+
* live host bytes beside floor bytes without mixing baselines within a surface.
|
|
1523
1617
|
*
|
|
1524
1618
|
* The emitted entries keep the release's own order and its storage and
|
|
1525
1619
|
* executable declarations, and carry digests recomputed over the bytes the fill
|
|
@@ -1531,8 +1625,12 @@ function readManifestEntry(destination, source) {
|
|
|
1531
1625
|
* ```ts
|
|
1532
1626
|
* import { filesToHost } from '@orkestrel/scaffold/server'
|
|
1533
1627
|
*
|
|
1534
|
-
*
|
|
1535
|
-
* //
|
|
1628
|
+
* // A floor declaring the host-owned `scripts/codex.sh` path and the canon
|
|
1629
|
+
* // `AGENTS.md` destination. The script's live bytes are taken; the canon
|
|
1630
|
+
* // destination keeps the floor's.
|
|
1631
|
+
* filesToHost([{ path: 'scripts/codex.sh', lookup: 'found', hex: '23212f62696e2f73680a' }], floor)
|
|
1632
|
+
* // { manifest: { entries: [ … ], roots: [ … ], digest: '…' },
|
|
1633
|
+
* // bytes: { 'scripts/codex.sh': '23212f62696e2f73680a', 'AGENTS.md': floor.bytes['AGENTS.md'] } }
|
|
1536
1634
|
* ```
|
|
1537
1635
|
*/
|
|
1538
1636
|
function filesToHost(files, floor) {
|
|
@@ -1540,12 +1638,12 @@ function filesToHost(files, floor) {
|
|
|
1540
1638
|
const held = /* @__PURE__ */ new Map();
|
|
1541
1639
|
for (const file of files) {
|
|
1542
1640
|
if (file.lookup !== "found" || !declared.has(file.path)) return void 0;
|
|
1543
|
-
if (!isDeferredPath(file.path)) held.set(file.path, file.hex);
|
|
1641
|
+
if (!isDeferredPath(file.path) && !isCanonPath(file.path)) held.set(file.path, file.hex);
|
|
1544
1642
|
}
|
|
1545
1643
|
const entries = [];
|
|
1546
1644
|
const bytes = {};
|
|
1547
1645
|
for (const entry of floor.manifest.entries) {
|
|
1548
|
-
const hex = isDeferredPath(entry.destination) ? floor.bytes[entry.destination] : held.get(entry.destination);
|
|
1646
|
+
const hex = isDeferredPath(entry.destination) || isCanonPath(entry.destination) ? floor.bytes[entry.destination] : held.get(entry.destination);
|
|
1549
1647
|
if (hex === void 0) return void 0;
|
|
1550
1648
|
entries.push({
|
|
1551
1649
|
storage: entry.storage,
|
|
@@ -1676,9 +1774,15 @@ function stageBytes(host, root, destinations) {
|
|
|
1676
1774
|
* once. A directory is the same case — declaring an absent directory as an empty
|
|
1677
1775
|
* root would create an empty directory in every generated workspace.
|
|
1678
1776
|
*
|
|
1679
|
-
* The
|
|
1777
|
+
* The walk covers `HOST_PATHS` and `CANON_PATHS` together, because a release
|
|
1778
|
+
* ships both: a target receives the first set, and reads the second one out of
|
|
1779
|
+
* the installed package. Everything downstream — the missing-path refusal, the
|
|
1780
|
+
* storage collision guard, the sort, the digests, and the root inventory — reads
|
|
1781
|
+
* the union, so a canon path is staged under exactly the law a vendored one is.
|
|
1782
|
+
*
|
|
1783
|
+
* The vendoring deny-list applies to what the walk discovers beneath a staged
|
|
1680
1784
|
* directory, where a maintainer's local credential can legitimately sit, and
|
|
1681
|
-
* such a path is skipped. A path
|
|
1785
|
+
* such a path is skipped. A path either list names itself is curated data
|
|
1682
1786
|
* rather than discovery, so it is staged or the stage is refused.
|
|
1683
1787
|
*
|
|
1684
1788
|
* @example
|
|
@@ -1697,7 +1801,7 @@ function stageHost(checkout, host) {
|
|
|
1697
1801
|
const vendored = [];
|
|
1698
1802
|
const roots = [];
|
|
1699
1803
|
const missing = [];
|
|
1700
|
-
for (const path of HOST_PATHS) {
|
|
1804
|
+
for (const path of [...HOST_PATHS, ...CANON_PATHS]) {
|
|
1701
1805
|
const full = resolveContainedPath(source, path);
|
|
1702
1806
|
if (full === void 0) throw new ScaffoldError("INVALID", `Vendored path leaves its checkout at ${path}`, {
|
|
1703
1807
|
checkout: source,
|
|
@@ -2651,7 +2755,8 @@ var Materializer = class Materializer {
|
|
|
2651
2755
|
*
|
|
2652
2756
|
* @param plan - The compiled plan to compare.
|
|
2653
2757
|
* @param target - The directory to inspect.
|
|
2654
|
-
* @returns One finding per hydrated planned path, plus foreign files
|
|
2758
|
+
* @returns One finding per hydrated planned path, plus the foreign files
|
|
2759
|
+
* beneath owned host roots and inside the instruction canon.
|
|
2655
2760
|
* @throws {@link ScaffoldError} coded `INVALID` when an argument is not the
|
|
2656
2761
|
* exact shape, `TARGET` when the host or target cannot be read within its
|
|
2657
2762
|
* bounds, and `DESTROYED` after teardown.
|
|
@@ -2659,8 +2764,16 @@ var Materializer = class Materializer {
|
|
|
2659
2764
|
* @remarks
|
|
2660
2765
|
* Host directories expand before the target is read, so this method and
|
|
2661
2766
|
* {@link repair} compare the same paths with the same ownership. Foreign
|
|
2662
|
-
* candidates are files beneath those expanded roots
|
|
2663
|
-
*
|
|
2767
|
+
* candidates are files beneath those expanded roots and files the target holds
|
|
2768
|
+
* at a `CANON_PATHS` member, each in a group the plan selects; a file outside
|
|
2769
|
+
* both populations never becomes a deletion candidate merely because its group
|
|
2770
|
+
* is selected.
|
|
2771
|
+
*
|
|
2772
|
+
* The canon is staged for reading rather than for a target, so a copy of one of
|
|
2773
|
+
* its paths sitting in a target is a superseded artifact and reports foreign. A
|
|
2774
|
+
* path the plan claims inside the canon — the root instruction pointers and the
|
|
2775
|
+
* catalog agent file — pairs with its artifact and is compared like any other
|
|
2776
|
+
* planned path.
|
|
2664
2777
|
*/
|
|
2665
2778
|
audit(plan, target) {
|
|
2666
2779
|
this.#assertAlive();
|
|
@@ -2859,9 +2972,20 @@ var Materializer = class Materializer {
|
|
|
2859
2972
|
* recovery mechanism, so a path it cannot restore is not one this verb takes.
|
|
2860
2973
|
* A tree carrying uncommitted work is refused whole for the same reason.
|
|
2861
2974
|
*
|
|
2975
|
+
* One candidate list carries both foreign populations {@link audit} reports, so
|
|
2976
|
+
* a superseded instruction copy the target holds inside the canon is deleted in
|
|
2977
|
+
* the same transaction as a stray beneath an owned root. Membership decides it,
|
|
2978
|
+
* never byte identity: a copy a release behind no longer matches the bytes the
|
|
2979
|
+
* canon now stages, and matching bytes is exactly how such a copy would be
|
|
2980
|
+
* spared. An untracked leftover is left where it sits and stays a finding, which
|
|
2981
|
+
* is the seam a maintainer keeps a git-ignored file in.
|
|
2982
|
+
*
|
|
2862
2983
|
* The whole call refuses when the preview disagrees with the re-derivation on
|
|
2863
2984
|
* any foreign finding, including one the deletion itself would skip, because a
|
|
2864
2985
|
* preview stale anywhere is stale evidence.
|
|
2986
|
+
*
|
|
2987
|
+
* Every directory the deletions emptied is taken after the commit, so a swept
|
|
2988
|
+
* target does not keep the shape of the set it no longer holds.
|
|
2865
2989
|
*/
|
|
2866
2990
|
remove(plan, audit, worktree, target) {
|
|
2867
2991
|
this.#assertAlive();
|
|
@@ -2979,6 +3103,7 @@ var Materializer = class Materializer {
|
|
|
2979
3103
|
});
|
|
2980
3104
|
for (const name of listFiles(directory)) paths.add(`${root}/${name}`);
|
|
2981
3105
|
}
|
|
3106
|
+
for (const path of listCanonPaths(target, plan.groups)) paths.add(path);
|
|
2982
3107
|
return {
|
|
2983
3108
|
findings: planToFindings(hydrated, readSnapshot(target, [...paths])),
|
|
2984
3109
|
questions: []
|
|
@@ -3284,6 +3409,7 @@ var Materializer = class Materializer {
|
|
|
3284
3409
|
});
|
|
3285
3410
|
const removed = this.#close(transaction, staged, target);
|
|
3286
3411
|
for (const path of removed) this.#emitter.emit("remove", path);
|
|
3412
|
+
pruneEmptiedDirectories(target, removed);
|
|
3287
3413
|
return this.#finish({
|
|
3288
3414
|
target,
|
|
3289
3415
|
written: [],
|
|
@@ -4136,6 +4262,6 @@ var Upstream = class Upstream {
|
|
|
4136
4262
|
}
|
|
4137
4263
|
};
|
|
4138
4264
|
//#endregion
|
|
4139
|
-
export { BRANCH_PATTERN, DIGEST_PATTERN, DRIVE_PATTERN, INVALID_SEGMENT_CHARACTER_PATTERN, MANIFEST_NAME, MAX_BRANCH_LENGTH, MAX_ENDPOINT_LENGTH, MAX_INVENTORY_PATHS, MAX_PATH_DEPTH, MAX_PATH_SEGMENT_BYTES, MAX_UPSTREAM_CONCURRENCY, MAX_UPSTREAM_RETRIES, MAX_UPSTREAM_TIMEOUT, Materializer, RESERVED_SEGMENT_PATTERN, Upstream, WriteTransaction, computeDigest, computeFileDigest, computeManifestDigest, filesToHost, hexToDigest, isBranch, isCatalogEntries, isDependencies, isDependencyNames, isDigest, isEndpoint, isExactCaseFile, isFilesystemPath, isHost, isHostManifest, isInventory, isManifestEntry, isManifestRegionSet, isMaterializerHooks, isMaterializerOptions, isMirrors, isPaths, isPhysicalDirectory, isPhysicalFile, isTimeout, isUpstreamHooks, isUpstreamOptions, isVacant, isWorktree, listDirectories, listFiles, matchesAnchor, matchesExecutablePath, matchesExpectation, matchesGitPath, matchesMissingPath, matchesPrecondition, matchesProtectedPath, matchesSensitivePath, pathToStorage, readAnchor, readExpectation, readFileHex, readFileText, readHostFloor, readHostManifest, readManifestEntry, readSnapshot, resolveContainedPath, resolveRealPath, stageBytes, stageHost, stageInventory };
|
|
4265
|
+
export { BRANCH_PATTERN, DIGEST_PATTERN, DRIVE_PATTERN, INVALID_SEGMENT_CHARACTER_PATTERN, MANIFEST_NAME, MAX_BRANCH_LENGTH, MAX_ENDPOINT_LENGTH, MAX_INVENTORY_PATHS, MAX_PATH_DEPTH, MAX_PATH_SEGMENT_BYTES, MAX_UPSTREAM_CONCURRENCY, MAX_UPSTREAM_RETRIES, MAX_UPSTREAM_TIMEOUT, Materializer, RESERVED_SEGMENT_PATTERN, Upstream, WriteTransaction, computeDigest, computeFileDigest, computeManifestDigest, filesToHost, hexToDigest, isBranch, isCatalogEntries, isDependencies, isDependencyNames, isDigest, isEndpoint, isExactCaseFile, isFilesystemPath, isHost, isHostManifest, isInventory, isManifestEntry, isManifestRegionSet, isMaterializerHooks, isMaterializerOptions, isMirrors, isPaths, isPhysicalDirectory, isPhysicalFile, isTimeout, isUpstreamHooks, isUpstreamOptions, isVacant, isWorktree, listCanonPaths, listDirectories, listFiles, matchesAnchor, matchesExecutablePath, matchesExpectation, matchesGitPath, matchesMissingPath, matchesPrecondition, matchesProtectedPath, matchesSensitivePath, pathToStorage, pruneEmptiedDirectories, readAnchor, readExpectation, readFileHex, readFileText, readHostFloor, readHostManifest, readManifestEntry, readSnapshot, resolveContainedPath, resolveRealPath, stageBytes, stageHost, stageInventory };
|
|
4140
4266
|
|
|
4141
4267
|
//# sourceMappingURL=index.js.map
|