@sensigo/realm-cli 0.1.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 (190) hide show
  1. package/README.md +109 -0
  2. package/dist/agent/agent-utils.d.ts +27 -0
  3. package/dist/agent/agent-utils.d.ts.map +1 -0
  4. package/dist/agent/agent-utils.js +79 -0
  5. package/dist/agent/agent-utils.js.map +1 -0
  6. package/dist/agent/anthropic-provider.d.ts +23 -0
  7. package/dist/agent/anthropic-provider.d.ts.map +1 -0
  8. package/dist/agent/anthropic-provider.js +245 -0
  9. package/dist/agent/anthropic-provider.js.map +1 -0
  10. package/dist/agent/gate/slack-gate-notifier.d.ts +80 -0
  11. package/dist/agent/gate/slack-gate-notifier.d.ts.map +1 -0
  12. package/dist/agent/gate/slack-gate-notifier.js +315 -0
  13. package/dist/agent/gate/slack-gate-notifier.js.map +1 -0
  14. package/dist/agent/gate/slack-gate-server.d.ts +30 -0
  15. package/dist/agent/gate/slack-gate-server.d.ts.map +1 -0
  16. package/dist/agent/gate/slack-gate-server.js +99 -0
  17. package/dist/agent/gate/slack-gate-server.js.map +1 -0
  18. package/dist/agent/gate/slack-socket-client.d.ts +20 -0
  19. package/dist/agent/gate/slack-socket-client.d.ts.map +1 -0
  20. package/dist/agent/gate/slack-socket-client.js +141 -0
  21. package/dist/agent/gate/slack-socket-client.js.map +1 -0
  22. package/dist/agent/gate-intent-interpreter.d.ts +29 -0
  23. package/dist/agent/gate-intent-interpreter.d.ts.map +1 -0
  24. package/dist/agent/gate-intent-interpreter.js +33 -0
  25. package/dist/agent/gate-intent-interpreter.js.map +1 -0
  26. package/dist/agent/index.d.ts +4 -0
  27. package/dist/agent/index.d.ts.map +1 -0
  28. package/dist/agent/index.js +4 -0
  29. package/dist/agent/index.js.map +1 -0
  30. package/dist/agent/llm-provider.d.ts +46 -0
  31. package/dist/agent/llm-provider.d.ts.map +1 -0
  32. package/dist/agent/llm-provider.js +55 -0
  33. package/dist/agent/llm-provider.js.map +1 -0
  34. package/dist/agent/mcp/mcp-client.d.ts +18 -0
  35. package/dist/agent/mcp/mcp-client.d.ts.map +1 -0
  36. package/dist/agent/mcp/mcp-client.js +108 -0
  37. package/dist/agent/mcp/mcp-client.js.map +1 -0
  38. package/dist/agent/mcp/mcp-extensions.d.ts +40 -0
  39. package/dist/agent/mcp/mcp-extensions.d.ts.map +1 -0
  40. package/dist/agent/mcp/mcp-extensions.js +2 -0
  41. package/dist/agent/mcp/mcp-extensions.js.map +1 -0
  42. package/dist/agent/mcp-client.d.ts +18 -0
  43. package/dist/agent/mcp-client.d.ts.map +1 -0
  44. package/dist/agent/mcp-client.js +108 -0
  45. package/dist/agent/mcp-client.js.map +1 -0
  46. package/dist/agent/mcp-types.d.ts +40 -0
  47. package/dist/agent/mcp-types.d.ts.map +1 -0
  48. package/dist/agent/mcp-types.js +2 -0
  49. package/dist/agent/mcp-types.js.map +1 -0
  50. package/dist/agent/openai-provider.d.ts +30 -0
  51. package/dist/agent/openai-provider.d.ts.map +1 -0
  52. package/dist/agent/openai-provider.js +253 -0
  53. package/dist/agent/openai-provider.js.map +1 -0
  54. package/dist/agent/openai-reasoning-provider.d.ts +18 -0
  55. package/dist/agent/openai-reasoning-provider.d.ts.map +1 -0
  56. package/dist/agent/openai-reasoning-provider.js +76 -0
  57. package/dist/agent/openai-reasoning-provider.js.map +1 -0
  58. package/dist/agent/preflight.d.ts +36 -0
  59. package/dist/agent/preflight.d.ts.map +1 -0
  60. package/dist/agent/preflight.js +81 -0
  61. package/dist/agent/preflight.js.map +1 -0
  62. package/dist/agent/providers/agent-utils.d.ts +27 -0
  63. package/dist/agent/providers/agent-utils.d.ts.map +1 -0
  64. package/dist/agent/providers/agent-utils.js +79 -0
  65. package/dist/agent/providers/agent-utils.js.map +1 -0
  66. package/dist/agent/providers/anthropic-provider.d.ts +23 -0
  67. package/dist/agent/providers/anthropic-provider.d.ts.map +1 -0
  68. package/dist/agent/providers/anthropic-provider.js +257 -0
  69. package/dist/agent/providers/anthropic-provider.js.map +1 -0
  70. package/dist/agent/providers/llm-provider.d.ts +46 -0
  71. package/dist/agent/providers/llm-provider.d.ts.map +1 -0
  72. package/dist/agent/providers/llm-provider.js +56 -0
  73. package/dist/agent/providers/llm-provider.js.map +1 -0
  74. package/dist/agent/providers/openai-provider.d.ts +30 -0
  75. package/dist/agent/providers/openai-provider.d.ts.map +1 -0
  76. package/dist/agent/providers/openai-provider.js +253 -0
  77. package/dist/agent/providers/openai-provider.js.map +1 -0
  78. package/dist/agent/providers/openai-reasoning-provider.d.ts +19 -0
  79. package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -0
  80. package/dist/agent/providers/openai-reasoning-provider.js +89 -0
  81. package/dist/agent/providers/openai-reasoning-provider.js.map +1 -0
  82. package/dist/agent/run-agent.d.ts +50 -0
  83. package/dist/agent/run-agent.d.ts.map +1 -0
  84. package/dist/agent/run-agent.js +327 -0
  85. package/dist/agent/run-agent.js.map +1 -0
  86. package/dist/agent/slack-gate-notifier.d.ts +80 -0
  87. package/dist/agent/slack-gate-notifier.d.ts.map +1 -0
  88. package/dist/agent/slack-gate-notifier.js +315 -0
  89. package/dist/agent/slack-gate-notifier.js.map +1 -0
  90. package/dist/agent/slack-gate-poller.d.ts +28 -0
  91. package/dist/agent/slack-gate-poller.d.ts.map +1 -0
  92. package/dist/agent/slack-gate-poller.js +66 -0
  93. package/dist/agent/slack-gate-poller.js.map +1 -0
  94. package/dist/agent/slack-gate-server.d.ts +30 -0
  95. package/dist/agent/slack-gate-server.d.ts.map +1 -0
  96. package/dist/agent/slack-gate-server.js +99 -0
  97. package/dist/agent/slack-gate-server.js.map +1 -0
  98. package/dist/agent/slack-socket-client.d.ts +20 -0
  99. package/dist/agent/slack-socket-client.d.ts.map +1 -0
  100. package/dist/agent/slack-socket-client.js +141 -0
  101. package/dist/agent/slack-socket-client.js.map +1 -0
  102. package/dist/commands/agent.d.ts +3 -0
  103. package/dist/commands/agent.d.ts.map +1 -0
  104. package/dist/commands/agent.js +183 -0
  105. package/dist/commands/agent.js.map +1 -0
  106. package/dist/commands/cleanup.d.ts +16 -0
  107. package/dist/commands/cleanup.d.ts.map +1 -0
  108. package/dist/commands/cleanup.js +79 -0
  109. package/dist/commands/cleanup.js.map +1 -0
  110. package/dist/commands/diff.d.ts +41 -0
  111. package/dist/commands/diff.d.ts.map +1 -0
  112. package/dist/commands/diff.js +203 -0
  113. package/dist/commands/diff.js.map +1 -0
  114. package/dist/commands/init.d.ts +10 -0
  115. package/dist/commands/init.d.ts.map +1 -0
  116. package/dist/commands/init.js +97 -0
  117. package/dist/commands/init.js.map +1 -0
  118. package/dist/commands/inspect.d.ts +14 -0
  119. package/dist/commands/inspect.d.ts.map +1 -0
  120. package/dist/commands/inspect.js +224 -0
  121. package/dist/commands/inspect.js.map +1 -0
  122. package/dist/commands/list.d.ts +18 -0
  123. package/dist/commands/list.d.ts.map +1 -0
  124. package/dist/commands/list.js +88 -0
  125. package/dist/commands/list.js.map +1 -0
  126. package/dist/commands/mcp.d.ts +8 -0
  127. package/dist/commands/mcp.d.ts.map +1 -0
  128. package/dist/commands/mcp.js +22 -0
  129. package/dist/commands/mcp.js.map +1 -0
  130. package/dist/commands/migrate.d.ts +3 -0
  131. package/dist/commands/migrate.d.ts.map +1 -0
  132. package/dist/commands/migrate.js +42 -0
  133. package/dist/commands/migrate.js.map +1 -0
  134. package/dist/commands/register.d.ts +6 -0
  135. package/dist/commands/register.d.ts.map +1 -0
  136. package/dist/commands/register.js +51 -0
  137. package/dist/commands/register.js.map +1 -0
  138. package/dist/commands/replay-format.d.ts +3 -0
  139. package/dist/commands/replay-format.d.ts.map +1 -0
  140. package/dist/commands/replay-format.js +10 -0
  141. package/dist/commands/replay-format.js.map +1 -0
  142. package/dist/commands/replay.d.ts +38 -0
  143. package/dist/commands/replay.d.ts.map +1 -0
  144. package/dist/commands/replay.js +173 -0
  145. package/dist/commands/replay.js.map +1 -0
  146. package/dist/commands/respond.d.ts +20 -0
  147. package/dist/commands/respond.d.ts.map +1 -0
  148. package/dist/commands/respond.js +49 -0
  149. package/dist/commands/respond.js.map +1 -0
  150. package/dist/commands/resume.d.ts +15 -0
  151. package/dist/commands/resume.d.ts.map +1 -0
  152. package/dist/commands/resume.js +63 -0
  153. package/dist/commands/resume.js.map +1 -0
  154. package/dist/commands/run.d.ts +3 -0
  155. package/dist/commands/run.d.ts.map +1 -0
  156. package/dist/commands/run.js +127 -0
  157. package/dist/commands/run.js.map +1 -0
  158. package/dist/commands/serve.d.ts +33 -0
  159. package/dist/commands/serve.d.ts.map +1 -0
  160. package/dist/commands/serve.js +144 -0
  161. package/dist/commands/serve.js.map +1 -0
  162. package/dist/commands/test.d.ts +12 -0
  163. package/dist/commands/test.d.ts.map +1 -0
  164. package/dist/commands/test.js +58 -0
  165. package/dist/commands/test.js.map +1 -0
  166. package/dist/commands/validate.d.ts +3 -0
  167. package/dist/commands/validate.d.ts.map +1 -0
  168. package/dist/commands/validate.js +35 -0
  169. package/dist/commands/validate.js.map +1 -0
  170. package/dist/commands/watch.d.ts +18 -0
  171. package/dist/commands/watch.d.ts.map +1 -0
  172. package/dist/commands/watch.js +112 -0
  173. package/dist/commands/watch.js.map +1 -0
  174. package/dist/commands/webhook.d.ts +51 -0
  175. package/dist/commands/webhook.d.ts.map +1 -0
  176. package/dist/commands/webhook.js +227 -0
  177. package/dist/commands/webhook.js.map +1 -0
  178. package/dist/commands-registry.d.ts +7 -0
  179. package/dist/commands-registry.d.ts.map +1 -0
  180. package/dist/commands-registry.js +44 -0
  181. package/dist/commands-registry.js.map +1 -0
  182. package/dist/index.d.ts +3 -0
  183. package/dist/index.d.ts.map +1 -0
  184. package/dist/index.js +21 -0
  185. package/dist/index.js.map +1 -0
  186. package/dist/store/replay-store.d.ts +29 -0
  187. package/dist/store/replay-store.d.ts.map +1 -0
  188. package/dist/store/replay-store.js +31 -0
  189. package/dist/store/replay-store.js.map +1 -0
  190. package/package.json +83 -0
@@ -0,0 +1,63 @@
1
+ // resume command — removes a step from failed_steps so it can be re-executed.
2
+ import { Command } from 'commander';
3
+ import { WorkflowError } from '@sensigo/realm';
4
+ import { RESUMABLE_PHASES } from '@sensigo/realm';
5
+ /**
6
+ * Removes `stepName` from `failed_steps` so the DAG engine can re-evaluate its
7
+ * eligibility on the next execute-step call.
8
+ *
9
+ * @param runId The run to resume.
10
+ * @param stepName The failed step to re-enable.
11
+ * @param runStore Store holding run records.
12
+ * @param workflowStore Registrar for workflow definitions.
13
+ */
14
+ export async function resumeRun(runId, stepName, runStore, workflowStore) {
15
+ const run = await runStore.get(runId);
16
+ if (!RESUMABLE_PHASES.has(run.run_phase)) {
17
+ throw new WorkflowError(`Run ${runId} is in phase '${run.run_phase}', which is not resumable.`, {
18
+ code: 'STATE_TRANSITION_DENIED',
19
+ category: 'STATE',
20
+ agentAction: 'report_to_user',
21
+ retryable: false,
22
+ });
23
+ }
24
+ const workflow = await workflowStore.get(run.workflow_id);
25
+ if (workflow.steps[stepName] === undefined) {
26
+ throw new WorkflowError(`Step '${stepName}' not found in workflow '${run.workflow_id}'.`, {
27
+ code: 'STEP_NOT_FOUND',
28
+ category: 'ENGINE',
29
+ agentAction: 'report_to_user',
30
+ retryable: false,
31
+ });
32
+ }
33
+ if (!run.failed_steps.includes(stepName)) {
34
+ throw new WorkflowError(`Step '${stepName}' is not in failed_steps for run '${runId}'.`, {
35
+ code: 'STATE_TRANSITION_DENIED',
36
+ category: 'STATE',
37
+ agentAction: 'report_to_user',
38
+ retryable: false,
39
+ });
40
+ }
41
+ await runStore.update({
42
+ ...run,
43
+ failed_steps: run.failed_steps.filter((s) => s !== stepName),
44
+ });
45
+ }
46
+ export const resumeCommand = new Command('resume')
47
+ .description('Remove a step from failed_steps so it can be re-executed')
48
+ .argument('<run-id>', 'ID of the run to resume')
49
+ .requiredOption('--from <step>', 'Name of the failed step to re-enable')
50
+ .action(async (runId, opts) => {
51
+ const { JsonFileStore, JsonWorkflowStore } = await import('@sensigo/realm');
52
+ const runStore = new JsonFileStore();
53
+ const workflowStore = new JsonWorkflowStore();
54
+ try {
55
+ await resumeRun(runId, opts.from, runStore, workflowStore);
56
+ console.log(`Resumed: step '${opts.from}' removed from failed_steps on run '${runId}'.`);
57
+ }
58
+ catch (err) {
59
+ console.error(err instanceof Error ? err.message : String(err));
60
+ process.exit(1);
61
+ }
62
+ });
63
+ //# sourceMappingURL=resume.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resume.js","sourceRoot":"","sources":["../../src/commands/resume.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const runCommand: Command;
3
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAapC,eAAO,MAAM,UAAU,SAqInB,CAAC"}
@@ -0,0 +1,127 @@
1
+ // realm run <path> — interactive workflow runner (development driver).
2
+ import { Command } from 'commander';
3
+ import { createInterface } from 'node:readline/promises';
4
+ import { join } from 'node:path';
5
+ import { loadWorkflowFromFile, JsonFileStore, findEligibleSteps, executeChain, submitHumanResponse, } from '@sensigo/realm';
6
+ export const runCommand = new Command('run')
7
+ .argument('<path>', 'Path to workflow directory or workflow.yaml file')
8
+ .option('--params <json>', 'Initial run parameters as JSON string', '{}')
9
+ .description('Run a workflow interactively (development mode)')
10
+ .action(async (inputPath, options) => {
11
+ const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
12
+ ? inputPath
13
+ : join(inputPath, 'workflow.yaml');
14
+ // 1. Load workflow
15
+ let definition;
16
+ try {
17
+ definition = loadWorkflowFromFile(filePath);
18
+ }
19
+ catch (err) {
20
+ console.error(`Error loading workflow: ${err instanceof Error ? err.message : String(err)}`);
21
+ process.exit(1);
22
+ }
23
+ // 2. Parse params
24
+ let params;
25
+ try {
26
+ params = JSON.parse(options.params);
27
+ }
28
+ catch {
29
+ console.error('Error: --params is not valid JSON');
30
+ process.exit(1);
31
+ }
32
+ // 3. Create store and initial run record
33
+ const store = new JsonFileStore();
34
+ const initialRecord = await store.create({
35
+ workflowId: definition.id,
36
+ workflowVersion: definition.version,
37
+ params,
38
+ });
39
+ const runId = initialRecord.id;
40
+ console.log(`\nRealm — ${definition.name} v${definition.version}`);
41
+ console.log(`Run ID: ${runId}\n`);
42
+ // 4. Set up readline
43
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
44
+ // 5. Execution loop
45
+ let run = await store.get(runId);
46
+ try {
47
+ while (!run.terminal_state) {
48
+ // Handle open gate
49
+ if (run.pending_gate !== undefined) {
50
+ const g = run.pending_gate;
51
+ console.log(` ⏸ Gate: ${g.step_name} | gate_id: ${g.gate_id}`);
52
+ console.log(` Preview: ${JSON.stringify(g.preview, null, 2)}`);
53
+ const raw = await rl.question(` Choice [${g.choices.join('/')}]: `);
54
+ const choice = raw.trim();
55
+ const respondResult = await submitHumanResponse(store, definition, {
56
+ runId,
57
+ gateId: g.gate_id,
58
+ choice,
59
+ });
60
+ if (respondResult.status === 'ok') {
61
+ run = await store.get(runId);
62
+ console.log(` ✓ → ${run.run_phase}\n`);
63
+ }
64
+ else {
65
+ console.error(` ✗ ${respondResult.errors.join(', ')}\n`);
66
+ break;
67
+ }
68
+ continue;
69
+ }
70
+ const eligibleSteps = findEligibleSteps(definition, run);
71
+ if (eligibleSteps.length === 0) {
72
+ console.error(`\nNo eligible steps in phase '${run.run_phase}'. Workflow stalled.`);
73
+ break;
74
+ }
75
+ // Take the first eligible step (linear workflow for dev mode)
76
+ const stepName = eligibleSteps[0];
77
+ const stepDef = definition.steps[stepName];
78
+ console.log(`→ [${stepDef.execution}] ${stepName}: ${stepDef.description}`);
79
+ // Build dispatcher output based on execution type
80
+ let userOutput;
81
+ if (stepDef.execution === 'agent') {
82
+ const raw = await rl.question(' Agent output JSON (Enter for {}): ');
83
+ userOutput = raw.trim() === '' ? {} : JSON.parse(raw);
84
+ }
85
+ else {
86
+ // auto step
87
+ const hint = stepDef.handler !== undefined
88
+ ? `handler: ${stepDef.handler}`
89
+ : stepDef.uses_service !== undefined
90
+ ? `service: ${stepDef.uses_service}`
91
+ : 'auto';
92
+ const raw = await rl.question(` Mock output (${hint}) — JSON (Enter for {}): `);
93
+ userOutput = raw.trim() === '' ? {} : JSON.parse(raw);
94
+ }
95
+ const dispatcher = async () => userOutput;
96
+ const result = await executeChain(store, definition, {
97
+ runId,
98
+ command: stepName,
99
+ input: userOutput,
100
+ dispatcher,
101
+ });
102
+ if (result.status === 'ok') {
103
+ run = await store.get(runId);
104
+ const ev = result.evidence[0];
105
+ const hash = ev !== undefined ? ev.evidence_hash.slice(0, 8) : 'n/a';
106
+ const dur = ev !== undefined ? `${ev.duration_ms}ms` : 'n/a';
107
+ console.log(` ✓ → ${run.run_phase} | hash: ${hash}... | ${dur}\n`);
108
+ }
109
+ else if (result.status === 'confirm_required' && result.gate !== undefined) {
110
+ // Gate opened as part of this step — it will be handled at loop top.
111
+ run = await store.get(runId);
112
+ console.log(` Gate opened for '${result.gate.step_name}'.\n`);
113
+ }
114
+ else {
115
+ console.error(` ✗ ${result.status}: ${result.errors.join(', ')}\n`);
116
+ break;
117
+ }
118
+ }
119
+ if (run.terminal_state) {
120
+ console.log(`Run complete. Phase: ${run.run_phase}`);
121
+ }
122
+ }
123
+ finally {
124
+ rl.close();
125
+ }
126
+ });
127
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/commands/run.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACzC,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACtE,MAAM,CAAC,iBAAiB,EAAE,uCAAuC,EAAE,IAAI,CAAC;KACxE,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,OAA2B,EAAE,EAAE;IAC/D,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,mBAAmB;IACnB,IAAI,UAA8B,CAAC;IACnC,IAAI,CAAC;QACH,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,kBAAkB;IAClB,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAA4B,CAAC;IACjE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yCAAyC;IACzC,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;IAElC,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC;QACvC,UAAU,EAAE,UAAU,CAAC,EAAE;QACzB,eAAe,EAAE,UAAU,CAAC,OAAO;QACnC,MAAM;KACP,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC;IAE/B,OAAO,CAAC,GAAG,CAAC,aAAa,UAAU,CAAC,IAAI,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC;IAElC,qBAAqB;IACrB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE7E,oBAAoB;IACpB,IAAI,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAEjC,IAAI,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAC3B,mBAAmB;YACnB,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACnC,MAAM,CAAC,GAAG,GAAG,CAAC,YAAY,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,SAAS,eAAe,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;gBACjE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;gBAChE,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBACrE,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;gBAC1B,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,KAAK,EAAE,UAAU,EAAE;oBACjE,KAAK;oBACL,MAAM,EAAE,CAAC,CAAC,OAAO;oBACjB,MAAM;iBACP,CAAC,CAAC;gBACH,IAAI,aAAa,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;oBAClC,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;oBAC7B,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,SAAS,IAAI,CAAC,CAAC;gBAC1C,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC1D,MAAM;gBACR,CAAC;gBACD,SAAS;YACX,CAAC;YAED,MAAM,aAAa,GAAG,iBAAiB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAEzD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC/B,OAAO,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,SAAS,sBAAsB,CAAC,CAAC;gBACpF,MAAM;YACR,CAAC;YAED,8DAA8D;YAC9D,MAAM,QAAQ,GAAG,aAAa,CAAC,CAAC,CAAE,CAAC;YACnC,MAAM,OAAO,GAAmB,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAE,CAAC;YAE5D,OAAO,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,KAAK,QAAQ,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;YAE5E,kDAAkD;YAClD,IAAI,UAAmC,CAAC;YAExC,IAAI,OAAO,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;gBAClC,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC,CAAC;gBACtE,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC;YACrF,CAAC;iBAAM,CAAC;gBACN,YAAY;gBACZ,MAAM,IAAI,GACR,OAAO,CAAC,OAAO,KAAK,SAAS;oBAC3B,CAAC,CAAC,YAAY,OAAO,CAAC,OAAO,EAAE;oBAC/B,CAAC,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS;wBAClC,CAAC,CAAC,YAAY,OAAO,CAAC,YAAY,EAAE;wBACpC,CAAC,CAAC,MAAM,CAAC;gBACf,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,kBAAkB,IAAI,2BAA2B,CAAC,CAAC;gBACjF,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAA6B,CAAC;YACrF,CAAC;YAED,MAAM,UAAU,GAAmB,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC;YAE1D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE;gBACnD,KAAK;gBACL,OAAO,EAAE,QAAQ;gBACjB,KAAK,EAAE,UAAU;gBACjB,UAAU;aACX,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;gBAC3B,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC7B,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAC9B,MAAM,IAAI,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBACrE,MAAM,GAAG,GAAG,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC7D,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,SAAS,YAAY,IAAI,SAAS,GAAG,IAAI,CAAC,CAAC;YACtE,CAAC;iBAAM,IAAI,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7E,qEAAqE;gBACrE,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,sBAAsB,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,CAAC;YACjE,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrE,MAAM;YACR,CAAC;QACH,CAAC;QAED,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { type Server } from 'node:http';
2
+ import { Command } from 'commander';
3
+ import { JsonWorkflowStore } from '@sensigo/realm';
4
+ /**
5
+ * Checks an Authorization header's Bearer token using timing-safe comparison.
6
+ * Returns true only if the header is present, has the Bearer scheme, and the
7
+ * token matches byte-for-byte. Prevents timing side-channel attacks.
8
+ */
9
+ export declare function checkBearerToken(authHeader: string | undefined, expectedToken: string): boolean;
10
+ export interface StartServerOptions {
11
+ port: number;
12
+ host: string;
13
+ devMode: boolean;
14
+ token: string | undefined;
15
+ /** Custom workflow store — useful in tests to avoid writing to ~/.realm/. */
16
+ workflowStore?: JsonWorkflowStore;
17
+ }
18
+ /**
19
+ * Creates and starts the HTTP MCP server. Resolves once the server is listening.
20
+ * The caller is responsible for calling server.close() when done.
21
+ *
22
+ * Each HTTP request gets a fresh MCP server + stateless transport. The MCP SDK's
23
+ * Protocol.connect() does not allow reconnecting a server to a new transport, so
24
+ * per-request isolation is the correct pattern for stateless HTTP mode.
25
+ */
26
+ export declare function startHttpMcpServer(options: StartServerOptions): Promise<Server>;
27
+ /**
28
+ * `realm serve` — starts the Realm MCP server over HTTP.
29
+ * Designed for hosted agent platforms (OpenClaw, Claude.ai, custom backends) that
30
+ * cannot spawn a local stdio subprocess.
31
+ */
32
+ export declare const serveCommand: Command;
33
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAMnD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAO/F;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,6EAA6E;IAC7E,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+ErF;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY,SAsCrB,CAAC"}
@@ -0,0 +1,144 @@
1
+ // realm serve — starts the Realm MCP server over HTTP for hosted agent platforms.
2
+ // Requires REALM_SERVE_TOKEN env var for Bearer token auth, or --dev for local development.
3
+ import { createServer } from 'node:http';
4
+ import { timingSafeEqual } from 'node:crypto';
5
+ import { Command } from 'commander';
6
+ import { JsonWorkflowStore } from '@sensigo/realm';
7
+ import { createRealmMcpServer } from '@sensigo/realm-mcp';
8
+ import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
9
+ const MAX_BODY_BYTES = 1 * 1024 * 1024; // 1 MiB
10
+ /**
11
+ * Checks an Authorization header's Bearer token using timing-safe comparison.
12
+ * Returns true only if the header is present, has the Bearer scheme, and the
13
+ * token matches byte-for-byte. Prevents timing side-channel attacks.
14
+ */
15
+ export function checkBearerToken(authHeader, expectedToken) {
16
+ if (!authHeader?.startsWith('Bearer '))
17
+ return false;
18
+ const provided = authHeader.slice(7);
19
+ const a = Buffer.from(provided);
20
+ const b = Buffer.from(expectedToken);
21
+ if (a.length !== b.length)
22
+ return false;
23
+ return timingSafeEqual(a, b);
24
+ }
25
+ /**
26
+ * Creates and starts the HTTP MCP server. Resolves once the server is listening.
27
+ * The caller is responsible for calling server.close() when done.
28
+ *
29
+ * Each HTTP request gets a fresh MCP server + stateless transport. The MCP SDK's
30
+ * Protocol.connect() does not allow reconnecting a server to a new transport, so
31
+ * per-request isolation is the correct pattern for stateless HTTP mode.
32
+ */
33
+ export async function startHttpMcpServer(options) {
34
+ const { port, host, devMode, token, workflowStore } = options;
35
+ const httpServer = createServer(async (req, res) => {
36
+ // Auth gate — evaluated before any MCP logic.
37
+ if (!devMode) {
38
+ if (!checkBearerToken(req.headers['authorization'], token)) {
39
+ res.writeHead(401, {
40
+ 'WWW-Authenticate': 'Bearer',
41
+ 'Content-Type': 'application/json',
42
+ });
43
+ res.end(JSON.stringify({ error: 'Unauthorized' }));
44
+ return;
45
+ }
46
+ }
47
+ try {
48
+ // Collect the request body before handing off to the transport.
49
+ let totalBytes = 0;
50
+ const chunks = [];
51
+ for await (const chunk of req) {
52
+ totalBytes += chunk.length;
53
+ if (totalBytes > MAX_BODY_BYTES) {
54
+ res.writeHead(413, { 'Content-Type': 'application/json' });
55
+ res.end(JSON.stringify({ error: 'Request body too large' }));
56
+ req.destroy();
57
+ return;
58
+ }
59
+ chunks.push(chunk);
60
+ }
61
+ const rawBody = Buffer.concat(chunks).toString('utf-8');
62
+ let parsedBody;
63
+ if (rawBody.length > 0) {
64
+ try {
65
+ parsedBody = JSON.parse(rawBody);
66
+ }
67
+ catch {
68
+ res.writeHead(400, { 'Content-Type': 'application/json' });
69
+ res.end(JSON.stringify({ error: 'Invalid JSON in request body' }));
70
+ return;
71
+ }
72
+ }
73
+ const store = workflowStore ?? new JsonWorkflowStore();
74
+ const mcpServer = createRealmMcpServer({ workflowStore: store });
75
+ // Omitting sessionIdGenerator enables stateless mode (SDK default when absent).
76
+ const transport = new StreamableHTTPServerTransport({});
77
+ // @ts-expect-error — SDK type mismatch under exactOptionalPropertyTypes:
78
+ // StreamableHTTPServerTransport.onclose is (() => void) | undefined but
79
+ // Transport.onclose expects () => void. Runtime behaviour is correct.
80
+ await mcpServer.connect(transport);
81
+ await transport.handleRequest(req, res, parsedBody);
82
+ }
83
+ catch (err) {
84
+ if (!res.headersSent && !res.destroyed) {
85
+ res.writeHead(500, { 'Content-Type': 'application/json' });
86
+ res.end(JSON.stringify({ error: 'Internal server error' }));
87
+ }
88
+ else {
89
+ res.destroy(err instanceof Error ? err : new Error(String(err)));
90
+ }
91
+ }
92
+ });
93
+ return new Promise((resolve, reject) => {
94
+ let isListening = false;
95
+ httpServer.on('error', (err) => {
96
+ if (!isListening) {
97
+ reject(err);
98
+ }
99
+ else {
100
+ console.error('Realm MCP server error:', err);
101
+ httpServer.close(() => process.exit(1));
102
+ }
103
+ });
104
+ httpServer.listen(port, host, () => {
105
+ isListening = true;
106
+ resolve(httpServer);
107
+ });
108
+ });
109
+ }
110
+ /**
111
+ * `realm serve` — starts the Realm MCP server over HTTP.
112
+ * Designed for hosted agent platforms (OpenClaw, Claude.ai, custom backends) that
113
+ * cannot spawn a local stdio subprocess.
114
+ */
115
+ export const serveCommand = new Command('serve')
116
+ .description('Start the Realm MCP server over HTTP (for hosted agent platforms that cannot use stdio)')
117
+ .option('--port <number>', 'Port to listen on', '3001')
118
+ .option('--host <address>', 'Bind address', '127.0.0.1')
119
+ .option('--dev', 'Disable authentication (for local development only)')
120
+ .action(async (options) => {
121
+ const port = parseInt(options.port, 10);
122
+ const host = options.host;
123
+ const devMode = options.dev === true || process.env.REALM_DEV === '1';
124
+ const token = process.env.REALM_SERVE_TOKEN;
125
+ if (!devMode && !token) {
126
+ console.error('Error: REALM_SERVE_TOKEN is not set.\n' +
127
+ 'Set it to a secret token, or use --dev / REALM_DEV=1 for local development only.');
128
+ process.exit(1);
129
+ }
130
+ if (devMode) {
131
+ console.warn('Warning: Running in dev mode — authentication is disabled. ' +
132
+ 'Do not expose this to a network.');
133
+ }
134
+ const httpServer = await startHttpMcpServer({ port, host, devMode, token });
135
+ console.log(`Realm MCP server listening on http://${host}:${port}/`);
136
+ if (!devMode) {
137
+ console.log('Authentication: Bearer token (REALM_SERVE_TOKEN)');
138
+ }
139
+ // Graceful shutdown on SIGINT / SIGTERM.
140
+ const shutdown = () => httpServer.close(() => process.exit(0));
141
+ process.on('SIGINT', shutdown);
142
+ process.on('SIGTERM', shutdown);
143
+ });
144
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ import type { TestResult } from '@sensigo/realm-testing';
3
+ /**
4
+ * Formats fixture test results for display.
5
+ * Returns an array of output lines and the appropriate process exit code.
6
+ */
7
+ export declare function formatTestResults(results: TestResult[]): {
8
+ lines: string[];
9
+ exitCode: number;
10
+ };
11
+ export declare const testCommand: Command;
12
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAe9F;AAED,eAAO,MAAM,WAAW,SAoCpB,CAAC"}
@@ -0,0 +1,58 @@
1
+ // realm test <workflow-path> --fixtures <dir> — runs fixture-based workflow tests.
2
+ import { Command } from 'commander';
3
+ import chalk from 'chalk';
4
+ import { existsSync } from 'node:fs';
5
+ import { runFixtureTests } from '@sensigo/realm-testing';
6
+ /**
7
+ * Formats fixture test results for display.
8
+ * Returns an array of output lines and the appropriate process exit code.
9
+ */
10
+ export function formatTestResults(results) {
11
+ const lines = [];
12
+ let allPassed = true;
13
+ for (const result of results) {
14
+ if (result.passed) {
15
+ lines.push(` ${chalk.green('PASS')} ${result.name}`);
16
+ }
17
+ else {
18
+ allPassed = false;
19
+ const errorPart = result.error !== undefined ? `: ${result.error}` : '';
20
+ lines.push(` ${chalk.red('FAIL')} ${result.name}${errorPart}`);
21
+ }
22
+ }
23
+ return { lines, exitCode: allPassed ? 0 : 1 };
24
+ }
25
+ export const testCommand = new Command('test')
26
+ .argument('<workflow-path>', 'Path to workflow directory or workflow.yaml file')
27
+ .requiredOption('-f, --fixtures <dir>', 'Directory containing fixture YAML files')
28
+ .description('Run fixture-based workflow tests')
29
+ .action(async (workflowPath, opts) => {
30
+ if (!existsSync(opts.fixtures)) {
31
+ console.error(`Error: fixtures directory does not exist: ${opts.fixtures}`);
32
+ process.exit(1);
33
+ return;
34
+ }
35
+ let results;
36
+ try {
37
+ results = await runFixtureTests({ workflowPath, fixturesPath: opts.fixtures });
38
+ }
39
+ catch (err) {
40
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
41
+ process.exit(1);
42
+ return;
43
+ }
44
+ if (results.length === 0) {
45
+ console.error('Error: no fixture files found in the specified directory');
46
+ process.exit(1);
47
+ return;
48
+ }
49
+ const { lines, exitCode } = formatTestResults(results);
50
+ const passed = results.filter((r) => r.passed).length;
51
+ console.log(`\nRealm Test — ${workflowPath}`);
52
+ for (const line of lines) {
53
+ console.log(line);
54
+ }
55
+ console.log(`\n${passed}/${results.length} passed`);
56
+ process.exit(exitCode);
57
+ });
58
+ //# sourceMappingURL=test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const validateCommand: Command;
3
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,eAAO,MAAM,eAAe,SA+BxB,CAAC"}
@@ -0,0 +1,35 @@
1
+ // realm validate <path> — validates a workflow YAML file without registering it.
2
+ import { Command } from 'commander';
3
+ import { join } from 'node:path';
4
+ import { readFileSync } from 'node:fs';
5
+ import { loadWorkflowFromString, WorkflowError } from '@sensigo/realm';
6
+ export const validateCommand = new Command('validate')
7
+ .argument('<path>', 'Path to workflow directory or workflow.yaml file')
8
+ .description('Validate a workflow YAML file')
9
+ .action((inputPath) => {
10
+ const filePath = inputPath.endsWith('.yaml') || inputPath.endsWith('.yml')
11
+ ? inputPath
12
+ : join(inputPath, 'workflow.yaml');
13
+ let content;
14
+ try {
15
+ content = readFileSync(filePath, 'utf8');
16
+ }
17
+ catch (err) {
18
+ const message = err instanceof Error ? err.message : String(err);
19
+ console.error(`Error: ${message}`);
20
+ process.exit(1);
21
+ return;
22
+ }
23
+ try {
24
+ const definition = loadWorkflowFromString(content);
25
+ console.log(`Valid: ${definition.id} v${definition.version} (${Object.keys(definition.steps).length} steps)`);
26
+ }
27
+ catch (err) {
28
+ if (err instanceof WorkflowError) {
29
+ console.error(`Invalid: ${err.message}`);
30
+ process.exit(1);
31
+ }
32
+ throw err;
33
+ }
34
+ });
35
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEvE,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC;KACnD,QAAQ,CAAC,QAAQ,EAAE,kDAAkD,CAAC;KACtE,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,CAAC,SAAiB,EAAE,EAAE;IAC5B,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,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,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;QAChB,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;QACnD,OAAO,CAAC,GAAG,CACT,UAAU,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,OAAO,KAAK,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,SAAS,CACjG,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Command } from 'commander';
2
+ import type { WorkflowRegistrar } from '@sensigo/realm';
3
+ /**
4
+ * Watches a workflow YAML file and re-registers it into the given store on every change.
5
+ * Also watches the profiles directory alongside the YAML — any file change there triggers
6
+ * re-registration. If the profiles directory does not exist, only the YAML is watched.
7
+ * Performs an initial registration before entering the watch loop.
8
+ * Resolves when the watcher is closed (e.g. when the AbortSignal fires).
9
+ *
10
+ * @param filePath Path to the workflow YAML file.
11
+ * @param store The workflow registrar to register into — injected, never instantiated here.
12
+ * @param signal Optional AbortSignal; when aborted the watcher stops and the promise resolves.
13
+ * @param profilesDir Optional override for the profiles directory path. Defaults to
14
+ * `<workflow-dir>/profiles` (or `profiles_dir` declared in the YAML).
15
+ */
16
+ export declare function watchWorkflow(filePath: string, store: WorkflowRegistrar, signal?: AbortSignal, profilesDir?: string): Promise<void>;
17
+ export declare const watchCommand: Command;
18
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +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;AA0BxD;;;;;;;;;;;;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"}