@sensigo/realm-cli 0.22.0 → 0.23.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,11 +1,18 @@
1
1
  import { Command } from 'commander';
2
- import type { WorkflowDefinition } from '@sensigo/realm';
2
+ import type { WorkflowDefinition, LoaderWarning } from '@sensigo/realm';
3
3
  /**
4
4
  * Loads and validates a workflow for registration. Extension-declaring workflows get the
5
5
  * full extension load + config_schema two-pass; extension-free workflows are untouched.
6
+ * Returns the definition alongside every accumulated LoaderWarning (issue #169) — pass-1's
7
+ * structural warnings plus the sentinel-credential warnings, if any. Prints NOTHING itself;
8
+ * both callers (register's action, watch's registerFile) decide how to surface/act on warnings
9
+ * (register supports `--strict` + the dormant #170 reject; watch just prints and continues).
6
10
  * @throws on any validation or extension-load failure — nothing is persisted on throw.
7
11
  */
8
- export declare function loadWorkflowForRegistration(filePath: string): Promise<WorkflowDefinition>;
12
+ export declare function loadWorkflowForRegistration(filePath: string): Promise<{
13
+ definition: WorkflowDefinition;
14
+ warnings: LoaderWarning[];
15
+ }>;
9
16
  export declare const registerCommand: Command;
10
17
  /** @internal Exported for testing only. */
11
18
  export declare function lintWorkflowContext(definition: WorkflowDefinition): string[];
@@ -1 +1 @@
1
- {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAOzD;;;;GAIG;AACH,wBAAsB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsB/F;AAED,eAAO,MAAM,eAAe,SA4BxB,CAAC;AAEL,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA4B5E"}
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAkBxE;;;;;;;;GAQG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,UAAU,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CA2BxE;AAED,eAAO,MAAM,eAAe,SAqDxB,CAAC;AAEL,2CAA2C;AAC3C,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,kBAAkB,GAAG,MAAM,EAAE,CA4B5E"}
@@ -4,16 +4,30 @@
4
4
  // against the resolved adapters' config_schema (two-pass) BEFORE anything is persisted.
5
5
  import { Command } from 'commander';
6
6
  import { join } from 'node:path';
7
- import { loadWorkflowFromFile, JsonWorkflowStore } from '@sensigo/realm';
7
+ import { loadWorkflowFromFileWithDiagnostics, JsonWorkflowStore, resolveSeverity, } from '@sensigo/realm';
8
8
  import { loadProjectExtensions, } from '../extensions/load-project-extensions.js';
9
9
  import { ManifestSecretsError } from '../extensions/manifest-secrets.js';
10
+ import { printLoaderWarnings, rejectOnErrorSeverity, failsStrict } from '../lib/loader-warnings.js';
11
+ /** Wraps loadProjectExtensions' sentinel-credential warnings as LoaderWarning (issue #169). */
12
+ function wrapSentinelWarnings(sentinelWarnings) {
13
+ return (sentinelWarnings ?? []).map((message) => ({
14
+ code: 'EXTENSION_SENTINEL',
15
+ severity: resolveSeverity('EXTENSION_SENTINEL'),
16
+ scope: 'workflow',
17
+ message: `⚠ ${message}`,
18
+ }));
19
+ }
10
20
  /**
11
21
  * Loads and validates a workflow for registration. Extension-declaring workflows get the
12
22
  * full extension load + config_schema two-pass; extension-free workflows are untouched.
23
+ * Returns the definition alongside every accumulated LoaderWarning (issue #169) — pass-1's
24
+ * structural warnings plus the sentinel-credential warnings, if any. Prints NOTHING itself;
25
+ * both callers (register's action, watch's registerFile) decide how to surface/act on warnings
26
+ * (register supports `--strict` + the dormant #170 reject; watch just prints and continues).
13
27
  * @throws on any validation or extension-load failure — nothing is persisted on throw.
14
28
  */
15
29
  export async function loadWorkflowForRegistration(filePath) {
16
- const definition = loadWorkflowFromFile(filePath);
30
+ const { definition, warnings: pass1Warnings } = loadWorkflowFromFileWithDiagnostics(filePath);
17
31
  // Full module load + duck validation + manifest construction + config_schema two-pass
18
32
  // BEFORE persisting. Secret sources may be unavailable at provisioning time: degrade to
19
33
  // SENTINEL construction with a loud WARN (never silent, never a registration blocker);
@@ -29,24 +43,42 @@ export async function loadWorkflowForRegistration(filePath) {
29
43
  console.warn('⚠ Registering with SENTINEL credentials — execution paths still require real secret resolution.');
30
44
  loaded = await loadProjectExtensions(definition, { secretMode: 'sentinel' });
31
45
  }
32
- for (const warning of loaded.sentinelWarnings ?? [])
33
- console.warn(`⚠ ${warning}`);
34
46
  // Two-pass: re-validate with the resolved registry so step config is checked against
35
- // each adapter's config_schema before the definition is persisted.
36
- loadWorkflowFromFile(filePath, loaded.registry);
37
- return definition;
47
+ // each adapter's config_schema before the definition is persisted. Its warnings are proven
48
+ // identical to pass-1's (same content, registry only adds config_schema checks) — discarded
49
+ // here to avoid double-counting the same unknown key twice.
50
+ loadWorkflowFromFileWithDiagnostics(filePath, loaded.registry);
51
+ return {
52
+ definition,
53
+ warnings: [...pass1Warnings, ...wrapSentinelWarnings(loaded.sentinelWarnings)],
54
+ };
38
55
  }
39
56
  export const registerCommand = new Command('register')
40
57
  .argument('<path>', 'Path to workflow directory or workflow.yaml file')
58
+ .option('--strict', 'Exit non-zero and refuse to register if any loader warning is present (issue #169)')
41
59
  .description('Register a workflow definition')
42
- .action(async (inputPath) => {
60
+ .action(async (inputPath, opts) => {
43
61
  const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
44
62
  ? inputPath
45
63
  : join(inputPath, 'workflow.yaml');
46
64
  try {
47
- const definition = await loadWorkflowForRegistration(filePath);
65
+ const { definition, warnings } = await loadWorkflowForRegistration(filePath);
66
+ // Dormant issue #170 boundary-reject: inert today (DEFAULT_POLICY has no 'error' entries).
67
+ if (rejectOnErrorSeverity(warnings)) {
68
+ printLoaderWarnings(warnings);
69
+ console.error(`Error: '${definition.id}' has a warning escalated to an error by policy — refusing to register.`);
70
+ process.exit(1);
71
+ return;
72
+ }
73
+ if (opts.strict && failsStrict(warnings)) {
74
+ printLoaderWarnings(warnings);
75
+ console.error(`Error: '${definition.id}' v${definition.version} has ${warnings.length} warning(s); refusing to register due to --strict`);
76
+ process.exit(1);
77
+ return;
78
+ }
48
79
  const store = new JsonWorkflowStore();
49
80
  await store.register(definition);
81
+ printLoaderWarnings(warnings);
50
82
  const contextWarnings = lintWorkflowContext(definition);
51
83
  for (const warning of contextWarnings) {
52
84
  console.warn(`⚠ ${warning}`);
@@ -1 +1 @@
1
- {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../src/commands/register.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAuEpC,eAAO,MAAM,eAAe,SAqExB,CAAC"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoHpC,eAAO,MAAM,eAAe,SAiGxB,CAAC"}
@@ -9,36 +9,75 @@ import { Command } from 'commander';
9
9
  import { dirname, join, resolve } from 'node:path';
10
10
  import { readFileSync } from 'node:fs';
11
11
  import { load } from 'js-yaml';
12
- import { loadWorkflowFromString, loadWorkflowFromFile, findTrustRoot, WorkflowError, shouldEnforceTimeout, DEFAULT_EXECUTION_TIMEOUT_SECONDS, } from '@sensigo/realm';
12
+ import { loadWorkflowFromStringWithDiagnostics, loadWorkflowFromFileWithDiagnostics, findTrustRoot, WorkflowError, shouldEnforceTimeout, DEFAULT_EXECUTION_TIMEOUT_SECONDS, resolveSeverity, } from '@sensigo/realm';
13
13
  import { loadProjectExtensions, checkForOrphanedManifests, } from '../extensions/load-project-extensions.js';
14
+ import { printLoaderWarnings, rejectOnErrorSeverity, failsStrict } from '../lib/loader-warnings.js';
14
15
  /**
15
16
  * Advisory (issue A3, never rejects): an auto step declaring `retry:` but no `timeout_seconds`
16
17
  * has EVERY attempt bounded by the generous DEFAULT_EXECUTION_TIMEOUT_SECONDS default — a hung
17
- * attempt can take up to that long before the retry loop even considers the next one. Surfaces
18
- * one warning per such step so the author can opt into a tighter explicit timeout_seconds.
18
+ * attempt can take up to that long before the retry loop even considers the next one. Returns one
19
+ * RETRY_NO_TIMEOUT LoaderWarning per such step (issue #169: folded into the validate accumulator
20
+ * — printed via printLoaderWarnings alongside every other warning — instead of printed directly,
21
+ * so `--strict` and the dormant boundary-reject can see it too).
19
22
  */
20
- function warnRetryWithoutExplicitTimeout(definition) {
23
+ function findRetryWithoutExplicitTimeout(definition) {
24
+ const warnings = [];
21
25
  for (const [stepName, step] of Object.entries(definition.steps)) {
22
26
  if (shouldEnforceTimeout(step) &&
23
27
  step.retry !== undefined &&
24
28
  step.timeout_seconds === undefined) {
25
- console.warn(`⚠ Step '${stepName}': declares 'retry' but no 'timeout_seconds' — each attempt is ` +
26
- `bounded by the default execution timeout (${DEFAULT_EXECUTION_TIMEOUT_SECONDS}s). ` +
27
- `Consider an explicit 'timeout_seconds' if attempts should fail faster.`);
29
+ warnings.push({
30
+ code: 'RETRY_NO_TIMEOUT',
31
+ severity: resolveSeverity('RETRY_NO_TIMEOUT'),
32
+ scope: 'step',
33
+ step: stepName,
34
+ message: `⚠ Step '${stepName}': declares 'retry' but no 'timeout_seconds' — each attempt is ` +
35
+ `bounded by the default execution timeout (${DEFAULT_EXECUTION_TIMEOUT_SECONDS}s). ` +
36
+ `Consider an explicit 'timeout_seconds' if attempts should fail faster.`,
37
+ });
28
38
  }
29
39
  }
40
+ return warnings;
41
+ }
42
+ /** Wraps loadProjectExtensions' sentinel-credential warnings as LoaderWarning (issue #169). */
43
+ function wrapSentinelWarnings(sentinelWarnings) {
44
+ return (sentinelWarnings ?? []).map((message) => ({
45
+ code: 'EXTENSION_SENTINEL',
46
+ severity: resolveSeverity('EXTENSION_SENTINEL'),
47
+ scope: 'workflow',
48
+ message: `⚠ ${message}`,
49
+ }));
30
50
  }
31
51
  /**
32
- * The single success site BOTH validation branches (extension-free and file-based) share: the
33
- * advisory warning is structurally inseparable from the `Valid:` line it accompanies a branch
34
- * cannot drop the advisory without also dropping the `Valid:` print that existing tests assert.
52
+ * The single success-path printer BOTH validation branches (extension-free and file-based)
53
+ * share: prints every accumulated warning, then the summary line. Under `--strict`, a non-empty
54
+ * accumulator turns the summary line into a failing one and returns true (the caller exits 1);
55
+ * otherwise the summary line — and, when present, the description line existing tests assert on
56
+ * — print exactly as before and this returns false.
35
57
  */
36
- function printValidationSuccess(definition) {
37
- warnRetryWithoutExplicitTimeout(definition);
38
- console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
58
+ function printValidationOutcome(definition, warnings, strict) {
59
+ printLoaderWarnings(warnings);
60
+ const base = `Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`;
61
+ if (strict && failsStrict(warnings)) {
62
+ console.log(`${base} — ${warnings.length} warning(s); failing due to --strict`);
63
+ return true;
64
+ }
65
+ console.log(base);
39
66
  if (definition.description !== undefined) {
40
67
  console.log(` ${definition.description}`);
41
68
  }
69
+ return false;
70
+ }
71
+ /**
72
+ * The dormant issue #170 boundary-reject: inert today (DEFAULT_POLICY has no 'error' entries),
73
+ * but once #170 flips UNKNOWN_WORKFLOW_KEY/UNKNOWN_STEP_KEY, this refuses those workflows here.
74
+ */
75
+ function rejectIfPolicyEscalates(warnings) {
76
+ if (!rejectOnErrorSeverity(warnings))
77
+ return false;
78
+ printLoaderWarnings(warnings);
79
+ console.error(`Invalid: ${warnings.length} warning(s) present, and at least one is escalated to an error by policy.`);
80
+ return true;
42
81
  }
43
82
  /** Pre-scan: does the YAML carry a top-level `extensions` key? (Parse errors → false; the
44
83
  * real loader below reports them with its existing error surface.) */
@@ -57,11 +96,13 @@ function hasTopLevelExtensions(content) {
57
96
  export const validateCommand = new Command('validate')
58
97
  .argument('<path>', 'Path to workflow directory or workflow.yaml file')
59
98
  .option('--extensions-module <path>', "Extensions module that REPLACES the workflow's declared 'extensions' modules (repair/override)")
99
+ .option('--strict', 'Exit non-zero if any loader warning is present (unknown keys, retry-without-timeout, sentinel credentials — issue #169)')
60
100
  .description('Validate a workflow YAML file')
61
101
  .action(async (inputPath, opts) => {
62
102
  const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
63
103
  ? inputPath
64
104
  : join(inputPath, 'workflow.yaml');
105
+ const strict = opts.strict === true;
65
106
  let content;
66
107
  try {
67
108
  content = readFileSync(filePath, 'utf8');
@@ -81,10 +122,16 @@ export const validateCommand = new Command('validate')
81
122
  // WorkflowError, which the catch below renders as `Invalid:` + exit(1). resolve()
82
123
  // before dirname so a relative `workflow.yaml` doesn't collapse the walk to '.'.
83
124
  try {
84
- const definition = loadWorkflowFromString(content);
125
+ const { definition, warnings: loaderWarnings } = loadWorkflowFromStringWithDiagnostics(content);
85
126
  const workflowDir = dirname(resolve(filePath));
86
127
  checkForOrphanedManifests(workflowDir, findTrustRoot(workflowDir));
87
- printValidationSuccess(definition);
128
+ const accumulated = [...loaderWarnings, ...findRetryWithoutExplicitTimeout(definition)];
129
+ if (rejectIfPolicyEscalates(accumulated)) {
130
+ process.exit(1);
131
+ }
132
+ if (printValidationOutcome(definition, accumulated, strict)) {
133
+ process.exit(1);
134
+ }
88
135
  }
89
136
  catch (err) {
90
137
  if (err instanceof WorkflowError) {
@@ -98,21 +145,34 @@ export const validateCommand = new Command('validate')
98
145
  // Extensions declared (or an override supplied): file-based two-pass validation.
99
146
  try {
100
147
  // Pass 1: structural validation + extension resolution metadata (source_dir/trust_root).
101
- const definition = loadWorkflowFromFile(filePath);
148
+ // The universal, registry-independent structural load — its warnings are what we count.
149
+ const { definition, warnings: pass1Warnings } = loadWorkflowFromFileWithDiagnostics(filePath);
102
150
  const { registry, manifest, sentinelWarnings } = await loadProjectExtensions(definition, {
103
151
  ...(opts.extensionsModule !== undefined ? { overrideModule: opts.extensionsModule } : {}),
104
152
  secretMode: 'sentinel',
105
153
  });
106
- for (const warning of sentinelWarnings ?? [])
107
- console.warn(`⚠ ${warning}`);
108
- // Pass 2: step config validated against each resolved adapter's config_schema.
109
- loadWorkflowFromFile(filePath, registry);
110
- printValidationSuccess(definition);
154
+ // Pass 2: step config validated against each resolved adapter's config_schema. Same
155
+ // content as pass 1, registry only adds config_schema checks — its warnings are proven
156
+ // identical to pass 1's, so they are deliberately discarded here (not collected) to avoid
157
+ // double-counting the same unknown key twice.
158
+ loadWorkflowFromFileWithDiagnostics(filePath, registry);
159
+ const accumulated = [
160
+ ...pass1Warnings,
161
+ ...findRetryWithoutExplicitTimeout(definition),
162
+ ...wrapSentinelWarnings(sentinelWarnings),
163
+ ];
164
+ if (rejectIfPolicyEscalates(accumulated)) {
165
+ process.exit(1);
166
+ }
167
+ const strictFailed = printValidationOutcome(definition, accumulated, strict);
111
168
  if (manifest.modules.length > 0) {
112
169
  console.log(`Extensions: ${manifest.modules.map((m) => m.declared).join(', ')} ` +
113
170
  `(adapters: ${manifest.adapters.length}, handlers: ${manifest.handlers.length}, ` +
114
171
  `processors: ${manifest.processors.length})`);
115
172
  }
173
+ if (strictFailed) {
174
+ process.exit(1);
175
+ }
116
176
  }
117
177
  catch (err) {
118
178
  console.error(`Invalid: ${err instanceof Error ? err.message : String(err)}`);
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA+BxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AA4CxD;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Df;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
@@ -2,8 +2,9 @@
2
2
  import { watch, existsSync } from 'node:fs';
3
3
  import { join, dirname, resolve } from 'node:path';
4
4
  import { Command } from 'commander';
5
- import { loadWorkflowFromFile, WorkflowError } from '@sensigo/realm';
5
+ import { loadWorkflowFromFileWithDiagnostics, WorkflowError } from '@sensigo/realm';
6
6
  import { loadWorkflowForRegistration } from './register.js';
7
+ import { printLoaderWarnings, rejectOnErrorSeverity } from '../lib/loader-warnings.js';
7
8
  /**
8
9
  * Attempts to load and register a workflow YAML file.
9
10
  * Logs the result (success or validation error) to stdout/stderr.
@@ -11,14 +12,24 @@ import { loadWorkflowForRegistration } from './register.js';
11
12
  * workflow declares `extensions:`, the modules load + duck-validate and step config gets the
12
13
  * config_schema two-pass BEFORE persisting. NOTE: long-lived watch processes keep the FIRST
13
14
  * imported content of each module path (ESM cache) — restart watch to pick up module changes.
15
+ *
16
+ * Prints every accumulated loader warning via printLoaderWarnings (issue #169) and applies the
17
+ * dormant issue #170 boundary-reject (inert today) — but never `--strict` (watch is a dev loop;
18
+ * `--strict` is deliberately validate/register-only).
14
19
  * @param filePath Path to the workflow YAML file.
15
20
  * @param store The registrar to register into.
16
21
  */
17
22
  async function registerFile(filePath, store) {
18
23
  const timestamp = new Date().toISOString();
19
24
  try {
20
- const definition = await loadWorkflowForRegistration(filePath);
25
+ const { definition, warnings } = await loadWorkflowForRegistration(filePath);
26
+ if (rejectOnErrorSeverity(warnings)) {
27
+ printLoaderWarnings(warnings);
28
+ console.error(`[${timestamp}] Invalid: '${definition.id}' has a warning escalated to an error by policy — refusing to register.`);
29
+ return;
30
+ }
21
31
  await store.register(definition);
32
+ printLoaderWarnings(warnings);
22
33
  console.log(`[${timestamp}] Registered: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
23
34
  }
24
35
  catch (err) {
@@ -51,7 +62,10 @@ export async function watchWorkflow(filePath, store, signal, profilesDir) {
51
62
  if (resolvedProfilesDir === undefined) {
52
63
  const workflowDir = dirname(resolve(filePath));
53
64
  try {
54
- const definition = loadWorkflowFromFile(filePath);
65
+ // WithDiagnostics + discard its warnings (issue #169): this load exists only to read
66
+ // profiles_dir, not to surface anything — registerFile (just above) already owns
67
+ // surfacing every warning for this same file, so printing here would double it.
68
+ const { definition } = loadWorkflowFromFileWithDiagnostics(filePath);
55
69
  resolvedProfilesDir =
56
70
  definition.profiles_dir !== undefined
57
71
  ? resolve(workflowDir, definition.profiles_dir)
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import 'dotenv/config';
4
4
  import { Command } from 'commander';
5
5
  import { workflowCommands, runCommands, topLevelCommands } from './commands-registry.js';
6
6
  const program = new Command();
7
- program.name('realm').description('Realm workflow engine CLI').version('0.22.0');
7
+ program.name('realm').description('Realm workflow engine CLI').version('0.23.0');
8
8
  // realm workflow — operations on workflow definitions
9
9
  const workflowCmd = new Command('workflow').description('Manage workflow definitions');
10
10
  for (const cmd of workflowCommands)
@@ -0,0 +1,15 @@
1
+ import { type LoaderWarning, type WarningCode } from '@sensigo/realm';
2
+ /** Prints every warning via the single renderLoaderWarning format source. */
3
+ export declare function printLoaderWarnings(warnings: LoaderWarning[]): void;
4
+ /**
5
+ * The dormant issue #170 boundary-reject hook, factored ONCE so validate/register/watch can't
6
+ * drift from each other: resolves every warning against `policy` (default DEFAULT_POLICY — inert
7
+ * today, since every entry is 'warn') and returns true if ANY resolves to 'error'. Inert today;
8
+ * #170 flips DEFAULT_POLICY's UNKNOWN_WORKFLOW_KEY/UNKNOWN_STEP_KEY entries to make this live.
9
+ * Never called from the execution loader (run/agent/listen/create_workflow) — those stay lenient
10
+ * forever, grandfathering already-deployed workflows and keeping agents error-tolerant.
11
+ */
12
+ export declare function rejectOnErrorSeverity(warnings: LoaderWarning[], policy?: Record<WarningCode, 'warn' | 'error'>): boolean;
13
+ /** True if `--strict` should fail the command given these accumulated warnings. */
14
+ export declare function failsStrict(warnings: LoaderWarning[]): boolean;
15
+ //# sourceMappingURL=loader-warnings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-warnings.d.ts","sourceRoot":"","sources":["../../src/lib/loader-warnings.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AAExB,6EAA6E;AAC7E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI,CAInE;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,aAAa,EAAE,EACzB,MAAM,GAAE,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAkB,GAC7D,OAAO,CAET;AAWD,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,OAAO,CAE9D"}
@@ -0,0 +1,33 @@
1
+ // loader-warnings.ts — shared CLI surfacing for the structured loader-warning channel (issue
2
+ // #169). Every CLI command that prints loader warnings funnels through printLoaderWarnings (the
3
+ // only caller of renderLoaderWarning — no command hand-rolls a `⚠ ` string), and the dormant
4
+ // #170 boundary-reject is factored into ONE shared helper so validate/register/watch can't drift.
5
+ import { renderLoaderWarning, resolveSeverity, DEFAULT_POLICY, } from '@sensigo/realm';
6
+ /** Prints every warning via the single renderLoaderWarning format source. */
7
+ export function printLoaderWarnings(warnings) {
8
+ for (const w of warnings) {
9
+ console.warn(renderLoaderWarning(w));
10
+ }
11
+ }
12
+ /**
13
+ * The dormant issue #170 boundary-reject hook, factored ONCE so validate/register/watch can't
14
+ * drift from each other: resolves every warning against `policy` (default DEFAULT_POLICY — inert
15
+ * today, since every entry is 'warn') and returns true if ANY resolves to 'error'. Inert today;
16
+ * #170 flips DEFAULT_POLICY's UNKNOWN_WORKFLOW_KEY/UNKNOWN_STEP_KEY entries to make this live.
17
+ * Never called from the execution loader (run/agent/listen/create_workflow) — those stay lenient
18
+ * forever, grandfathering already-deployed workflows and keeping agents error-tolerant.
19
+ */
20
+ export function rejectOnErrorSeverity(warnings, policy = DEFAULT_POLICY) {
21
+ return warnings.some((w) => resolveSeverity(w.code, policy) === 'error');
22
+ }
23
+ /**
24
+ * `--strict`: every accumulated warning resolved against an all-'error' policy — i.e. any
25
+ * warning at all fails the command. Derived from DEFAULT_POLICY's own key set so it can never
26
+ * drift from the real WarningCode union (no hand-maintained code list here).
27
+ */
28
+ const ALL_ERROR_POLICY = Object.fromEntries(Object.keys(DEFAULT_POLICY).map((code) => [code, 'error']));
29
+ /** True if `--strict` should fail the command given these accumulated warnings. */
30
+ export function failsStrict(warnings) {
31
+ return rejectOnErrorSeverity(warnings, ALL_ERROR_POLICY);
32
+ }
33
+ //# sourceMappingURL=loader-warnings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader-warnings.js","sourceRoot":"","sources":["../../src/lib/loader-warnings.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,gGAAgG;AAChG,6FAA6F;AAC7F,kGAAkG;AAClG,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,cAAc,GAGf,MAAM,gBAAgB,CAAC;AAExB,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB,CAAC,QAAyB;IAC3D,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAyB,EACzB,SAAgD,cAAc;IAE9D,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,MAAM,gBAAgB,GAA0C,MAAM,CAAC,WAAW,CAC/E,MAAM,CAAC,IAAI,CAAC,cAAc,CAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CACrC,CAAC;AAE3C,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,QAAyB;IACnD,OAAO,qBAAqB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;AAC3D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sensigo/realm-cli",
3
- "version": "0.22.0",
3
+ "version": "0.23.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -61,9 +61,9 @@
61
61
  "vitest": "^4.1.0"
62
62
  },
63
63
  "dependencies": {
64
- "@sensigo/realm": "^0.22.0",
65
- "@sensigo/realm-mcp": "^0.22.0",
66
- "@sensigo/realm-testing": "^0.22.0",
64
+ "@sensigo/realm": "^0.23.0",
65
+ "@sensigo/realm-mcp": "^0.23.0",
66
+ "@sensigo/realm-testing": "^0.23.0",
67
67
  "@modelcontextprotocol/sdk": "1.29.0",
68
68
  "chalk": "^5.0.0",
69
69
  "commander": "^14.0.3",