@synap-core/eve 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 (64) hide show
  1. package/README.md +251 -0
  2. package/dist/add-R6RGUYER.js +22 -0
  3. package/dist/add-R6RGUYER.js.map +1 -0
  4. package/dist/auth-7FFZNARZ-4OIRGZ7R.js +31 -0
  5. package/dist/auth-7FFZNARZ-4OIRGZ7R.js.map +1 -0
  6. package/dist/chunk-22RIHU4J.js +975 -0
  7. package/dist/chunk-22RIHU4J.js.map +1 -0
  8. package/dist/chunk-23XQDB7K.js +1773 -0
  9. package/dist/chunk-23XQDB7K.js.map +1 -0
  10. package/dist/chunk-5TBV2VHZ.js +6067 -0
  11. package/dist/chunk-5TBV2VHZ.js.map +1 -0
  12. package/dist/chunk-D7P3IYYR.js +44 -0
  13. package/dist/chunk-D7P3IYYR.js.map +1 -0
  14. package/dist/chunk-EHPC7CKE.js +757 -0
  15. package/dist/chunk-EHPC7CKE.js.map +1 -0
  16. package/dist/chunk-FAE5UZFE.js +17 -0
  17. package/dist/chunk-FAE5UZFE.js.map +1 -0
  18. package/dist/chunk-HRF6TNXX.js +53 -0
  19. package/dist/chunk-HRF6TNXX.js.map +1 -0
  20. package/dist/chunk-HVJEW7TU.js +495 -0
  21. package/dist/chunk-HVJEW7TU.js.map +1 -0
  22. package/dist/chunk-JO5H5G6U.js +1529 -0
  23. package/dist/chunk-JO5H5G6U.js.map +1 -0
  24. package/dist/chunk-MUEQNBE6.js +1140 -0
  25. package/dist/chunk-MUEQNBE6.js.map +1 -0
  26. package/dist/chunk-O5WTCVMZ.js +3391 -0
  27. package/dist/chunk-O5WTCVMZ.js.map +1 -0
  28. package/dist/chunk-ROKIQIEX.js +65 -0
  29. package/dist/chunk-ROKIQIEX.js.map +1 -0
  30. package/dist/chunk-T7GCAJK5.js +4895 -0
  31. package/dist/chunk-T7GCAJK5.js.map +1 -0
  32. package/dist/chunk-UOQWJ3S4.js +138 -0
  33. package/dist/chunk-UOQWJ3S4.js.map +1 -0
  34. package/dist/chunk-YQWV5W4U.js +3479 -0
  35. package/dist/chunk-YQWV5W4U.js.map +1 -0
  36. package/dist/chunk-ZPDNZRVW.js +272 -0
  37. package/dist/chunk-ZPDNZRVW.js.map +1 -0
  38. package/dist/config-store-KTOWIKAS-XVZHNPKW.js +11 -0
  39. package/dist/config-store-KTOWIKAS-XVZHNPKW.js.map +1 -0
  40. package/dist/dist-2VRFSXMO.js +40 -0
  41. package/dist/dist-2VRFSXMO.js.map +1 -0
  42. package/dist/dist-C2QB4IKT.js +340 -0
  43. package/dist/dist-C2QB4IKT.js.map +1 -0
  44. package/dist/dist-DEIUVZ57.js +299 -0
  45. package/dist/dist-DEIUVZ57.js.map +1 -0
  46. package/dist/dist-DSKHGECB.js +36 -0
  47. package/dist/dist-DSKHGECB.js.map +1 -0
  48. package/dist/dist-GN2DN7CI.js +95 -0
  49. package/dist/dist-GN2DN7CI.js.map +1 -0
  50. package/dist/dist-TZL4XW2R.js +58 -0
  51. package/dist/dist-TZL4XW2R.js.map +1 -0
  52. package/dist/dist-ZP2APOYV.js +53 -0
  53. package/dist/dist-ZP2APOYV.js.map +1 -0
  54. package/dist/index.js +15083 -0
  55. package/dist/index.js.map +1 -0
  56. package/dist/operational-5RT6AZJI-ZEMPD32Q.js +12 -0
  57. package/dist/operational-5RT6AZJI-ZEMPD32Q.js.map +1 -0
  58. package/dist/reconcile-A4I3Z7VX-GQMEN4GC.js +12 -0
  59. package/dist/reconcile-A4I3Z7VX-GQMEN4GC.js.map +1 -0
  60. package/dist/rsshub-GOJBTNOD-UNNVKBFL.js +18 -0
  61. package/dist/rsshub-GOJBTNOD-UNNVKBFL.js.map +1 -0
  62. package/dist/synap-image-install-X36REYQ5-UGO4MAOP.js +17 -0
  63. package/dist/synap-image-install-X36REYQ5-UGO4MAOP.js.map +1 -0
  64. package/package.json +44 -0
@@ -0,0 +1,340 @@
1
+ import { createRequire as __eveCreateRequire } from 'module'; const require = __eveCreateRequire(import.meta.url);
2
+ import {
3
+ AGENTS,
4
+ AiModeSchema,
5
+ AiProviderSchema,
6
+ BuilderEngineSchema,
7
+ ConfigManager,
8
+ CredentialsManager,
9
+ DEFAULT_HERMES_CONFIG,
10
+ EVE_BACKGROUND_ACTIONS,
11
+ EntityStateManager,
12
+ LEGACY_CODER_ENGINE_SLUGS,
13
+ PIPELINE_AGENT_TYPES,
14
+ PIPELINE_PERSONALITIES,
15
+ PodProviderError,
16
+ SetupProfileKindSchema,
17
+ SetupProfileSchema,
18
+ UsbSetupManifestSchema,
19
+ VERSION,
20
+ agentsToProvision,
21
+ allAgentTypes,
22
+ assigneeForAction,
23
+ buildAndPackageImage,
24
+ buildConfigDebugPayload,
25
+ buildDiscoveryDebugPayload,
26
+ buildEventsDebugPayload,
27
+ buildMaterializedDebugPayload,
28
+ configManager,
29
+ configureChannel,
30
+ createAllowedEmbedOriginChecker,
31
+ credentialsManager,
32
+ deployToCoolify,
33
+ describePodProviderResult,
34
+ detectAppConfig,
35
+ detectCoolifyEnvironments,
36
+ detectCoolifyTargets,
37
+ disableChannel,
38
+ discoverAndBackfillPodConfig,
39
+ discoverAndBackfillPodUrl,
40
+ discoverPodConfig,
41
+ ensureOpenWebuiBootstrapSecrets,
42
+ ensureSynapLoopbackOverride,
43
+ entityStateManager,
44
+ findCoolifyAppByName,
45
+ formatHardwareReport,
46
+ getAccessUrls,
47
+ getAppImageName,
48
+ getCoolifyTargetsFromEnv,
49
+ getServerIp,
50
+ getSetupProfilePath,
51
+ isAllowedEmbedOrigin,
52
+ isValidEveBackgroundAction,
53
+ listCoolifyApps,
54
+ listEveBackgroundActions,
55
+ migrateStateDirectory,
56
+ probeHardware,
57
+ pruneOldImagesForRepo,
58
+ readChannelStatus,
59
+ readSetupProfile,
60
+ readUsbSetupManifest,
61
+ redactSecrets,
62
+ resetPodUrlCache,
63
+ resolveAgent,
64
+ resolvePipelinePersonality,
65
+ resolvePodUrl,
66
+ resolvePodUrlDetailed,
67
+ runStateCoherenceChecks,
68
+ setPodProviderEnabled,
69
+ syncCoolifyAppImage,
70
+ upsertPodProvider,
71
+ validateChannelCredentials,
72
+ writeOpenwebuiEnv,
73
+ writeSetupProfile,
74
+ writeUsbSetupManifest
75
+ } from "./chunk-5TBV2VHZ.js";
76
+ import {
77
+ configStore
78
+ } from "./chunk-ROKIQIEX.js";
79
+ import {
80
+ AI_CONSUMERS,
81
+ AI_CONSUMERS_NEEDING_RECREATE,
82
+ COMPONENTS,
83
+ DEFAULT_HUB_PATH,
84
+ EVE_DASHBOARD_SERVICE,
85
+ POD_DEPLOY_DIR_CANDIDATES,
86
+ SYNAP_BACKEND_CONTAINERS,
87
+ SYNAP_BACKEND_INTERNAL_URL,
88
+ addonComponentIds,
89
+ allComponentIds,
90
+ buildOpenwebuiManagedConfig,
91
+ buildOpenwebuiModelSources,
92
+ connectTraefikToEveNetwork,
93
+ copySynapSkillIntoClaudeProject,
94
+ defaultSkillsDir,
95
+ ensureEveSkillsLayout,
96
+ findPodDeployDir,
97
+ formatExtrasSummary,
98
+ generateSynapPlugin,
99
+ getAdminJwt,
100
+ getAdminJwtPostHealth,
101
+ getAdminJwtPostHealthDetailed,
102
+ getAdminReadyStatus,
103
+ getConfig,
104
+ getConfigDetailed,
105
+ getStatus,
106
+ hasAnyProvider,
107
+ isLoopbackUrl,
108
+ isSynapLoopbackReachable,
109
+ listModelSources,
110
+ pickPrimaryProvider,
111
+ probeAdminAuth,
112
+ provisionOwuiUserInSynap,
113
+ publicComponentUrl,
114
+ pushSynapFunctionsToOpenwebui,
115
+ pushSynapSkillsToOpenwebuiPrompts,
116
+ reconcile,
117
+ reconcileOpenwebuiManagedConfig,
118
+ reconcileOpenwebuiManagedConfigViaAdmin,
119
+ reconcileOpenwebuiManagedConfigViaAdminDetailed,
120
+ registerModelSource,
121
+ registerOpenwebuiAdminApi,
122
+ registerSynapAsOpenwebuiToolServer,
123
+ resetSynapLoopbackProbeCache,
124
+ resolveComponent,
125
+ resolveHubBaseUrl,
126
+ resolveOpenwebuiAdminUrl,
127
+ resolveSynapUrl,
128
+ resolveSynapUrlOnHost,
129
+ restartBackendContainer,
130
+ restartHermesIfRunning,
131
+ saveConfig,
132
+ saveConfigDetailed,
133
+ selectedIds,
134
+ serviceComponents,
135
+ syncOpenwebuiExtras,
136
+ syncOwuiUsersToSynap,
137
+ syncSynapKnowledgeToOpenwebui,
138
+ upsertAllModelSources,
139
+ validateBaseDomain,
140
+ waitForHealth,
141
+ waitForHealthDetailed,
142
+ wireAllInstalledComponents,
143
+ wireComponentAi,
144
+ writeBuilderProjectEnv,
145
+ writeClaudeCodeSettings,
146
+ writeHermesConfigYaml,
147
+ writeHermesEnvFile,
148
+ writeSandboxEnvFile
149
+ } from "./chunk-O5WTCVMZ.js";
150
+ import {
151
+ DEFAULT_CODE_ENGINE,
152
+ clearCpUserSession,
153
+ ensureSecretValue,
154
+ isCpSessionStale,
155
+ readAgentKey,
156
+ readAgentKeyOrLegacy,
157
+ readAgentKeyOrLegacySync,
158
+ readCodeEngine,
159
+ readCpUserSession,
160
+ readEveSecrets,
161
+ secretsPath,
162
+ writeAgentKey,
163
+ writeCodeEngine,
164
+ writeCpUserSession,
165
+ writeEveSecrets
166
+ } from "./chunk-T7GCAJK5.js";
167
+ import {
168
+ appendOperationalEvent,
169
+ getEveEventsPath,
170
+ getEveStateHome,
171
+ getEveStatePath,
172
+ readOperationalEvents
173
+ } from "./chunk-HRF6TNXX.js";
174
+ import "./chunk-FAE5UZFE.js";
175
+ import "./chunk-D7P3IYYR.js";
176
+ export {
177
+ AGENTS,
178
+ AI_CONSUMERS,
179
+ AI_CONSUMERS_NEEDING_RECREATE,
180
+ AiModeSchema,
181
+ AiProviderSchema,
182
+ BuilderEngineSchema,
183
+ COMPONENTS,
184
+ ConfigManager,
185
+ CredentialsManager,
186
+ DEFAULT_CODE_ENGINE,
187
+ DEFAULT_HERMES_CONFIG,
188
+ DEFAULT_HUB_PATH,
189
+ EVE_BACKGROUND_ACTIONS,
190
+ EVE_DASHBOARD_SERVICE,
191
+ EntityStateManager,
192
+ LEGACY_CODER_ENGINE_SLUGS,
193
+ PIPELINE_AGENT_TYPES,
194
+ PIPELINE_PERSONALITIES,
195
+ POD_DEPLOY_DIR_CANDIDATES,
196
+ PodProviderError,
197
+ SYNAP_BACKEND_CONTAINERS,
198
+ SYNAP_BACKEND_INTERNAL_URL,
199
+ SetupProfileKindSchema,
200
+ SetupProfileSchema,
201
+ UsbSetupManifestSchema,
202
+ VERSION,
203
+ addonComponentIds,
204
+ agentsToProvision,
205
+ allAgentTypes,
206
+ allComponentIds,
207
+ appendOperationalEvent,
208
+ assigneeForAction,
209
+ buildAndPackageImage,
210
+ buildConfigDebugPayload,
211
+ buildDiscoveryDebugPayload,
212
+ buildEventsDebugPayload,
213
+ buildMaterializedDebugPayload,
214
+ buildOpenwebuiManagedConfig,
215
+ buildOpenwebuiModelSources,
216
+ clearCpUserSession,
217
+ configManager,
218
+ configStore,
219
+ configureChannel,
220
+ connectTraefikToEveNetwork,
221
+ copySynapSkillIntoClaudeProject,
222
+ createAllowedEmbedOriginChecker,
223
+ credentialsManager,
224
+ defaultSkillsDir,
225
+ deployToCoolify,
226
+ describePodProviderResult,
227
+ detectAppConfig,
228
+ detectCoolifyEnvironments,
229
+ detectCoolifyTargets,
230
+ disableChannel,
231
+ discoverAndBackfillPodConfig,
232
+ discoverAndBackfillPodUrl,
233
+ discoverPodConfig,
234
+ ensureEveSkillsLayout,
235
+ ensureOpenWebuiBootstrapSecrets,
236
+ ensureSecretValue,
237
+ ensureSynapLoopbackOverride,
238
+ entityStateManager,
239
+ findCoolifyAppByName,
240
+ findPodDeployDir,
241
+ formatExtrasSummary,
242
+ formatHardwareReport,
243
+ generateSynapPlugin,
244
+ getAccessUrls,
245
+ getAdminJwt,
246
+ getAdminJwtPostHealth,
247
+ getAdminJwtPostHealthDetailed,
248
+ getAdminReadyStatus,
249
+ getAppImageName,
250
+ getConfig,
251
+ getConfigDetailed,
252
+ getCoolifyTargetsFromEnv,
253
+ getEveEventsPath,
254
+ getEveStateHome,
255
+ getEveStatePath,
256
+ getServerIp,
257
+ getSetupProfilePath,
258
+ getStatus,
259
+ hasAnyProvider,
260
+ isAllowedEmbedOrigin,
261
+ isCpSessionStale,
262
+ isLoopbackUrl,
263
+ isSynapLoopbackReachable,
264
+ isValidEveBackgroundAction,
265
+ listCoolifyApps,
266
+ listEveBackgroundActions,
267
+ listModelSources,
268
+ migrateStateDirectory,
269
+ pickPrimaryProvider,
270
+ probeAdminAuth,
271
+ probeHardware,
272
+ provisionOwuiUserInSynap,
273
+ pruneOldImagesForRepo,
274
+ publicComponentUrl,
275
+ pushSynapFunctionsToOpenwebui,
276
+ pushSynapSkillsToOpenwebuiPrompts,
277
+ readAgentKey,
278
+ readAgentKeyOrLegacy,
279
+ readAgentKeyOrLegacySync,
280
+ readChannelStatus,
281
+ readCodeEngine,
282
+ readCpUserSession,
283
+ readEveSecrets,
284
+ readOperationalEvents,
285
+ readSetupProfile,
286
+ readUsbSetupManifest,
287
+ reconcile,
288
+ reconcileOpenwebuiManagedConfig,
289
+ reconcileOpenwebuiManagedConfigViaAdmin,
290
+ reconcileOpenwebuiManagedConfigViaAdminDetailed,
291
+ redactSecrets,
292
+ registerModelSource,
293
+ registerOpenwebuiAdminApi,
294
+ registerSynapAsOpenwebuiToolServer,
295
+ resetPodUrlCache,
296
+ resetSynapLoopbackProbeCache,
297
+ resolveAgent,
298
+ resolveComponent,
299
+ resolveHubBaseUrl,
300
+ resolveOpenwebuiAdminUrl,
301
+ resolvePipelinePersonality,
302
+ resolvePodUrl,
303
+ resolvePodUrlDetailed,
304
+ resolveSynapUrl,
305
+ resolveSynapUrlOnHost,
306
+ restartBackendContainer,
307
+ restartHermesIfRunning,
308
+ runStateCoherenceChecks,
309
+ saveConfig,
310
+ saveConfigDetailed,
311
+ secretsPath,
312
+ selectedIds,
313
+ serviceComponents,
314
+ setPodProviderEnabled,
315
+ syncCoolifyAppImage,
316
+ syncOpenwebuiExtras,
317
+ syncOwuiUsersToSynap,
318
+ syncSynapKnowledgeToOpenwebui,
319
+ upsertAllModelSources,
320
+ upsertPodProvider,
321
+ validateBaseDomain,
322
+ validateChannelCredentials,
323
+ waitForHealth,
324
+ waitForHealthDetailed,
325
+ wireAllInstalledComponents,
326
+ wireComponentAi,
327
+ writeAgentKey,
328
+ writeBuilderProjectEnv,
329
+ writeClaudeCodeSettings,
330
+ writeCodeEngine,
331
+ writeCpUserSession,
332
+ writeEveSecrets,
333
+ writeHermesConfigYaml,
334
+ writeHermesEnvFile,
335
+ writeOpenwebuiEnv,
336
+ writeSandboxEnvFile,
337
+ writeSetupProfile,
338
+ writeUsbSetupManifest
339
+ };
340
+ //# sourceMappingURL=dist-C2QB4IKT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,299 @@
1
+ import { createRequire as __eveCreateRequire } from 'module'; const require = __eveCreateRequire(import.meta.url);
2
+ import "./chunk-D7P3IYYR.js";
3
+
4
+ // ../@eve/mouth/dist/index.js
5
+ import { execFile } from "child_process";
6
+ import { promisify } from "util";
7
+ import { randomBytes } from "crypto";
8
+ import { mkdtemp, writeFile, rm } from "fs/promises";
9
+ import { tmpdir } from "os";
10
+ import { join } from "path";
11
+ import { execFile as execFile2 } from "child_process";
12
+ import { promisify as promisify2 } from "util";
13
+ import { randomBytes as randomBytes2 } from "crypto";
14
+ var execFileAsync = promisify(execFile);
15
+ var STALWART_IMAGE = "stalwartlabs/stalwart:v0.16";
16
+ var STALWART_CONTAINER = "eve-mouth-stalwart";
17
+ var PUBLIC_TCP_PORTS = [25, 465, 587, 993, 995];
18
+ var LOOPBACK_TCP_PORTS = [143, 110, 4190];
19
+ var STALWART_PUBLIC_PORTS = PUBLIC_TCP_PORTS;
20
+ var StalwartService = class {
21
+ config;
22
+ constructor(config = {}) {
23
+ this.config = config;
24
+ }
25
+ /** True if the Stalwart container is running. */
26
+ async isRunning() {
27
+ try {
28
+ const { stdout } = await execFileAsync("docker", [
29
+ "ps",
30
+ "--filter",
31
+ `name=^${STALWART_CONTAINER}$`,
32
+ "--format",
33
+ "{{.Names}}"
34
+ ]);
35
+ return stdout.trim() === STALWART_CONTAINER;
36
+ } catch {
37
+ return false;
38
+ }
39
+ }
40
+ /** True if a container with this name exists in any state (running or stopped). */
41
+ async exists() {
42
+ try {
43
+ const { stdout } = await execFileAsync("docker", [
44
+ "ps",
45
+ "-aq",
46
+ "--filter",
47
+ `name=^${STALWART_CONTAINER}$`
48
+ ]);
49
+ return stdout.trim().length > 0;
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+ /** Ensure the shared Docker bridge exists; ignores "already exists". */
55
+ async ensureNetwork() {
56
+ try {
57
+ await execFileAsync("docker", ["network", "create", "eve-network"]);
58
+ } catch {
59
+ }
60
+ }
61
+ /**
62
+ * Install + start the Stalwart container. Returns the bootstrap admin
63
+ * password (generated when not supplied, `undefined` when the container was
64
+ * already up so the caller never clobbers a stored secret with '').
65
+ *
66
+ * Idempotent: a stopped container with the same name is started rather than
67
+ * recreated (a bare `docker run --name` would otherwise fail on the conflict).
68
+ */
69
+ async install(config) {
70
+ const merged = { ...this.config, ...config };
71
+ if (await this.isRunning()) {
72
+ console.log("Stalwart is already running");
73
+ return { adminPassword: merged.adminPassword || void 0 };
74
+ }
75
+ await this.ensureNetwork();
76
+ if (await this.exists()) {
77
+ console.log("Stalwart container exists but is stopped \u2014 starting it");
78
+ await this.start();
79
+ return { adminPassword: merged.adminPassword || void 0 };
80
+ }
81
+ const adminPassword = merged.adminPassword && merged.adminPassword.trim().length > 0 ? merged.adminPassword : randomBytes(18).toString("base64url");
82
+ console.log(`Pulling Stalwart image (${STALWART_IMAGE})...`);
83
+ await execFileAsync("docker", ["pull", STALWART_IMAGE]);
84
+ const dir = await mkdtemp(join(tmpdir(), "eve-stalwart-"));
85
+ const envFile = join(dir, "stalwart.env");
86
+ await writeFile(envFile, `STALWART_RECOVERY_ADMIN=admin:${adminPassword}
87
+ `, { mode: 384 });
88
+ const portArgs = [
89
+ ...PUBLIC_TCP_PORTS.flatMap((p) => ["-p", `${p}:${p}`]),
90
+ ...LOOPBACK_TCP_PORTS.flatMap((p) => ["-p", `127.0.0.1:${p}:${p}`])
91
+ ];
92
+ try {
93
+ console.log("Starting Stalwart...");
94
+ await execFileAsync("docker", [
95
+ "run",
96
+ "-d",
97
+ "--name",
98
+ STALWART_CONTAINER,
99
+ "--restart",
100
+ "unless-stopped",
101
+ "--network",
102
+ "eve-network",
103
+ ...portArgs,
104
+ "--env-file",
105
+ envFile,
106
+ ...merged.publicUrl ? ["-e", `STALWART_PUBLIC_URL=${merged.publicUrl}`] : [],
107
+ "-v",
108
+ "stalwart-etc:/etc/stalwart",
109
+ "-v",
110
+ "stalwart-data:/var/lib/stalwart",
111
+ STALWART_IMAGE
112
+ ]);
113
+ } finally {
114
+ await rm(dir, { recursive: true, force: true });
115
+ }
116
+ return { adminPassword };
117
+ }
118
+ async start() {
119
+ if (await this.isRunning()) {
120
+ console.log("Stalwart is already running");
121
+ return;
122
+ }
123
+ await execFileAsync("docker", ["start", STALWART_CONTAINER]);
124
+ console.log("Stalwart started");
125
+ }
126
+ async stop() {
127
+ await execFileAsync("docker", ["stop", STALWART_CONTAINER]);
128
+ console.log("Stalwart stopped");
129
+ }
130
+ };
131
+ var execFileAsync2 = promisify2(execFile2);
132
+ var BULWARK_IMAGE = "ghcr.io/bulwarkmail/webmail:latest";
133
+ var BULWARK_CONTAINER = "eve-mouth-bulwark";
134
+ var BulwarkService = class {
135
+ config;
136
+ constructor(config = {}) {
137
+ this.config = config;
138
+ }
139
+ async isRunning() {
140
+ try {
141
+ const { stdout } = await execFileAsync2("docker", [
142
+ "ps",
143
+ "--filter",
144
+ `name=^${BULWARK_CONTAINER}$`,
145
+ "--format",
146
+ "{{.Names}}"
147
+ ]);
148
+ return stdout.trim() === BULWARK_CONTAINER;
149
+ } catch {
150
+ return false;
151
+ }
152
+ }
153
+ async exists() {
154
+ try {
155
+ const { stdout } = await execFileAsync2("docker", [
156
+ "ps",
157
+ "-aq",
158
+ "--filter",
159
+ `name=^${BULWARK_CONTAINER}$`
160
+ ]);
161
+ return stdout.trim().length > 0;
162
+ } catch {
163
+ return false;
164
+ }
165
+ }
166
+ async ensureNetwork() {
167
+ try {
168
+ await execFileAsync2("docker", ["network", "create", "eve-network"]);
169
+ } catch {
170
+ }
171
+ }
172
+ /**
173
+ * Install + start Bulwark. Returns the SESSION_SECRET actually used
174
+ * (generated when not supplied, `undefined` when the container was already
175
+ * up) so the caller can persist it without clobbering a stored value.
176
+ *
177
+ * Idempotent: a stopped container is started rather than recreated.
178
+ */
179
+ async install(config) {
180
+ const merged = { ...this.config, ...config };
181
+ if (await this.isRunning()) {
182
+ console.log("Bulwark is already running");
183
+ return { sessionSecret: merged.sessionSecret || void 0 };
184
+ }
185
+ await this.ensureNetwork();
186
+ if (await this.exists()) {
187
+ console.log("Bulwark container exists but is stopped \u2014 starting it");
188
+ await this.start();
189
+ return { sessionSecret: merged.sessionSecret || void 0 };
190
+ }
191
+ const sessionSecret = merged.sessionSecret && merged.sessionSecret.trim().length > 0 ? merged.sessionSecret : randomBytes2(32).toString("hex");
192
+ console.log(`Pulling Bulwark image (${BULWARK_IMAGE})...`);
193
+ await execFileAsync2("docker", ["pull", BULWARK_IMAGE]);
194
+ console.log("Starting Bulwark...");
195
+ await execFileAsync2("docker", [
196
+ "run",
197
+ "-d",
198
+ "--name",
199
+ BULWARK_CONTAINER,
200
+ "--restart",
201
+ "unless-stopped",
202
+ "--network",
203
+ "eve-network",
204
+ "-e",
205
+ `SESSION_SECRET=${sessionSecret}`,
206
+ "-e",
207
+ "ADMIN_CONFIG_DIR=/data/admin",
208
+ ...merged.jmapUrl ? ["-e", `JMAP_SERVER_URL=${merged.jmapUrl}`] : [],
209
+ "-v",
210
+ "bulwark-data:/data",
211
+ BULWARK_IMAGE
212
+ ]);
213
+ return { sessionSecret };
214
+ }
215
+ async start() {
216
+ if (await this.isRunning()) {
217
+ console.log("Bulwark is already running");
218
+ return;
219
+ }
220
+ await execFileAsync2("docker", ["start", BULWARK_CONTAINER]);
221
+ console.log("Bulwark started");
222
+ }
223
+ async stop() {
224
+ await execFileAsync2("docker", ["stop", BULWARK_CONTAINER]);
225
+ console.log("Bulwark stopped");
226
+ }
227
+ };
228
+ var STALWART_INTERNAL_URL = "http://eve-mouth-stalwart:8080";
229
+ var StalwartAdmin = class {
230
+ baseUrl;
231
+ authHeader;
232
+ constructor(config) {
233
+ this.baseUrl = (config.baseUrl ?? STALWART_INTERNAL_URL).replace(/\/$/, "");
234
+ const user = config.adminUser ?? "admin";
235
+ this.authHeader = "Basic " + Buffer.from(`${user}:${config.adminPassword}`).toString("base64");
236
+ }
237
+ async request(method, path, body) {
238
+ const res = await fetch(`${this.baseUrl}${path}`, {
239
+ method,
240
+ headers: {
241
+ Authorization: this.authHeader,
242
+ "Content-Type": "application/json",
243
+ Accept: "application/json"
244
+ },
245
+ body: body === void 0 ? void 0 : JSON.stringify(body)
246
+ });
247
+ if (!res.ok) {
248
+ const text = await res.text().catch(() => "");
249
+ throw new Error(`Stalwart API ${method} ${path} \u2192 ${res.status} ${res.statusText}${text ? `: ${text}` : ""}`);
250
+ }
251
+ if (res.status === 204) return void 0;
252
+ return await res.json().catch(() => void 0);
253
+ }
254
+ /** True if Stalwart's liveness endpoint responds 2xx. */
255
+ async isLive() {
256
+ try {
257
+ const res = await fetch(`${this.baseUrl}/healthz/live`);
258
+ return res.ok;
259
+ } catch {
260
+ return false;
261
+ }
262
+ }
263
+ /** Create a local domain (idempotent on the caller's side — 409 surfaces as an error). */
264
+ async createDomain(name) {
265
+ await this.request("POST", "/api/principal", { type: "domain", name });
266
+ }
267
+ /** Create an individual mailbox account. */
268
+ async createAccount(input) {
269
+ await this.request("POST", "/api/principal", {
270
+ type: "individual",
271
+ name: input.email,
272
+ secrets: [input.password],
273
+ emails: [input.email],
274
+ ...input.description ? { description: input.description } : {}
275
+ });
276
+ }
277
+ /** List principals, optionally filtered by type ("individual" | "domain" | …). */
278
+ async listPrincipals(type) {
279
+ const qs = type ? `?type=${encodeURIComponent(type)}` : "";
280
+ const data = await this.request(
281
+ "GET",
282
+ `/api/principal${qs}`
283
+ );
284
+ if (Array.isArray(data)) return data;
285
+ return data?.items ?? [];
286
+ }
287
+ };
288
+ export {
289
+ BULWARK_CONTAINER,
290
+ BULWARK_IMAGE,
291
+ BulwarkService,
292
+ STALWART_CONTAINER,
293
+ STALWART_IMAGE,
294
+ STALWART_INTERNAL_URL,
295
+ STALWART_PUBLIC_PORTS,
296
+ StalwartAdmin,
297
+ StalwartService
298
+ };
299
+ //# sourceMappingURL=dist-DEIUVZ57.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../@eve/mouth/dist/index.js"],"sourcesContent":["// src/lib/stalwart.ts\nimport { execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport { randomBytes } from \"crypto\";\nimport { mkdtemp, writeFile, rm } from \"fs/promises\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nvar execFileAsync = promisify(execFile);\nvar STALWART_IMAGE = \"stalwartlabs/stalwart:v0.16\";\nvar STALWART_CONTAINER = \"eve-mouth-stalwart\";\nvar PUBLIC_TCP_PORTS = [25, 465, 587, 993, 995];\nvar LOOPBACK_TCP_PORTS = [143, 110, 4190];\nvar STALWART_PUBLIC_PORTS = PUBLIC_TCP_PORTS;\nvar StalwartService = class {\n config;\n constructor(config = {}) {\n this.config = config;\n }\n /** True if the Stalwart container is running. */\n async isRunning() {\n try {\n const { stdout } = await execFileAsync(\"docker\", [\n \"ps\",\n \"--filter\",\n `name=^${STALWART_CONTAINER}$`,\n \"--format\",\n \"{{.Names}}\"\n ]);\n return stdout.trim() === STALWART_CONTAINER;\n } catch {\n return false;\n }\n }\n /** True if a container with this name exists in any state (running or stopped). */\n async exists() {\n try {\n const { stdout } = await execFileAsync(\"docker\", [\n \"ps\",\n \"-aq\",\n \"--filter\",\n `name=^${STALWART_CONTAINER}$`\n ]);\n return stdout.trim().length > 0;\n } catch {\n return false;\n }\n }\n /** Ensure the shared Docker bridge exists; ignores \"already exists\". */\n async ensureNetwork() {\n try {\n await execFileAsync(\"docker\", [\"network\", \"create\", \"eve-network\"]);\n } catch {\n }\n }\n /**\n * Install + start the Stalwart container. Returns the bootstrap admin\n * password (generated when not supplied, `undefined` when the container was\n * already up so the caller never clobbers a stored secret with '').\n *\n * Idempotent: a stopped container with the same name is started rather than\n * recreated (a bare `docker run --name` would otherwise fail on the conflict).\n */\n async install(config) {\n const merged = { ...this.config, ...config };\n if (await this.isRunning()) {\n console.log(\"Stalwart is already running\");\n return { adminPassword: merged.adminPassword || void 0 };\n }\n await this.ensureNetwork();\n if (await this.exists()) {\n console.log(\"Stalwart container exists but is stopped \\u2014 starting it\");\n await this.start();\n return { adminPassword: merged.adminPassword || void 0 };\n }\n const adminPassword = merged.adminPassword && merged.adminPassword.trim().length > 0 ? merged.adminPassword : randomBytes(18).toString(\"base64url\");\n console.log(`Pulling Stalwart image (${STALWART_IMAGE})...`);\n await execFileAsync(\"docker\", [\"pull\", STALWART_IMAGE]);\n const dir = await mkdtemp(join(tmpdir(), \"eve-stalwart-\"));\n const envFile = join(dir, \"stalwart.env\");\n await writeFile(envFile, `STALWART_RECOVERY_ADMIN=admin:${adminPassword}\n`, { mode: 384 });\n const portArgs = [\n ...PUBLIC_TCP_PORTS.flatMap((p) => [\"-p\", `${p}:${p}`]),\n ...LOOPBACK_TCP_PORTS.flatMap((p) => [\"-p\", `127.0.0.1:${p}:${p}`])\n ];\n try {\n console.log(\"Starting Stalwart...\");\n await execFileAsync(\"docker\", [\n \"run\",\n \"-d\",\n \"--name\",\n STALWART_CONTAINER,\n \"--restart\",\n \"unless-stopped\",\n \"--network\",\n \"eve-network\",\n ...portArgs,\n \"--env-file\",\n envFile,\n ...merged.publicUrl ? [\"-e\", `STALWART_PUBLIC_URL=${merged.publicUrl}`] : [],\n \"-v\",\n \"stalwart-etc:/etc/stalwart\",\n \"-v\",\n \"stalwart-data:/var/lib/stalwart\",\n STALWART_IMAGE\n ]);\n } finally {\n await rm(dir, { recursive: true, force: true });\n }\n return { adminPassword };\n }\n async start() {\n if (await this.isRunning()) {\n console.log(\"Stalwart is already running\");\n return;\n }\n await execFileAsync(\"docker\", [\"start\", STALWART_CONTAINER]);\n console.log(\"Stalwart started\");\n }\n async stop() {\n await execFileAsync(\"docker\", [\"stop\", STALWART_CONTAINER]);\n console.log(\"Stalwart stopped\");\n }\n};\n\n// src/lib/bulwark.ts\nimport { execFile as execFile2 } from \"child_process\";\nimport { promisify as promisify2 } from \"util\";\nimport { randomBytes as randomBytes2 } from \"crypto\";\nvar execFileAsync2 = promisify2(execFile2);\nvar BULWARK_IMAGE = \"ghcr.io/bulwarkmail/webmail:latest\";\nvar BULWARK_CONTAINER = \"eve-mouth-bulwark\";\nvar BulwarkService = class {\n config;\n constructor(config = {}) {\n this.config = config;\n }\n async isRunning() {\n try {\n const { stdout } = await execFileAsync2(\"docker\", [\n \"ps\",\n \"--filter\",\n `name=^${BULWARK_CONTAINER}$`,\n \"--format\",\n \"{{.Names}}\"\n ]);\n return stdout.trim() === BULWARK_CONTAINER;\n } catch {\n return false;\n }\n }\n async exists() {\n try {\n const { stdout } = await execFileAsync2(\"docker\", [\n \"ps\",\n \"-aq\",\n \"--filter\",\n `name=^${BULWARK_CONTAINER}$`\n ]);\n return stdout.trim().length > 0;\n } catch {\n return false;\n }\n }\n async ensureNetwork() {\n try {\n await execFileAsync2(\"docker\", [\"network\", \"create\", \"eve-network\"]);\n } catch {\n }\n }\n /**\n * Install + start Bulwark. Returns the SESSION_SECRET actually used\n * (generated when not supplied, `undefined` when the container was already\n * up) so the caller can persist it without clobbering a stored value.\n *\n * Idempotent: a stopped container is started rather than recreated.\n */\n async install(config) {\n const merged = { ...this.config, ...config };\n if (await this.isRunning()) {\n console.log(\"Bulwark is already running\");\n return { sessionSecret: merged.sessionSecret || void 0 };\n }\n await this.ensureNetwork();\n if (await this.exists()) {\n console.log(\"Bulwark container exists but is stopped \\u2014 starting it\");\n await this.start();\n return { sessionSecret: merged.sessionSecret || void 0 };\n }\n const sessionSecret = merged.sessionSecret && merged.sessionSecret.trim().length > 0 ? merged.sessionSecret : randomBytes2(32).toString(\"hex\");\n console.log(`Pulling Bulwark image (${BULWARK_IMAGE})...`);\n await execFileAsync2(\"docker\", [\"pull\", BULWARK_IMAGE]);\n console.log(\"Starting Bulwark...\");\n await execFileAsync2(\"docker\", [\n \"run\",\n \"-d\",\n \"--name\",\n BULWARK_CONTAINER,\n \"--restart\",\n \"unless-stopped\",\n \"--network\",\n \"eve-network\",\n \"-e\",\n `SESSION_SECRET=${sessionSecret}`,\n \"-e\",\n \"ADMIN_CONFIG_DIR=/data/admin\",\n ...merged.jmapUrl ? [\"-e\", `JMAP_SERVER_URL=${merged.jmapUrl}`] : [],\n \"-v\",\n \"bulwark-data:/data\",\n BULWARK_IMAGE\n ]);\n return { sessionSecret };\n }\n async start() {\n if (await this.isRunning()) {\n console.log(\"Bulwark is already running\");\n return;\n }\n await execFileAsync2(\"docker\", [\"start\", BULWARK_CONTAINER]);\n console.log(\"Bulwark started\");\n }\n async stop() {\n await execFileAsync2(\"docker\", [\"stop\", BULWARK_CONTAINER]);\n console.log(\"Bulwark stopped\");\n }\n};\n\n// src/lib/admin.ts\nvar STALWART_INTERNAL_URL = \"http://eve-mouth-stalwart:8080\";\nvar StalwartAdmin = class {\n baseUrl;\n authHeader;\n constructor(config) {\n this.baseUrl = (config.baseUrl ?? STALWART_INTERNAL_URL).replace(/\\/$/, \"\");\n const user = config.adminUser ?? \"admin\";\n this.authHeader = \"Basic \" + Buffer.from(`${user}:${config.adminPassword}`).toString(\"base64\");\n }\n async request(method, path, body) {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: {\n Authorization: this.authHeader,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\"\n },\n body: body === void 0 ? void 0 : JSON.stringify(body)\n });\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n throw new Error(`Stalwart API ${method} ${path} \\u2192 ${res.status} ${res.statusText}${text ? `: ${text}` : \"\"}`);\n }\n if (res.status === 204) return void 0;\n return await res.json().catch(() => void 0);\n }\n /** True if Stalwart's liveness endpoint responds 2xx. */\n async isLive() {\n try {\n const res = await fetch(`${this.baseUrl}/healthz/live`);\n return res.ok;\n } catch {\n return false;\n }\n }\n /** Create a local domain (idempotent on the caller's side — 409 surfaces as an error). */\n async createDomain(name) {\n await this.request(\"POST\", \"/api/principal\", { type: \"domain\", name });\n }\n /** Create an individual mailbox account. */\n async createAccount(input) {\n await this.request(\"POST\", \"/api/principal\", {\n type: \"individual\",\n name: input.email,\n secrets: [input.password],\n emails: [input.email],\n ...input.description ? { description: input.description } : {}\n });\n }\n /** List principals, optionally filtered by type (\"individual\" | \"domain\" | …). */\n async listPrincipals(type) {\n const qs = type ? `?type=${encodeURIComponent(type)}` : \"\";\n const data = await this.request(\n \"GET\",\n `/api/principal${qs}`\n );\n if (Array.isArray(data)) return data;\n return data?.items ?? [];\n }\n};\nexport {\n BULWARK_CONTAINER,\n BULWARK_IMAGE,\n BulwarkService,\n STALWART_CONTAINER,\n STALWART_IMAGE,\n STALWART_INTERNAL_URL,\n STALWART_PUBLIC_PORTS,\n StalwartAdmin,\n StalwartService\n};\n"],"mappings":"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","names":[]}