@sensigo/realm-cli 0.39.0 → 0.41.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 (109) hide show
  1. package/dist/agent/drive-failure.d.ts +62 -0
  2. package/dist/agent/drive-failure.d.ts.map +1 -0
  3. package/dist/agent/drive-failure.js +241 -0
  4. package/dist/agent/drive-failure.js.map +1 -0
  5. package/dist/agent/providers/agent-utils.d.ts +156 -0
  6. package/dist/agent/providers/agent-utils.d.ts.map +1 -1
  7. package/dist/agent/providers/agent-utils.js +423 -1
  8. package/dist/agent/providers/agent-utils.js.map +1 -1
  9. package/dist/agent/providers/anthropic-provider.d.ts +51 -1
  10. package/dist/agent/providers/anthropic-provider.d.ts.map +1 -1
  11. package/dist/agent/providers/anthropic-provider.js +109 -30
  12. package/dist/agent/providers/anthropic-provider.js.map +1 -1
  13. package/dist/agent/providers/llm-provider.d.ts +13 -1
  14. package/dist/agent/providers/llm-provider.d.ts.map +1 -1
  15. package/dist/agent/providers/llm-provider.js +8 -4
  16. package/dist/agent/providers/llm-provider.js.map +1 -1
  17. package/dist/agent/providers/openai-provider.d.ts +6 -1
  18. package/dist/agent/providers/openai-provider.d.ts.map +1 -1
  19. package/dist/agent/providers/openai-provider.js +75 -20
  20. package/dist/agent/providers/openai-provider.js.map +1 -1
  21. package/dist/agent/providers/openai-reasoning-provider.d.ts +4 -1
  22. package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -1
  23. package/dist/agent/providers/openai-reasoning-provider.js +21 -6
  24. package/dist/agent/providers/openai-reasoning-provider.js.map +1 -1
  25. package/dist/agent/run-agent.d.ts +9 -0
  26. package/dist/agent/run-agent.d.ts.map +1 -1
  27. package/dist/agent/run-agent.js +775 -680
  28. package/dist/agent/run-agent.js.map +1 -1
  29. package/dist/agent/run-attach.d.ts.map +1 -1
  30. package/dist/agent/run-attach.js +26 -2
  31. package/dist/agent/run-attach.js.map +1 -1
  32. package/dist/agent/test-support/anthropic-stub.d.ts +45 -0
  33. package/dist/agent/test-support/anthropic-stub.d.ts.map +1 -0
  34. package/dist/agent/test-support/anthropic-stub.js +146 -0
  35. package/dist/agent/test-support/anthropic-stub.js.map +1 -0
  36. package/dist/agent/test-support/composed-journey.d.ts +40 -0
  37. package/dist/agent/test-support/composed-journey.d.ts.map +1 -0
  38. package/dist/agent/test-support/composed-journey.js +104 -0
  39. package/dist/agent/test-support/composed-journey.js.map +1 -0
  40. package/dist/agent/test-support/mcp-server-entry.d.ts +20 -0
  41. package/dist/agent/test-support/mcp-server-entry.d.ts.map +1 -0
  42. package/dist/agent/test-support/mcp-server-entry.js +39 -0
  43. package/dist/agent/test-support/mcp-server-entry.js.map +1 -0
  44. package/dist/agent/test-support/openai-stub.d.ts +47 -0
  45. package/dist/agent/test-support/openai-stub.d.ts.map +1 -0
  46. package/dist/agent/test-support/openai-stub.js +115 -0
  47. package/dist/agent/test-support/openai-stub.js.map +1 -0
  48. package/dist/commands/agent.d.ts +6 -0
  49. package/dist/commands/agent.d.ts.map +1 -1
  50. package/dist/commands/agent.js +44 -3
  51. package/dist/commands/agent.js.map +1 -1
  52. package/dist/commands/drain.d.ts.map +1 -1
  53. package/dist/commands/drain.js +37 -3
  54. package/dist/commands/drain.js.map +1 -1
  55. package/dist/commands/gc.d.ts.map +1 -1
  56. package/dist/commands/gc.js.map +1 -1
  57. package/dist/commands/inspect.d.ts.map +1 -1
  58. package/dist/commands/inspect.js +61 -2
  59. package/dist/commands/inspect.js.map +1 -1
  60. package/dist/commands/list.d.ts.map +1 -1
  61. package/dist/commands/list.js +86 -0
  62. package/dist/commands/list.js.map +1 -1
  63. package/dist/commands/listen.d.ts +13 -0
  64. package/dist/commands/listen.d.ts.map +1 -1
  65. package/dist/commands/listen.js +36 -4
  66. package/dist/commands/listen.js.map +1 -1
  67. package/dist/commands/purge.d.ts +22 -1
  68. package/dist/commands/purge.d.ts.map +1 -1
  69. package/dist/commands/purge.js +70 -42
  70. package/dist/commands/purge.js.map +1 -1
  71. package/dist/commands/register.d.ts +25 -0
  72. package/dist/commands/register.d.ts.map +1 -1
  73. package/dist/commands/register.js +91 -21
  74. package/dist/commands/register.js.map +1 -1
  75. package/dist/commands/respond.d.ts.map +1 -1
  76. package/dist/commands/respond.js +23 -1
  77. package/dist/commands/respond.js.map +1 -1
  78. package/dist/commands/run.d.ts +34 -0
  79. package/dist/commands/run.d.ts.map +1 -1
  80. package/dist/commands/run.js +225 -11
  81. package/dist/commands/run.js.map +1 -1
  82. package/dist/commands/test.d.ts.map +1 -1
  83. package/dist/commands/test.js +48 -8
  84. package/dist/commands/test.js.map +1 -1
  85. package/dist/commands/validate.d.ts +19 -0
  86. package/dist/commands/validate.d.ts.map +1 -1
  87. package/dist/commands/validate.js +358 -84
  88. package/dist/commands/validate.js.map +1 -1
  89. package/dist/commands/watch.d.ts +30 -0
  90. package/dist/commands/watch.d.ts.map +1 -1
  91. package/dist/commands/watch.js +159 -23
  92. package/dist/commands/watch.js.map +1 -1
  93. package/dist/commands/workflow-list.d.ts +16 -0
  94. package/dist/commands/workflow-list.d.ts.map +1 -0
  95. package/dist/commands/workflow-list.js +96 -0
  96. package/dist/commands/workflow-list.js.map +1 -0
  97. package/dist/commands-registry.d.ts.map +1 -1
  98. package/dist/commands-registry.js +2 -0
  99. package/dist/commands-registry.js.map +1 -1
  100. package/dist/extensions/load-project-extensions.d.ts.map +1 -1
  101. package/dist/extensions/load-project-extensions.js +9 -3
  102. package/dist/extensions/load-project-extensions.js.map +1 -1
  103. package/dist/index.js +22 -1
  104. package/dist/index.js.map +1 -1
  105. package/dist/lib/loader-warnings.d.ts +45 -3
  106. package/dist/lib/loader-warnings.d.ts.map +1 -1
  107. package/dist/lib/loader-warnings.js +106 -5
  108. package/dist/lib/loader-warnings.js.map +1 -1
  109. package/package.json +5 -4
@@ -1,5 +1,24 @@
1
1
  import { Command } from 'commander';
2
2
  import type { WorkflowRegistrar } from '@sensigo/realm';
3
+ /**
4
+ * A trailing-edge coalescer: every `trigger()` (re)arms one timer, so a burst of calls inside the
5
+ * window produces exactly one `fn()` at the end of it (issue #449).
6
+ *
7
+ * WHAT ACTUALLY BURSTS, precisely — the YAML watcher is not the reason. On this platform the
8
+ * basename filter already reduces an atomic save to ONE passing event. The burst is the
9
+ * profiles watcher, which has no filter: creating a file there emits `rename` + `change`, two
10
+ * events, probe-proven. Cross-platform event shapes vary besides, so one instance is shared by
11
+ * both watchers rather than reasoned about per-watcher.
12
+ *
13
+ * `cancel()` exists because an abort must not leave a pending timer: it would fire after the
14
+ * watch resolved, re-registering into a store whose owner has moved on. Idempotent.
15
+ *
16
+ * @internal Exported for testing only.
17
+ */
18
+ export declare function makeCoalescedTrigger(fn: () => void, delayMs: number): {
19
+ trigger(): void;
20
+ cancel(): void;
21
+ };
3
22
  /**
4
23
  * Watches a workflow YAML file and re-registers it into the given store on every change.
5
24
  * Also watches the profiles directory alongside the YAML — any file change there triggers
@@ -7,6 +26,17 @@ import type { WorkflowRegistrar } from '@sensigo/realm';
7
26
  * Performs an initial registration before entering the watch loop.
8
27
  * Resolves when the watcher is closed (e.g. when the AbortSignal fires).
9
28
  *
29
+ * Three mechanics worth knowing (issue #449):
30
+ * - The YAML watch is on the file's DIRECTORY, filtered by basename — a file watch dies with the
31
+ * inode an atomic save renames away.
32
+ * - Both watchers are persistent, so they hold the process open; Ctrl+C is what stops it.
33
+ * - Each save's event burst is coalesced into one re-registration on a 100ms trailing edge.
34
+ *
35
+ * RESTART REQUIRED for three things, all read once at startup and never re-read: the extension
36
+ * modules (ESM cache, note below), a `profiles/` directory created after the watch began, and a
37
+ * `profiles_dir:` value edited mid-watch — an edit to that key keeps watching the OLD directory
38
+ * until you restart. No late-mount machinery; watch-before-create is a separate feature.
39
+ *
10
40
  * @param filePath Path to the workflow YAML file.
11
41
  * @param store The workflow registrar to register into — injected, never instantiated here.
12
42
  * @param signal Optional AbortSignal; when aborted the watcher stops and the promise resolves.
@@ -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;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"}
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,OAAO,KAAK,EAAE,iBAAiB,EAAiB,MAAM,gBAAgB,CAAC;AAgGvE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,MAAM,IAAI,EACd,OAAO,EAAE,MAAM,GACd;IAAE,OAAO,IAAI,IAAI,CAAC;IAAC,MAAM,IAAI,IAAI,CAAA;CAAE,CAerC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;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+Gf;AAED,eAAO,MAAM,YAAY,SAoBrB,CAAC"}
@@ -1,10 +1,10 @@
1
1
  // realm workflow watch <path> — watches a workflow YAML and re-registers on change.
2
2
  import { watch, existsSync } from 'node:fs';
3
- import { join, dirname, resolve } from 'node:path';
3
+ import { join, dirname, resolve, basename } from 'node:path';
4
4
  import { Command } from 'commander';
5
- import { loadWorkflowFromFileWithDiagnostics, WorkflowError } from '@sensigo/realm';
6
- import { loadWorkflowForRegistration } from './register.js';
7
- import { printLoaderWarnings, rejectOnErrorSeverity } from '../lib/loader-warnings.js';
5
+ import { loadWorkflowFromFileWithDiagnostics, renderLoaderWarning, WorkflowError, } from '@sensigo/realm';
6
+ import { loadWorkflowForRegistration, ExtensionLoadError } from './register.js';
7
+ import { renderLoadFailure, renderEscalationLine, printLoaderWarnings, rejectOnErrorSeverity, } from '../lib/loader-warnings.js';
8
8
  /**
9
9
  * Attempts to load and register a workflow YAML file.
10
10
  * Logs the result (success or validation error) to stdout/stderr.
@@ -14,27 +14,71 @@ import { printLoaderWarnings, rejectOnErrorSeverity } from '../lib/loader-warnin
14
14
  * imported content of each module path (ESM cache) — restart watch to pick up module changes.
15
15
  *
16
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).
17
+ * issue #170 boundary-reject, LIVE since the flip — but never `--strict` (watch is a dev loop;
18
+ * `--strict` is deliberately validate/register-only). Unlike validate/register this refuses
19
+ * WITHOUT exiting: the watcher keeps running so the author can fix the key and be re-registered on
20
+ * the next save, which is the whole point of a dev loop.
19
21
  * @param filePath Path to the workflow YAML file.
20
22
  * @param store The registrar to register into.
21
23
  */
24
+ /**
25
+ * issue #425: watch's own lines are timestamped and its warnings block was not, so on a busy
26
+ * watch session the warnings floated free of the save that produced them. One gated header ties
27
+ * them together. GATED because the clean-save path below calls printLoaderWarnings
28
+ * unconditionally: an ungated header would print `[iso] 0 warnings:` over nothing on every
29
+ * successful save. On console.warn, so it heads the block it belongs to rather than splitting
30
+ * across channels.
31
+ */
32
+ function printWarningsBlock(timestamp, warnings, opts) {
33
+ if (warnings.length === 0)
34
+ return;
35
+ console.warn(`[${timestamp}] ${warnings.length} ${warnings.length === 1 ? 'warning' : 'warnings'}:`);
36
+ // issue #463 — `plain` renders without printLoaderWarnings' `— REFUSED below` substitution. On
37
+ // the extensions-failure path the escalation gate never ran and the refusal below is the
38
+ // extensions error, so the substitution would name the wrong cause (test.ts's render comment,
39
+ // #450's reasoning). The three boundary callers pass no opts and keep the substitution — there a
40
+ // refusal of the warning's own follows: the escalation line, or renderLoadFailure's `Invalid:`.
41
+ if (opts?.plain === true) {
42
+ for (const w of warnings)
43
+ console.warn(renderLoaderWarning(w));
44
+ }
45
+ else {
46
+ printLoaderWarnings(warnings);
47
+ }
48
+ }
22
49
  async function registerFile(filePath, store) {
23
50
  const timestamp = new Date().toISOString();
24
51
  try {
25
52
  const { definition, warnings } = await loadWorkflowForRegistration(filePath);
26
53
  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.`);
54
+ printWarningsBlock(timestamp, warnings);
55
+ // One grammar with validate and register (issue #451) plus a tail those two do not
56
+ // need. They exit, so the refusal is the exit; watch CONTINUES, and a line that only
57
+ // named the warning would leave it unsaid whether the file was registered anyway.
58
+ console.error(`[${timestamp}] ${renderEscalationLine(warnings)} — refusing to register.`);
29
59
  return;
30
60
  }
31
61
  await store.register(definition);
32
- printLoaderWarnings(warnings);
33
- console.log(`[${timestamp}] Registered: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
62
+ printWarningsBlock(timestamp, warnings);
63
+ const stepCount = Object.keys(definition.steps).length;
64
+ console.log(`[${timestamp}] Registered: ${definition.id} v${definition.version} (${stepCount} ${stepCount === 1 ? 'step' : 'steps'})`);
34
65
  }
35
66
  catch (err) {
36
- if (err instanceof WorkflowError) {
37
- console.error(`[${timestamp}] Invalid: ${err.message}`);
67
+ if (err instanceof ExtensionLoadError) {
68
+ // issue #451 — the sentence run, validate and register print for this class. The
69
+ // watcher keeps running: fix the module, save, and the next pass re-registers.
70
+ // issue #463 — the workflow's own warnings first, in the plain form (see printWarningsBlock);
71
+ // the block's empty-array return is the belt under the ABSENT guard.
72
+ if (err.warnings !== undefined) {
73
+ printWarningsBlock(timestamp, [...err.warnings], { plain: true });
74
+ }
75
+ console.error(`[${timestamp}] Error loading extensions: ${err.message}`);
76
+ }
77
+ else if (err instanceof WorkflowError) {
78
+ // issue #424 — see the comment at validate.ts's extension-free catch.
79
+ if (err.warnings !== undefined)
80
+ printWarningsBlock(timestamp, [...err.warnings]);
81
+ console.error(`[${timestamp}] ${renderLoadFailure(err)}`);
38
82
  }
39
83
  else {
40
84
  const message = err instanceof Error ? err.message : String(err);
@@ -42,6 +86,41 @@ async function registerFile(filePath, store) {
42
86
  }
43
87
  }
44
88
  }
89
+ /** The trailing-edge window a save's event burst collapses into (issue #449). */
90
+ const COALESCE_MS = 100;
91
+ /**
92
+ * A trailing-edge coalescer: every `trigger()` (re)arms one timer, so a burst of calls inside the
93
+ * window produces exactly one `fn()` at the end of it (issue #449).
94
+ *
95
+ * WHAT ACTUALLY BURSTS, precisely — the YAML watcher is not the reason. On this platform the
96
+ * basename filter already reduces an atomic save to ONE passing event. The burst is the
97
+ * profiles watcher, which has no filter: creating a file there emits `rename` + `change`, two
98
+ * events, probe-proven. Cross-platform event shapes vary besides, so one instance is shared by
99
+ * both watchers rather than reasoned about per-watcher.
100
+ *
101
+ * `cancel()` exists because an abort must not leave a pending timer: it would fire after the
102
+ * watch resolved, re-registering into a store whose owner has moved on. Idempotent.
103
+ *
104
+ * @internal Exported for testing only.
105
+ */
106
+ export function makeCoalescedTrigger(fn, delayMs) {
107
+ let timer;
108
+ return {
109
+ trigger() {
110
+ if (timer !== undefined)
111
+ clearTimeout(timer);
112
+ timer = setTimeout(() => {
113
+ timer = undefined;
114
+ fn();
115
+ }, delayMs);
116
+ },
117
+ cancel() {
118
+ if (timer !== undefined)
119
+ clearTimeout(timer);
120
+ timer = undefined;
121
+ },
122
+ };
123
+ }
45
124
  /**
46
125
  * Watches a workflow YAML file and re-registers it into the given store on every change.
47
126
  * Also watches the profiles directory alongside the YAML — any file change there triggers
@@ -49,6 +128,17 @@ async function registerFile(filePath, store) {
49
128
  * Performs an initial registration before entering the watch loop.
50
129
  * Resolves when the watcher is closed (e.g. when the AbortSignal fires).
51
130
  *
131
+ * Three mechanics worth knowing (issue #449):
132
+ * - The YAML watch is on the file's DIRECTORY, filtered by basename — a file watch dies with the
133
+ * inode an atomic save renames away.
134
+ * - Both watchers are persistent, so they hold the process open; Ctrl+C is what stops it.
135
+ * - Each save's event burst is coalesced into one re-registration on a 100ms trailing edge.
136
+ *
137
+ * RESTART REQUIRED for three things, all read once at startup and never re-read: the extension
138
+ * modules (ESM cache, note below), a `profiles/` directory created after the watch began, and a
139
+ * `profiles_dir:` value edited mid-watch — an edit to that key keeps watching the OLD directory
140
+ * until you restart. No late-mount machinery; watch-before-create is a separate feature.
141
+ *
52
142
  * @param filePath Path to the workflow YAML file.
53
143
  * @param store The workflow registrar to register into — injected, never instantiated here.
54
144
  * @param signal Optional AbortSignal; when aborted the watcher stops and the promise resolves.
@@ -76,18 +166,63 @@ export async function watchWorkflow(filePath, store, signal, profilesDir) {
76
166
  resolvedProfilesDir = join(workflowDir, 'profiles');
77
167
  }
78
168
  }
79
- const watchYaml = new Promise((resolve, reject) => {
80
- const watcher = watch(filePath, { persistent: false, signal });
81
- watcher.on('change', (eventType) => {
82
- if (eventType === 'change') {
83
- void registerFile(filePath, store);
84
- }
169
+ // issue #449 `fs.watch` on the FILE dies with the inode. A vim-style atomic save writes a
170
+ // temp file and renames it over the target, so the watched inode is renamed away: the save that
171
+ // does it can still slip through as the dying inode's final `change` (executed: v2 DOES
172
+ // register), but the handle is dead from then on — the NEXT atomic save, and an ordinary
173
+ // in-place write after it, emit nothing at all (executed: count stays 2 through both). One vim
174
+ // save left watch silently blind to every later edit.
175
+ //
176
+ // Watching the DIRECTORY and filtering by basename fixes it structurally: the directory sees
177
+ // the rename INTO the name, and a directory handle has no inode to die with. No eventType
178
+ // filter — event shapes vary by platform, and on this one an atomic save's passing event is a
179
+ // `rename`, not a `change`.
180
+ //
181
+ // issue #449 — the missing-file contract, preserved deliberately. `fs.watch` on an absent FILE
182
+ // threw ENOENT and the action exited 1; a DIRECTORY watch would happily watch nothing forever,
183
+ // silently. Same error, same exit, raised explicitly now that the watch itself no longer does.
184
+ //
185
+ // POSITION IS LOAD-BEARING: before any resource exists. Thrown after the watcher was created,
186
+ // this left a live persistent watcher behind a reported failure — executed: the rejection
187
+ // arrives, a workflow.yaml created afterwards still gets registered by the phantom, and the
188
+ // caller's event loop is held open by a watch it was told had failed. It also orphaned the
189
+ // never-awaited watchYaml promise, so a later 'error' on the leaked handle would have surfaced
190
+ // as an unhandled rejection. The CLI never saw either — its catch calls process.exit(1) — but
191
+ // the function's own contract ("resolves when the watcher is closed") cannot be honoured by a
192
+ // rejection that closes nothing.
193
+ if (!existsSync(filePath)) {
194
+ throw new Error(`ENOENT: no such file or directory, watch '${filePath}'`);
195
+ }
196
+ // Computed BEFORE the Promise below: the executor's `resolve` parameter shadows node:path's
197
+ // `resolve`, so path math inside it is a trap.
198
+ const watchDir = dirname(resolve(filePath));
199
+ const watchName = basename(filePath);
200
+ // ONE coalescer shared by both watchers, created after the initial registration above so that
201
+ // first pass stays immediate. See makeCoalescedTrigger for what actually bursts.
202
+ const coalesced = makeCoalescedTrigger(() => {
203
+ void registerFile(filePath, store);
204
+ }, COALESCE_MS);
205
+ const watchYaml = new Promise((resolveWatch, reject) => {
206
+ // persistent: true (issue #449) — this was the liveness half. Non-persistent watchers do not
207
+ // hold the event loop, so the real CLI ran its initial registration and exited ~0.6s later
208
+ // while claiming to watch. No in-process test could ever see it: under vitest the runner's
209
+ // own loop keeps the process alive, which is exactly what `persistent` decides.
210
+ const watcher = watch(watchDir, { persistent: true, signal });
211
+ watcher.on('change', (_eventType, filename) => {
212
+ // `null` is in the type and means "the platform could not say which file" — treat it as
213
+ // possibly-ours rather than dropping a real edit. Buffer only under encoding:'buffer',
214
+ // which is never set here.
215
+ if (filename === watchName || filename === null)
216
+ coalesced.trigger();
85
217
  });
86
218
  watcher.on('error', (err) => {
87
219
  reject(err);
88
220
  });
89
221
  watcher.on('close', () => {
90
- resolve();
222
+ // Before resolving, or a pending timer fires after the watch is over — re-registering into
223
+ // a store whose owner has finished with it.
224
+ coalesced.cancel();
225
+ resolveWatch();
91
226
  });
92
227
  });
93
228
  // Only watch the profiles directory if it exists.
@@ -95,16 +230,17 @@ export async function watchWorkflow(filePath, store, signal, profilesDir) {
95
230
  return watchYaml;
96
231
  }
97
232
  const profilesDirPath = resolvedProfilesDir;
98
- const watchProfiles = new Promise((resolve, reject) => {
99
- const watcher = watch(profilesDirPath, { persistent: false, signal });
233
+ const watchProfiles = new Promise((resolveWatch, reject) => {
234
+ const watcher = watch(profilesDirPath, { persistent: true, signal });
100
235
  watcher.on('change', () => {
101
- void registerFile(filePath, store);
236
+ coalesced.trigger();
102
237
  });
103
238
  watcher.on('error', (err) => {
104
239
  reject(err);
105
240
  });
106
241
  watcher.on('close', () => {
107
- resolve();
242
+ coalesced.cancel();
243
+ resolveWatch();
108
244
  });
109
245
  });
110
246
  await Promise.all([watchYaml, watchProfiles]);
@@ -1 +1 @@
1
- {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mCAAmC,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpF,OAAO,EAAE,2BAA2B,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvF;;;;;;;;;;;;;GAaG;AACH,KAAK,UAAU,YAAY,CAAC,QAAgB,EAAE,KAAwB;IACpE,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,MAAM,2BAA2B,CAAC,QAAQ,CAAC,CAAC;QAC7E,IAAI,qBAAqB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;YAC9B,OAAO,CAAC,KAAK,CACX,IAAI,SAAS,eAAe,UAAU,CAAC,EAAE,yEAAyE,CACnH,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QACjC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CACT,IAAI,SAAS,iBAAiB,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,SAAS,CACrH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,KAAK,CAAC,IAAI,SAAS,YAAY,OAAO,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,KAAwB,EACxB,MAAoB,EACpB,WAAoB;IAEpB,MAAM,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAEpC,gFAAgF;IAChF,IAAI,mBAAmB,GAAG,WAAW,CAAC;IACtC,IAAI,mBAAmB,KAAK,SAAS,EAAE,CAAC;QACtC,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC;YACH,qFAAqF;YACrF,iFAAiF;YACjF,gFAAgF;YAChF,MAAM,EAAE,UAAU,EAAE,GAAG,mCAAmC,CAAC,QAAQ,CAAC,CAAC;YACrE,mBAAmB;gBACjB,UAAU,CAAC,YAAY,KAAK,SAAS;oBACnC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC;oBAC/C,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,mBAAmB,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtD,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAE/D,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,SAAiB,EAAE,EAAE;YACzC,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC3B,KAAK,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,EAAE,CAAC;QACrC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,eAAe,GAAG,mBAAmB,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAEtE,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,KAAK,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;YACjC,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACtE,WAAW,CAAC,+DAA+D,CAAC;KAC5E,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,EAAE;IAClC,MAAM,QAAQ,GACZ,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;QACvD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAEvC,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,YAAY,QAAQ,yBAAyB,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ import type { WorkflowDefinition } from '@sensigo/realm';
3
+ /**
4
+ * Alphabetical by id — the documented order, and the only one an operator can predict.
5
+ *
6
+ * Extracted and exported because the filesystem is not a reliable witness for it: `readdirSync`
7
+ * happens to return alphabetical order on this repo's ext4, so a cell that registers entries out
8
+ * of order and reads them back would pass with the sort deleted. This pins the rule itself.
9
+ *
10
+ * @internal Exported for testing only.
11
+ */
12
+ export declare function sortedById(workflows: WorkflowDefinition[]): WorkflowDefinition[];
13
+ /** The SCHEMA column: current, or a legacy marker naming the remedy. */
14
+ export declare function schemaCell(schemaVersion: number | undefined): string;
15
+ export declare const workflowListCommand: Command;
16
+ //# sourceMappingURL=workflow-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-list.d.ts","sourceRoot":"","sources":["../../src/commands/workflow-list.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,kBAAkB,EAAE,GAAG,kBAAkB,EAAE,CAEhF;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMpE;AAMD,eAAO,MAAM,mBAAmB,SA6E5B,CAAC"}
@@ -0,0 +1,96 @@
1
+ // workflow-list.ts — `realm workflow list`: what is actually in the registry (issue #427).
2
+ //
3
+ // The registry was a black box. `realm workflow register` wrote into it, everything else read
4
+ // from it by id, and nothing showed an operator what was there — so a definition registered
5
+ // under an older realm sat there indefinitely and invisibly. A CURRENT-SCHEMA one keeps running,
6
+ // grandfathered; an older one is worse than that, because it cannot run at all — every runtime
7
+ // consumer resolves through the store's get(), which refuses it. Either way nothing surfaced it
8
+ // until something tried to use it. This is the read surface that makes a pre-upgrade audit
9
+ // possible: list what you have, then audit each one with
10
+ // `realm workflow validate --registered <id>`.
11
+ import { Command } from 'commander';
12
+ import { JsonWorkflowStore, CURRENT_WORKFLOW_SCHEMA_VERSION } from '@sensigo/realm';
13
+ /**
14
+ * Alphabetical by id — the documented order, and the only one an operator can predict.
15
+ *
16
+ * Extracted and exported because the filesystem is not a reliable witness for it: `readdirSync`
17
+ * happens to return alphabetical order on this repo's ext4, so a cell that registers entries out
18
+ * of order and reads them back would pass with the sort deleted. This pins the rule itself.
19
+ *
20
+ * @internal Exported for testing only.
21
+ */
22
+ export function sortedById(workflows) {
23
+ return [...workflows].sort((a, b) => a.id.localeCompare(b.id));
24
+ }
25
+ /** The SCHEMA column: current, or a legacy marker naming the remedy. */
26
+ export function schemaCell(schemaVersion) {
27
+ if (schemaVersion === CURRENT_WORKFLOW_SCHEMA_VERSION)
28
+ return `${schemaVersion} (current)`;
29
+ // An absent schema_version predates the field entirely — there is no number to show, and
30
+ // printing `undefined — legacy` would be worse than saying only what is true.
31
+ if (schemaVersion === undefined)
32
+ return 'legacy (re-register)';
33
+ return `${schemaVersion} — legacy (re-register)`;
34
+ }
35
+ function pad(value, width) {
36
+ return value.length >= width ? value : value + ' '.repeat(width - value.length);
37
+ }
38
+ export const workflowListCommand = new Command('list')
39
+ .description('List registered workflow definitions (sorted by id)')
40
+ .option('--json', 'Emit the listing as JSON on stdout, and nothing else')
41
+ .action(async (opts) => {
42
+ const store = new JsonWorkflowStore();
43
+ const { workflows, unreadable, mismatched } = await store.listWithDiagnostics();
44
+ const sorted = sortedById(workflows);
45
+ if (opts.json === true) {
46
+ console.log(JSON.stringify({
47
+ workflows: sorted.map((w) => ({
48
+ id: w.id,
49
+ name: w.name,
50
+ version: w.version,
51
+ origin: w.origin ?? null,
52
+ schema_version: w.schema_version ?? null,
53
+ current: w.schema_version === CURRENT_WORKFLOW_SCHEMA_VERSION,
54
+ })),
55
+ unreadable,
56
+ mismatched,
57
+ }, null, 2));
58
+ return;
59
+ }
60
+ const rows = sorted.map((w) => ({
61
+ id: w.id,
62
+ name: w.name,
63
+ version: String(w.version),
64
+ origin: w.origin ?? '-',
65
+ schema: schemaCell(w.schema_version),
66
+ }));
67
+ const widths = {
68
+ id: Math.max(2, ...rows.map((r) => r.id.length)),
69
+ name: Math.max(4, ...rows.map((r) => r.name.length)),
70
+ version: Math.max(7, ...rows.map((r) => r.version.length)),
71
+ origin: Math.max(6, ...rows.map((r) => r.origin.length)),
72
+ };
73
+ console.log(`${pad('ID', widths.id)} ${pad('NAME', widths.name)} ${pad('VERSION', widths.version)} ${pad('ORIGIN', widths.origin)} SCHEMA`);
74
+ for (const r of rows) {
75
+ console.log(`${pad(r.id, widths.id)} ${pad(r.name, widths.name)} ${pad(r.version, widths.version)} ${pad(r.origin, widths.origin)} ${r.schema}`);
76
+ }
77
+ console.log(`\n${rows.length} ${rows.length === 1 ? 'workflow' : 'workflows'} registered.`);
78
+ // The census lines go to stderr: they are not part of the listing a script would consume,
79
+ // and an operator piping stdout should still see them.
80
+ if (unreadable.length > 0) {
81
+ const names = unreadable.map((u) => u.file).join(', ');
82
+ console.warn(unreadable.length === 1
83
+ ? `⚠ 1 file in the registry could not be parsed: ${names} — realm cannot audit what it cannot read.`
84
+ : `⚠ ${unreadable.length} files in the registry could not be parsed: ${names} — realm cannot audit what it cannot read.`);
85
+ }
86
+ if (mismatched.length > 0) {
87
+ const detail = mismatched.map((m) => `${m.file} (id '${m.id}')`).join(', ');
88
+ console.warn(mismatched.length === 1
89
+ ? `⚠ 1 file whose stored id differs from its filename: ${detail} — '--registered' resolves by filename.`
90
+ : `⚠ ${mismatched.length} files whose stored id differs from their filename: ${detail} — '--registered' resolves by filename.`);
91
+ }
92
+ // Exit 0 ALWAYS, including with unreadable entries: this is a read surface, and reporting
93
+ // the broken entry IS the signal. Exiting non-zero would make `workflow list` unusable in
94
+ // the very scripts that most want to know.
95
+ });
96
+ //# sourceMappingURL=workflow-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-list.js","sourceRoot":"","sources":["../../src/commands/workflow-list.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"commands-registry.d.ts","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAkCA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,+BAQ5B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,WAAW,+BAiBvB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,+BAM5B,CAAC"}
1
+ {"version":3,"file":"commands-registry.d.ts","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAmCA,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,+BAS5B,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,WAAW,+BAiBvB,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,gBAAgB,+BAM5B,CAAC"}
@@ -21,6 +21,7 @@ import { diffCommand } from './commands/diff.js';
21
21
  import { initCommand } from './commands/init.js';
22
22
  import { testCommand } from './commands/test.js';
23
23
  import { watchCommand } from './commands/watch.js';
24
+ import { workflowListCommand } from './commands/workflow-list.js';
24
25
  import { listCommand } from './commands/list.js';
25
26
  import { mcpCommand } from './commands/mcp.js';
26
27
  import { serveCommand } from './commands/serve.js';
@@ -34,6 +35,7 @@ import { listenCommand } from './commands/listen.js';
34
35
  /** Commands that operate on workflow definitions (realm workflow <cmd>). */
35
36
  export const workflowCommands = [
36
37
  initCommand,
38
+ workflowListCommand,
37
39
  validateCommand,
38
40
  registerCommand,
39
41
  watchCommand,
@@ -1 +1 @@
1
- {"version":3,"file":"commands-registry.js","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+EAA+E;AAC/E,6CAA6C;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,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,gGAAgG;AAChG,aAAa;AACb,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW;IACX,eAAe;IACf,eAAe;IACf,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,cAAc;IACd,aAAa;IACb,WAAW;IACX,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,YAAY;IACZ,SAAS;IACT,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,YAAY;IACZ,iBAAiB;CAClB,CAAC;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;CACd,CAAC"}
1
+ {"version":3,"file":"commands-registry.js","sourceRoot":"","sources":["../src/commands-registry.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,+EAA+E;AAC/E,6CAA6C;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,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,gGAAgG;AAChG,aAAa;AACb,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,WAAW;IACX,mBAAmB;IACnB,eAAe;IACf,eAAe;IACf,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;CACf,CAAC;AAEF,gEAAgE;AAChE,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,WAAW;IACX,cAAc;IACd,aAAa;IACb,WAAW;IACX,aAAa;IACb,cAAc;IACd,cAAc;IACd,cAAc;IACd,cAAc;IACd,YAAY;IACZ,SAAS;IACT,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,YAAY;IACZ,iBAAiB;CAClB,CAAC;AAEF,sDAAsD;AACtD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,UAAU;IACV,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,aAAa;CACd,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"load-project-extensions.d.ts","sourceRoot":"","sources":["../../src/extensions/load-project-extensions.ts"],"names":[],"mappings":"AAwBA,OAAO,EAEL,iBAAiB,EAiBlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAGV,iBAAiB,EAGjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAA8C,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpG,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oFAAoF;IACpF,SAAS,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAC/D,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAmDD,uEAAuE;AACvE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAqCpF;AAkFD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE,4BAA4B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CA6IlC;AAyiBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAQhE"}
1
+ {"version":3,"file":"load-project-extensions.d.ts","sourceRoot":"","sources":["../../src/extensions/load-project-extensions.ts"],"names":[],"mappings":"AAwBA,OAAO,EAEL,iBAAiB,EAiBlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAGV,iBAAiB,EAGjB,uBAAuB,EACvB,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAMxB,OAAO,EAA8C,KAAK,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEpG,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,oFAAoF;IACpF,SAAS,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,uBAAuB,CAAC,QAAQ,CAAC,CAAA;KAAE,CAAC;IAC/D,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC;AAmDD,uEAAuE;AACvE,wBAAgB,2BAA2B,IAAI,IAAI,CAElD;AAuCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CA2CpF;AAkFD;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,IAAI,CAAC,EAAE,4BAA4B,GAClC,OAAO,CAAC,uBAAuB,CAAC,CA6IlC;AAyiBD;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,CAAC,EAAE,MAAM,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,CAAC,UAAU,EAAE,kBAAkB,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAQhE"}
@@ -120,9 +120,15 @@ export function checkForOrphanedManifests(sourceDir, trustRoot) {
120
120
  : `Deployment manifests at ${orphans.map((o) => `'${o}'`).join(', ')}`;
121
121
  const nearest = orphans[0];
122
122
  // Throw WorkflowError (VALIDATION class — the same class the yaml-loader raises for
123
- // structural validation failures) so `realm workflow validate`'s existing
124
- // `if (err instanceof WorkflowError)` handler renders it as `Invalid:` rather than a stack
125
- // trace, and every execution/registration path treats it as a load failure.
123
+ // structural validation failures) so every command treats it as a load failure rather than a
124
+ // stack trace. WHICH sentence renders it depends on how the command reached this guard
125
+ // (issue #445): validate's extension-FREE arm calls checkForOrphanedManifests directly and
126
+ // renders `Invalid:`; a load that comes THROUGH loadProjectExtensions surfaces via each
127
+ // command's own extension-load catch as `Error loading extensions:` — every CLI surface that
128
+ // reaches this loader renders the failure that way (issue #466 closed the census: run, test,
129
+ // validate, register, watch, agent, respond, drain). serve/mcp resolve through this loader too
130
+ // (via makeRegistryProvider) but render via their MCP protocol envelopes, not a CLI sentence —
131
+ // out of this list by kind, not by omission.
126
132
  throw new WorkflowError(`${found} will NOT be loaded — manifests are read only from the deployment root ` +
127
133
  `'${join(trustRoot, 'realm.yaml')}'. Move it to '${join(trustRoot, 'realm.yaml')}' ` +
128
134
  `(the nearest package.json/.git ancestor of the workflow), or add a package.json/.git ` +