runspec-node 0.28.1 → 0.30.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.
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AAyCA,wBAAgB,KAAK,IAAI,IAAI,CAoC5B;AAuLD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBtE"}
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"AA0CA,wBAAgB,KAAK,IAAI,IAAI,CA8C5B;AAuLD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBtE"}
package/dist/serve.js CHANGED
@@ -43,6 +43,7 @@ const finder_1 = require("./finder");
43
43
  const loader_1 = require("./loader");
44
44
  const inference_1 = require("./inference");
45
45
  const cli_1 = require("./cli");
46
+ const discovery_1 = require("./discovery");
46
47
  const MCP_PROTOCOL_VERSION = '2024-11-05';
47
48
  const ERR_PARSE = -32700;
48
49
  const ERR_METHOD_NOT_FOUND = -32601;
@@ -102,6 +103,18 @@ function serve() {
102
103
  }
103
104
  if (!isServeMatch(runnable.serve, context))
104
105
  continue;
106
+ // `serve` is an operator surface — skip runnables not discoverable to the
107
+ // `operator` audience (orthogonal to the serve *context* filter above). An
108
+ // internal helper (discoverable=false, or a list without "operator") is
109
+ // hidden from the agent surface this way.
110
+ const discErrors = (0, discovery_1.validateDiscoverable)(runnable.discoverable);
111
+ if (discErrors.length > 0) {
112
+ for (const err of discErrors)
113
+ process.stderr.write(`runspec serve: ${name}.discoverable: ${err}\n`);
114
+ process.exit(1);
115
+ }
116
+ if (!(0, discovery_1.isDiscoverableTo)(runnable.discoverable, discovery_1.OPERATOR))
117
+ continue;
105
118
  const inferred = (0, inference_1.inferScript)(runnable, config.autonomyDefault);
106
119
  tools[name] = (0, cli_1.buildSchema)(name, inferred, 'mcp');
107
120
  argSpecs[name] = inferred.args ?? {};
package/dist/serve.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../src/serve.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runspec-node",
3
- "version": "0.28.1",
3
+ "version": "0.30.0",
4
4
  "description": "Node/TypeScript language pack for runspec",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/cli.ts CHANGED
@@ -7,6 +7,7 @@ import * as logs from './logs';
7
7
  import { loadRaw } from './loader';
8
8
  import { inferScript } from './inference';
9
9
  import { parse } from './parser';
10
+ import { normaliseDiscoverable } from './discovery';
10
11
  import type { ScriptSpec, ArgSpec } from './models';
11
12
 
12
13
  const _CLI_CONFIG = path.join(__dirname, 'runspec.toml');
@@ -520,6 +521,7 @@ export function buildSchema(name: string, script: ScriptSpec, fmt: string): Reco
520
521
  description: script.description ?? '',
521
522
  'x-autonomy': script.autonomy ?? 'confirm',
522
523
  'x-output': script.output ?? 'text',
524
+ 'x-discoverable': normaliseDiscoverable(script.discoverable),
523
525
  inputSchema: { type: 'object', properties },
524
526
  };
525
527
 
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Discoverability audiences for runnables (the `discoverable` keyword).
3
+ *
4
+ * `discoverable` declares *which audiences* may discover a runnable, orthogonal
5
+ * to `serve` (which declares *the context*). Metadata only — it adds no runtime
6
+ * behaviour; the surfaces (`runspec serve`, `runspec local`, a future
7
+ * self-service catalog) read it to decide what to expose to whom.
8
+ *
9
+ * Canonical form is a list of audience strings:
10
+ * absent / true → ["operator"] (default; operator-visible)
11
+ * false → [] (hidden from all surfaces)
12
+ * ["operator", ...] → as written (validated)
13
+ *
14
+ * `self-service` is never implied — a runnable reaches a visitor-facing catalog
15
+ * only by listing it explicitly, so the default never exposes it to untrusted
16
+ * users. Mirrors packages/python/runspec/runspec/discovery.py.
17
+ */
18
+
19
+ export const OPERATOR = 'operator';
20
+ export const SELF_SERVICE = 'self-service';
21
+ export const AUDIENCES: readonly string[] = [OPERATOR, SELF_SERVICE];
22
+
23
+ export type Discoverable = boolean | string[] | undefined;
24
+
25
+ export function normaliseDiscoverable(value: Discoverable): string[] {
26
+ if (value === undefined || value === true) return [OPERATOR];
27
+ if (value === false) return [];
28
+ if (Array.isArray(value)) {
29
+ const seen: string[] = [];
30
+ for (const item of value) {
31
+ if (typeof item === 'string' && !seen.includes(item)) seen.push(item);
32
+ }
33
+ return seen;
34
+ }
35
+ return [OPERATOR];
36
+ }
37
+
38
+ export function validateDiscoverable(value: Discoverable): string[] {
39
+ if (value === undefined || typeof value === 'boolean') return [];
40
+ if (Array.isArray(value)) {
41
+ if (value.length === 0) {
42
+ return ['discoverable = [] is invalid — write false to hide everywhere, or omit to default to true'];
43
+ }
44
+ const unknown = value.filter((a) => !AUDIENCES.includes(a));
45
+ if (unknown.length > 0) {
46
+ return [`discoverable contains unknown audience(s) ${JSON.stringify(unknown)} — valid values are 'operator' and 'self-service'`];
47
+ }
48
+ return [];
49
+ }
50
+ return [`discoverable must be true, false, or a list of audiences ('operator', 'self-service'), got ${typeof value}`];
51
+ }
52
+
53
+ export function isDiscoverableTo(value: Discoverable, audience: string): boolean {
54
+ return normaliseDiscoverable(value).includes(audience);
55
+ }
package/src/loader.ts CHANGED
@@ -35,10 +35,13 @@ function normaliseLogging(raw: Record<string, unknown> | undefined): LoggingConf
35
35
  // response body), and verbosity for debugging is handled by the `--debug`
36
36
  // flag injected at parse time.
37
37
  //
38
- // `summary` (default true) writes one record per run to the audit log and
39
- // one human-readable line to stderr at process exit: duration, exit code,
40
- // log-event counts by level. Suppress per-invocation with `--no-summary`
41
- // or `RUNSPEC_NO_SUMMARY=1`.
38
+ // `summary` (default true) writes one structured record per run to the audit
39
+ // log at process exit (duration, exit code, per-level event counts) — the data
40
+ // the console history/analytics tabs and `runspec logs` read. `summary_console`
41
+ // (default false) additionally echoes a one-line human-readable summary to the
42
+ // terminal (stderr); off by default so stdout stays clean for pipes and the
43
+ // line never lands on a stream that log processors (e.g. Rundeck) tag as ERROR.
44
+ // Suppress both per-invocation with `--no-summary` or `RUNSPEC_NO_SUMMARY=1`.
42
45
  if (raw === undefined) return undefined;
43
46
  // `store` selects the file layout: 'single' = one rotating {runnable}.log;
44
47
  // 'per-run' = one file per invocation. Unknown values fall back to 'single'
@@ -48,6 +51,7 @@ function normaliseLogging(raw: Record<string, unknown> | undefined): LoggingConf
48
51
  rotate: String(raw['rotate'] ?? 'midnight'),
49
52
  keep: Number(raw['keep'] ?? 7),
50
53
  summary: raw['summary'] !== undefined ? Boolean(raw['summary']) : true,
54
+ summaryConsole: raw['summary_console'] !== undefined ? Boolean(raw['summary_console']) : false,
51
55
  store: store === 'per-run' ? 'per-run' : 'single',
52
56
  };
53
57
  }
@@ -63,6 +67,7 @@ function normaliseScript(name: string, raw: Record<string, unknown>): ScriptSpec
63
67
  autonomy: raw['autonomy'] as string | undefined,
64
68
  autonomyReason: raw['autonomy-reason'] as string | undefined,
65
69
  output: raw['output'] as string | undefined,
70
+ discoverable: raw['discoverable'] as boolean | string[] | undefined,
66
71
  requireCommand: (raw['require-command'] as boolean | undefined) ?? false,
67
72
  args: normaliseArgs((raw['args'] ?? {}) as Record<string, unknown>),
68
73
  groups: normaliseGroups((raw['groups'] ?? {}) as Record<string, unknown>),
@@ -75,6 +75,10 @@ interface SummaryState {
75
75
  emitted: boolean;
76
76
  user: string;
77
77
  userTarget: string | undefined;
78
+ /** Write the structured record to the audit log (gated by `summary`). */
79
+ writeRecord: boolean;
80
+ /** Echo the human-readable line to stderr (gated by `summary_console`). */
81
+ writeConsole: boolean;
78
82
  }
79
83
 
80
84
  let _summaryState: SummaryState | null = null;
@@ -225,8 +229,9 @@ function formatConsole(record: LogRecord, showTracebacks: boolean): string {
225
229
  * Treated as the runnable's primary output — captured as the response body
226
230
  * when `runspec serve` invokes the runnable as a subprocess.
227
231
  *
228
- * Drops `runspec.runsummary` records — those are file-only; the human form
229
- * of the summary is written directly to stderr by the exit hook.
232
+ * Drops `runspec.runsummary` records — those are file-only; the optional human
233
+ * echo of the summary is written directly to stderr by the exit hook (gated by
234
+ * `summary_console`).
230
235
  */
231
236
  class StdoutHandler implements Handler {
232
237
  constructor(public readonly level: number, private readonly showTracebacks: boolean) {}
@@ -490,9 +495,10 @@ function formatSummaryLine(state: SummaryState, durationMs: number, exitCode: nu
490
495
  const errors = (counts.ERROR ?? 0) + (counts.CRITICAL ?? 0);
491
496
  const secs = (durationMs / 1000).toFixed(2);
492
497
  const runnable = state.runnable;
493
- // Abbreviated level words ("warn"/"err", never "warning"/"error") so the line
494
- // doesn't trip Rundeck's case-insensitive `error` log-highlight/level filters,
495
- // which would otherwise paint a clean run red over the literal "0 errors".
498
+ // Abbreviated level words ("warn"/"err", never "warning"/"error") keep the line
499
+ // terse. (Stream-tagging log processors like Rundeck classify by stream, not
500
+ // text this echo is opt-in and stays on stderr, so a clean run isn't flagged
501
+ // ERROR unless an operator turns `summary_console` on in that env.)
496
502
  const events = `${total} events (${warnings} warn, ${errors} err)`;
497
503
  const userPart = state.userTarget
498
504
  ? ` | user: ${state.user} → ${state.userTarget} (sudo)`
@@ -519,28 +525,36 @@ export function emitRunSummary(): void {
519
525
  // process.exitCode if the user set it. Defaults to 0.
520
526
  const exitCode = state.exitCode !== 0 ? state.exitCode : (state.exception ? 1 : 0);
521
527
 
522
- try {
523
- getLogger(RUN_SUMMARY_LOGGER).info('run completed', {
524
- event: 'run_summary',
525
- runnable: state.runnable,
526
- command_path: state.commandPath,
527
- duration_ms: durationMs,
528
- exit_code: exitCode,
529
- agent: state.agent,
530
- autonomy: state.autonomy,
531
- exception: state.exception,
532
- events: { ...state.counter.counts },
533
- user: state.user,
534
- user_target: state.userTarget ?? null,
535
- });
536
- } catch {
537
- // never disrupt shutdown
528
+ // Audit record — gated by `summary`; the data the console + `runspec logs` read.
529
+ if (state.writeRecord) {
530
+ try {
531
+ getLogger(RUN_SUMMARY_LOGGER).info('run completed', {
532
+ event: 'run_summary',
533
+ runnable: state.runnable,
534
+ command_path: state.commandPath,
535
+ duration_ms: durationMs,
536
+ exit_code: exitCode,
537
+ agent: state.agent,
538
+ autonomy: state.autonomy,
539
+ exception: state.exception,
540
+ events: { ...state.counter.counts },
541
+ user: state.user,
542
+ user_target: state.userTarget ?? null,
543
+ });
544
+ } catch {
545
+ // never disrupt shutdown
546
+ }
538
547
  }
539
548
 
540
- try {
541
- process.stderr.write(formatSummaryLine(state, durationMs, exitCode) + '\n');
542
- } catch {
543
- // never disrupt shutdown
549
+ // Human-readable echo — opt-in (`summary_console`). Stays on stderr so it never
550
+ // pollutes stdout pipes; off by default so it never reaches Rundeck's
551
+ // stderr=ERROR tagging unless the operator explicitly asks for it.
552
+ if (state.writeConsole) {
553
+ try {
554
+ process.stderr.write(formatSummaryLine(state, durationMs, exitCode) + '\n');
555
+ } catch {
556
+ // never disrupt shutdown
557
+ }
544
558
  }
545
559
  }
546
560
 
@@ -781,7 +795,10 @@ export interface ConfigureLoggingOptions {
781
795
  *
782
796
  * Run summary (when `logCfg.summary` is true and `noSummary` is false)
783
797
  * counts log events by level and emits a single record at process exit
784
- * with duration, exit code, exception class, and per-level counts.
798
+ * with duration, exit code, exception class, and per-level counts to the
799
+ * audit file. The human-readable one-line echo to stderr is opt-in via
800
+ * `logCfg.summaryConsole` (default false) so stdout stays clean for pipes and
801
+ * the line never reaches a stderr=ERROR log processor by default.
785
802
  */
786
803
  export function configureLogging(opts: ConfigureLoggingOptions): void {
787
804
  if (!opts.logCfg || _configured) return;
@@ -814,12 +831,19 @@ export function configureLogging(opts: ConfigureLoggingOptions): void {
814
831
  _handlers.push(counter);
815
832
 
816
833
  const runnablePrefix = opts.runnableName.toUpperCase().replace(/-/g, '_');
817
- const summaryEnabled =
818
- opts.logCfg.summary !== false &&
819
- !opts.noSummary &&
820
- !['1', 'true', 'yes'].includes((process.env[`RUNSPEC_${runnablePrefix}_ARG_NO_SUMMARY`] ?? '').toLowerCase());
821
-
822
- if (summaryEnabled) {
834
+ // Per-invocation kill switch (--no-summary / env) suppresses both parts.
835
+ const suppressed =
836
+ !!opts.noSummary ||
837
+ ['1', 'true', 'yes'].includes((process.env[`RUNSPEC_${runnablePrefix}_ARG_NO_SUMMARY`] ?? '').toLowerCase());
838
+ // `summary` gates the structured audit record (the data the console
839
+ // history/analytics tabs and `runspec logs` read). `summary_console` gates the
840
+ // human-readable terminal echo — off by default so stdout stays clean for pipes
841
+ // and the line never reaches a stream that log processors (e.g. Rundeck, which
842
+ // tags stderr as ERROR) would flag.
843
+ const writeRecord = opts.logCfg.summary !== false && !suppressed;
844
+ const writeConsole = opts.logCfg.summaryConsole === true && !suppressed;
845
+
846
+ if (writeRecord || writeConsole) {
823
847
  const [user, userTarget] = _getInvoker();
824
848
  _summaryState = {
825
849
  counter,
@@ -833,6 +857,8 @@ export function configureLogging(opts: ConfigureLoggingOptions): void {
833
857
  emitted: false,
834
858
  user,
835
859
  userTarget,
860
+ writeRecord,
861
+ writeConsole,
836
862
  };
837
863
  }
838
864
 
package/src/models.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  export interface LoggingConfig {
2
2
  rotate: string;
3
3
  keep: number;
4
+ /** Write the structured run-summary record to the audit log (default true) —
5
+ * the data the console history/analytics tabs and `runspec logs` read. */
4
6
  summary: boolean;
7
+ /** Also echo a one-line human-readable summary to stderr at exit (default
8
+ * false). Off by default so stdout stays clean for pipes and the line is
9
+ * never tagged ERROR by stream-classifying log processors (e.g. Rundeck). */
10
+ summaryConsole?: boolean;
5
11
  /** Log file layout: 'single' (default, one rotating {runnable}.log) or
6
12
  * 'per-run' (one {runnable}.{utc-ts}.{run_id}.log per invocation). */
7
13
  store?: string;
@@ -55,6 +61,7 @@ export interface ScriptSpec {
55
61
  autonomyReason?: string;
56
62
  output?: string;
57
63
  serve?: boolean | string[];
64
+ discoverable?: boolean | string[];
58
65
  requireCommand?: boolean;
59
66
  args: Record<string, ArgSpec>;
60
67
  groups: Record<string, GroupSpec>;
package/src/serve.ts CHANGED
@@ -6,6 +6,7 @@ import { findConfig } from './finder';
6
6
  import { loadRaw } from './loader';
7
7
  import { inferScript } from './inference';
8
8
  import { buildSchema } from './cli';
9
+ import { OPERATOR, isDiscoverableTo, validateDiscoverable } from './discovery';
9
10
 
10
11
  const MCP_PROTOCOL_VERSION = '2024-11-05';
11
12
  const ERR_PARSE = -32700;
@@ -66,6 +67,16 @@ export function serve(): void {
66
67
  process.exit(1);
67
68
  }
68
69
  if (!isServeMatch(runnable.serve, context)) continue;
70
+ // `serve` is an operator surface — skip runnables not discoverable to the
71
+ // `operator` audience (orthogonal to the serve *context* filter above). An
72
+ // internal helper (discoverable=false, or a list without "operator") is
73
+ // hidden from the agent surface this way.
74
+ const discErrors = validateDiscoverable(runnable.discoverable);
75
+ if (discErrors.length > 0) {
76
+ for (const err of discErrors) process.stderr.write(`runspec serve: ${name}.discoverable: ${err}\n`);
77
+ process.exit(1);
78
+ }
79
+ if (!isDiscoverableTo(runnable.discoverable, OPERATOR)) continue;
69
80
  const inferred = inferScript(runnable, config.autonomyDefault);
70
81
  tools[name] = buildSchema(name, inferred, 'mcp');
71
82
  argSpecs[name] = inferred.args ?? {};
@@ -0,0 +1,59 @@
1
+ import { normaliseDiscoverable, validateDiscoverable, isDiscoverableTo } from '../src/discovery';
2
+
3
+ describe('normaliseDiscoverable', () => {
4
+ test('absent defaults to operator', () => {
5
+ expect(normaliseDiscoverable(undefined)).toEqual(['operator']);
6
+ });
7
+ test('true is operator', () => {
8
+ expect(normaliseDiscoverable(true)).toEqual(['operator']);
9
+ });
10
+ test('false is empty', () => {
11
+ expect(normaliseDiscoverable(false)).toEqual([]);
12
+ });
13
+ test('list passthrough', () => {
14
+ expect(normaliseDiscoverable(['operator', 'self-service'])).toEqual(['operator', 'self-service']);
15
+ });
16
+ test('dedupes preserving order', () => {
17
+ expect(normaliseDiscoverable(['operator', 'operator', 'self-service'])).toEqual(['operator', 'self-service']);
18
+ });
19
+ });
20
+
21
+ describe('isDiscoverableTo', () => {
22
+ test('default reaches operator', () => {
23
+ expect(isDiscoverableTo(undefined, 'operator')).toBe(true);
24
+ });
25
+ test('bare true never implies self-service', () => {
26
+ expect(isDiscoverableTo(true, 'self-service')).toBe(false);
27
+ });
28
+ test('false reaches nobody', () => {
29
+ expect(isDiscoverableTo(false, 'operator')).toBe(false);
30
+ expect(isDiscoverableTo(false, 'self-service')).toBe(false);
31
+ });
32
+ test('explicit self-service', () => {
33
+ expect(isDiscoverableTo(['operator', 'self-service'], 'self-service')).toBe(true);
34
+ });
35
+ test('self-service-only hides from operator', () => {
36
+ expect(isDiscoverableTo(['self-service'], 'operator')).toBe(false);
37
+ });
38
+ });
39
+
40
+ describe('validateDiscoverable', () => {
41
+ test('undefined/true/false ok', () => {
42
+ expect(validateDiscoverable(undefined)).toEqual([]);
43
+ expect(validateDiscoverable(true)).toEqual([]);
44
+ expect(validateDiscoverable(false)).toEqual([]);
45
+ });
46
+ test('known audiences ok', () => {
47
+ expect(validateDiscoverable(['operator', 'self-service'])).toEqual([]);
48
+ });
49
+ test('empty list rejected', () => {
50
+ const errs = validateDiscoverable([]);
51
+ expect(errs.length).toBe(1);
52
+ expect(errs[0]).toContain('write false');
53
+ });
54
+ test('unknown audience rejected', () => {
55
+ const errs = validateDiscoverable(['operator', 'admins']);
56
+ expect(errs.length).toBe(1);
57
+ expect(errs[0]).toContain('unknown audience');
58
+ });
59
+ });
@@ -191,6 +191,14 @@ describe('complex.toml', () => {
191
191
  // Defaults to false where unset.
192
192
  expect(raw.runnables['pipeline'].requireCommand).toBe(false);
193
193
  });
194
+
195
+ test('discoverable: raw value preserved by the loader', () => {
196
+ const raw = loadRaw(COMPLEX);
197
+ expect(raw.runnables['pipeline'].discoverable).toEqual(['operator', 'self-service']);
198
+ expect(raw.runnables['db'].discoverable).toBe(false);
199
+ // Absent on the subcommands → undefined (defaults to operator-visible downstream).
200
+ expect(raw.runnables['pipeline'].commands['run'].discoverable).toBeUndefined();
201
+ });
194
202
  });
195
203
 
196
204
  // ── cross-fixture: inference rules ────────────────────────────────────────────
@@ -178,7 +178,7 @@ test('normalises [config.logging] with defaults', () => {
178
178
  description = "hi"
179
179
  `);
180
180
  const raw = loadRaw(file);
181
- expect(raw.config.logging).toEqual({ rotate: 'midnight', keep: 7, summary: true, store: 'single' });
181
+ expect(raw.config.logging).toEqual({ rotate: 'midnight', keep: 7, summary: true, summaryConsole: false, store: 'single' });
182
182
  });
183
183
 
184
184
  test('normalises [config.logging] store = per-run', () => {
@@ -222,7 +222,7 @@ summary = false
222
222
  description = "hi"
223
223
  `);
224
224
  const raw = loadRaw(file);
225
- expect(raw.config.logging).toEqual({ rotate: '10 MB', keep: 3, summary: false, store: 'single' });
225
+ expect(raw.config.logging).toEqual({ rotate: '10 MB', keep: 3, summary: false, summaryConsole: false, store: 'single' });
226
226
  });
227
227
 
228
228
  test('[config.logging] summary defaults to true when omitted', () => {
@@ -111,9 +111,9 @@ test('summary writes one record to the audit file', () => {
111
111
  expect(typeof s.extra.duration_ms).toBe('number');
112
112
  });
113
113
 
114
- test('summary writes a one-line summary to stderr', () => {
114
+ test('summary_console writes a one-line summary to stderr', () => {
115
115
  const dir = tmpDir();
116
- configureLogging(makeCfg(dir));
116
+ configureLogging(makeCfg(dir, { summaryConsole: true }));
117
117
  getLogger('test.stderr').info('ran');
118
118
  const cap = captureStderr();
119
119
  emitRunSummary();
@@ -123,6 +123,21 @@ test('summary writes a one-line summary to stderr', () => {
123
123
  expect(joined).toContain('events');
124
124
  });
125
125
 
126
+ test('console echo is off by default — record written, no stderr line', () => {
127
+ const dir = tmpDir();
128
+ configureLogging(makeCfg(dir)); // summary on (default), summary_console off (default)
129
+ getLogger('test.default').info('ran');
130
+ const cap = captureStderr();
131
+ emitRunSummary();
132
+ cap.restore();
133
+ // No human-readable line on stderr...
134
+ expect(cap.lines.join('')).not.toContain('runspec: myscript');
135
+ // ...but the structured audit record is still written to the file.
136
+ const content = fs.readFileSync(path.join(dir, 'logs', 'myscript.log'), 'utf-8');
137
+ const summary = content.trim().split('\n').map(l => JSON.parse(l)).find(o => o.logger === RUN_SUMMARY_LOGGER);
138
+ expect(summary.extra.event).toBe('run_summary');
139
+ });
140
+
126
141
  test('summary is not echoed to stdout or stderr via console handlers', () => {
127
142
  const dir = tmpDir();
128
143
  const stdoutLines: string[] = [];
@@ -163,13 +178,36 @@ test('noSummary option disables summary', () => {
163
178
  expect(fs.existsSync(path.join(dir, 'logs', 'myscript.log'))).toBe(false);
164
179
  });
165
180
 
166
- test('summary=false in config disables summary', () => {
181
+ test('summary=false in config disables the audit record', () => {
167
182
  const dir = tmpDir();
168
183
  configureLogging(makeCfg(dir, { summary: false }));
184
+ getLogger('t').info('ran');
169
185
  const cap = captureStderr();
170
186
  emitRunSummary();
171
187
  cap.restore();
172
188
  expect(cap.lines.join('')).not.toContain('runspec: ');
189
+ const logFile = path.join(dir, 'logs', 'myscript.log');
190
+ const records = fs.existsSync(logFile)
191
+ ? fs.readFileSync(logFile, 'utf-8').trim().split('\n').map(l => JSON.parse(l))
192
+ : [];
193
+ expect(records.find(o => o.logger === RUN_SUMMARY_LOGGER)).toBeUndefined();
194
+ });
195
+
196
+ test('summary_console works independently of summary (line on, record off)', () => {
197
+ const dir = tmpDir();
198
+ configureLogging(makeCfg(dir, { summary: false, summaryConsole: true }));
199
+ getLogger('t').info('ran');
200
+ const cap = captureStderr();
201
+ emitRunSummary();
202
+ cap.restore();
203
+ // The human line is emitted...
204
+ expect(cap.lines.join('')).toContain('runspec: myscript completed');
205
+ // ...but no run_summary record lands in the audit file.
206
+ const logFile = path.join(dir, 'logs', 'myscript.log');
207
+ const records = fs.existsSync(logFile)
208
+ ? fs.readFileSync(logFile, 'utf-8').trim().split('\n').map(l => JSON.parse(l))
209
+ : [];
210
+ expect(records.find(o => o.logger === RUN_SUMMARY_LOGGER)).toBeUndefined();
173
211
  });
174
212
 
175
213
  test('RUNSPEC_MYSCRIPT_ARG_NO_SUMMARY=1 disables summary', () => {
@@ -185,10 +223,9 @@ test('RUNSPEC_MYSCRIPT_ARG_NO_SUMMARY=1 disables summary', () => {
185
223
  // ── stderr line shape ────────────────────────────────────────────────────────
186
224
 
187
225
  test('success line uses abbreviated "warn"/"err" (no "warning"/"error")', () => {
188
- // Abbreviated levels keep the line from tripping Rundeck's case-insensitive
189
- // `error` log-highlight filter, which would paint a clean run red.
226
+ // Abbreviated levels keep the line terse (the console echo is opt-in).
190
227
  const dir = tmpDir();
191
- configureLogging(makeCfg(dir));
228
+ configureLogging(makeCfg(dir, { summaryConsole: true }));
192
229
  getLogger('t').warning('one');
193
230
  const cap = captureStderr();
194
231
  emitRunSummary();
@@ -201,7 +238,7 @@ test('success line uses abbreviated "warn"/"err" (no "warning"/"error")', () =>
201
238
 
202
239
  test('counts render without pluralising the level words', () => {
203
240
  const dir = tmpDir();
204
- configureLogging(makeCfg(dir));
241
+ configureLogging(makeCfg(dir, { summaryConsole: true }));
205
242
  getLogger('t').warning('a');
206
243
  getLogger('t').warning('b');
207
244
  const cap = captureStderr();
@@ -217,7 +254,7 @@ test('user appended to stderr line (no sudo)', () => {
217
254
  const origSudo = process.env['SUDO_USER'];
218
255
  delete process.env['SUDO_USER'];
219
256
  process.env['USER'] = 'alice';
220
- configureLogging(makeCfg(dir));
257
+ configureLogging(makeCfg(dir, { summaryConsole: true }));
221
258
  const cap = captureStderr();
222
259
  emitRunSummary();
223
260
  cap.restore();
@@ -229,7 +266,7 @@ test('sudo user shown with arrow and target', () => {
229
266
  const dir = tmpDir();
230
267
  process.env['SUDO_USER'] = 'alice';
231
268
  process.env['USER'] = 'root';
232
- configureLogging(makeCfg(dir));
269
+ configureLogging(makeCfg(dir, { summaryConsole: true }));
233
270
  const cap = captureStderr();
234
271
  emitRunSummary();
235
272
  cap.restore();