@revisium/orchestrator 0.1.0-alpha.5 → 0.1.0-alpha.6

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 (191) hide show
  1. package/README.md +149 -1
  2. package/dist/api/graphql-api/filters/agent-observability-exception.filter.js +24 -0
  3. package/dist/api/graphql-api/filters/agent-observability-exception.filter.js.map +1 -0
  4. package/dist/api/graphql-api/graphql-api.module.js +2 -0
  5. package/dist/api/graphql-api/graphql-api.module.js.map +1 -1
  6. package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-bridge.service.js +296 -0
  7. package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-bridge.service.js.map +1 -0
  8. package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-mappers.js +64 -0
  9. package/dist/api/graphql-api/graphql-ws/agent-observability-subscription-mappers.js.map +1 -0
  10. package/dist/api/graphql-api/graphql-ws/constants.js +2 -0
  11. package/dist/api/graphql-api/graphql-ws/constants.js.map +1 -1
  12. package/dist/api/graphql-api/graphql-ws/pubsub.module.js +5 -2
  13. package/dist/api/graphql-api/graphql-ws/pubsub.module.js.map +1 -1
  14. package/dist/api/graphql-api/registerGraphqlEnums.js +6 -1
  15. package/dist/api/graphql-api/registerGraphqlEnums.js.map +1 -1
  16. package/dist/api/graphql-api/runs/inputs/get-agent-log.input.js +48 -0
  17. package/dist/api/graphql-api/runs/inputs/get-agent-log.input.js.map +1 -0
  18. package/dist/api/graphql-api/runs/model/agent-activity.model.js +367 -0
  19. package/dist/api/graphql-api/runs/model/agent-activity.model.js.map +1 -0
  20. package/dist/api/graphql-api/runs/runs-subscription.resolver.js +35 -4
  21. package/dist/api/graphql-api/runs/runs-subscription.resolver.js.map +1 -1
  22. package/dist/api/graphql-api/runs/runs.resolver.js +35 -0
  23. package/dist/api/graphql-api/runs/runs.resolver.js.map +1 -1
  24. package/dist/cli/commands/doctor-report.js +39 -0
  25. package/dist/cli/commands/doctor-report.js.map +1 -0
  26. package/dist/cli/commands/lifecycle.js +237 -0
  27. package/dist/cli/commands/lifecycle.js.map +1 -0
  28. package/dist/cli/commands/mcp.js +46 -8
  29. package/dist/cli/commands/mcp.js.map +1 -1
  30. package/dist/cli/commands/revisium-helpers.js +2 -2
  31. package/dist/cli/index.js +5 -29
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/program.js +7 -23
  34. package/dist/cli/program.js.map +1 -1
  35. package/dist/config.js +42 -5
  36. package/dist/config.js.map +1 -1
  37. package/dist/control-plane/bootstrap.js +93 -0
  38. package/dist/control-plane/bootstrap.js.map +1 -0
  39. package/dist/control-plane/schema-migration.js +7 -11
  40. package/dist/control-plane/schema-migration.js.map +1 -1
  41. package/dist/control-plane/seed-default-playbook.js +23 -0
  42. package/dist/control-plane/seed-default-playbook.js.map +1 -1
  43. package/dist/e2e/kit/agents.js +17 -5
  44. package/dist/e2e/kit/agents.js.map +1 -1
  45. package/dist/e2e/kit/assertions.js +20 -0
  46. package/dist/e2e/kit/assertions.js.map +1 -1
  47. package/dist/e2e/kit/harness.js +12 -1
  48. package/dist/e2e/kit/harness.js.map +1 -1
  49. package/dist/e2e/kit/scenarios.js +1 -1
  50. package/dist/e2e/recovery-dd-crash-child.js +3 -2
  51. package/dist/e2e/recovery-dd-crash-child.js.map +1 -1
  52. package/dist/engine/dbos.service.js +20 -0
  53. package/dist/engine/dbos.service.js.map +1 -1
  54. package/dist/engine/ensure-postgres.js +11 -9
  55. package/dist/engine/ensure-postgres.js.map +1 -1
  56. package/dist/features/runs/queries/handlers/runs-query.handlers.js +135 -0
  57. package/dist/features/runs/queries/handlers/runs-query.handlers.js.map +1 -1
  58. package/dist/features/runs/queries/impl/get-agent-activity.query.js +7 -0
  59. package/dist/features/runs/queries/impl/get-agent-activity.query.js.map +1 -0
  60. package/dist/features/runs/queries/impl/get-agent-attempts.query.js +7 -0
  61. package/dist/features/runs/queries/impl/get-agent-attempts.query.js.map +1 -0
  62. package/dist/features/runs/queries/impl/get-agent-log.query.js +7 -0
  63. package/dist/features/runs/queries/impl/get-agent-log.query.js.map +1 -0
  64. package/dist/features/runs/queries/index.js +4 -1
  65. package/dist/features/runs/queries/index.js.map +1 -1
  66. package/dist/features/runs/runs-api.service.js +12 -0
  67. package/dist/features/runs/runs-api.service.js.map +1 -1
  68. package/dist/host/daemon.js +68 -0
  69. package/dist/host/daemon.js.map +1 -0
  70. package/dist/host/ensure-host.js +109 -0
  71. package/dist/host/ensure-host.js.map +1 -0
  72. package/dist/host/host-runtime.js +52 -0
  73. package/dist/host/host-runtime.js.map +1 -0
  74. package/dist/http/graphql-host.js +8 -2
  75. package/dist/http/graphql-host.js.map +1 -1
  76. package/dist/http/graphql-host.module.js +3 -0
  77. package/dist/http/graphql-host.module.js.map +1 -1
  78. package/dist/mcp/mcp-capabilities.js +6 -1
  79. package/dist/mcp/mcp-capabilities.js.map +1 -1
  80. package/dist/mcp/mcp-facade.service.js +24 -0
  81. package/dist/mcp/mcp-facade.service.js.map +1 -1
  82. package/dist/mcp/mcp-http.service.js +95 -0
  83. package/dist/mcp/mcp-http.service.js.map +1 -0
  84. package/dist/mcp/mcp-tools.js +58 -0
  85. package/dist/mcp/mcp-tools.js.map +1 -1
  86. package/dist/observability/agent-activity-reporter.js +185 -0
  87. package/dist/observability/agent-activity-reporter.js.map +1 -0
  88. package/dist/observability/agent-observability.service.js +1142 -0
  89. package/dist/observability/agent-observability.service.js.map +1 -0
  90. package/dist/observability/index.js +4 -0
  91. package/dist/observability/index.js.map +1 -0
  92. package/dist/observability/types.js +11 -0
  93. package/dist/observability/types.js.map +1 -0
  94. package/dist/pipeline/data-driven-task.workflow.js +37 -75
  95. package/dist/pipeline/data-driven-task.workflow.js.map +1 -1
  96. package/dist/pipeline/pipeline.service.js +54 -15
  97. package/dist/pipeline/pipeline.service.js.map +1 -1
  98. package/dist/pipeline-core/validate-capability.js +23 -0
  99. package/dist/pipeline-core/validate-capability.js.map +1 -0
  100. package/dist/pipeline-core/validate-conflicts.js +37 -0
  101. package/dist/pipeline-core/validate-conflicts.js.map +1 -0
  102. package/dist/pipeline-core/validate-dataflow.js +180 -0
  103. package/dist/pipeline-core/validate-dataflow.js.map +1 -0
  104. package/dist/pipeline-core/validate-diff.js +158 -0
  105. package/dist/pipeline-core/validate-diff.js.map +1 -0
  106. package/dist/pipeline-core/validate-edges.js +44 -0
  107. package/dist/pipeline-core/validate-edges.js.map +1 -0
  108. package/dist/pipeline-core/validate-graph.js +123 -0
  109. package/dist/pipeline-core/validate-graph.js.map +1 -0
  110. package/dist/pipeline-core/validate-loops.js +226 -0
  111. package/dist/pipeline-core/validate-loops.js.map +1 -0
  112. package/dist/pipeline-core/validate-parallel.js +132 -0
  113. package/dist/pipeline-core/validate-parallel.js.map +1 -0
  114. package/dist/pipeline-core/validate-sink.js +27 -0
  115. package/dist/pipeline-core/validate-sink.js.map +1 -0
  116. package/dist/pipeline-core/validate-topology.js +140 -0
  117. package/dist/pipeline-core/validate-topology.js.map +1 -0
  118. package/dist/pipeline-core/validate-verdict.js +72 -0
  119. package/dist/pipeline-core/validate-verdict.js.map +1 -0
  120. package/dist/pipeline-core/validate.js +34 -1107
  121. package/dist/pipeline-core/validate.js.map +1 -1
  122. package/dist/revisium/run.service.js +15 -1
  123. package/dist/revisium/run.service.js.map +1 -1
  124. package/dist/runners/codex.service.js +51 -0
  125. package/dist/runners/codex.service.js.map +1 -0
  126. package/dist/runners/integrator-branch-naming.js +24 -0
  127. package/dist/runners/integrator-branch-naming.js.map +1 -0
  128. package/dist/runners/integrator-git.js +84 -0
  129. package/dist/runners/integrator-git.js.map +1 -0
  130. package/dist/runners/integrator-remote.js +34 -0
  131. package/dist/runners/integrator-remote.js.map +1 -0
  132. package/dist/runners/integrator-types.js +9 -0
  133. package/dist/runners/integrator-types.js.map +1 -0
  134. package/dist/runners/integrator.js +12 -132
  135. package/dist/runners/integrator.js.map +1 -1
  136. package/dist/runners/runner.module.js +4 -2
  137. package/dist/runners/runner.module.js.map +1 -1
  138. package/dist/smoke/cli.js +47 -0
  139. package/dist/smoke/cli.js.map +1 -0
  140. package/dist/smoke/isolation.js +113 -0
  141. package/dist/smoke/isolation.js.map +1 -0
  142. package/dist/task-control-plane/task-control-plane-api.service.js +24 -1
  143. package/dist/task-control-plane/task-control-plane-api.service.js.map +1 -1
  144. package/dist/task-control-plane/task-control-plane.module.js +21 -1
  145. package/dist/task-control-plane/task-control-plane.module.js.map +1 -1
  146. package/dist/worker/artifact-store.js +6 -1
  147. package/dist/worker/artifact-store.js.map +1 -1
  148. package/dist/worker/build-context.js +135 -1
  149. package/dist/worker/build-context.js.map +1 -1
  150. package/dist/worker/claude-code-runner.js +75 -76
  151. package/dist/worker/claude-code-runner.js.map +1 -1
  152. package/dist/worker/codex-runner.js +474 -0
  153. package/dist/worker/codex-runner.js.map +1 -0
  154. package/dist/worker/result-envelope.js +51 -79
  155. package/dist/worker/result-envelope.js.map +1 -1
  156. package/dist/worker/runner-common.js +106 -0
  157. package/dist/worker/runner-common.js.map +1 -0
  158. package/dist/worker/runner-dispatch.js +3 -1
  159. package/dist/worker/runner-dispatch.js.map +1 -1
  160. package/dist/worker/runner.js.map +1 -1
  161. package/dist/worker/stub-runner.js +3 -3
  162. package/dist/worker/stub-runner.js.map +1 -1
  163. package/package.json +1 -1
  164. package/dist/app.module.js +0 -28
  165. package/dist/app.module.js.map +0 -1
  166. package/dist/cli/commands/bootstrap.js +0 -100
  167. package/dist/cli/commands/bootstrap.js.map +0 -1
  168. package/dist/cli/commands/dev.js +0 -143
  169. package/dist/cli/commands/dev.js.map +0 -1
  170. package/dist/cli/commands/inbox.js +0 -288
  171. package/dist/cli/commands/inbox.js.map +0 -1
  172. package/dist/cli/commands/playbook.js +0 -74
  173. package/dist/cli/commands/playbook.js.map +0 -1
  174. package/dist/cli/commands/poll-workflow-state.js +0 -144
  175. package/dist/cli/commands/poll-workflow-state.js.map +0 -1
  176. package/dist/cli/commands/revisium-context.js +0 -23
  177. package/dist/cli/commands/revisium-context.js.map +0 -1
  178. package/dist/cli/commands/revisium.js +0 -89
  179. package/dist/cli/commands/revisium.js.map +0 -1
  180. package/dist/cli/commands/run.js +0 -451
  181. package/dist/cli/commands/run.js.map +0 -1
  182. package/dist/cli/commands/serve.js +0 -26
  183. package/dist/cli/commands/serve.js.map +0 -1
  184. package/dist/cli/live-guard.js +0 -49
  185. package/dist/cli/live-guard.js.map +0 -1
  186. package/dist/cli/needs-host.js +0 -77
  187. package/dist/cli/needs-host.js.map +0 -1
  188. package/dist/mcp/mcp-stdio.service.js +0 -48
  189. package/dist/mcp/mcp-stdio.service.js.map +0 -1
  190. package/dist/mcp/mcp.module.js +0 -21
  191. package/dist/mcp/mcp.module.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-report.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor-report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAqBH,MAAM,UAAU,iBAAiB,CAAC,CAAoB;IACpD,0EAA0E;IAC1E,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,yCAAyC,CAAC,EAAE,CAAC;IAC5E,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,oEAAoE;IACpE,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CACT,iCAAiC,CAAC,CAAC,IAAI,CAAC,GAAG,oEAAoE,CAChH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CACT,oBAAoB,CAAC,CAAC,IAAI,CAAC,GAAG,mDAAmD,CAAC,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAClH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,qGAAqG,CAAC,CAAC;IACrH,CAAC;IAED,0EAA0E;IAC1E,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAChD,MAAM,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC,UAAU,CAAC,GAAG,gBAAgB,CAAC,CAAC;IAC/F,CAAC;SAAM,IAAI,CAAC,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,CAAC,IAAI,CACT,4BAA4B,CAAC,CAAC,UAAU,CAAC,GAAG,sCAAsC,CAAC,CAAC,UAAU,CAAC,IAAI,GAAG,CACvG,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CACT,yGAAyG,CAC1G,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,237 @@
1
+ import { closeSync, existsSync, openSync, readSync, statSync } from 'node:fs';
2
+ import { baseUrl, getConfig, isAlive, isHealthy, readRuntime, removeRuntime, } from '../config.js';
3
+ import { killTree, tailLines, waitForExit } from './revisium-helpers.js';
4
+ import { buildDoctorReport } from './doctor-report.js';
5
+ import { ensureHost, expectedGraphqlPort, isGraphqlHealthy } from '../../host/ensure-host.js';
6
+ import { runHostDaemon } from '../../host/daemon.js';
7
+ import { isHostRunning, readHostRuntime, removeHostRuntime } from '../../host/host-runtime.js';
8
+ const DEFAULT_LOG_LINES = 50;
9
+ /** A --profile flag sets REVO_PROFILE so the resolved profile flows to the daemon child via env. */
10
+ function applyProfileEnv(options) {
11
+ if (options.profile)
12
+ process.env['REVO_PROFILE'] = options.profile;
13
+ }
14
+ /** `revo start` — bring up the whole stack (host daemon + standalone) and print its endpoints. */
15
+ async function startStack(options) {
16
+ applyProfileEnv(options);
17
+ const { profile, dataDir } = getConfig();
18
+ try {
19
+ const { runtime, alreadyRunning } = await ensureHost();
20
+ const standalone = readRuntime();
21
+ console.log(alreadyRunning ? `Revo already running (profile ${profile})` : `Revo started (profile ${profile})`);
22
+ console.log(`Host daemon: pid ${runtime.pid}`);
23
+ console.log(`GraphQL: ${baseUrl(runtime.graphqlPort)}/graphql`);
24
+ if (standalone)
25
+ console.log(`Revisium: ${baseUrl(standalone.httpPort)} (pg ${standalone.pgPort})`);
26
+ console.log(`Data dir: ${dataDir}`);
27
+ }
28
+ catch (err) {
29
+ console.error(err instanceof Error ? err.message : String(err));
30
+ process.exitCode = 1;
31
+ }
32
+ }
33
+ /** Stop a pid gracefully: SIGTERM, then SIGKILL if it has not exited within the grace period. */
34
+ async function stopProcess(pid) {
35
+ if (!isAlive(pid))
36
+ return;
37
+ killTree(pid, 'SIGTERM');
38
+ if (!(await waitForExit(pid, 20_000))) {
39
+ killTree(pid, 'SIGKILL');
40
+ await waitForExit(pid, 5_000);
41
+ }
42
+ }
43
+ /** `revo stop` — stop the host daemon first (it owns DBOS), then the standalone Revisium daemon. */
44
+ async function stopStack(options) {
45
+ applyProfileEnv(options);
46
+ let stopped = false;
47
+ // Host first (it owns DBOS); then the standalone daemon underneath it.
48
+ const host = readHostRuntime();
49
+ if (host && isAlive(host.pid)) {
50
+ await stopProcess(host.pid);
51
+ stopped = true;
52
+ }
53
+ removeHostRuntime();
54
+ const standalone = readRuntime();
55
+ if (standalone && isAlive(standalone.pid)) {
56
+ await stopProcess(standalone.pid);
57
+ stopped = true;
58
+ }
59
+ removeRuntime();
60
+ console.log(stopped ? 'stopped' : 'not running');
61
+ }
62
+ /** `revo status` — summarize the stack: profile, data dir, host daemon, and Revisium health. */
63
+ async function statusStack(options) {
64
+ applyProfileEnv(options);
65
+ const { profile, dataDir } = getConfig();
66
+ console.log(`Profile: ${profile}`);
67
+ console.log(`Data dir: ${dataDir}`);
68
+ const host = readHostRuntime();
69
+ if (host && isHostRunning()) {
70
+ const healthy = await isGraphqlHealthy(host.graphqlPort);
71
+ console.log(`Host daemon: running (pid ${host.pid}) — GraphQL ${baseUrl(host.graphqlPort)}/graphql ${healthy ? 'OK' : 'FAILING'}`);
72
+ }
73
+ else {
74
+ console.log(`Host daemon: stopped (GraphQL port ${expectedGraphqlPort()})`);
75
+ }
76
+ const standalone = readRuntime();
77
+ if (standalone && isAlive(standalone.pid)) {
78
+ const healthy = await isHealthy(standalone.httpPort);
79
+ console.log(`Revisium: running (pid ${standalone.pid}) on ${baseUrl(standalone.httpPort)} pg ${standalone.pgPort} — health ${healthy ? 'OK' : 'FAILING'}`);
80
+ }
81
+ else {
82
+ console.log('Revisium: stopped');
83
+ }
84
+ }
85
+ /** `revo restart` — stop then start the whole stack (same profile). The dev code-reload primitive. */
86
+ async function restartStack(options) {
87
+ applyProfileEnv(options);
88
+ console.log('Restarting Revo stack…');
89
+ await stopStack(options);
90
+ await startStack(options);
91
+ }
92
+ /** `revo doctor` — diagnose the stack as a pure client: process/port/profile/stale-file health. */
93
+ async function doctorStack(options) {
94
+ applyProfileEnv(options);
95
+ const { profile, dataDir } = getConfig();
96
+ const host = readHostRuntime();
97
+ const hostAlive = host !== null && isAlive(host.pid);
98
+ const hostHealthy = host !== null && hostAlive && (await isGraphqlHealthy(host.graphqlPort));
99
+ const standalone = readRuntime();
100
+ const standaloneAlive = standalone !== null && isAlive(standalone.pid);
101
+ const standaloneHealthy = standalone !== null && standaloneAlive && (await isHealthy(standalone.httpPort));
102
+ const report = buildDoctorReport({
103
+ host: {
104
+ present: host !== null,
105
+ alive: hostAlive,
106
+ healthy: hostHealthy,
107
+ pid: host?.pid ?? null,
108
+ port: host?.graphqlPort ?? null,
109
+ },
110
+ standalone: {
111
+ present: standalone !== null,
112
+ alive: standaloneAlive,
113
+ healthy: standaloneHealthy,
114
+ pid: standalone?.pid ?? null,
115
+ port: standalone?.httpPort ?? null,
116
+ },
117
+ });
118
+ console.log(`Profile: ${profile}`);
119
+ console.log(`Data dir: ${dataDir}`);
120
+ if (report.ok) {
121
+ console.log('OK — stack is healthy.');
122
+ return;
123
+ }
124
+ for (const issue of report.issues)
125
+ console.log(`✗ ${issue}`);
126
+ process.exitCode = 1;
127
+ }
128
+ /** Resolve which logs to read: `host`, `standalone`, or both (default). Profile-scoped paths. */
129
+ function resolveLogTargets(target) {
130
+ const { logFile, hostLogFile } = getConfig();
131
+ const host = { label: 'host', file: hostLogFile };
132
+ const standalone = { label: 'standalone', file: logFile };
133
+ if (target === 'host')
134
+ return [host];
135
+ if (target === 'standalone')
136
+ return [standalone];
137
+ return [host, standalone];
138
+ }
139
+ /** `revo logs [target]` — print the tail of the daemon logs; a pure file read (works when down). */
140
+ async function logsStack(target, options) {
141
+ applyProfileEnv(options);
142
+ if (target !== undefined && target !== 'host' && target !== 'standalone') {
143
+ console.error(`Invalid logs target "${target}". Use "host" or "standalone".`);
144
+ process.exitCode = 1;
145
+ return;
146
+ }
147
+ const requested = Number(options.lines ?? DEFAULT_LOG_LINES);
148
+ const lines = Number.isInteger(requested) && requested > 0 ? requested : DEFAULT_LOG_LINES;
149
+ const targets = resolveLogTargets(target);
150
+ for (const { label, file } of targets) {
151
+ const tail = tailLines(file, lines);
152
+ console.log(`==> [${label}] ${file} <==`);
153
+ console.log(tail === '' ? '(no log yet)' : tail);
154
+ console.log('');
155
+ }
156
+ if (options.follow)
157
+ await followLogs(targets);
158
+ }
159
+ /**
160
+ * Follow mode: poll each log for bytes appended past a tracked offset and stream them, labelled,
161
+ * until interrupted (Ctrl-C). The daemons open their logs append-only (no rotation), so a byte
162
+ * offset is a stable cursor; a shrink (manual truncate) simply resyncs to the new end.
163
+ */
164
+ async function followLogs(targets) {
165
+ const offsets = new Map();
166
+ for (const { file } of targets)
167
+ offsets.set(file, existsSync(file) ? statSync(file).size : 0);
168
+ for (;;) {
169
+ for (const { label, file } of targets) {
170
+ if (!existsSync(file))
171
+ continue;
172
+ const size = statSync(file).size;
173
+ const from = offsets.get(file) ?? 0;
174
+ if (size > from) {
175
+ const fd = openSync(file, 'r');
176
+ try {
177
+ const buf = Buffer.alloc(size - from);
178
+ readSync(fd, buf, 0, buf.length, from);
179
+ process.stdout.write(prefixLines(label, buf.toString('utf8')));
180
+ }
181
+ finally {
182
+ closeSync(fd);
183
+ }
184
+ }
185
+ offsets.set(file, size);
186
+ }
187
+ await new Promise((resolve) => setTimeout(resolve, 500));
188
+ }
189
+ }
190
+ /** Prefix each non-empty line of a streamed chunk with its tier label for interleaved follow output. */
191
+ function prefixLines(label, chunk) {
192
+ return chunk
193
+ .split('\n')
194
+ .map((line) => (line === '' ? line : `[${label}] ${line}`))
195
+ .join('\n');
196
+ }
197
+ /** Register the lifecycle commands (start/stop/status/restart/doctor/logs) + the hidden `__daemon` entrypoint. */
198
+ export function registerLifecycle(program) {
199
+ program
200
+ .command('start')
201
+ .description('Start the Revo stack (host daemon + standalone Revisium)')
202
+ .option('--profile <name>', 'Runtime profile (default|dev)')
203
+ .action((options) => startStack(options));
204
+ program
205
+ .command('stop')
206
+ .description('Stop the Revo stack (host daemon first, then standalone)')
207
+ .option('--profile <name>', 'Runtime profile (default|dev)')
208
+ .action((options) => stopStack(options));
209
+ program
210
+ .command('status')
211
+ .description('Show Revo stack status (host daemon, Revisium, profile)')
212
+ .option('--profile <name>', 'Runtime profile (default|dev)')
213
+ .action((options) => statusStack(options));
214
+ program
215
+ .command('restart')
216
+ .description('Restart the Revo stack (stop, then start)')
217
+ .option('--profile <name>', 'Runtime profile (default|dev)')
218
+ .action((options) => restartStack(options));
219
+ program
220
+ .command('doctor')
221
+ .description('Diagnose the Revo stack (process/port/profile health)')
222
+ .option('--profile <name>', 'Runtime profile (default|dev)')
223
+ .action((options) => doctorStack(options));
224
+ program
225
+ .command('logs [target]')
226
+ .description('Tail Revo logs (target: host | standalone; default both)')
227
+ .option('--profile <name>', 'Runtime profile (default|dev)')
228
+ .option('-n, --lines <count>', 'Lines to show from the end', String(DEFAULT_LOG_LINES))
229
+ .option('-f, --follow', 'Stream new log output until interrupted')
230
+ .action((target, options) => logsStack(target, options));
231
+ // Internal: the detached daemon entrypoint spawned by ensureHost (not a user-facing command).
232
+ program
233
+ .command('__daemon', { hidden: true })
234
+ .description('Run the host daemon in the foreground (internal — spawned by `revo start`)')
235
+ .action(() => runHostDaemon());
236
+ }
237
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/cli/commands/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,54 @@
1
- import { McpStdioService } from '../../mcp/mcp-stdio.service.js';
2
- async function startMcp(app) {
3
- if (!app) {
4
- console.error('mcp requires the host context — invoke via the host path');
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
3
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
6
+ import { readPackageVersion } from '../../package-info.js';
7
+ import { ensureHost } from '../../host/ensure-host.js';
8
+ import { readHostRuntime } from '../../host/host-runtime.js';
9
+ /**
10
+ * `revo mcp` — a thin stdio↔daemon MCP bridge (ADR 0006). It ensures the host daemon is up, then
11
+ * proxies tool list/call from the stdio client (Claude Code) to the daemon's in-process MCP server
12
+ * over StreamableHTTP. It does NOT build AppModule or launch DBOS — the daemon is the single DBOS
13
+ * owner, so every tool runs against the one host and read tools never trigger a recovery pass.
14
+ */
15
+ async function runMcpBridge() {
16
+ await ensureHost();
17
+ const runtime = readHostRuntime();
18
+ if (!runtime) {
19
+ console.error('Revo host daemon is not available — run `revo start`.');
5
20
  process.exitCode = 1;
6
21
  return;
7
22
  }
8
- await app.get(McpStdioService).start();
23
+ const version = readPackageVersion();
24
+ const upstream = new Client({ name: 'revo-mcp-bridge', version });
25
+ await upstream.connect(new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${runtime.mcpPort}/mcp`)));
26
+ // Downstream stdio server (faces Claude Code) — forwards tools to the daemon's MCP server.
27
+ const server = new Server({ name: 'revo', version }, { capabilities: { tools: {} } });
28
+ server.setRequestHandler(ListToolsRequestSchema, () => upstream.listTools());
29
+ server.setRequestHandler(CallToolRequestSchema, (request) => upstream.callTool(request.params));
30
+ const transport = new StdioServerTransport();
31
+ const closed = new Promise((resolve) => {
32
+ transport.onclose = () => resolve();
33
+ process.stdin.once('end', resolve);
34
+ process.stdin.once('close', resolve);
35
+ process.once('SIGINT', resolve);
36
+ process.once('SIGTERM', resolve);
37
+ });
38
+ try {
39
+ await server.connect(transport);
40
+ await closed;
41
+ }
42
+ finally {
43
+ await upstream.close().catch(() => undefined);
44
+ await server.close().catch(() => undefined);
45
+ }
9
46
  }
10
- export function registerMcp(program, app) {
47
+ /** Register `revo mcp` — the thin stdio bridge to the daemon's MCP front door (no AppModule/DBOS). */
48
+ export function registerMcp(program) {
11
49
  program
12
50
  .command('mcp')
13
- .description('Start the local stdio MCP server for task development control')
14
- .action(() => startMcp(app));
51
+ .description('Start the local stdio MCP server (bridges to the running Revo daemon)')
52
+ .action(() => runMcpBridge());
15
53
  }
16
54
  //# sourceMappingURL=mcp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/cli/commands/mcp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,KAAK,UAAU,QAAQ,CAAC,GAAwC;IAC9D,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CAAC,0DAA0D,CAAC,CAAC;QAC1E,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,GAA6B;IACzE,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,+DAA+D,CAAC;SAC5E,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../../src/cli/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Private helpers shared between `revisium.ts` (stop/logs) and `ensure-revisium.ts`.
3
- * Extracted to avoid duplication (F9).
2
+ * Process + log helpers shared by the lifecycle CLI (`lifecycle.ts`: stop/logs) and the daemon
3
+ * bring-up path (`ensure-revisium.ts`). Extracted to avoid duplication (F9).
4
4
  */
5
5
  import { existsSync, readFileSync } from 'node:fs';
6
6
  import { isAlive } from '../config.js';
package/dist/cli/index.js CHANGED
@@ -1,32 +1,8 @@
1
+ // reflect-metadata is required by the daemon entrypoint (`revo __daemon` → NestFactory); load it once
2
+ // here so it is present whichever command runs.
1
3
  import 'reflect-metadata';
2
- import { isMcpCommand, needsHost } from './needs-host.js';
3
4
  import { buildProgram } from './program.js';
4
- const argv = process.argv;
5
- if (needsHost(argv)) {
6
- // Host path: dev:ping, dev:status (and future run/work when they move onto DBOS).
7
- // Nest/DBOS/AppModule are imported lazily so the host-free path never loads them.
8
- const mcpCommand = isMcpCommand(argv);
9
- if (mcpCommand) {
10
- process.env.REVO_MCP_STDIO = '1';
11
- }
12
- else {
13
- delete process.env.REVO_MCP_STDIO;
14
- }
15
- const { NestFactory } = await import('@nestjs/core');
16
- const { AppModule } = await import('../app.module.js');
17
- const app = await NestFactory.createApplicationContext(AppModule, { logger: mcpCommand ? false : ['error', 'warn'] });
18
- try {
19
- await buildProgram(app).parseAsync(argv);
20
- }
21
- finally {
22
- // onApplicationShutdown → DBOS.shutdown() only; daemon is NOT stopped (Round 3).
23
- await app.close();
24
- }
25
- }
26
- else {
27
- // Host-free path: revisium start/stop/status/logs, bootstrap, run, work,
28
- // --help, --version, empty/unknown commands.
29
- // Nest/DBOS are NOT loaded here — fast and safe for daemon-management commands.
30
- await buildProgram().parseAsync(argv);
31
- }
5
+ // The CLI is a lightweight client/process-manager (ADR 0006): it NEVER builds AppModule or launches
6
+ // DBOS. The only long-lived host is the daemon, spawned detached via the hidden `__daemon` command.
7
+ await buildProgram().parseAsync(process.argv);
32
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;AAE1B,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;IACpB,kFAAkF;IAClF,kFAAkF;IAClF,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,GAAG,CAAC;IACnC,CAAC;SAAM,CAAC;QACN,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACpC,CAAC;IACD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,CAAC;IACrD,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,wBAAwB,CAAC,SAAS,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACtH,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;YAAS,CAAC;QACT,iFAAiF;QACjF,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC;AACH,CAAC;KAAM,CAAC;IACN,yEAAyE;IACzE,6CAA6C;IAC7C,gFAAgF;IAChF,MAAM,YAAY,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,gDAAgD;AAChD,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,oGAAoG;AACpG,oGAAoG;AACpG,MAAM,YAAY,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -1,37 +1,21 @@
1
1
  import { Command } from 'commander';
2
2
  import { readPackageVersion } from '../package-info.js';
3
- import { registerBootstrap } from './commands/bootstrap.js';
4
- import { registerDev } from './commands/dev.js';
5
- import { registerInbox } from './commands/inbox.js';
3
+ import { registerLifecycle } from './commands/lifecycle.js';
6
4
  import { registerMcp } from './commands/mcp.js';
7
- import { registerPlaybook } from './commands/playbook.js';
8
- import { registerRevisium } from './commands/revisium.js';
9
- import { registerRun } from './commands/run.js';
10
- import { registerServe } from './commands/serve.js';
11
5
  export { readPackageVersion };
12
6
  /**
13
- * Build the commander program.
14
- *
15
- * @param app - Optional Nest app context (host path only).
16
- * - When `app` is provided, dev:ping/dev:status actions are wired to the DI context.
17
- * - When `app` is absent (host-free path or tests), dev command DEFINITIONS are still
18
- * registered so `dev:ping --help` works; actions guard on the absent `app`.
19
- * - The no-arg overload is preserved for program.test.ts compatibility.
7
+ * Build the Revo CLI. The CLI is lifecycle-only (ADR 0006): `revo start/stop/status/...` manage the
8
+ * whole stack, and `revo mcp` is a thin stdio bridge to the daemon. Orchestration (runs, inbox,
9
+ * method, …) is reached through the daemon's MCP + GraphQL front doors, not the CLI.
20
10
  */
21
- export function buildProgram(app) {
11
+ export function buildProgram() {
22
12
  const program = new Command();
23
13
  program
24
14
  .name('revo')
25
15
  .description('Agent orchestrator CLI')
26
16
  .version(readPackageVersion(), '-v, --version', 'Print the revo version');
27
- registerRevisium(program);
28
- registerBootstrap(program);
29
- registerPlaybook(program);
30
- registerRun(program, app);
31
- registerInbox(program, app); // G6: forward app so gate resolve path can access DbosService
32
- registerMcp(program, app);
33
- registerDev(program, app);
34
- registerServe(program);
17
+ registerLifecycle(program);
18
+ registerMcp(program);
35
19
  return program;
36
20
  }
37
21
  //# sourceMappingURL=program.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,GAA6B;IACxD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,wBAAwB,CAAC;SACrC,OAAO,CAAC,kBAAkB,EAAE,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAC;IAC5E,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1B,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3B,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAC1B,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1B,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,8DAA8D;IAC3F,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1B,WAAW,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;IAC1B,aAAa,CAAC,OAAO,CAAC,CAAC;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,MAAM,CAAC;SACZ,WAAW,CAAC,wBAAwB,CAAC;SACrC,OAAO,CAAC,kBAAkB,EAAE,EAAE,eAAe,EAAE,wBAAwB,CAAC,CAAC;IAC5E,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC3B,WAAW,CAAC,OAAO,CAAC,CAAC;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/dist/config.js CHANGED
@@ -3,6 +3,16 @@ import { existsSync, mkdirSync, readFileSync, rmSync } from 'node:fs';
3
3
  import { dirname, join, resolve } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import os from 'node:os';
6
+ /**
7
+ * Runtime profiles let an installed package (`default`) and a source checkout (`dev`) run on one
8
+ * machine at once: a profile shifts the whole isolation band off the committed defaults, so the two
9
+ * never share a port, data dir, or `dbos` database. Custom layouts set the REVO_* knobs directly
10
+ * instead of adding a profile here. The single source of band constants (offset/suffix/db name).
11
+ */
12
+ export const PROFILES = {
13
+ default: { suffix: '', portOffset: 0, dbosDb: 'dbos' },
14
+ dev: { suffix: '-dev', portOffset: 400, dbosDb: 'dbos_dev' },
15
+ };
6
16
  export const GRAPHQL_PORT_OFFSET = 1;
7
17
  const sourceDir = dirname(fileURLToPath(import.meta.url));
8
18
  export const repoRoot = resolve(sourceDir, '..');
@@ -19,13 +29,37 @@ function loadConfig() {
19
29
  }
20
30
  let cachedConfig = null;
21
31
  /** Parse a positive-integer env var, or undefined if unset/invalid. */
22
- function numEnv(name) {
23
- const raw = process.env[name];
32
+ function numEnv(name, env = process.env) {
33
+ const raw = env[name];
24
34
  if (raw === undefined)
25
35
  return undefined;
26
36
  const n = Number.parseInt(raw, 10);
27
37
  return Number.isFinite(n) && n > 0 ? n : undefined;
28
38
  }
39
+ /** Resolve the active profile from REVO_PROFILE (default `default`); unknown names fail loudly. */
40
+ export function resolveProfileName(env = process.env) {
41
+ const raw = env['REVO_PROFILE'];
42
+ if (!raw)
43
+ return 'default';
44
+ if (Object.prototype.hasOwnProperty.call(PROFILES, raw))
45
+ return raw;
46
+ throw new Error(`Unknown REVO_PROFILE '${raw}'. Known profiles: ${Object.keys(PROFILES).join(', ')}. ` +
47
+ 'Set REVO_DATA_DIR/REVO_PORT/REVO_PG_PORT/REVO_DBOS_DB explicitly for a custom layout.');
48
+ }
49
+ /**
50
+ * Layer profile + env into the data dir and ports: the profile sets the band, then an explicit
51
+ * REVO_* env var overrides that single knob. Pure (no fs) so the precedence is unit-testable.
52
+ */
53
+ export function resolveProfileConfig(raw, env = process.env) {
54
+ const profile = resolveProfileName(env);
55
+ const band = PROFILES[profile];
56
+ return {
57
+ profile,
58
+ dataDir: env['REVO_DATA_DIR'] ?? `${raw.dataDir}${band.suffix}`,
59
+ preferredPort: numEnv('REVO_PORT', env) ?? raw.preferredPort + band.portOffset,
60
+ preferredPgPort: numEnv('REVO_PG_PORT', env) ?? raw.preferredPgPort + band.portOffset,
61
+ };
62
+ }
29
63
  /**
30
64
  * Test/CI isolation: env overrides keep a throwaway daemon (and its embedded Postgres + DBOS db)
31
65
  * fully separate from the developer's dogfooding control-plane. `REVO_DATA_DIR` redirects the data
@@ -37,14 +71,17 @@ export function getConfig() {
37
71
  if (cachedConfig)
38
72
  return cachedConfig;
39
73
  const rawConfig = loadConfig();
40
- const dataDir = expandHome(process.env['REVO_DATA_DIR'] ?? rawConfig.dataDir);
74
+ const { profile, dataDir: profileDataDir, preferredPort, preferredPgPort } = resolveProfileConfig(rawConfig);
75
+ const dataDir = expandHome(profileDataDir);
41
76
  mkdirSync(dataDir, { recursive: true });
42
77
  cachedConfig = {
43
78
  ...rawConfig,
79
+ profile,
44
80
  dataDir,
45
- preferredPort: numEnv('REVO_PORT') ?? rawConfig.preferredPort,
46
- preferredPgPort: numEnv('REVO_PG_PORT') ?? rawConfig.preferredPgPort,
81
+ preferredPort,
82
+ preferredPgPort,
47
83
  logFile: join(dataDir, 'standalone.log'),
84
+ hostLogFile: join(dataDir, 'host.log'),
48
85
  runtimeFile: join(dataDir, 'runtime.json'),
49
86
  };
50
87
  return cachedConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AAsBzB;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,OAAO,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;IACtD,GAAG,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE;CACpD,CAAC;AAYX,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;AAEjD,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;IACtC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAC;IAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAe,CAAC;AACpE,CAAC;AAED,IAAI,YAAY,GAAsB,IAAI,CAAC;AAE3C,uEAAuE;AACvE,SAAS,MAAM,CAAC,IAAY,EAAE,MAAyB,OAAO,CAAC,GAAG;IAChE,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;IACtB,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACnC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACrD,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,MAAM,GAAG,GAAG,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC;QAAE,OAAO,GAAkB,CAAC;IACnF,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,sBAAsB,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QACpF,uFAAuF,CAC1F,CAAC;AACJ,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAsE,EACtE,MAAyB,OAAO,CAAC,GAAG;IAEpC,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO;QACL,OAAO;QACP,OAAO,EAAE,GAAG,CAAC,eAAe,CAAC,IAAI,GAAG,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE;QAC/D,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,UAAU;QAC9E,eAAe,EAAE,MAAM,CAAC,cAAc,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,eAAe,GAAG,IAAI,CAAC,UAAU;KACtF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,YAAY;QAAE,OAAO,YAAY,CAAC;IAEtC,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAC7G,MAAM,OAAO,GAAG,UAAU,CAAC,cAAc,CAAC,CAAC;IAC3C,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAExC,YAAY,GAAG;QACb,GAAG,SAAS;QACZ,OAAO;QACP,OAAO;QACP,aAAa;QACb,eAAe;QACf,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC;QACxC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC;QACtC,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC;KAC3C,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC;IACpC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAE1C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAiB,CAAC;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE,CAAC;IACpC,IAAI,UAAU,CAAC,WAAW,CAAC;QAAE,MAAM,CAAC,WAAW,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,MAAM,EAAE,IAAI,EAAE,GAAG,SAAS,EAAE,CAAC;IAC7B,OAAO,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACnD,OAAO,cAAc,IAAI,IAAI,IAAI,IAAI,GAAG,IAAI,OAAO,IAAI,MAAM,EAAE,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IAChE,CAAC;IAED,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,SAAS,EAAE,CAAC;IACvD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,MAAM,QAAQ,GAAG,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC;QAC9C,CAAC,CAAC,OAAO,CAAC,QAAQ;QAClB,CAAC,CAAC,SAAS,EAAE,CAAC,aAAa,CAAC;IAC9B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,GAAG,MAAM,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CAAC,qDAAqD,QAAQ,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,GAAG,mBAAmB,CAAC;IAC5C,IAAI,IAAI,GAAG,MAAM,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,6CAA6C,QAAQ,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE;QACjC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;QAC3B,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAC5C,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY;IAC7C,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1C,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY;IAC1C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,OAAO,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,CAAC;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}