@sublang/slc 0.1.0 → 0.3.0

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.
Files changed (54) hide show
  1. package/README.md +126 -94
  2. package/dist/app.d.ts +13 -2
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +60 -11
  5. package/dist/app.js.map +1 -1
  6. package/dist/cligent-agent.d.ts +19 -0
  7. package/dist/cligent-agent.d.ts.map +1 -1
  8. package/dist/cligent-agent.js +125 -30
  9. package/dist/cligent-agent.js.map +1 -1
  10. package/dist/compiled-executor.d.ts +6 -0
  11. package/dist/compiled-executor.d.ts.map +1 -1
  12. package/dist/compiled-executor.js +1 -0
  13. package/dist/compiled-executor.js.map +1 -1
  14. package/dist/config-file.d.ts +9 -0
  15. package/dist/config-file.d.ts.map +1 -1
  16. package/dist/config-file.js +28 -2
  17. package/dist/config-file.js.map +1 -1
  18. package/dist/config.d.ts +8 -0
  19. package/dist/config.d.ts.map +1 -1
  20. package/dist/config.js +12 -2
  21. package/dist/config.js.map +1 -1
  22. package/dist/emitted-imports.d.ts +6 -0
  23. package/dist/emitted-imports.d.ts.map +1 -0
  24. package/dist/emitted-imports.js +36 -0
  25. package/dist/emitted-imports.js.map +1 -0
  26. package/dist/entry-module.d.ts.map +1 -1
  27. package/dist/entry-module.js +3 -1
  28. package/dist/entry-module.js.map +1 -1
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/playbook-ports.d.ts +8 -0
  34. package/dist/playbook-ports.d.ts.map +1 -1
  35. package/dist/playbook-ports.js +14 -2
  36. package/dist/playbook-ports.js.map +1 -1
  37. package/dist/progress.d.ts +71 -0
  38. package/dist/progress.d.ts.map +1 -0
  39. package/dist/progress.js +96 -0
  40. package/dist/progress.js.map +1 -0
  41. package/dist/runner.d.ts +6 -0
  42. package/dist/runner.d.ts.map +1 -1
  43. package/dist/runner.js +71 -1
  44. package/dist/runner.js.map +1 -1
  45. package/dist/slc.config.template.yaml +5 -1
  46. package/package.json +8 -5
  47. package/dist/file-capability.d.ts +0 -46
  48. package/dist/file-capability.d.ts.map +0 -1
  49. package/dist/file-capability.js +0 -234
  50. package/dist/file-capability.js.map +0 -1
  51. package/dist/file-grants.d.ts +0 -79
  52. package/dist/file-grants.d.ts.map +0 -1
  53. package/dist/file-grants.js +0 -133
  54. package/dist/file-grants.js.map +0 -1
@@ -1,234 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
- /**
4
- * Host-supplied file capability for compiled phase artifacts (FCAP-1..6; DR-008).
5
- *
6
- * A {@link FileCapability} gives a compiled artifact deterministic, confined
7
- * whole-file access through three operations — `read`, `list`, and `write` — over
8
- * virtual POSIX paths inside a per-run root. A leading `/` names the run root, not
9
- * an operating-system absolute path; paths are normalized (repeated separators
10
- * collapsed, `.` removed, `..` resolved) and confined to the root after resolving
11
- * symlinks, so a path that escapes the root or uses platform-absolute syntax (for
12
- * example a Windows drive path) is rejected as `invalid_path` (FCAP-2). Reads and
13
- * writes return the exact-byte `sha256:` hash with no content transformation
14
- * (FCAP-3, FCAP-5); writes are atomic whole-file replacements and honor an
15
- * `ifMatch` compare-and-swap that returns `stale` on a hash mismatch (FCAP-6);
16
- * listing returns only immediate children, directories before files then
17
- * lexicographic (FCAP-4).
18
- *
19
- * This module is the artifact-facing surface. The host-side per-run grant model
20
- * that authorizes each operation (default-deny, writable target/linked only) is a
21
- * later FCAP concern; this capability authorizes by run-root containment alone.
22
- * See specs/dev/file-capability.md.
23
- */
24
- import { randomUUID } from 'node:crypto';
25
- import { readFile, readdir, realpath, rename, stat, writeFile, } from 'node:fs/promises';
26
- import { basename, dirname, join, relative, resolve, sep } from 'node:path';
27
- import { hashBytes } from './hash.js';
28
- /**
29
- * Creates a {@link FileCapability} rooted at `runRoot`, confining every operation
30
- * to that directory after symlink resolution (FCAP-1..6).
31
- */
32
- export function createFileCapability(runRoot) {
33
- const root = resolve(runRoot);
34
- let realRoot = null;
35
- const canonicalRoot = () => (realRoot ??= realpath(root));
36
- async function resolveHost(path) {
37
- if (isPlatformAbsolute(path)) {
38
- return fail('invalid_path', `path "${path}" uses platform-absolute syntax`);
39
- }
40
- const segments = normalizeVirtual(path);
41
- if (segments === null) {
42
- return fail('invalid_path', `path "${path}" escapes the run root`);
43
- }
44
- const host = segments.length === 0 ? root : join(root, ...segments);
45
- const real = await realpathAllowingMissing(host);
46
- if (!isInside(await canonicalRoot(), real)) {
47
- return fail('invalid_path', `path "${path}" escapes the run root after resolving symlinks`);
48
- }
49
- return { ok: true, value: host };
50
- }
51
- // Serialize writes per resolved host path so an ifMatch read-check-rename runs
52
- // without another write to the same path interleaving at an await — making the
53
- // compare-and-swap atomic across operations through this capability (FCAP-6).
54
- const writeLocks = new Map();
55
- function serializeWrite(host, op) {
56
- const prior = writeLocks.get(host) ?? Promise.resolve();
57
- const run = prior.then(op, op);
58
- writeLocks.set(host, run.then(() => undefined, () => undefined));
59
- return run;
60
- }
61
- return {
62
- async read(path) {
63
- const resolved = await resolveHost(path);
64
- if (!resolved.ok) {
65
- return resolved;
66
- }
67
- try {
68
- const info = await stat(resolved.value);
69
- if (info.isDirectory()) {
70
- return fail('not_file', `path "${path}" is a directory`);
71
- }
72
- const bytes = await readFile(resolved.value);
73
- return { ok: true, value: { bytes, hash: hashBytes(bytes) } };
74
- }
75
- catch (error) {
76
- return fromFsError(error, path);
77
- }
78
- },
79
- async list(path) {
80
- const resolved = await resolveHost(path);
81
- if (!resolved.ok) {
82
- return resolved;
83
- }
84
- try {
85
- const info = await stat(resolved.value);
86
- if (!info.isDirectory()) {
87
- return fail('not_directory', `path "${path}" is not a directory`);
88
- }
89
- const dirents = await readdir(resolved.value, { withFileTypes: true });
90
- const entries = dirents
91
- .map((entry) => ({
92
- name: entry.name,
93
- kind: entry.isDirectory() ? 'directory' : 'file',
94
- }))
95
- .sort(compareEntries);
96
- return { ok: true, value: { entries } };
97
- }
98
- catch (error) {
99
- return fromFsError(error, path);
100
- }
101
- },
102
- async write(path, bytes, opts) {
103
- const resolved = await resolveHost(path);
104
- if (!resolved.ok) {
105
- return resolved;
106
- }
107
- const host = resolved.value;
108
- return serializeWrite(host, async () => {
109
- try {
110
- const current = await currentHash(host);
111
- if (current.kind === 'directory') {
112
- return fail('not_file', `path "${path}" is a directory`);
113
- }
114
- if (opts?.ifMatch !== undefined && opts.ifMatch !== current.hash) {
115
- return fail('stale', `path "${path}" did not match ifMatch ${opts.ifMatch}`);
116
- }
117
- await atomicWrite(host, bytes);
118
- return { ok: true, value: { hash: hashBytes(bytes) } };
119
- }
120
- catch (error) {
121
- return fromFsError(error, path);
122
- }
123
- });
124
- },
125
- };
126
- }
127
- /** The current exact-byte hash of `host`, or `null` when it does not exist. */
128
- async function currentHash(host) {
129
- try {
130
- const info = await stat(host);
131
- if (info.isDirectory()) {
132
- return { kind: 'directory' };
133
- }
134
- return { kind: 'file', hash: hashBytes(await readFile(host)) };
135
- }
136
- catch (error) {
137
- if (isNotFound(error)) {
138
- return { kind: 'absent', hash: null };
139
- }
140
- throw error;
141
- }
142
- }
143
- /** Atomically replaces or creates `host` by writing a sibling temp file and renaming. */
144
- async function atomicWrite(host, bytes) {
145
- const temp = join(dirname(host), `.${basename(host)}.${randomUUID()}.tmp`);
146
- await writeFile(temp, bytes);
147
- await rename(temp, host);
148
- }
149
- /**
150
- * Normalizes a virtual POSIX path to in-root segments, treating a leading `/` as
151
- * the root and resolving `.`/`..`; returns `null` when `..` escapes the root.
152
- */
153
- function normalizeVirtual(path) {
154
- const out = [];
155
- for (const part of path.split('/')) {
156
- if (part === '' || part === '.') {
157
- continue;
158
- }
159
- if (part === '..') {
160
- if (out.length === 0) {
161
- return null;
162
- }
163
- out.pop();
164
- continue;
165
- }
166
- out.push(part);
167
- }
168
- return out;
169
- }
170
- /** Rejects Windows drive paths and UNC syntax (DR-008 platform-absolute paths). */
171
- function isPlatformAbsolute(path) {
172
- return /^[a-zA-Z]:[\\/]/.test(path) || path.startsWith('\\');
173
- }
174
- /**
175
- * Canonicalizes a virtual POSIX path to its normalized `/`-prefixed form — the key
176
- * the host-side grant model matches on — or `null` when the path is
177
- * platform-absolute or escapes the run root (FCAP-2).
178
- */
179
- export function canonicalize(path) {
180
- if (isPlatformAbsolute(path)) {
181
- return null;
182
- }
183
- const segments = normalizeVirtual(path);
184
- if (segments === null) {
185
- return null;
186
- }
187
- return `/${segments.join('/')}`;
188
- }
189
- /** Resolves `host` through symlinks, falling back to the deepest existing ancestor. */
190
- async function realpathAllowingMissing(host) {
191
- try {
192
- return await realpath(host);
193
- }
194
- catch (error) {
195
- if (!isNotFound(error)) {
196
- throw error;
197
- }
198
- const parent = dirname(host);
199
- if (parent === host) {
200
- return host;
201
- }
202
- return join(await realpathAllowingMissing(parent), basename(host));
203
- }
204
- }
205
- function isInside(root, candidate) {
206
- if (candidate === root) {
207
- return true;
208
- }
209
- const rel = relative(root, candidate);
210
- return rel !== '' && rel !== '..' && !rel.startsWith(`..${sep}`);
211
- }
212
- /** Orders entries with directories before files, then lexicographically by name. */
213
- function compareEntries(a, b) {
214
- if (a.kind !== b.kind) {
215
- return a.kind === 'directory' ? -1 : 1;
216
- }
217
- return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
218
- }
219
- function fromFsError(error, path) {
220
- if (isNotFound(error)) {
221
- return fail('not_found', `path "${path}" was not found`);
222
- }
223
- return fail('io_error', `path "${path}": ${messageOf(error)}`);
224
- }
225
- function isNotFound(error) {
226
- return error?.code === 'ENOENT';
227
- }
228
- function fail(code, diagnostic) {
229
- return { ok: false, code, diagnostic };
230
- }
231
- function messageOf(error) {
232
- return error instanceof Error ? error.message : String(error);
233
- }
234
- //# sourceMappingURL=file-capability.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-capability.js","sourceRoot":"","sources":["../src/file-capability.ts"],"names":[],"mappings":"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"}
@@ -1,79 +0,0 @@
1
- /**
2
- * Host-side per-run grant model for the file capability (FCAP-11..14; DR-008).
3
- *
4
- * A compiled phase artifact reaches files only through a {@link FileCapability}
5
- * the host builds for that run. The capability is default-deny: an operation
6
- * succeeds only when its path is inside the run root (enforced by the artifact-
7
- * facing layer in `file-capability.ts`) and is covered by a {@link Grant} of the
8
- * matching access. {@link buildRunGrants} encodes the policy — the only writable
9
- * path is the run's `target` (compile) or `linked` (link), and read grants are
10
- * the run's source/object inputs, its link target when applicable, and the
11
- * recorded semantic-input closure, each enumerated as a file grant.
12
- * {@link createGuardedCapability} wraps a run-root capability with that grant set,
13
- * reporting `unauthorized` for any ungranted access.
14
- *
15
- * Directory listing and recursive directory reads are withheld: until a pinning
16
- * extension defines directory listing and subtree identities, this model grants
17
- * neither (DR-008), so a pinned phase cannot widen its closure at run time.
18
- * Scope failures (`invalid_path`, `unauthorized`) are distinguished by
19
- * {@link isScopeFailure} so the executor can fail them like a generic check rather
20
- * than a phase `BLOCKED`. See specs/dev/file-capability.md.
21
- */
22
- import { type FileCapability, type FileErrorCode, type SlcPath } from './file-capability.js';
23
- import { type Hash } from './hash.js';
24
- /** Whether a grant authorizes reading or writing (DR-008). */
25
- export type GrantAccess = 'read' | 'write';
26
- /** Whether a grant covers a file or a directory (DR-008). */
27
- export type GrantKind = 'file' | 'directory';
28
- /** Why a path is granted, for audit and diagnostics (DR-008). */
29
- export type GrantReason = 'source' | 'object' | 'linkTarget' | 'semanticInput' | 'target' | 'linked';
30
- /** One host-side authorization over a normalized virtual path (DR-008). */
31
- export interface Grant {
32
- /** Normalized virtual path (see {@link canonicalize}). */
33
- path: string;
34
- access: GrantAccess;
35
- kind: GrantKind;
36
- /** Directory grants only: whether `list` is allowed. */
37
- listing?: boolean;
38
- /** Directory read grants only: whether descendant reads are covered. */
39
- recursive?: boolean;
40
- /** Expected identity for audit: file hash, listing identity, or subtree identity. */
41
- identity?: Hash;
42
- reason: GrantReason;
43
- }
44
- /** The run inputs a grant set is closed over (DR-008; the closure to authorize). */
45
- export interface RunGrantSpec {
46
- kind: 'compile' | 'link';
47
- /** Compile source input. */
48
- source?: SlcPath;
49
- /** Link object artifacts. */
50
- objects?: readonly SlcPath[];
51
- /** Runtime link target, when the run consumes one. */
52
- linkTarget?: SlcPath;
53
- /** Compile writable target. */
54
- target?: SlcPath;
55
- /** Link writable artifact. */
56
- linked?: SlcPath;
57
- /** Recorded semantic-input closure files, each enumerated (DR-007). */
58
- semanticInputs?: readonly {
59
- path: SlcPath;
60
- identity?: Hash;
61
- }[];
62
- }
63
- /**
64
- * Builds the default-deny grant set for a run (FCAP-12, FCAP-13).
65
- *
66
- * The only writable grant is the run's `target` (compile) or `linked` (link); read
67
- * grants enumerate the source/object inputs, the link target when present, and the
68
- * semantic-input closure. Directory listing and recursive reads are not granted.
69
- */
70
- export declare function buildRunGrants(spec: RunGrantSpec): Grant[];
71
- /**
72
- * Wraps a run-root capability with a grant set, denying every ungranted access
73
- * (FCAP-11). Path validity and run-root containment are left to the wrapped
74
- * capability, so an invalid or escaping path still reports `invalid_path`.
75
- */
76
- export declare function createGuardedCapability(runRoot: string, grants: readonly Grant[]): FileCapability;
77
- /** Reports whether a capability error is a host-enforced scope failure (FCAP-14). */
78
- export declare function isScopeFailure(code: FileErrorCode): boolean;
79
- //# sourceMappingURL=file-grants.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-grants.d.ts","sourceRoot":"","sources":["../src/file-grants.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,aAAa,EAElB,KAAK,OAAO,EAGb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,8DAA8D;AAC9D,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3C,6DAA6D;AAC7D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,WAAW,CAAC;AAE7C,iEAAiE;AACjE,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,eAAe,GACf,QAAQ,GACR,QAAQ,CAAC;AAEb,2EAA2E;AAC3E,MAAM,WAAW,KAAK;IACpB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,CAAC;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wEAAwE;IACxE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,qFAAqF;IACrF,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,GAAG,MAAM,CAAC;IACzB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;IAC7B,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,cAAc,CAAC,EAAE,SAAS;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,IAAI,CAAA;KAAE,EAAE,CAAC;CAChE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,KAAK,EAAE,CAqB1D;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,KAAK,EAAE,GACvB,cAAc,CAahB;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAE3D"}
@@ -1,133 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2026 SubLang International <https://sublang.ai>
3
- /**
4
- * Host-side per-run grant model for the file capability (FCAP-11..14; DR-008).
5
- *
6
- * A compiled phase artifact reaches files only through a {@link FileCapability}
7
- * the host builds for that run. The capability is default-deny: an operation
8
- * succeeds only when its path is inside the run root (enforced by the artifact-
9
- * facing layer in `file-capability.ts`) and is covered by a {@link Grant} of the
10
- * matching access. {@link buildRunGrants} encodes the policy — the only writable
11
- * path is the run's `target` (compile) or `linked` (link), and read grants are
12
- * the run's source/object inputs, its link target when applicable, and the
13
- * recorded semantic-input closure, each enumerated as a file grant.
14
- * {@link createGuardedCapability} wraps a run-root capability with that grant set,
15
- * reporting `unauthorized` for any ungranted access.
16
- *
17
- * Directory listing and recursive directory reads are withheld: until a pinning
18
- * extension defines directory listing and subtree identities, this model grants
19
- * neither (DR-008), so a pinned phase cannot widen its closure at run time.
20
- * Scope failures (`invalid_path`, `unauthorized`) are distinguished by
21
- * {@link isScopeFailure} so the executor can fail them like a generic check rather
22
- * than a phase `BLOCKED`. See specs/dev/file-capability.md.
23
- */
24
- import { canonicalize, createFileCapability, } from './file-capability.js';
25
- import {} from './hash.js';
26
- /**
27
- * Builds the default-deny grant set for a run (FCAP-12, FCAP-13).
28
- *
29
- * The only writable grant is the run's `target` (compile) or `linked` (link); read
30
- * grants enumerate the source/object inputs, the link target when present, and the
31
- * semantic-input closure. Directory listing and recursive reads are not granted.
32
- */
33
- export function buildRunGrants(spec) {
34
- const grants = [];
35
- if (spec.kind === 'compile' && spec.target !== undefined) {
36
- grants.push(fileGrant(spec.target, 'write', 'target'));
37
- }
38
- if (spec.kind === 'link' && spec.linked !== undefined) {
39
- grants.push(fileGrant(spec.linked, 'write', 'linked'));
40
- }
41
- if (spec.source !== undefined) {
42
- grants.push(fileGrant(spec.source, 'read', 'source'));
43
- }
44
- for (const object of spec.objects ?? []) {
45
- grants.push(fileGrant(object, 'read', 'object'));
46
- }
47
- if (spec.linkTarget !== undefined) {
48
- grants.push(fileGrant(spec.linkTarget, 'read', 'linkTarget'));
49
- }
50
- for (const input of spec.semanticInputs ?? []) {
51
- grants.push(fileGrant(input.path, 'read', 'semanticInput', input.identity));
52
- }
53
- return grants;
54
- }
55
- /**
56
- * Wraps a run-root capability with a grant set, denying every ungranted access
57
- * (FCAP-11). Path validity and run-root containment are left to the wrapped
58
- * capability, so an invalid or escaping path still reports `invalid_path`.
59
- */
60
- export function createGuardedCapability(runRoot, grants) {
61
- const inner = createFileCapability(runRoot);
62
- return {
63
- async read(path) {
64
- return authorize(grants, path, 'read') ?? inner.read(path);
65
- },
66
- async list(path) {
67
- return authorizeList(grants, path) ?? inner.list(path);
68
- },
69
- async write(path, bytes, opts) {
70
- return authorize(grants, path, 'write') ?? inner.write(path, bytes, opts);
71
- },
72
- };
73
- }
74
- /** Reports whether a capability error is a host-enforced scope failure (FCAP-14). */
75
- export function isScopeFailure(code) {
76
- return code === 'invalid_path' || code === 'unauthorized';
77
- }
78
- /**
79
- * Returns an `unauthorized` denial when no grant covers `path` for `access`, or
80
- * `null` to defer to the wrapped capability (which validates the path itself).
81
- */
82
- function authorize(grants, path, access) {
83
- const canonical = canonicalize(path);
84
- if (canonical === null) {
85
- return null;
86
- }
87
- if (!covers(grants, canonical, access)) {
88
- return deny(`no ${access} grant covers "${path}"`);
89
- }
90
- return null;
91
- }
92
- function authorizeList(grants, path) {
93
- const canonical = canonicalize(path);
94
- if (canonical === null) {
95
- return null;
96
- }
97
- const granted = grants.some((grant) => grant.access === 'read' &&
98
- grant.path === canonical &&
99
- grant.kind === 'directory' &&
100
- grant.listing === true);
101
- return granted ? null : deny(`no listing grant covers "${path}"`);
102
- }
103
- function covers(grants, canonical, access) {
104
- return grants.some((grant) => {
105
- if (grant.access !== access) {
106
- return false;
107
- }
108
- if (grant.path === canonical) {
109
- return true;
110
- }
111
- return (access === 'read' &&
112
- grant.kind === 'directory' &&
113
- grant.recursive === true &&
114
- isUnder(grant.path, canonical));
115
- });
116
- }
117
- function isUnder(ancestor, candidate) {
118
- const prefix = ancestor === '/' ? '/' : `${ancestor}/`;
119
- return candidate.startsWith(prefix);
120
- }
121
- function fileGrant(path, access, reason, identity) {
122
- const canonical = canonicalize(path);
123
- if (canonical === null) {
124
- throw new Error(`grant path "${path}" is not a valid run-root path`);
125
- }
126
- return identity === undefined
127
- ? { path: canonical, access, kind: 'file', reason }
128
- : { path: canonical, access, kind: 'file', identity, reason };
129
- }
130
- function deny(diagnostic) {
131
- return { ok: false, code: 'unauthorized', diagnostic };
132
- }
133
- //# sourceMappingURL=file-grants.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"file-grants.js","sourceRoot":"","sources":["../src/file-grants.ts"],"names":[],"mappings":"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"}