@telorun/cli 0.70.0 → 0.71.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 (41) hide show
  1. package/dist/cli.js +11 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/commands/cel.d.ts.map +1 -1
  4. package/dist/commands/cel.js +26 -11
  5. package/dist/commands/cel.js.map +1 -1
  6. package/dist/commands/check.d.ts.map +1 -1
  7. package/dist/commands/check.js +43 -8
  8. package/dist/commands/check.js.map +1 -1
  9. package/dist/commands/install.d.ts.map +1 -1
  10. package/dist/commands/install.js +27 -17
  11. package/dist/commands/install.js.map +1 -1
  12. package/dist/commands/module.d.ts.map +1 -1
  13. package/dist/commands/module.js +36 -31
  14. package/dist/commands/module.js.map +1 -1
  15. package/dist/commands/publish.d.ts.map +1 -1
  16. package/dist/commands/publish.js +40 -24
  17. package/dist/commands/publish.js.map +1 -1
  18. package/dist/commands/run.d.ts.map +1 -1
  19. package/dist/commands/run.js +15 -4
  20. package/dist/commands/run.js.map +1 -1
  21. package/dist/commands/search.d.ts.map +1 -1
  22. package/dist/commands/search.js +19 -10
  23. package/dist/commands/search.js.map +1 -1
  24. package/dist/commands/upgrade.d.ts.map +1 -1
  25. package/dist/commands/upgrade.js +35 -21
  26. package/dist/commands/upgrade.js.map +1 -1
  27. package/dist/controller-progress.d.ts.map +1 -1
  28. package/dist/controller-progress.js +0 -0
  29. package/dist/controller-progress.js.map +1 -1
  30. package/dist/debug-event-subscriber.d.ts.map +1 -1
  31. package/dist/debug-event-subscriber.js +2 -1
  32. package/dist/debug-event-subscriber.js.map +1 -1
  33. package/dist/logger.d.ts +23 -0
  34. package/dist/logger.d.ts.map +1 -1
  35. package/dist/logger.js +65 -36
  36. package/dist/logger.js.map +1 -1
  37. package/dist/output.d.ts +111 -0
  38. package/dist/output.d.ts.map +1 -0
  39. package/dist/output.js +143 -0
  40. package/dist/output.js.map +1 -0
  41. package/package.json +1 -1
package/dist/logger.d.ts CHANGED
@@ -1,11 +1,33 @@
1
1
  import type { AnalysisDiagnostic, LoadedGraph } from "@telorun/analyzer";
2
2
  import { type RuntimeDiagnostic } from "@telorun/kernel";
3
+ /** One diagnostic as `-o json` reports it. The shape is the machine contract
4
+ * that replaces parsing the prose form: `code` is what a caller branches on,
5
+ * and the location is pre-resolved because deriving it needs the loaded graph,
6
+ * which the consumer does not have. */
7
+ export interface JsonDiagnostic {
8
+ file: string;
9
+ line: number;
10
+ column: number;
11
+ severity: "error" | "warning";
12
+ code?: string;
13
+ message: string;
14
+ }
15
+ /** The logger's colouring delegates to `Output`'s per-stream palettes.
16
+ *
17
+ * Its methods paint text destined for STDOUT; `log.err` is the same palette
18
+ * bound to stderr. Which one a caller wants is decided by where it writes, not
19
+ * by the process — `formatDiagnostics` writes to stderr and `check`'s summary
20
+ * to stdout, and one shared decision was wrong for whichever stream was
21
+ * redirected. Under `-o json` both palettes are plain, so structured output
22
+ * cannot carry escapes. */
3
23
  export declare function createLogger(verbose: boolean): {
4
24
  info: (...args: any[]) => void;
5
25
  ok: (text: string) => string;
6
26
  warn: (text: string) => string;
7
27
  error: (text: string) => string;
8
28
  dim: (text: string) => string;
29
+ /** Palette for text written to stderr. */
30
+ err: import("./output.js").Palette;
9
31
  verbose: boolean;
10
32
  };
11
33
  export type Logger = ReturnType<typeof createLogger>;
@@ -27,5 +49,6 @@ export declare function formatDiagnostics(diagnostics: RuntimeDiagnostic[], log:
27
49
  export declare function formatAnalysisDiagnostics(diagnostics: AnalysisDiagnostic[], graph: LoadedGraph, log: Logger, entryPath: string): {
28
50
  errorCount: number;
29
51
  warnCount: number;
52
+ diagnostics: JsonDiagnostic[];
30
53
  };
31
54
  //# sourceMappingURL=logger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAIL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAyCzB,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO;oBAezB,GAAG,EAAE;eACV,MAAM;iBACJ,MAAM;kBACL,MAAM;gBACR,MAAM;;EAGrB;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAErD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,iBAAiB,EAAE,EAChC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,WAAW,GAClB,IAAI,CAmEN;AAED;;yBAEyB;AACzB,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,kBAAkB,EAAE,EACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAqB3C"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGzE,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,iBAAiB,CAAC;AAwDzB;;;wCAGwC;AACxC,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;4BAO4B;AAC5B,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO;oBAGzB,GAAG,EAAE;eAGV,MAAM;iBACJ,MAAM;kBACL,MAAM;gBACR,MAAM;IAClB,0CAA0C;;;EAI7C;AAED,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC;AAErD;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,iBAAiB,EAAE,EAChC,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,WAAW,GAClB,IAAI,CAuEN;AAED;;yBAEyB;AACzB,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,kBAAkB,EAAE,EACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,cAAc,EAAE,CAAA;CAAE,CAmC1E"}
package/dist/logger.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { DiagnosticSeverity } from "@telorun/analyzer";
2
2
  import { findPositions, resolveRange } from "@telorun/ide-support";
3
- import { decideColor, describeBlockedGroup, groupBlockedResources, } from "@telorun/kernel";
3
+ import { describeBlockedGroup, groupBlockedResources, } from "@telorun/kernel";
4
4
  import * as path from "path";
5
5
  import { fileURLToPath } from "url";
6
+ import { output } from "./output.js";
6
7
  /** Render a manifest source for display: a local `file://` URL (how the loader
7
8
  * canonicalizes on-disk manifests) becomes a CWD-relative path, a real remote
8
9
  * URL (`http(s)://`) is kept absolute, and a bare path is made relative. */
@@ -26,7 +27,7 @@ function displaySourcePath(raw) {
26
27
  * Undefined when nothing located it — a diagnostic whose resource is synthetic
27
28
  * and whose file matches no graph source. A pointer to line 1 would be worse
28
29
  * than none: it sends the reader somewhere the error is not. */
29
- function resolveLocation(graph, d, fallbackSource) {
30
+ function resolveLocationParts(graph, d, fallbackSource) {
30
31
  const located = findPositions(graph, d.data);
31
32
  if (!located && !d.range)
32
33
  return undefined;
@@ -34,28 +35,38 @@ function resolveLocation(graph, d, fallbackSource) {
34
35
  positionIndex: located?.positionIndex,
35
36
  sourceLine: located?.sourceLine,
36
37
  });
37
- return `${displaySourcePath(located?.file ?? fallbackSource)}:${range.start.line + 1}:${range.start.character + 1}`;
38
+ // 1-based for display; the analyzer's own range is 0-based.
39
+ return {
40
+ file: displaySourcePath(located?.file ?? fallbackSource),
41
+ line: range.start.line + 1,
42
+ column: range.start.character + 1,
43
+ };
38
44
  }
45
+ function resolveLocation(graph, d, fallbackSource) {
46
+ const parts = resolveLocationParts(graph, d, fallbackSource);
47
+ return parts && `${parts.file}:${parts.line}:${parts.column}`;
48
+ }
49
+ /** The logger's colouring delegates to `Output`'s per-stream palettes.
50
+ *
51
+ * Its methods paint text destined for STDOUT; `log.err` is the same palette
52
+ * bound to stderr. Which one a caller wants is decided by where it writes, not
53
+ * by the process — `formatDiagnostics` writes to stderr and `check`'s summary
54
+ * to stdout, and one shared decision was wrong for whichever stream was
55
+ * redirected. Under `-o json` both palettes are plain, so structured output
56
+ * cannot carry escapes. */
39
57
  export function createLogger(verbose) {
40
- // The color decision follows `kernel/specs/logging.md` §11.2's precedence
41
- // order exactly, shared with the `pretty` log encoding rather than
42
- // reimplemented here. Notably this adds `NO_COLOR` support, which the CLI
43
- // previously ignored, and stops treating a bare `FORCE_COLOR=0` as "on" —
44
- // both behavior changes, both required by the spec.
45
- //
46
- // The decision is made against stdout, which is where this logger writes.
47
- const useColor = decideColor({
48
- setting: "auto",
49
- env: process.env,
50
- isTTY: Boolean(process.stdout.isTTY),
51
- });
52
- const wrap = (code, text) => (useColor ? `\x1b[${code}m${text}\x1b[0m` : text);
58
+ const out = output();
53
59
  return {
54
- info: (...args) => console.log(...args),
55
- ok: (text) => wrap("32", text),
56
- warn: (text) => wrap("33", text),
57
- error: (text) => wrap("31", text),
58
- dim: (text) => wrap("2", text),
60
+ info: (...args) => {
61
+ if (!out.isJson)
62
+ out.line(args.map((a) => String(a)).join(" "));
63
+ },
64
+ ok: (text) => out.stdout.ok(text),
65
+ warn: (text) => out.stdout.warn(text),
66
+ error: (text) => out.stdout.error(text),
67
+ dim: (text) => out.stdout.dim(text),
68
+ /** Palette for text written to stderr. */
69
+ err: out.stderr,
59
70
  verbose,
60
71
  };
61
72
  }
@@ -74,12 +85,16 @@ export function formatDiagnostics(diagnostics, log, displayPath, graph) {
74
85
  // Column the `error`/`warning` label occupies, so a collapsed group line sits
75
86
  // under the resource names it summarizes rather than under the label.
76
87
  const NAME_COLUMN = " ".repeat(" error ".length);
88
+ const out = output();
89
+ // This renderer writes to stderr throughout, so it paints with the stderr
90
+ // palette — the stdout one may be coloured when stderr is redirected.
91
+ const paint = log.err;
77
92
  const render = (entries, indent) => {
78
93
  for (const d of entries) {
79
94
  const skip = d.derived && !log.verbose;
80
95
  if (!skip) {
81
- const severityLabel = d.severity === "warning" ? log.warn("warning") : log.error("error");
82
- const code = d.code ? ` ${log.dim(d.code)}` : "";
96
+ const severityLabel = d.severity === "warning" ? paint.warn("warning") : paint.error("error");
97
+ const code = d.code ? ` ${paint.dim(d.code)}` : "";
83
98
  // A static failure that nothing could locate falls through to the
84
99
  // resource / bare-path branches below, which at least name what failed.
85
100
  const location = d.origin && graph
@@ -91,28 +106,28 @@ export function formatDiagnostics(diagnostics, log, displayPath, graph) {
91
106
  if (!d.details)
92
107
  return;
93
108
  for (const line of d.details.split("\n")) {
94
- console.error(`${detailIndent}${log.dim(line)}`);
109
+ out.errLine(`${detailIndent}${paint.dim(line)}`);
95
110
  }
96
111
  };
97
112
  if (location) {
98
113
  // Static-analysis failure — the position names the exact spot, so it
99
114
  // renders exactly as `telo check` does. Repeating the resource here
100
115
  // would duplicate it: an analyzer message already names its own.
101
- console.error(`${indent}${location} ${severityLabel} ${d.message}${code}`);
116
+ out.errLine(`${indent}${location} ${severityLabel} ${d.message}${code}`);
102
117
  printDetails(`${indent} `);
103
118
  }
104
119
  else if (d.resource) {
105
120
  // Runtime diagnostic — the failure is pinned to a resource, so the
106
121
  // entry manifest path adds no information. Show kind + name + message
107
122
  // and any structured details indented below.
108
- const who = `${d.kind ? `${log.dim(d.kind)} ` : ""}${d.resource}`;
109
- console.error(`${indent} ${severityLabel} ${who}: ${d.message}${code}`);
123
+ const who = `${d.kind ? `${paint.dim(d.kind)} ` : ""}${d.resource}`;
124
+ out.errLine(`${indent} ${severityLabel} ${who}: ${d.message}${code}`);
110
125
  printDetails(`${indent}${NAME_COLUMN} `);
111
126
  }
112
127
  else {
113
128
  // Non-resource diagnostic (e.g. loader/parse failure) — keep the file
114
129
  // path since it is the only location cue we have.
115
- console.error(`${indent}${displayPath} ${severityLabel} ${d.message}${code}`);
130
+ out.errLine(`${indent}${displayPath} ${severityLabel} ${d.message}${code}`);
116
131
  printDetails(`${indent} `);
117
132
  }
118
133
  }
@@ -124,7 +139,7 @@ export function formatDiagnostics(diagnostics, log, displayPath, graph) {
124
139
  }
125
140
  if (!log.verbose) {
126
141
  for (const [blockedBy, names] of groupBlockedResources(entries)) {
127
- console.error(`${indent}${NAME_COLUMN}${log.dim(describeBlockedGroup(blockedBy, names))}`);
142
+ out.errLine(`${indent}${NAME_COLUMN}${paint.dim(describeBlockedGroup(blockedBy, names))}`);
128
143
  }
129
144
  }
130
145
  };
@@ -136,20 +151,34 @@ export function formatDiagnostics(diagnostics, log, displayPath, graph) {
136
151
  export function formatAnalysisDiagnostics(diagnostics, graph, log, entryPath) {
137
152
  let errorCount = 0;
138
153
  let warnCount = 0;
154
+ const out = output();
155
+ const collected = [];
139
156
  for (const d of diagnostics) {
140
157
  // `check` prints one line per diagnostic and has no resource-named form to
141
158
  // fall back to, so an unlocatable one still leads with the entry manifest.
142
- const loc = resolveLocation(graph, d, entryPath) ?? `${displaySourcePath(entryPath)}:1:1`;
143
- const severityLabel = (d.severity ?? DiagnosticSeverity.Warning) <= DiagnosticSeverity.Error
144
- ? log.error("error")
145
- : log.warn("warning");
159
+ const parts = resolveLocationParts(graph, d, entryPath) ?? {
160
+ file: displaySourcePath(entryPath),
161
+ line: 1,
162
+ column: 1,
163
+ };
164
+ const isError = (d.severity ?? DiagnosticSeverity.Warning) <= DiagnosticSeverity.Error;
165
+ const severityLabel = isError ? log.error("error") : log.warn("warning");
146
166
  const code = d.code ? ` ${log.dim(String(d.code))}` : "";
147
- console.log(`${loc} ${severityLabel} ${d.message}${code}`);
148
- if ((d.severity ?? DiagnosticSeverity.Warning) <= DiagnosticSeverity.Error)
167
+ // Silent under `-o json`: the structured payload carries the same
168
+ // diagnostics with their location resolved, so printing here too would
169
+ // interleave prose into a document a consumer parses.
170
+ out.line(`${parts.file}:${parts.line}:${parts.column} ${severityLabel} ${d.message}${code}`);
171
+ collected.push({
172
+ ...parts,
173
+ severity: isError ? "error" : "warning",
174
+ ...(d.code === undefined ? {} : { code: String(d.code) }),
175
+ message: d.message,
176
+ });
177
+ if (isError)
149
178
  errorCount++;
150
179
  else
151
180
  warnCount++;
152
181
  }
153
- return { errorCount, warnCount };
182
+ return { errorCount, warnCount, diagnostics: collected };
154
183
  }
155
184
  //# sourceMappingURL=logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /** Output encodings the CLI can produce. `yaml` is deliberately absent: the flag
2
+ * is an enum precisely so it can gain a value later without a second flag. */
3
+ export type OutputFormat = "text" | "json";
4
+ export declare const OUTPUT_FORMATS: OutputFormat[];
5
+ /** A colour palette bound to ONE stream.
6
+ *
7
+ * Colour is a property of the descriptor being written to, not of the process:
8
+ * `telo check 2>/dev/null` leaves stdout a TTY and stderr not, and a single
9
+ * process-wide decision is wrong for one of them either way. The CLI used to
10
+ * decide once from `process.stdout.isTTY` while `formatDiagnostics` wrote to
11
+ * stderr, so redirecting one stream and not the other produced escapes where
12
+ * they could not be rendered — the leak this splits apart. */
13
+ export interface Palette {
14
+ ok(text: string): string;
15
+ warn(text: string): string;
16
+ error(text: string): string;
17
+ dim(text: string): string;
18
+ }
19
+ /** The minimum of a writable stream this needs. Narrow on purpose: a test hands
20
+ * in a recording pair, so `Output` never reads process globals. */
21
+ export interface OutputStream {
22
+ isTTY?: boolean;
23
+ write(chunk: string): unknown;
24
+ }
25
+ export interface OutputOptions {
26
+ format: OutputFormat;
27
+ stdout?: OutputStream;
28
+ stderr?: OutputStream;
29
+ env?: NodeJS.ProcessEnv;
30
+ }
31
+ /** The single seam every CLI-owned write goes through.
32
+ *
33
+ * The stream split is the whole contract:
34
+ *
35
+ * - **stdout is the machine surface.** Under `-o json` it carries the payload
36
+ * and nothing else, so a consumer parses it whole.
37
+ * - **stderr is the human surface, in BOTH formats.** Prose keeps flowing under
38
+ * `-o json` — the convention npm, cargo and kubectl follow — because the
39
+ * alternative is silence: a command that reports a failure reason through
40
+ * prose would otherwise have it swallowed, leaving `{"ok":false}` with no
41
+ * cause. Suppressing stderr was error swallowing, which Telo forbids.
42
+ *
43
+ * `telo run` is exempt from `-o json` entirely; see `emit`. */
44
+ export declare class Output {
45
+ readonly format: OutputFormat;
46
+ readonly stdout: Palette;
47
+ readonly stderr: Palette;
48
+ private readonly outStream;
49
+ private readonly errStream;
50
+ constructor(options: OutputOptions);
51
+ get isJson(): boolean;
52
+ /** Human-readable line on stdout. Suppressed under `-o json`, where stdout is
53
+ * reserved for the payload. */
54
+ line(text?: string): void;
55
+ /** Human-readable line on stderr. Written in BOTH formats — stderr is not the
56
+ * machine contract, and silencing it loses the reason a command failed. */
57
+ errLine(text?: string): void;
58
+ /** Emit a command's structured RESULT ENVELOPE. A no-op in text mode.
59
+ *
60
+ * Every command that owns its stdout calls this exactly once, including when
61
+ * it has nothing interesting to report — a consumer cannot distinguish
62
+ * "nothing to say" from "this command ignores the flag", so a bare envelope
63
+ * is the difference between a contract and a guess.
64
+ *
65
+ * `telo run` is the ONE exemption, and it is a property of the command rather
66
+ * than an oversight: the kernel runs in-process and the app's own output goes
67
+ * to these same descriptors (`teeStdio` copies, it does not redirect), so
68
+ * NEITHER stream is the CLI's to claim. An envelope written after arbitrary
69
+ * app output is unparseable, which is the exact failure `-o json` exists to
70
+ * remove. The machine surface for a run already exists and is `--debug`,
71
+ * whose wire protocol is framed per event precisely because it shares a
72
+ * stream. */
73
+ emit(payload: unknown): void;
74
+ /** Write a bare DOCUMENT to stdout, in either format.
75
+ *
76
+ * For the commands whose structured form is the document itself rather than a
77
+ * result report — `cel`, `search`, `module versions|manifest|digest|resources|kinds`.
78
+ * Unconditional because their per-command `--json` flag predates `-o` and
79
+ * must keep working under the default `text` format. One serializer with
80
+ * `emit`, so the CLI has a single JSON encoding rather than three. */
81
+ document(payload: unknown): void;
82
+ /** Write verbatim content to stdout, unconditionally and with no framing.
83
+ *
84
+ * For the one case that is neither prose nor a JSON payload: `telo module
85
+ * manifest` printing a module's `telo.yaml` bytes, which ARE the output. It
86
+ * bypasses format handling because the bytes are the answer in every format
87
+ * — the `--json` path wraps them in a document instead and never reaches
88
+ * here. */
89
+ raw(content: string): void;
90
+ }
91
+ export declare function configureOutput(format: OutputFormat): void;
92
+ /** Swap the ambient instance, returning a restore function.
93
+ *
94
+ * For tests of code that reaches the seam through the accessor rather than
95
+ * through a parameter — they hand in an `Output` over recording streams instead
96
+ * of spying on `process.stderr.write`. */
97
+ export declare function installOutput(replacement: Output): () => void;
98
+ export declare function output(): Output;
99
+ /** yargs has already rejected anything outside `choices` by the time a handler
100
+ * runs, so an unrecognized value here means the enum grew and this function was
101
+ * not updated. Throwing is the point: silently degrading `-o yaml` to text is
102
+ * the worst failure a format flag can have. */
103
+ export declare function parseOutputFormat(value: unknown): OutputFormat;
104
+ /** Free-function forms of the seam, for the many call sites that only need to
105
+ * write a line and would otherwise each bind a local. They read the singleton
106
+ * per call, so they observe the configured format no matter when they run. */
107
+ export declare const outLine: (text?: string) => void;
108
+ export declare const outErrLine: (text?: string) => void;
109
+ export declare const outEmit: (payload: unknown) => void;
110
+ export declare const outDocument: (payload: unknown) => void;
111
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAEA;+EAC+E;AAC/E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C,eAAO,MAAM,cAAc,EAAE,YAAY,EAAqB,CAAC;AAE/D;;;;;;;+DAO+D;AAC/D,MAAM,WAAW,OAAO;IACtB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAiBD;oEACoE;AACpE,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;;;;;;;;gEAYgE;AAChE,qBAAa,MAAM;IACjB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,OAAO,EAAE,aAAa;IAkBlC,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED;oCACgC;IAChC,IAAI,CAAC,IAAI,SAAK,GAAG,IAAI;IAIrB;gFAC4E;IAC5E,OAAO,CAAC,IAAI,SAAK,GAAG,IAAI;IAIxB;;;;;;;;;;;;;;kBAcc;IACd,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI5B;;;;;;2EAMuE;IACvE,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIhC;;;;;;gBAMY;IACZ,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;CAG3B;AAWD,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CAE1D;AAED;;;;2CAI2C;AAC3C,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,IAAI,CAM7D;AAED,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED;;;gDAGgD;AAChD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAK9D;AAED;;+EAE+E;AAC/E,eAAO,MAAM,OAAO,GAAI,aAAS,KAAG,IAA0B,CAAC;AAC/D,eAAO,MAAM,UAAU,GAAI,aAAS,KAAG,IAA6B,CAAC;AACrE,eAAO,MAAM,OAAO,GAAI,SAAS,OAAO,KAAG,IAA6B,CAAC;AACzE,eAAO,MAAM,WAAW,GAAI,SAAS,OAAO,KAAG,IAAiC,CAAC"}
package/dist/output.js ADDED
@@ -0,0 +1,143 @@
1
+ import { decideColor } from "@telorun/kernel";
2
+ export const OUTPUT_FORMATS = ["text", "json"];
3
+ const PLAIN = {
4
+ ok: (t) => t,
5
+ warn: (t) => t,
6
+ error: (t) => t,
7
+ dim: (t) => t,
8
+ };
9
+ function paletteFor(isTTY, env) {
10
+ // Follows `kernel/specs/logging.md` §11.2 precedence, shared with the `pretty`
11
+ // log encoding rather than reimplemented.
12
+ if (!decideColor({ setting: "auto", env, isTTY }))
13
+ return PLAIN;
14
+ const wrap = (code) => (text) => `\x1b[${code}m${text}\x1b[0m`;
15
+ return { ok: wrap("32"), warn: wrap("33"), error: wrap("31"), dim: wrap("2") };
16
+ }
17
+ /** The single seam every CLI-owned write goes through.
18
+ *
19
+ * The stream split is the whole contract:
20
+ *
21
+ * - **stdout is the machine surface.** Under `-o json` it carries the payload
22
+ * and nothing else, so a consumer parses it whole.
23
+ * - **stderr is the human surface, in BOTH formats.** Prose keeps flowing under
24
+ * `-o json` — the convention npm, cargo and kubectl follow — because the
25
+ * alternative is silence: a command that reports a failure reason through
26
+ * prose would otherwise have it swallowed, leaving `{"ok":false}` with no
27
+ * cause. Suppressing stderr was error swallowing, which Telo forbids.
28
+ *
29
+ * `telo run` is exempt from `-o json` entirely; see `emit`. */
30
+ export class Output {
31
+ format;
32
+ stdout;
33
+ stderr;
34
+ outStream;
35
+ errStream;
36
+ constructor(options) {
37
+ const { format, stdout = process.stdout, stderr = process.stderr, env = process.env, } = options;
38
+ this.format = format;
39
+ this.outStream = stdout;
40
+ this.errStream = stderr;
41
+ // Structured output must never carry escapes: a consumer parses it, and no
42
+ // terminal renders it. Deciding this here rather than at each call site is
43
+ // what makes "JSON is always clean" true by construction. stderr keeps its
44
+ // colour under `-o json` because it stays the human surface.
45
+ this.stdout = format === "text" ? paletteFor(Boolean(stdout.isTTY), env) : PLAIN;
46
+ this.stderr = paletteFor(Boolean(stderr.isTTY), env);
47
+ }
48
+ get isJson() {
49
+ return this.format === "json";
50
+ }
51
+ /** Human-readable line on stdout. Suppressed under `-o json`, where stdout is
52
+ * reserved for the payload. */
53
+ line(text = "") {
54
+ if (this.format === "text")
55
+ this.outStream.write(`${text}\n`);
56
+ }
57
+ /** Human-readable line on stderr. Written in BOTH formats — stderr is not the
58
+ * machine contract, and silencing it loses the reason a command failed. */
59
+ errLine(text = "") {
60
+ this.errStream.write(`${text}\n`);
61
+ }
62
+ /** Emit a command's structured RESULT ENVELOPE. A no-op in text mode.
63
+ *
64
+ * Every command that owns its stdout calls this exactly once, including when
65
+ * it has nothing interesting to report — a consumer cannot distinguish
66
+ * "nothing to say" from "this command ignores the flag", so a bare envelope
67
+ * is the difference between a contract and a guess.
68
+ *
69
+ * `telo run` is the ONE exemption, and it is a property of the command rather
70
+ * than an oversight: the kernel runs in-process and the app's own output goes
71
+ * to these same descriptors (`teeStdio` copies, it does not redirect), so
72
+ * NEITHER stream is the CLI's to claim. An envelope written after arbitrary
73
+ * app output is unparseable, which is the exact failure `-o json` exists to
74
+ * remove. The machine surface for a run already exists and is `--debug`,
75
+ * whose wire protocol is framed per event precisely because it shares a
76
+ * stream. */
77
+ emit(payload) {
78
+ if (this.format === "json")
79
+ this.outStream.write(serialize(payload));
80
+ }
81
+ /** Write a bare DOCUMENT to stdout, in either format.
82
+ *
83
+ * For the commands whose structured form is the document itself rather than a
84
+ * result report — `cel`, `search`, `module versions|manifest|digest|resources|kinds`.
85
+ * Unconditional because their per-command `--json` flag predates `-o` and
86
+ * must keep working under the default `text` format. One serializer with
87
+ * `emit`, so the CLI has a single JSON encoding rather than three. */
88
+ document(payload) {
89
+ this.outStream.write(serialize(payload));
90
+ }
91
+ /** Write verbatim content to stdout, unconditionally and with no framing.
92
+ *
93
+ * For the one case that is neither prose nor a JSON payload: `telo module
94
+ * manifest` printing a module's `telo.yaml` bytes, which ARE the output. It
95
+ * bypasses format handling because the bytes are the answer in every format
96
+ * — the `--json` path wraps them in a document instead and never reaches
97
+ * here. */
98
+ raw(content) {
99
+ this.outStream.write(content);
100
+ }
101
+ }
102
+ function serialize(payload) {
103
+ return `${JSON.stringify(payload, null, 2)}\n`;
104
+ }
105
+ /** Configured once from argv by a yargs middleware, before any handler runs, so
106
+ * call sites far from the handler reach the same decision without threading it
107
+ * through every signature. Tests construct an `Output` directly instead. */
108
+ let current = new Output({ format: "text" });
109
+ export function configureOutput(format) {
110
+ current = new Output({ format });
111
+ }
112
+ /** Swap the ambient instance, returning a restore function.
113
+ *
114
+ * For tests of code that reaches the seam through the accessor rather than
115
+ * through a parameter — they hand in an `Output` over recording streams instead
116
+ * of spying on `process.stderr.write`. */
117
+ export function installOutput(replacement) {
118
+ const previous = current;
119
+ current = replacement;
120
+ return () => {
121
+ current = previous;
122
+ };
123
+ }
124
+ export function output() {
125
+ return current;
126
+ }
127
+ /** yargs has already rejected anything outside `choices` by the time a handler
128
+ * runs, so an unrecognized value here means the enum grew and this function was
129
+ * not updated. Throwing is the point: silently degrading `-o yaml` to text is
130
+ * the worst failure a format flag can have. */
131
+ export function parseOutputFormat(value) {
132
+ if (OUTPUT_FORMATS.includes(value))
133
+ return value;
134
+ throw new Error(`Unsupported --output format '${String(value)}'. Expected one of: ${OUTPUT_FORMATS.join(", ")}.`);
135
+ }
136
+ /** Free-function forms of the seam, for the many call sites that only need to
137
+ * write a line and would otherwise each bind a local. They read the singleton
138
+ * per call, so they observe the configured format no matter when they run. */
139
+ export const outLine = (text = "") => current.line(text);
140
+ export const outErrLine = (text = "") => current.errLine(text);
141
+ export const outEmit = (payload) => current.emit(payload);
142
+ export const outDocument = (payload) => current.document(payload);
143
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@telorun/cli",
3
- "version": "0.70.0",
3
+ "version": "0.71.0",
4
4
  "description": "Telo CLI - Command-line interface for the Telo runtime.",
5
5
  "keywords": [
6
6
  "telo",