@telorun/cli 0.70.0 → 0.72.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 (46) hide show
  1. package/dist/bundle/partition-layers.d.ts +11 -26
  2. package/dist/bundle/partition-layers.d.ts.map +1 -1
  3. package/dist/bundle/partition-layers.js +37 -88
  4. package/dist/bundle/partition-layers.js.map +1 -1
  5. package/dist/cli.js +11 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/cel.d.ts +18 -0
  8. package/dist/commands/cel.d.ts.map +1 -1
  9. package/dist/commands/cel.js +60 -12
  10. package/dist/commands/cel.js.map +1 -1
  11. package/dist/commands/check.d.ts.map +1 -1
  12. package/dist/commands/check.js +43 -8
  13. package/dist/commands/check.js.map +1 -1
  14. package/dist/commands/install.d.ts.map +1 -1
  15. package/dist/commands/install.js +27 -17
  16. package/dist/commands/install.js.map +1 -1
  17. package/dist/commands/module.d.ts.map +1 -1
  18. package/dist/commands/module.js +36 -31
  19. package/dist/commands/module.js.map +1 -1
  20. package/dist/commands/publish.d.ts.map +1 -1
  21. package/dist/commands/publish.js +57 -26
  22. package/dist/commands/publish.js.map +1 -1
  23. package/dist/commands/run.d.ts.map +1 -1
  24. package/dist/commands/run.js +15 -4
  25. package/dist/commands/run.js.map +1 -1
  26. package/dist/commands/search.d.ts.map +1 -1
  27. package/dist/commands/search.js +19 -10
  28. package/dist/commands/search.js.map +1 -1
  29. package/dist/commands/upgrade.d.ts.map +1 -1
  30. package/dist/commands/upgrade.js +35 -21
  31. package/dist/commands/upgrade.js.map +1 -1
  32. package/dist/controller-progress.d.ts.map +1 -1
  33. package/dist/controller-progress.js +0 -0
  34. package/dist/controller-progress.js.map +1 -1
  35. package/dist/debug-event-subscriber.d.ts.map +1 -1
  36. package/dist/debug-event-subscriber.js +2 -1
  37. package/dist/debug-event-subscriber.js.map +1 -1
  38. package/dist/logger.d.ts +33 -0
  39. package/dist/logger.d.ts.map +1 -1
  40. package/dist/logger.js +73 -37
  41. package/dist/logger.js.map +1 -1
  42. package/dist/output.d.ts +111 -0
  43. package/dist/output.d.ts.map +1 -0
  44. package/dist/output.js +143 -0
  45. package/dist/output.js.map +1 -0
  46. package/package.json +6 -6
@@ -1,4 +1,4 @@
1
- import { type ArtifactSelector } from "@telorun/analyzer";
1
+ import { type ArtifactSelector, type ModuleFileClaim } from "@telorun/analyzer";
2
2
  import type { PayloadLayer } from "@telorun/kernel";
3
3
  /** Manifest-relative POSIX path of a selected file, grouped into the layer it
4
4
  * belongs to. Content is read by the caller — this module decides membership
@@ -16,29 +16,13 @@ export interface Partition {
16
16
  /** `assets:` patterns that matched nothing — almost always a typo, and invisible
17
17
  * in `layers` because an empty layer is dropped. */
18
18
  unmatchedAssets: string[];
19
- /** `siblings=` patterns that matched nothing, with the candidate that declared
19
+ /** `siblings=` patterns that matched nothing, with the claim that declared
20
20
  * each one. */
21
21
  unmatchedSiblings: Array<{
22
- purl: string;
22
+ origin: string;
23
23
  pattern: string;
24
24
  }>;
25
25
  }
26
- interface ControllerClaim {
27
- selector: ArtifactSelector;
28
- /** Entry-point path exactly as `path=` names it, manifest-relative. */
29
- entry: string;
30
- /** Sibling patterns declared on the same candidate. */
31
- siblings: string[];
32
- /** For diagnostics: the PURL this claim came from. */
33
- purl: string;
34
- }
35
- /**
36
- * Every bundled-controller candidate declared anywhere in the manifest, with its
37
- * selector and the files it claims. Read from `controllers:` on each doc — the
38
- * manifest already names each entry point, so the partition is derived rather
39
- * than declared.
40
- */
41
- export declare function readControllerClaims(manifestText: string): ControllerClaim[];
42
26
  /**
43
27
  * Partition the selected payload into the layers a module artifact ships.
44
28
  *
@@ -53,13 +37,15 @@ export declare function readControllerClaims(manifestText: string): ControllerCl
53
37
  * therefore costs bytes, never a module-not-found at runtime. Both declarations
54
38
  * are optional and only ever buy laziness.
55
39
  *
56
- * `files` are the manifest-relative paths `selectFiles` produced; `assetPatterns`
57
- * is the author's `assets:` list. Every bundled controller's `path=` entry joins
58
- * the payload whether or not `files:` selected it — the manifest already names
59
- * it, so restating it would be pure duplication. Layers with no files are
60
- * dropped, so a controller-only module publishes exactly one payload layer.
40
+ * `claims` is everything the manifest names read by `collectModuleFileClaims`,
41
+ * which asks each syntax's own owner (this module recognises neither a PURL nor
42
+ * a YAML tag). `files` are the manifest-relative paths `selectFiles` produced;
43
+ * `assetPatterns` is the author's `assets:` list. A claimed file joins the
44
+ * payload whether or not `files:` selected it the manifest already names it,
45
+ * so restating it would be pure duplication. Layers with no files are dropped,
46
+ * so a controller-only module publishes exactly one payload layer.
61
47
  */
62
- export declare function partitionLayers(manifestText: string, files: string[], assetPatterns: string[]): Partition;
48
+ export declare function partitionLayers(claims: readonly ModuleFileClaim[], files: string[], assetPatterns: string[]): Partition;
63
49
  /**
64
50
  * One line per layer for the publish output, so an author can see that a file they
65
51
  * meant as a sidecar or an asset landed in `common` instead.
@@ -69,5 +55,4 @@ export declare function partitionLayers(manifestText: string, files: string[], a
69
55
  * silence about the single mistake this output exists to catch.
70
56
  */
71
57
  export declare function describePartition(partition: Partition): string[];
72
- export {};
73
58
  //# sourceMappingURL=partition-layers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"partition-layers.d.ts","sourceRoot":"","sources":["../../src/bundle/partition-layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAKpD;;uDAEuD;AACvD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;uEAEuE;AACvE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB;yDACqD;IACrD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;oBACgB;IAChB,iBAAiB,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7D;AAgBD,UAAU,eAAe;IACvB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;CACd;AAQD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,EAAE,CAmC5E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,SAAS,CAgEX;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,CAYhE"}
1
+ {"version":3,"file":"partition-layers.d.ts","sourceRoot":"","sources":["../../src/bundle/partition-layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;uDAEuD;AACvD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED;;uEAEuE;AACvE,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB;yDACqD;IACrD,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;oBACgB;IAChB,iBAAiB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,SAAS,CA4EX;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,EAAE,CAYhE"}
@@ -1,67 +1,5 @@
1
- import { describeSelector, selectorFromQualifiers, selectorKey, } from "@telorun/analyzer";
1
+ import { describeSelector, selectorKey, } from "@telorun/analyzer";
2
2
  import { selectByPatterns } from "@telorun/glob";
3
- import { defaultCustomTags } from "@telorun/templating";
4
- import { PackageURL } from "packageurl-js";
5
- import { parseAllDocuments } from "yaml";
6
- /** `pkg:telo/local/<format>?path=…` — the bundled-controller delivery mode.
7
- * Anything else (`pkg:npm`, `pkg:cargo`) fetches from its own ecosystem and
8
- * contributes no layer. */
9
- const BUNDLED_TYPE = "telo";
10
- const BUNDLED_NAMESPACE = "local";
11
- /** Qualifier naming extra files that belong in a controller's layer — what an
12
- * entry point loads but the manifest cannot otherwise see (a `.wasm` beside its
13
- * glue, a native library opened at runtime). Comma-separated
14
- * `.gitignore`-style patterns, matched through the one glob engine. Optional:
15
- * an unclaimed sidecar joins the common layer, which every controller-hosting
16
- * kernel pulls, so omitting it costs bytes rather than a broken import. */
17
- const SIBLINGS_QUALIFIER = "siblings";
18
- /** Normalize a `path=` / sibling value to the manifest-relative POSIX form
19
- * `selectFiles` returns, so membership is a string comparison. */
20
- function normalizeRelative(value) {
21
- return value.replace(/^\.\//, "").replace(/\\/g, "/");
22
- }
23
- /**
24
- * Every bundled-controller candidate declared anywhere in the manifest, with its
25
- * selector and the files it claims. Read from `controllers:` on each doc — the
26
- * manifest already names each entry point, so the partition is derived rather
27
- * than declared.
28
- */
29
- export function readControllerClaims(manifestText) {
30
- const claims = [];
31
- for (const doc of parseAllDocuments(manifestText, { customTags: defaultCustomTags() })) {
32
- const json = doc.toJSON();
33
- const candidates = Array.isArray(json?.controllers) ? json.controllers : [];
34
- for (const candidate of candidates) {
35
- if (typeof candidate !== "string")
36
- continue;
37
- let parsed;
38
- try {
39
- parsed = PackageURL.fromString(candidate);
40
- }
41
- catch {
42
- // Not a parseable PURL — publish is not the place to reject it; the
43
- // analyzer and the controller loader both report it with better context.
44
- continue;
45
- }
46
- if (parsed.type !== BUNDLED_TYPE || parsed.namespace !== BUNDLED_NAMESPACE)
47
- continue;
48
- const entry = parsed.qualifiers?.path;
49
- if (typeof entry !== "string" || entry === "")
50
- continue;
51
- const siblings = String(parsed.qualifiers?.[SIBLINGS_QUALIFIER] ?? "")
52
- .split(",")
53
- .map((p) => p.trim())
54
- .filter((p) => p !== "");
55
- claims.push({
56
- selector: selectorFromQualifiers(parsed.name, parsed.qualifiers, `controller "${candidate}"`),
57
- entry: normalizeRelative(entry),
58
- siblings,
59
- purl: candidate,
60
- });
61
- }
62
- }
63
- return claims;
64
- }
65
3
  /**
66
4
  * Partition the selected payload into the layers a module artifact ships.
67
5
  *
@@ -76,24 +14,30 @@ export function readControllerClaims(manifestText) {
76
14
  * therefore costs bytes, never a module-not-found at runtime. Both declarations
77
15
  * are optional and only ever buy laziness.
78
16
  *
79
- * `files` are the manifest-relative paths `selectFiles` produced; `assetPatterns`
80
- * is the author's `assets:` list. Every bundled controller's `path=` entry joins
81
- * the payload whether or not `files:` selected it — the manifest already names
82
- * it, so restating it would be pure duplication. Layers with no files are
83
- * dropped, so a controller-only module publishes exactly one payload layer.
17
+ * `claims` is everything the manifest names read by `collectModuleFileClaims`,
18
+ * which asks each syntax's own owner (this module recognises neither a PURL nor
19
+ * a YAML tag). `files` are the manifest-relative paths `selectFiles` produced;
20
+ * `assetPatterns` is the author's `assets:` list. A claimed file joins the
21
+ * payload whether or not `files:` selected it the manifest already names it,
22
+ * so restating it would be pure duplication. Layers with no files are dropped,
23
+ * so a controller-only module publishes exactly one payload layer.
84
24
  */
85
- export function partitionLayers(manifestText, files, assetPatterns) {
86
- const claims = readControllerClaims(manifestText);
87
- // A controller entry point is part of the payload because `controllers:` names
88
- // it, not because `files:` restates it. `files:` keeps its role for everything
89
- // the manifest cannot otherwise see assets, static files, sidecars — and a
90
- // module whose only payload is its controller declares no `files:` at all.
25
+ export function partitionLayers(claims, files, assetPatterns) {
26
+ // Narrowing predicates, so the controller branch reaches `selector` and
27
+ // `siblings` as declared fields rather than through a non-null assertion
28
+ // the claim type is a discriminated union precisely so this is checked.
29
+ const controllers = claims.filter((claim) => claim.role === "controller");
30
+ const claimedAssets = claims.filter((claim) => claim.role === "assets");
31
+ // A claimed file is part of the payload because the manifest names it, not
32
+ // because `files:` restates it. `files:` keeps its role for everything the
33
+ // manifest cannot otherwise see — static files, sidecars — and a module whose
34
+ // only payload is its controller declares no `files:` at all.
91
35
  //
92
36
  // Sibling patterns are still matched against `files:` alone: a sibling is a
93
37
  // glob over the payload, so a pattern that selects nothing there means the
94
38
  // author forgot to include the file, which `unmatchedSiblings` reports.
95
- const selected = new Set([...files, ...claims.map((claim) => claim.entry)]);
96
- const unclaimed = new Set(files);
39
+ const selected = new Set([...files, ...claims.map((claim) => claim.path)]);
40
+ const unclaimed = new Set([...files, ...claimedAssets.map((claim) => claim.path)]);
97
41
  // Controller layers first: a file an entry point or sibling claims belongs to
98
42
  // that selector, never to assets or common, so the layer a kernel skips is
99
43
  // genuinely skippable. A file several candidates claim is copied into each of
@@ -102,30 +46,35 @@ export function partitionLayers(manifestText, files, assetPatterns) {
102
46
  // would break the "a declaration never costs correctness" guarantee.
103
47
  const bySelector = new Map();
104
48
  const unmatchedSiblings = [];
105
- for (const claim of claims) {
49
+ for (const claim of controllers) {
106
50
  const key = selectorKey(claim.selector);
107
51
  let plan = bySelector.get(key);
108
52
  if (!plan) {
109
53
  plan = { role: "controller", selector: claim.selector, files: [] };
110
54
  bySelector.set(key, plan);
111
55
  }
112
- const siblings = selectByPatterns([...selected], claim.siblings, {
113
- applyDefaultIgnore: false,
114
- });
115
- for (const pattern of claim.siblings) {
56
+ const patterns = [...claim.siblings];
57
+ const siblings = selectByPatterns([...selected], patterns, { applyDefaultIgnore: false });
58
+ for (const pattern of patterns) {
116
59
  if (selectByPatterns([...selected], [pattern], { applyDefaultIgnore: false }).length === 0) {
117
- unmatchedSiblings.push({ purl: claim.purl, pattern });
60
+ unmatchedSiblings.push({ origin: claim.origin, pattern });
118
61
  }
119
62
  }
120
- for (const file of [claim.entry, ...siblings]) {
63
+ for (const file of [claim.path, ...siblings]) {
121
64
  unclaimed.delete(file);
122
65
  if (!plan.files.includes(file))
123
66
  plan.files.push(file);
124
67
  }
125
68
  }
126
- const assetFiles = selectByPatterns([...unclaimed], assetPatterns, {
127
- applyDefaultIgnore: false,
128
- });
69
+ // A file a tag embeds is an asset by declaration, so it needs no `assets:`
70
+ // pattern to be lazy — the manifest already said what it is. A pattern can
71
+ // still claim more, and a file claimed both ways is one file.
72
+ const assetFiles = [
73
+ ...new Set([
74
+ ...claimedAssets.map((claim) => claim.path).filter((file) => unclaimed.has(file)),
75
+ ...selectByPatterns([...unclaimed], assetPatterns, { applyDefaultIgnore: false }),
76
+ ]),
77
+ ].sort();
129
78
  for (const file of assetFiles)
130
79
  unclaimed.delete(file);
131
80
  const unmatchedAssets = assetPatterns.filter((pattern) => !pattern.startsWith("!") &&
@@ -157,8 +106,8 @@ export function describePartition(partition) {
157
106
  for (const pattern of partition.unmatchedAssets) {
158
107
  lines.push(`assets pattern '${pattern}' matched no file`);
159
108
  }
160
- for (const { purl, pattern } of partition.unmatchedSiblings) {
161
- lines.push(`siblings pattern '${pattern}' matched no file (from ${purl})`);
109
+ for (const { origin, pattern } of partition.unmatchedSiblings) {
110
+ lines.push(`siblings pattern '${pattern}' matched no file (from ${origin})`);
162
111
  }
163
112
  return lines;
164
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"partition-layers.js","sourceRoot":"","sources":["../../src/bundle/partition-layers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"partition-layers.js","sourceRoot":"","sources":["../../src/bundle/partition-layers.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import yargs from "yargs";
3
3
  import { hideBin } from "yargs/helpers";
4
+ import { OUTPUT_FORMATS, configureOutput, parseOutputFormat } from "./output.js";
4
5
  import { celCommand } from "./commands/cel.js";
5
6
  import { checkCommand } from "./commands/check.js";
6
7
  import { installCommand } from "./commands/install.js";
@@ -47,6 +48,16 @@ cli
47
48
  default: true,
48
49
  describe: "Persist the analysis/validator cache to disk. Use --no-cache-write for an ephemeral, read-only run (validates in-memory, reads the baked cache but never writes it).",
49
50
  })
51
+ .option("output", {
52
+ alias: "o",
53
+ type: "string",
54
+ choices: OUTPUT_FORMATS,
55
+ default: "text",
56
+ describe: "Output format for the CLI's own output. `json` is a machine contract and never carries colour. Note `telo run` streams the app's stdout/stderr through untouched — the app picks its own encoding via its `logging:` block.",
57
+ })
58
+ // Runs before any handler, so a call site deep inside a command reaches the
59
+ // same decision without the format being threaded through every signature.
60
+ .middleware((argv) => configureOutput(parseOutputFormat(argv.output)), true)
50
61
  .demandCommand(1, "Please specify a command or path to run")
51
62
  .strict()
52
63
  .help()
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACnC,UAAU,CAAC,MAAM,CAAC;KAClB,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAEnC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAe,CAAC;AACpC,GAAG,GAAG,YAAY,CAAC,GAAG,CAAe,CAAC;AACtC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AACxC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAe,CAAC;AACvC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AACxC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAe,CAAC;AACpC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAe,CAAC;AACvC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AAExC,GAAG;KACA,MAAM,CAAC,SAAS,EAAE;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,wBAAwB;CACnC,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,8BAA8B;CACzC,CAAC;KACD,MAAM,CAAC,kBAAkB,EAAE;IAC1B,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,4BAA4B;CACvC,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,2CAA2C;CACtD,CAAC;KACD,MAAM,CAAC,aAAa,EAAE;IACrB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,IAAI;IACb,QAAQ,EACN,sKAAsK;CACzK,CAAC;KACD,aAAa,CAAC,CAAC,EAAE,yCAAyC,CAAC;KAC3D,MAAM,EAAE;KACR,IAAI,EAAE;KACN,OAAO,EAAE;KACT,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAEvD,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;KACnC,UAAU,CAAC,MAAM,CAAC;KAClB,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAEnC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAe,CAAC;AACpC,GAAG,GAAG,YAAY,CAAC,GAAG,CAAe,CAAC;AACtC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AACxC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAe,CAAC;AACvC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AACxC,GAAG,GAAG,UAAU,CAAC,GAAG,CAAe,CAAC;AACpC,GAAG,GAAG,aAAa,CAAC,GAAG,CAAe,CAAC;AACvC,GAAG,GAAG,cAAc,CAAC,GAAG,CAAe,CAAC;AAExC,GAAG;KACA,MAAM,CAAC,SAAS,EAAE;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,wBAAwB;CACnC,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,8BAA8B;CACzC,CAAC;KACD,MAAM,CAAC,kBAAkB,EAAE;IAC1B,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,4BAA4B;CACvC,CAAC;KACD,MAAM,CAAC,OAAO,EAAE;IACf,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,2CAA2C;CACtD,CAAC;KACD,MAAM,CAAC,aAAa,EAAE;IACrB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,IAAI;IACb,QAAQ,EACN,sKAAsK;CACzK,CAAC;KACD,MAAM,CAAC,QAAQ,EAAE;IAChB,KAAK,EAAE,GAAG;IACV,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,cAAc;IACvB,OAAO,EAAE,MAAe;IACxB,QAAQ,EACN,6NAA6N;CAChO,CAAC;IACF,4EAA4E;IAC5E,2EAA2E;KAC1E,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC;KAC3E,aAAa,CAAC,CAAC,EAAE,yCAAyC,CAAC;KAC3D,MAAM,EAAE;KACR,IAAI,EAAE;KACN,OAAO,EAAE;KACT,KAAK,EAAE,CAAC"}
@@ -1,3 +1,21 @@
1
+ import { type CelFunctionInfo } from "@telorun/templating";
1
2
  import type { Argv } from "yargs";
3
+ /** A CEL built-in, in the same shape as a catalog entry so one listing covers
4
+ * both halves of what a manifest may call. `receiver` is what the catalog
5
+ * cannot express: a built-in is usually a METHOD, and calling it as a global
6
+ * does not type-check. Leaving them out was the reason an author could read
7
+ * this command end to end and still write `startsWith(key, 'x')`. */
8
+ interface CelBuiltinInfo {
9
+ name: string;
10
+ signature: string;
11
+ category: "builtin";
12
+ receiver: string | null;
13
+ }
14
+ /** The `--json` document: Telo's catalog followed by CEL's built-ins. Exported
15
+ * for tests — the listing is what every new CEL diagnostic points a reader at,
16
+ * so "does it contain the functions those diagnostics are about" is worth
17
+ * asserting without spawning a CLI. */
18
+ export declare function functionListing(): (CelFunctionInfo | CelBuiltinInfo)[];
2
19
  export declare function celCommand(yargs: Argv): Argv;
20
+ export {};
3
21
  //# sourceMappingURL=cel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cel.d.ts","sourceRoot":"","sources":["../../src/commands/cel.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAiElC,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAkC5C"}
1
+ {"version":3,"file":"cel.d.ts","sourceRoot":"","sources":["../../src/commands/cel.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAGlC;;;;sEAIsE;AACtE,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAWD;;;wCAGwC;AACxC,wBAAgB,eAAe,IAAI,CAAC,eAAe,GAAG,cAAc,CAAC,EAAE,CAEtE;AAiGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAkC5C"}
@@ -1,9 +1,31 @@
1
- import { buildCelEnvironment, celFunctionCatalog } from "@telorun/templating";
1
+ import { buildCelEnvironment, celBuiltinFunctions, celFunctionCatalog, } from "@telorun/templating";
2
2
  import { enableBigIntJson, nodeCelHandlers } from "@telorun/kernel";
3
+ import { output } from "../output.js";
4
+ function builtins() {
5
+ return celBuiltinFunctions().map((fn) => ({
6
+ name: fn.name,
7
+ signature: fn.signature,
8
+ category: "builtin",
9
+ receiver: fn.receiverType,
10
+ }));
11
+ }
12
+ /** The `--json` document: Telo's catalog followed by CEL's built-ins. Exported
13
+ * for tests — the listing is what every new CEL diagnostic points a reader at,
14
+ * so "does it contain the functions those diagnostics are about" is worth
15
+ * asserting without spawning a CLI. */
16
+ export function functionListing() {
17
+ return [...celFunctionCatalog(), ...builtins()];
18
+ }
3
19
  function printFunctions(asJson) {
4
20
  const catalog = celFunctionCatalog();
5
- if (asJson) {
6
- console.log(JSON.stringify(catalog, null, 2));
21
+ const out = output();
22
+ // `--json` predates the global flag and is an alias for it. The array IS the
23
+ // contract, so it is emitted bare rather than inside an envelope. Built-ins
24
+ // are appended rather than merged into a new shape: a consumer reading
25
+ // `signature` and `name` keeps working, and one reading `category` sees a
26
+ // new value rather than a changed one.
27
+ if (asJson || out.isJson) {
28
+ out.document(functionListing());
7
29
  return;
8
30
  }
9
31
  const byCategory = new Map();
@@ -13,18 +35,33 @@ function printFunctions(asJson) {
13
35
  byCategory.set(fn.category, list);
14
36
  }
15
37
  for (const [category, fns] of byCategory) {
16
- console.log(`\n${category}`);
38
+ out.line(`\n${category}`);
17
39
  for (const fn of fns) {
18
40
  const tags = [
19
41
  fn.hostBacked ? "host" : null,
20
42
  fn.deterministic ? null : "non-deterministic",
21
43
  ].filter(Boolean);
22
44
  const suffix = tags.length ? ` [${tags.join(", ")}]` : "";
23
- console.log(` ${fn.signature}${suffix}`);
24
- console.log(` ${fn.summary}`);
45
+ out.line(` ${fn.signature}${suffix}`);
46
+ out.line(` ${fn.summary}`);
25
47
  }
26
48
  }
27
- console.log();
49
+ // Grouped by receiver, because the grouping IS the information: everything
50
+ // under `on string` must be called on a value, and the globals must not be.
51
+ const byReceiver = new Map();
52
+ for (const fn of builtins()) {
53
+ const key = fn.receiver ?? "";
54
+ const list = byReceiver.get(key) ?? [];
55
+ list.push(fn.signature);
56
+ byReceiver.set(key, list);
57
+ }
58
+ out.line("\nCEL built-ins (provided by CEL itself)");
59
+ for (const [receiver, signatures] of [...byReceiver].sort(([a], [b]) => a.localeCompare(b))) {
60
+ out.line(` ${receiver === "" ? "global functions" : `on ${receiver}`}`);
61
+ for (const signature of signatures.sort())
62
+ out.line(` ${signature}`);
63
+ }
64
+ out.line();
28
65
  }
29
66
  function evalExpression(expr, contextJson, asJson) {
30
67
  // The one command that evaluates CEL without a kernel, so it installs the
@@ -33,12 +70,17 @@ function evalExpression(expr, contextJson, asJson) {
33
70
  // it through `boot()`, which is what keeps the CLI and an embedding Node app
34
71
  // identical: hosting a kernel is the only thing that installs it.
35
72
  enableBigIntJson();
73
+ const out = output();
36
74
  let context;
37
75
  try {
38
76
  context = contextJson ? JSON.parse(contextJson) : {};
39
77
  }
40
78
  catch (err) {
41
- console.error(`Invalid --context JSON: ${err instanceof Error ? err.message : String(err)}`);
79
+ const message = `Invalid --context JSON: ${err instanceof Error ? err.message : String(err)}`;
80
+ // Prose on stderr plus a non-zero exit — never an envelope on stdout.
81
+ // stdout is the document, and an error object there would be
82
+ // indistinguishable from a CEL expression that evaluated to one.
83
+ out.errLine(message);
42
84
  process.exit(1);
43
85
  }
44
86
  // Real Node handlers so host-backed functions (sha256, base64, …) behave
@@ -49,14 +91,20 @@ function evalExpression(expr, contextJson, asJson) {
49
91
  result = env.parse(expr)(context);
50
92
  }
51
93
  catch (err) {
52
- console.error(err instanceof Error ? err.message : String(err));
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ // Prose on stderr plus a non-zero exit — never an envelope on stdout.
96
+ // stdout is the document, and an error object there would be
97
+ // indistinguishable from a CEL expression that evaluated to one.
98
+ out.errLine(message);
53
99
  process.exit(1);
54
100
  }
55
- if (asJson) {
56
- console.log(JSON.stringify(result, null, 2));
101
+ // The evaluated value IS the contract — emitted bare, exactly as `--json`
102
+ // already did, so the int64 encoding installed above stays observable.
103
+ if (asJson || out.isJson) {
104
+ out.document(result);
57
105
  }
58
106
  else {
59
- console.log(typeof result === "bigint" ? result.toString() : result);
107
+ out.line(String(typeof result === "bigint" ? result.toString() : result));
60
108
  }
61
109
  }
62
110
  export function celCommand(yargs) {
@@ -1 +1 @@
1
- {"version":3,"file":"cel.js","sourceRoot":"","sources":["../../src/commands/cel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAwB,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGpE,SAAS,cAAc,CAAC,MAAe;IACrC,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC;IACrC,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,GAAG,EAA6B,CAAC;IACxD,KAAK,MAAM,EAAE,IAAI,OAAO,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/C,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACd,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,UAAU,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC,CAAC;QAC7B,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG;gBACX,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI;gBAC7B,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB;aAC9C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,SAAS,GAAG,MAAM,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,WAA+B,EAAE,MAAe;IACpF,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,6EAA6E;IAC7E,kEAAkE;IAClE,gBAAgB,EAAE,CAAC;IAEnB,IAAI,OAAgC,CAAC;IACrC,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yEAAyE;IACzE,oCAAoC;IACpC,MAAM,GAAG,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjD,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAW;IACpC,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,6CAA6C,EAAE,CAAC,GAAG,EAAE,EAAE,CACjF,GAAG;SACA,OAAO,CACN,WAAW,EACX,gEAAgE,EAChE,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,EACnF,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAC7C;SACA,OAAO,CACN,mBAAmB,EACnB,uDAAuD,EACvD,CAAC,CAAC,EAAE,EAAE,CACJ,CAAC;SACE,UAAU,CAAC,YAAY,EAAE;QACxB,QAAQ,EAAE,6CAA6C;QACvD,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,IAAI;KACnB,CAAC;SACD,MAAM,CAAC,SAAS,EAAE;QACjB,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,mEAAmE;KAC9E,CAAC;SACD,MAAM,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,EACpF,CAAC,IAAI,EAAE,EAAE,CACP,cAAc,CACZ,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EACvB,IAAI,CAAC,OAA6B,EAClC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CACnB,CACJ;SACA,aAAa,CAAC,CAAC,EAAE,6CAA6C,CAAC,CACnE,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"cel.js","sourceRoot":"","sources":["../../src/commands/cel.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAwOlC,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DhB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAoB9C"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AA+PlC,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EhB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,CAoB9C"}
@@ -6,7 +6,8 @@ import { defaultTransportRegistry } from "@telorun/kernel/transports";
6
6
  import * as fs from "fs/promises";
7
7
  import * as path from "path";
8
8
  import { pathToFileURL } from "url";
9
- import { createLogger, formatAnalysisDiagnostics, formatDiagnostics } from "../logger.js";
9
+ import { createLogger, formatAnalysisDiagnostics, formatDiagnostics, } from "../logger.js";
10
+ import { outErrLine, output } from "../output.js";
10
11
  import { RecordingCacheSource, readOriginDigests, revalidateMutableOciRefs, writeOriginDigests, } from "../manifest-freshness.js";
11
12
  const DEFAULT_REGISTRY_URL = "https://registry.telo.run";
12
13
  function cacheTargetFor(entryPath) {
@@ -70,7 +71,7 @@ async function dropStaleEntry(file, session, log) {
70
71
  await fs.rm(file, { force: true });
71
72
  }
72
73
  catch (err) {
73
- process.stderr.write(`${log.warn(`[manifest-cache] could not remove stale entry ${file}: ${err instanceof Error ? err.message : String(err)}`)}\n`);
74
+ outErrLine(`${log.err.warn(`[manifest-cache] could not remove stale entry ${file}: ${err instanceof Error ? err.message : String(err)}`)}\n`);
74
75
  }
75
76
  session.loader.forget(pathToFileURL(file).href);
76
77
  for (const recorder of session.recorders) {
@@ -110,6 +111,7 @@ knownDigests, log) {
110
111
  return {
111
112
  errorCount: 0,
112
113
  warnCount: 0,
114
+ diagnostics: [],
113
115
  staleFiles: freshness.staleFiles,
114
116
  digests: freshness.digests,
115
117
  };
@@ -141,7 +143,7 @@ knownDigests, log) {
141
143
  await writeOriginDigests(cacheTarget.manifestsDir, digests);
142
144
  }
143
145
  catch (err) {
144
- process.stderr.write(`${log.warn(`[manifest-cache] write failed: ${err instanceof Error ? err.message : String(err)}`)}\n`);
146
+ outErrLine(`${log.err.warn(`[manifest-cache] write failed: ${err instanceof Error ? err.message : String(err)}`)}\n`);
145
147
  }
146
148
  }
147
149
  return { ...counts, staleFiles: [], digests };
@@ -150,8 +152,25 @@ knownDigests, log) {
150
152
  const sourceLine = err.sourceLine;
151
153
  const displayPath = isUrl ? entryPath : path.relative(process.cwd(), entryPath);
152
154
  const loc = sourceLine !== undefined ? `:${sourceLine + 1}` : "";
153
- formatDiagnostics([{ message: err instanceof Error ? err.message : String(err) }], log, `${displayPath}${loc}`);
154
- return { errorCount: 1, warnCount: 0, staleFiles: [], digests: new Map() };
155
+ const message = err instanceof Error ? err.message : String(err);
156
+ formatDiagnostics([{ message }], log, `${displayPath}${loc}`);
157
+ // A load failure is a diagnostic like any other to a `-o json` consumer;
158
+ // dropping it there would make the payload disagree with the exit code.
159
+ return {
160
+ errorCount: 1,
161
+ warnCount: 0,
162
+ diagnostics: [
163
+ {
164
+ file: displayPath,
165
+ line: sourceLine !== undefined ? sourceLine + 1 : 1,
166
+ column: 1,
167
+ severity: "error",
168
+ message,
169
+ },
170
+ ],
171
+ staleFiles: [],
172
+ digests: new Map(),
173
+ };
155
174
  }
156
175
  }
157
176
  export async function check(argv) {
@@ -168,6 +187,7 @@ export async function check(argv) {
168
187
  const session = openSession([...cacheTargets.values()], registryUrl);
169
188
  let totalErrors = 0;
170
189
  let totalWarns = 0;
190
+ const allDiagnostics = [];
171
191
  for (const p of argv.paths) {
172
192
  const cacheTarget = cacheTargetFor(resolveEntryPath(p));
173
193
  let outcome = await checkOne(p, registryUrl, session, cacheTarget, cacheWrite, null, log);
@@ -184,9 +204,11 @@ export async function check(argv) {
184
204
  }
185
205
  totalErrors += outcome.errorCount;
186
206
  totalWarns += outcome.warnCount;
207
+ allDiagnostics.push(...outcome.diagnostics);
187
208
  }
209
+ const out = output();
188
210
  if (totalErrors === 0 && totalWarns === 0) {
189
- console.log(log.ok("✓") + " No issues found");
211
+ out.line(log.ok("✓") + " No issues found");
190
212
  }
191
213
  else {
192
214
  const parts = [];
@@ -194,10 +216,23 @@ export async function check(argv) {
194
216
  parts.push(log.error(`${totalErrors} error${totalErrors !== 1 ? "s" : ""}`));
195
217
  if (totalWarns > 0)
196
218
  parts.push(log.warn(`${totalWarns} warning${totalWarns !== 1 ? "s" : ""}`));
197
- console.log(`\n${parts.join(", ")}`);
219
+ out.line(`\n${parts.join(", ")}`);
198
220
  }
221
+ // Emitted even when clean: an empty `diagnostics` array is the answer, and a
222
+ // consumer must not have to treat "no output" as success.
223
+ out.emit({
224
+ ok: totalErrors === 0,
225
+ errorCount: totalErrors,
226
+ warnCount: totalWarns,
227
+ diagnostics: allDiagnostics,
228
+ });
229
+ // `process.exitCode`, not `process.exit()`: the structured payload was just
230
+ // written, and on a pipe `write` is asynchronous while `exit` does not flush. A
231
+ // large diagnostic set exceeds the 64 KB pipe buffer, and truncated JSON is a
232
+ // parse failure for the one consumer this format exists for. Returning lets
233
+ // the event loop drain.
199
234
  if (totalErrors > 0)
200
- process.exit(1);
235
+ process.exitCode = 1;
201
236
  }
202
237
  export function checkCommand(yargs) {
203
238
  return yargs.command("check <paths..>", "Check one or more Telo manifests for errors without running them", (y) => y