@creezio/electron-shell 0.22.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/.creezio-src-hash.json +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/meili.d.ts +1 -1
- package/dist/meili.d.ts.map +1 -1
- package/dist/meili.js +1 -1
- package/dist/meili.js.map +1 -1
- package/dist-cjs/index.js +6 -8
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/meili.js +1 -2
- package/dist-cjs/meili.js.map +1 -1
- package/package.json +9 -9
- package/dist/desktop/legacy-brand-compat.d.ts +0 -45
- package/dist/desktop/legacy-brand-compat.d.ts.map +0 -1
- package/dist/desktop/legacy-brand-compat.js +0 -49
- package/dist/desktop/legacy-brand-compat.js.map +0 -1
- package/dist/factory-reset-runtime.d.ts +0 -11
- package/dist/factory-reset-runtime.d.ts.map +0 -1
- package/dist/factory-reset-runtime.js +0 -77
- package/dist/factory-reset-runtime.js.map +0 -1
- package/dist/host/ai-workspace/actions.d.ts +0 -12
- package/dist/host/ai-workspace/actions.d.ts.map +0 -1
- package/dist/host/ai-workspace/actions.js +0 -243
- package/dist/host/ai-workspace/actions.js.map +0 -1
- package/dist/host/ai-workspace/bindings.d.ts +0 -51
- package/dist/host/ai-workspace/bindings.d.ts.map +0 -1
- package/dist/host/ai-workspace/bindings.js +0 -40
- package/dist/host/ai-workspace/bindings.js.map +0 -1
- package/dist/host/ai-workspace/index.d.ts +0 -11
- package/dist/host/ai-workspace/index.d.ts.map +0 -1
- package/dist/host/ai-workspace/index.js +0 -6
- package/dist/host/ai-workspace/index.js.map +0 -1
- package/dist/host/ai-workspace/manager.d.ts +0 -128
- package/dist/host/ai-workspace/manager.d.ts.map +0 -1
- package/dist/host/ai-workspace/manager.js +0 -519
- package/dist/host/ai-workspace/manager.js.map +0 -1
- package/dist/host/ai-workspace/profile-window.d.ts +0 -37
- package/dist/host/ai-workspace/profile-window.d.ts.map +0 -1
- package/dist/host/ai-workspace/profile-window.js +0 -121
- package/dist/host/ai-workspace/profile-window.js.map +0 -1
- package/dist/host/ai-workspace/screencast.d.ts +0 -56
- package/dist/host/ai-workspace/screencast.d.ts.map +0 -1
- package/dist/host/ai-workspace/screencast.js +0 -245
- package/dist/host/ai-workspace/screencast.js.map +0 -1
- package/dist/host/ai-workspace/types.d.ts +0 -40
- package/dist/host/ai-workspace/types.d.ts.map +0 -1
- package/dist/host/ai-workspace/types.js +0 -6
- package/dist/host/ai-workspace/types.js.map +0 -1
- package/dist/host/brand-host-runtime.d.ts +0 -107
- package/dist/host/brand-host-runtime.d.ts.map +0 -1
- package/dist/host/brand-host-runtime.js +0 -274
- package/dist/host/brand-host-runtime.js.map +0 -1
- package/dist/host/brand-host-stack.d.ts +0 -117
- package/dist/host/brand-host-stack.d.ts.map +0 -1
- package/dist/host/brand-host-stack.js +0 -253
- package/dist/host/brand-host-stack.js.map +0 -1
- package/dist/host/brand-kernel-http.d.ts +0 -34
- package/dist/host/brand-kernel-http.d.ts.map +0 -1
- package/dist/host/brand-kernel-http.js +0 -95
- package/dist/host/brand-kernel-http.js.map +0 -1
- package/dist/host/brand-meili-boot.d.ts +0 -67
- package/dist/host/brand-meili-boot.d.ts.map +0 -1
- package/dist/host/brand-meili-boot.js +0 -100
- package/dist/host/brand-meili-boot.js.map +0 -1
- package/dist/host/bridge-client.d.ts +0 -54
- package/dist/host/bridge-client.d.ts.map +0 -1
- package/dist/host/bridge-client.js +0 -187
- package/dist/host/bridge-client.js.map +0 -1
- package/dist/host/context.d.ts +0 -70
- package/dist/host/context.d.ts.map +0 -1
- package/dist/host/context.js +0 -16
- package/dist/host/context.js.map +0 -1
- package/dist/host/contracts.d.ts +0 -39
- package/dist/host/contracts.d.ts.map +0 -1
- package/dist/host/contracts.js +0 -26
- package/dist/host/contracts.js.map +0 -1
- package/dist/host/crash-reporter.d.ts +0 -65
- package/dist/host/crash-reporter.d.ts.map +0 -1
- package/dist/host/crash-reporter.js +0 -371
- package/dist/host/crash-reporter.js.map +0 -1
- package/dist/host/ensure-kit-binaries.d.ts +0 -17
- package/dist/host/ensure-kit-binaries.d.ts.map +0 -1
- package/dist/host/ensure-kit-binaries.js +0 -205
- package/dist/host/ensure-kit-binaries.js.map +0 -1
- package/dist/host/feature-off-host.d.ts +0 -130
- package/dist/host/feature-off-host.d.ts.map +0 -1
- package/dist/host/feature-off-host.js +0 -138
- package/dist/host/feature-off-host.js.map +0 -1
- package/dist/host/hermes/crm-key.d.ts +0 -49
- package/dist/host/hermes/crm-key.d.ts.map +0 -1
- package/dist/host/hermes/crm-key.js +0 -126
- package/dist/host/hermes/crm-key.js.map +0 -1
- package/dist/host/hermes/ensure-crm-key-db.d.ts +0 -7
- package/dist/host/hermes/ensure-crm-key-db.d.ts.map +0 -1
- package/dist/host/hermes/ensure-crm-key-db.js +0 -84
- package/dist/host/hermes/ensure-crm-key-db.js.map +0 -1
- package/dist/host/hermes/launcher.d.ts +0 -98
- package/dist/host/hermes/launcher.d.ts.map +0 -1
- package/dist/host/hermes/launcher.js +0 -972
- package/dist/host/hermes/launcher.js.map +0 -1
- package/dist/host/hermes/runtime-bootstrap.d.ts +0 -172
- package/dist/host/hermes/runtime-bootstrap.d.ts.map +0 -1
- package/dist/host/hermes/runtime-bootstrap.js +0 -789
- package/dist/host/hermes/runtime-bootstrap.js.map +0 -1
- package/dist/host/hermes/skills-seed.d.ts +0 -40
- package/dist/host/hermes/skills-seed.d.ts.map +0 -1
- package/dist/host/hermes/skills-seed.js +0 -100
- package/dist/host/hermes/skills-seed.js.map +0 -1
- package/dist/host/host-stack.d.ts +0 -35
- package/dist/host/host-stack.d.ts.map +0 -1
- package/dist/host/host-stack.js +0 -38
- package/dist/host/host-stack.js.map +0 -1
- package/dist/host/kit-os-resources.d.ts +0 -6
- package/dist/host/kit-os-resources.d.ts.map +0 -1
- package/dist/host/kit-os-resources.js +0 -88
- package/dist/host/kit-os-resources.js.map +0 -1
- package/dist/host/load-electron.d.ts +0 -2
- package/dist/host/load-electron.d.ts.map +0 -1
- package/dist/host/load-electron.js +0 -44
- package/dist/host/load-electron.js.map +0 -1
- package/dist/host/local-config.d.ts +0 -120
- package/dist/host/local-config.d.ts.map +0 -1
- package/dist/host/local-config.js +0 -633
- package/dist/host/local-config.js.map +0 -1
- package/dist/host/meili/browse.d.ts +0 -58
- package/dist/host/meili/browse.d.ts.map +0 -1
- package/dist/host/meili/browse.js +0 -98
- package/dist/host/meili/browse.js.map +0 -1
- package/dist/host/meili/coherence-db.d.ts +0 -35
- package/dist/host/meili/coherence-db.d.ts.map +0 -1
- package/dist/host/meili/coherence-db.js +0 -129
- package/dist/host/meili/coherence-db.js.map +0 -1
- package/dist/host/meili/coherence-query.d.ts +0 -10
- package/dist/host/meili/coherence-query.d.ts.map +0 -1
- package/dist/host/meili/coherence-query.js +0 -23
- package/dist/host/meili/coherence-query.js.map +0 -1
- package/dist/host/meili/coherence.d.ts +0 -53
- package/dist/host/meili/coherence.d.ts.map +0 -1
- package/dist/host/meili/coherence.js +0 -148
- package/dist/host/meili/coherence.js.map +0 -1
- package/dist/host/meili/feed.d.ts +0 -82
- package/dist/host/meili/feed.d.ts.map +0 -1
- package/dist/host/meili/feed.js +0 -100
- package/dist/host/meili/feed.js.map +0 -1
- package/dist/host/meili/generic-indexer.d.ts +0 -34
- package/dist/host/meili/generic-indexer.d.ts.map +0 -1
- package/dist/host/meili/generic-indexer.js +0 -333
- package/dist/host/meili/generic-indexer.js.map +0 -1
- package/dist/host/meili/index-schema.d.ts +0 -64
- package/dist/host/meili/index-schema.d.ts.map +0 -1
- package/dist/host/meili/index-schema.js +0 -70
- package/dist/host/meili/index-schema.js.map +0 -1
- package/dist/host/meili/index.d.ts +0 -13
- package/dist/host/meili/index.d.ts.map +0 -1
- package/dist/host/meili/index.js +0 -8
- package/dist/host/meili/index.js.map +0 -1
- package/dist/host/meili/indexer.d.ts +0 -31
- package/dist/host/meili/indexer.d.ts.map +0 -1
- package/dist/host/meili/indexer.js +0 -49
- package/dist/host/meili/indexer.js.map +0 -1
- package/dist/host/meili-launcher.d.ts +0 -30
- package/dist/host/meili-launcher.d.ts.map +0 -1
- package/dist/host/meili-launcher.js +0 -115
- package/dist/host/meili-launcher.js.map +0 -1
- package/dist/host/n8n/agent-isolation.d.ts +0 -55
- package/dist/host/n8n/agent-isolation.d.ts.map +0 -1
- package/dist/host/n8n/agent-isolation.js +0 -158
- package/dist/host/n8n/agent-isolation.js.map +0 -1
- package/dist/host/n8n/api-key.d.ts +0 -67
- package/dist/host/n8n/api-key.d.ts.map +0 -1
- package/dist/host/n8n/api-key.js +0 -297
- package/dist/host/n8n/api-key.js.map +0 -1
- package/dist/host/n8n/launcher.d.ts +0 -126
- package/dist/host/n8n/launcher.d.ts.map +0 -1
- package/dist/host/n8n/launcher.js +0 -1170
- package/dist/host/n8n/launcher.js.map +0 -1
- package/dist/host/n8n/runtime-bootstrap.d.ts +0 -44
- package/dist/host/n8n/runtime-bootstrap.d.ts.map +0 -1
- package/dist/host/n8n/runtime-bootstrap.js +0 -230
- package/dist/host/n8n/runtime-bootstrap.js.map +0 -1
- package/dist/host/node-runtime.d.ts +0 -52
- package/dist/host/node-runtime.d.ts.map +0 -1
- package/dist/host/node-runtime.js +0 -257
- package/dist/host/node-runtime.js.map +0 -1
- package/dist/host/npm-cli.d.ts +0 -43
- package/dist/host/npm-cli.d.ts.map +0 -1
- package/dist/host/npm-cli.js +0 -213
- package/dist/host/npm-cli.js.map +0 -1
- package/dist/host/plugins/accept-check.d.ts +0 -19
- package/dist/host/plugins/accept-check.d.ts.map +0 -1
- package/dist/host/plugins/accept-check.js +0 -172
- package/dist/host/plugins/accept-check.js.map +0 -1
- package/dist/host/plugins/brand-bindings.d.ts +0 -103
- package/dist/host/plugins/brand-bindings.d.ts.map +0 -1
- package/dist/host/plugins/brand-bindings.js +0 -65
- package/dist/host/plugins/brand-bindings.js.map +0 -1
- package/dist/host/plugins/control-adapters.d.ts +0 -11
- package/dist/host/plugins/control-adapters.d.ts.map +0 -1
- package/dist/host/plugins/control-adapters.js +0 -83
- package/dist/host/plugins/control-adapters.js.map +0 -1
- package/dist/host/plugins/control-extras.d.ts +0 -61
- package/dist/host/plugins/control-extras.d.ts.map +0 -1
- package/dist/host/plugins/control-extras.js +0 -382
- package/dist/host/plugins/control-extras.js.map +0 -1
- package/dist/host/plugins/control-plane.d.ts +0 -42
- package/dist/host/plugins/control-plane.d.ts.map +0 -1
- package/dist/host/plugins/control-plane.js +0 -124
- package/dist/host/plugins/control-plane.js.map +0 -1
- package/dist/host/plugins/control-token.d.ts +0 -24
- package/dist/host/plugins/control-token.d.ts.map +0 -1
- package/dist/host/plugins/control-token.js +0 -77
- package/dist/host/plugins/control-token.js.map +0 -1
- package/dist/host/plugins/crm-key.d.ts +0 -25
- package/dist/host/plugins/crm-key.d.ts.map +0 -1
- package/dist/host/plugins/crm-key.js +0 -126
- package/dist/host/plugins/crm-key.js.map +0 -1
- package/dist/host/plugins/data.d.ts +0 -21
- package/dist/host/plugins/data.d.ts.map +0 -1
- package/dist/host/plugins/data.js +0 -100
- package/dist/host/plugins/data.js.map +0 -1
- package/dist/host/plugins/events.d.ts +0 -6
- package/dist/host/plugins/events.d.ts.map +0 -1
- package/dist/host/plugins/events.js +0 -6
- package/dist/host/plugins/events.js.map +0 -1
- package/dist/host/plugins/execution-grant.d.ts +0 -6
- package/dist/host/plugins/execution-grant.d.ts.map +0 -1
- package/dist/host/plugins/execution-grant.js +0 -6
- package/dist/host/plugins/execution-grant.js.map +0 -1
- package/dist/host/plugins/git.d.ts +0 -56
- package/dist/host/plugins/git.d.ts.map +0 -1
- package/dist/host/plugins/git.js +0 -357
- package/dist/host/plugins/git.js.map +0 -1
- package/dist/host/plugins/host.d.ts +0 -68
- package/dist/host/plugins/host.d.ts.map +0 -1
- package/dist/host/plugins/host.js +0 -276
- package/dist/host/plugins/host.js.map +0 -1
- package/dist/host/plugins/launcher.d.ts +0 -146
- package/dist/host/plugins/launcher.d.ts.map +0 -1
- package/dist/host/plugins/launcher.js +0 -489
- package/dist/host/plugins/launcher.js.map +0 -1
- package/dist/host/plugins/runtime.d.ts +0 -28
- package/dist/host/plugins/runtime.d.ts.map +0 -1
- package/dist/host/plugins/runtime.js +0 -430
- package/dist/host/plugins/runtime.js.map +0 -1
- package/dist/host/plugins/test-runner.d.ts +0 -15
- package/dist/host/plugins/test-runner.d.ts.map +0 -1
- package/dist/host/plugins/test-runner.js +0 -106
- package/dist/host/plugins/test-runner.js.map +0 -1
- package/dist/host/safe-storage.d.ts +0 -21
- package/dist/host/safe-storage.d.ts.map +0 -1
- package/dist/host/safe-storage.js +0 -55
- package/dist/host/safe-storage.js.map +0 -1
- package/dist/host/sandbox/embed-sandbox.d.ts +0 -133
- package/dist/host/sandbox/embed-sandbox.d.ts.map +0 -1
- package/dist/host/sandbox/embed-sandbox.js +0 -378
- package/dist/host/sandbox/embed-sandbox.js.map +0 -1
- package/dist/host/sandbox/os-sandbox.d.ts +0 -41
- package/dist/host/sandbox/os-sandbox.d.ts.map +0 -1
- package/dist/host/sandbox/os-sandbox.js +0 -98
- package/dist/host/sandbox/os-sandbox.js.map +0 -1
- package/dist/host/server-env.d.ts +0 -50
- package/dist/host/server-env.d.ts.map +0 -1
- package/dist/host/server-env.js +0 -64
- package/dist/host/server-env.js.map +0 -1
- package/dist/host/server-launcher.d.ts +0 -49
- package/dist/host/server-launcher.d.ts.map +0 -1
- package/dist/host/server-launcher.js +0 -43
- package/dist/host/server-launcher.js.map +0 -1
- package/dist/host/tunnel/cloudflared-respawn.d.ts +0 -58
- package/dist/host/tunnel/cloudflared-respawn.d.ts.map +0 -1
- package/dist/host/tunnel/cloudflared-respawn.js +0 -73
- package/dist/host/tunnel/cloudflared-respawn.js.map +0 -1
- package/dist/host/tunnel/tunnel.d.ts +0 -72
- package/dist/host/tunnel/tunnel.d.ts.map +0 -1
- package/dist/host/tunnel/tunnel.js +0 -462
- package/dist/host/tunnel/tunnel.js.map +0 -1
- package/dist/logger.d.ts +0 -44
- package/dist/logger.d.ts.map +0 -1
- package/dist/logger.js +0 -252
- package/dist/logger.js.map +0 -1
- package/dist-cjs/desktop/legacy-brand-compat.js +0 -56
- package/dist-cjs/desktop/legacy-brand-compat.js.map +0 -1
- package/dist-cjs/factory-reset-runtime.js +0 -117
- package/dist-cjs/factory-reset-runtime.js.map +0 -1
- package/dist-cjs/host/ai-workspace/actions.js +0 -247
- package/dist-cjs/host/ai-workspace/actions.js.map +0 -1
- package/dist-cjs/host/ai-workspace/bindings.js +0 -49
- package/dist-cjs/host/ai-workspace/bindings.js.map +0 -1
- package/dist-cjs/host/ai-workspace/index.js +0 -21
- package/dist-cjs/host/ai-workspace/index.js.map +0 -1
- package/dist-cjs/host/ai-workspace/manager.js +0 -528
- package/dist-cjs/host/ai-workspace/manager.js.map +0 -1
- package/dist-cjs/host/ai-workspace/profile-window.js +0 -125
- package/dist-cjs/host/ai-workspace/profile-window.js.map +0 -1
- package/dist-cjs/host/ai-workspace/screencast.js +0 -249
- package/dist-cjs/host/ai-workspace/screencast.js.map +0 -1
- package/dist-cjs/host/ai-workspace/types.js +0 -7
- package/dist-cjs/host/ai-workspace/types.js.map +0 -1
- package/dist-cjs/host/brand-host-runtime.js +0 -286
- package/dist-cjs/host/brand-host-runtime.js.map +0 -1
- package/dist-cjs/host/brand-host-stack.js +0 -259
- package/dist-cjs/host/brand-host-stack.js.map +0 -1
- package/dist-cjs/host/brand-kernel-http.js +0 -101
- package/dist-cjs/host/brand-kernel-http.js.map +0 -1
- package/dist-cjs/host/brand-meili-boot.js +0 -106
- package/dist-cjs/host/brand-meili-boot.js.map +0 -1
- package/dist-cjs/host/bridge-client.js +0 -191
- package/dist-cjs/host/bridge-client.js.map +0 -1
- package/dist-cjs/host/context.js +0 -20
- package/dist-cjs/host/context.js.map +0 -1
- package/dist-cjs/host/contracts.js +0 -32
- package/dist-cjs/host/contracts.js.map +0 -1
- package/dist-cjs/host/crash-reporter.js +0 -422
- package/dist-cjs/host/crash-reporter.js.map +0 -1
- package/dist-cjs/host/ensure-kit-binaries.js +0 -212
- package/dist-cjs/host/ensure-kit-binaries.js.map +0 -1
- package/dist-cjs/host/feature-off-host.js +0 -144
- package/dist-cjs/host/feature-off-host.js.map +0 -1
- package/dist-cjs/host/hermes/crm-key.js +0 -137
- package/dist-cjs/host/hermes/crm-key.js.map +0 -1
- package/dist-cjs/host/hermes/ensure-crm-key-db.js +0 -89
- package/dist-cjs/host/hermes/ensure-crm-key-db.js.map +0 -1
- package/dist-cjs/host/hermes/launcher.js +0 -981
- package/dist-cjs/host/hermes/launcher.js.map +0 -1
- package/dist-cjs/host/hermes/runtime-bootstrap.js +0 -853
- package/dist-cjs/host/hermes/runtime-bootstrap.js.map +0 -1
- package/dist-cjs/host/hermes/skills-seed.js +0 -110
- package/dist-cjs/host/hermes/skills-seed.js.map +0 -1
- package/dist-cjs/host/host-stack.js +0 -42
- package/dist-cjs/host/host-stack.js.map +0 -1
- package/dist-cjs/host/kit-os-resources.js +0 -96
- package/dist-cjs/host/kit-os-resources.js.map +0 -1
- package/dist-cjs/host/load-electron.js +0 -47
- package/dist-cjs/host/load-electron.js.map +0 -1
- package/dist-cjs/host/local-config.js +0 -640
- package/dist-cjs/host/local-config.js.map +0 -1
- package/dist-cjs/host/meili/browse.js +0 -103
- package/dist-cjs/host/meili/browse.js.map +0 -1
- package/dist-cjs/host/meili/coherence-db.js +0 -139
- package/dist-cjs/host/meili/coherence-db.js.map +0 -1
- package/dist-cjs/host/meili/coherence-query.js +0 -25
- package/dist-cjs/host/meili/coherence-query.js.map +0 -1
- package/dist-cjs/host/meili/coherence.js +0 -158
- package/dist-cjs/host/meili/coherence.js.map +0 -1
- package/dist-cjs/host/meili/feed.js +0 -108
- package/dist-cjs/host/meili/feed.js.map +0 -1
- package/dist-cjs/host/meili/generic-indexer.js +0 -340
- package/dist-cjs/host/meili/generic-indexer.js.map +0 -1
- package/dist-cjs/host/meili/index-schema.js +0 -79
- package/dist-cjs/host/meili/index-schema.js.map +0 -1
- package/dist-cjs/host/meili/index.js +0 -45
- package/dist-cjs/host/meili/index.js.map +0 -1
- package/dist-cjs/host/meili/indexer.js +0 -85
- package/dist-cjs/host/meili/indexer.js.map +0 -1
- package/dist-cjs/host/meili-launcher.js +0 -121
- package/dist-cjs/host/meili-launcher.js.map +0 -1
- package/dist-cjs/host/n8n/agent-isolation.js +0 -173
- package/dist-cjs/host/n8n/agent-isolation.js.map +0 -1
- package/dist-cjs/host/n8n/api-key.js +0 -314
- package/dist-cjs/host/n8n/api-key.js.map +0 -1
- package/dist-cjs/host/n8n/launcher.js +0 -1209
- package/dist-cjs/host/n8n/launcher.js.map +0 -1
- package/dist-cjs/host/n8n/runtime-bootstrap.js +0 -244
- package/dist-cjs/host/n8n/runtime-bootstrap.js.map +0 -1
- package/dist-cjs/host/node-runtime.js +0 -274
- package/dist-cjs/host/node-runtime.js.map +0 -1
- package/dist-cjs/host/npm-cli.js +0 -224
- package/dist-cjs/host/npm-cli.js.map +0 -1
- package/dist-cjs/host/plugins/accept-check.js +0 -176
- package/dist-cjs/host/plugins/accept-check.js.map +0 -1
- package/dist-cjs/host/plugins/brand-bindings.js +0 -78
- package/dist-cjs/host/plugins/brand-bindings.js.map +0 -1
- package/dist-cjs/host/plugins/control-adapters.js +0 -89
- package/dist-cjs/host/plugins/control-adapters.js.map +0 -1
- package/dist-cjs/host/plugins/control-extras.js +0 -397
- package/dist-cjs/host/plugins/control-extras.js.map +0 -1
- package/dist-cjs/host/plugins/control-plane.js +0 -130
- package/dist-cjs/host/plugins/control-plane.js.map +0 -1
- package/dist-cjs/host/plugins/control-token.js +0 -90
- package/dist-cjs/host/plugins/control-token.js.map +0 -1
- package/dist-cjs/host/plugins/crm-key.js +0 -135
- package/dist-cjs/host/plugins/crm-key.js.map +0 -1
- package/dist-cjs/host/plugins/data.js +0 -107
- package/dist-cjs/host/plugins/data.js.map +0 -1
- package/dist-cjs/host/plugins/events.js +0 -19
- package/dist-cjs/host/plugins/events.js.map +0 -1
- package/dist-cjs/host/plugins/execution-grant.js +0 -11
- package/dist-cjs/host/plugins/execution-grant.js.map +0 -1
- package/dist-cjs/host/plugins/git.js +0 -371
- package/dist-cjs/host/plugins/git.js.map +0 -1
- package/dist-cjs/host/plugins/host.js +0 -283
- package/dist-cjs/host/plugins/host.js.map +0 -1
- package/dist-cjs/host/plugins/launcher.js +0 -514
- package/dist-cjs/host/plugins/launcher.js.map +0 -1
- package/dist-cjs/host/plugins/runtime.js +0 -446
- package/dist-cjs/host/plugins/runtime.js.map +0 -1
- package/dist-cjs/host/plugins/test-runner.js +0 -112
- package/dist-cjs/host/plugins/test-runner.js.map +0 -1
- package/dist-cjs/host/safe-storage.js +0 -95
- package/dist-cjs/host/safe-storage.js.map +0 -1
- package/dist-cjs/host/sandbox/embed-sandbox.js +0 -396
- package/dist-cjs/host/sandbox/embed-sandbox.js.map +0 -1
- package/dist-cjs/host/sandbox/os-sandbox.js +0 -106
- package/dist-cjs/host/sandbox/os-sandbox.js.map +0 -1
- package/dist-cjs/host/server-env.js +0 -69
- package/dist-cjs/host/server-env.js.map +0 -1
- package/dist-cjs/host/server-launcher.js +0 -52
- package/dist-cjs/host/server-launcher.js.map +0 -1
- package/dist-cjs/host/tunnel/cloudflared-respawn.js +0 -80
- package/dist-cjs/host/tunnel/cloudflared-respawn.js.map +0 -1
- package/dist-cjs/host/tunnel/tunnel.js +0 -470
- package/dist-cjs/host/tunnel/tunnel.js.map +0 -1
- package/dist-cjs/logger.js +0 -269
- package/dist-cjs/logger.js.map +0 -1
|
@@ -1,972 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sidecar Hermes Agent + WebUI — factory brand-agnostic.
|
|
3
|
-
* SoT extrait de TempoFlow hermes-launcher.ts (R3.3) — chemins gold intacts.
|
|
4
|
-
*/
|
|
5
|
-
import { spawn } from "node:child_process";
|
|
6
|
-
import crypto from "node:crypto";
|
|
7
|
-
import fs from "node:fs";
|
|
8
|
-
import http from "node:http";
|
|
9
|
-
import path from "node:path";
|
|
10
|
-
import { buildHermesHomeEnvFile, buildNextHermesEnv, HERMES_DESKTOP_API_PORT, HERMES_DESKTOP_WEBUI_PORT, hermesPublicStatus, mergeEmbedUserEnv, resolveHermesBinary, sanitizeHermesEmbedConfig, shouldSpawnEmbeddedHermes, } from "@creezio/platform-core";
|
|
11
|
-
import { hostLog, hostProductName } from "../context.js";
|
|
12
|
-
import { applyOsSandboxEnv, hermesSandboxPaths, upsertHermesMcpConfig, upsertHermesSandboxConfig, } from "../sandbox/embed-sandbox.js";
|
|
13
|
-
import { findFreePort } from "../server-env.js";
|
|
14
|
-
import { resolveDesktopNodeBinary } from "../node-runtime.js";
|
|
15
|
-
import { ensureHermesRuntime, ensureHermesWebuiTree, getBootstrapError, getBootstrapPhase, hermesRuntimeCacheDir, hermesVendorDir, hermesWebuiInstallDir, resolveHermesAgentDir, resolveHermesPython, hermesFhsFallbackDirs, } from "./runtime-bootstrap.js";
|
|
16
|
-
/**
|
|
17
|
-
* Password WebUI en mode serveur : `HERMES_WEBUI_PASSWORD` explicite, sinon
|
|
18
|
-
* superadmin flotte (`CREEZIO_SUPERADMIN_PASSWORD`). null = desktop loopback
|
|
19
|
-
* (auth off, contrat gold sans prompt).
|
|
20
|
-
*/
|
|
21
|
-
export function serverWebuiPassword() {
|
|
22
|
-
const explicit = (process.env.HERMES_WEBUI_PASSWORD || "").trim();
|
|
23
|
-
if (explicit)
|
|
24
|
-
return explicit;
|
|
25
|
-
const superadmin = (process.env.CREEZIO_SUPERADMIN_PASSWORD || "").trim();
|
|
26
|
-
return superadmin.length >= 12 ? superadmin : null;
|
|
27
|
-
}
|
|
28
|
-
/** Clear legacy generated WebUI password (gold: no login prompt on loopback). */
|
|
29
|
-
export function clearGeneratedWebuiPassword(home, stateDir, secretPrefix) {
|
|
30
|
-
clearGeneratedWebuiPasswordImpl(home, stateDir, secretPrefix);
|
|
31
|
-
}
|
|
32
|
-
/** @deprecated gold marker alias */
|
|
33
|
-
export function clearTempoflowGeneratedWebuiPassword(home, stateDir, secretPrefix) {
|
|
34
|
-
clearGeneratedWebuiPasswordImpl(home, stateDir, secretPrefix);
|
|
35
|
-
}
|
|
36
|
-
function clearGeneratedWebuiPasswordImpl(home, stateDir, secretPrefix) {
|
|
37
|
-
const files = [
|
|
38
|
-
path.join(home, ".tempoflow-webui-password"),
|
|
39
|
-
path.join(home, ".desktop-hermes-webui-password"),
|
|
40
|
-
path.join(home, ".certivan-webui-password"),
|
|
41
|
-
path.join(home, ".fidu-webui-password"),
|
|
42
|
-
];
|
|
43
|
-
if (secretPrefix) {
|
|
44
|
-
files.push(path.join(home, `.${secretPrefix}-webui-password`));
|
|
45
|
-
}
|
|
46
|
-
for (const f of files) {
|
|
47
|
-
try {
|
|
48
|
-
if (fs.existsSync(f))
|
|
49
|
-
fs.unlinkSync(f);
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
/* ignore */
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
const envPath = path.join(home, ".env");
|
|
56
|
-
try {
|
|
57
|
-
if (fs.existsSync(envPath)) {
|
|
58
|
-
const body = fs.readFileSync(envPath, "utf8");
|
|
59
|
-
const next = body
|
|
60
|
-
.split(/\r?\n/)
|
|
61
|
-
.filter((line) => !/^\s*HERMES_WEBUI_PASSWORD\s*=/.test(line))
|
|
62
|
-
.join("\n");
|
|
63
|
-
if (next !== body)
|
|
64
|
-
fs.writeFileSync(envPath, next, { mode: 0o600 });
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
/* ignore */
|
|
69
|
-
}
|
|
70
|
-
const settingsPath = path.join(stateDir, "settings.json");
|
|
71
|
-
try {
|
|
72
|
-
if (fs.existsSync(settingsPath)) {
|
|
73
|
-
const raw = JSON.parse(fs.readFileSync(settingsPath, "utf8"));
|
|
74
|
-
if (raw && typeof raw === "object" && "password_hash" in raw) {
|
|
75
|
-
delete raw.password_hash;
|
|
76
|
-
fs.writeFileSync(settingsPath, JSON.stringify(raw, null, 2) + "\n", {
|
|
77
|
-
mode: 0o600,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
/* ignore */
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
export function createHermesHost(opts) {
|
|
87
|
-
const { ctx, store } = opts;
|
|
88
|
-
const homeDir = () => path.join(ctx.userDataDir, "hermes-home");
|
|
89
|
-
const product = () => hostProductName(ctx);
|
|
90
|
-
const state = {
|
|
91
|
-
running: null,
|
|
92
|
-
starting: false,
|
|
93
|
-
lastError: null,
|
|
94
|
-
version: null,
|
|
95
|
-
logs: [],
|
|
96
|
-
binaryPath: null,
|
|
97
|
-
webuiStatus: "stopped",
|
|
98
|
-
webuiError: null,
|
|
99
|
-
installing: false,
|
|
100
|
-
lastStartPath: null,
|
|
101
|
-
};
|
|
102
|
-
/** "bootstrap" = runtime installé pendant ce boot ; "reuse" = déjà présent. */
|
|
103
|
-
function getHermesLastStartPath() {
|
|
104
|
-
return state.lastStartPath;
|
|
105
|
-
}
|
|
106
|
-
const LOG_MAX = 200;
|
|
107
|
-
let startInFlight = null;
|
|
108
|
-
function pushLog(line) {
|
|
109
|
-
const ts = new Date().toISOString().slice(11, 19);
|
|
110
|
-
state.logs.push("[" + ts + "] " + line);
|
|
111
|
-
if (state.logs.length > LOG_MAX)
|
|
112
|
-
state.logs.shift();
|
|
113
|
-
hostLog(ctx, "hermes", line);
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Dossiers d'outils LÉGITIMES pour le PATH confiné des process Hermes :
|
|
117
|
-
* venv Hermes, Node TempoFlow, MinGit embarqué. Rien du PC hôte.
|
|
118
|
-
*/
|
|
119
|
-
function hermesToolPathDirs(primaryDir) {
|
|
120
|
-
const dirs = [primaryDir];
|
|
121
|
-
try {
|
|
122
|
-
const node = resolveDesktopNodeBinary(ctx);
|
|
123
|
-
if (node && path.isAbsolute(node))
|
|
124
|
-
dirs.push(path.dirname(node));
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
/* app pas prête */
|
|
128
|
-
}
|
|
129
|
-
try {
|
|
130
|
-
const git = ctx.getGitBinary?.() || null;
|
|
131
|
-
if (git)
|
|
132
|
-
dirs.push(path.dirname(git));
|
|
133
|
-
}
|
|
134
|
-
catch {
|
|
135
|
-
/* absent */
|
|
136
|
-
}
|
|
137
|
-
return dirs;
|
|
138
|
-
}
|
|
139
|
-
function findHermesBinary() {
|
|
140
|
-
// Même racine que le bootstrap (space-safe si userData a des espaces).
|
|
141
|
-
const runtime = hermesRuntimeCacheDir(ctx);
|
|
142
|
-
const profile = path.join(runtime, "os-profile");
|
|
143
|
-
const localApp = path.join(runtime, "bin");
|
|
144
|
-
const vendorBin = path.join(hermesVendorDir(ctx), "bin");
|
|
145
|
-
// Sandbox TempoFlow d’abord — pas le profil Windows Admin.
|
|
146
|
-
const sandLocalBin = path.join(profile, "AppData", "Local", "hermes", "bin");
|
|
147
|
-
const sandHermesBin = path.join(profile, ".hermes", "bin");
|
|
148
|
-
const sandAgentScripts = process.platform === "win32"
|
|
149
|
-
? path.join(profile, "AppData", "Local", "hermes", "hermes-agent", "venv", "Scripts")
|
|
150
|
-
: path.join(profile, ".hermes", "hermes-agent", "venv", "bin");
|
|
151
|
-
// Legacy (userData à espaces) — migration / installs antérieures.
|
|
152
|
-
const legacyRuntime = path.join(ctx.userDataDir, "hermes-runtime");
|
|
153
|
-
const legacyProfile = path.join(legacyRuntime, "os-profile");
|
|
154
|
-
const resolved = resolveHermesBinary({
|
|
155
|
-
platform: process.platform,
|
|
156
|
-
env: process.env,
|
|
157
|
-
searchDirs: [
|
|
158
|
-
localApp,
|
|
159
|
-
vendorBin,
|
|
160
|
-
sandLocalBin,
|
|
161
|
-
sandHermesBin,
|
|
162
|
-
sandAgentScripts,
|
|
163
|
-
path.join(legacyRuntime, "bin"),
|
|
164
|
-
path.join(legacyProfile, ".hermes", "bin"),
|
|
165
|
-
path.join(legacyProfile, ".hermes", "hermes-agent", "venv", "bin"),
|
|
166
|
-
// Containers root Linux : installs FHS antérieures au verrou
|
|
167
|
-
// HERMES_INSTALL_DIR (/usr/local) — jamais consulté sur desktop.
|
|
168
|
-
...hermesFhsFallbackDirs(process.platform, typeof process.getuid === "function" ? process.getuid() : null),
|
|
169
|
-
].filter(Boolean),
|
|
170
|
-
// OS TempoFlow : jamais de `which`/`where` — sandbox uniquement.
|
|
171
|
-
// Overrides env autorisés seulement hors build packagé (dev/tests).
|
|
172
|
-
allowEnvOverride: !ctx.isPackaged,
|
|
173
|
-
envPrefix: ctx.manifest.envPrefix,
|
|
174
|
-
existsSync: (p) => {
|
|
175
|
-
try {
|
|
176
|
-
return fs.existsSync(p);
|
|
177
|
-
}
|
|
178
|
-
catch {
|
|
179
|
-
return false;
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
|
-
state.binaryPath = resolved;
|
|
184
|
-
return resolved;
|
|
185
|
-
}
|
|
186
|
-
function ensureApiKey(home) {
|
|
187
|
-
fs.mkdirSync(home, { recursive: true });
|
|
188
|
-
const prefix = ctx.secretFilePrefix || ctx.manifest.brandId || "desktop";
|
|
189
|
-
/** Canon marque : `.certivan-api-server-key` / `.tempoflow-api-server-key`. */
|
|
190
|
-
const keyFile = path.join(home, `.${prefix}-api-server-key`);
|
|
191
|
-
const desktop = path.join(home, ".desktop-hermes-api-key");
|
|
192
|
-
const tempoflow = path.join(home, ".tempoflow-api-server-key");
|
|
193
|
-
for (const f of [keyFile, desktop, tempoflow]) {
|
|
194
|
-
try {
|
|
195
|
-
const existing = fs.readFileSync(f, "utf8").trim();
|
|
196
|
-
if (existing.length >= 16) {
|
|
197
|
-
if (f !== keyFile)
|
|
198
|
-
fs.writeFileSync(keyFile, existing, { mode: 0o600 });
|
|
199
|
-
return existing;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
catch {
|
|
203
|
-
/* */
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
const key = crypto.randomBytes(24).toString("base64url");
|
|
207
|
-
fs.writeFileSync(keyFile, key, { mode: 0o600 });
|
|
208
|
-
return key;
|
|
209
|
-
}
|
|
210
|
-
async function writeHermesHome(opts) {
|
|
211
|
-
const paths = hermesSandboxPaths(opts.home);
|
|
212
|
-
fs.mkdirSync(paths.home, { recursive: true });
|
|
213
|
-
fs.mkdirSync(paths.profileHome, { recursive: true });
|
|
214
|
-
fs.mkdirSync(paths.workspace, { recursive: true });
|
|
215
|
-
// README pour l’utilisateur / support — le workspace OS est ICI, pas ~/workspace.
|
|
216
|
-
const readme = path.join(paths.workspace, "README-WORKSPACE.txt");
|
|
217
|
-
if (!fs.existsSync(readme)) {
|
|
218
|
-
fs.writeFileSync(readme, [
|
|
219
|
-
product() + " — workspace Hermes",
|
|
220
|
-
"",
|
|
221
|
-
"Workspace pour le Work général (brouillons, scripts, analyses).",
|
|
222
|
-
"Il vit dans le profil desktop (userData), pas dans C:\\Users\\…\\workspace.",
|
|
223
|
-
"",
|
|
224
|
-
"Plugins : NE PAS installer ici.",
|
|
225
|
-
"Utiliser PLUGINS_API_URL (control plane) → userData/plugins/.",
|
|
226
|
-
"",
|
|
227
|
-
].join("\n"), "utf8");
|
|
228
|
-
}
|
|
229
|
-
const llm = store.getLlmKeys();
|
|
230
|
-
const bridgeEnv = ctx.getHermesBridgeEnv?.(opts.crmPort != null ? { crmPort: opts.crmPort } : undefined) || {};
|
|
231
|
-
const envBody = buildHermesHomeEnvFile({
|
|
232
|
-
apiKey: opts.apiKey,
|
|
233
|
-
apiPort: opts.apiPort,
|
|
234
|
-
openaiKey: llm.openai,
|
|
235
|
-
anthropicKey: llm.anthropic,
|
|
236
|
-
userEnv: store.getEmbedUserEnv("hermes"),
|
|
237
|
-
bridgeEnv,
|
|
238
|
-
// Pas de password WebUI : loopback + auth optionnelle (voir PLAN-HERMES).
|
|
239
|
-
});
|
|
240
|
-
fs.writeFileSync(path.join(opts.home, ".env"), envBody, { mode: 0o600 });
|
|
241
|
-
if (ctx.seedHermesSkills) {
|
|
242
|
-
try {
|
|
243
|
-
await Promise.resolve(ctx.seedHermesSkills(opts.home));
|
|
244
|
-
}
|
|
245
|
-
catch (e) {
|
|
246
|
-
pushLog("skills seed: " + (e instanceof Error ? e.message : e));
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
const cfgPath = path.join(opts.home, "config.yaml");
|
|
250
|
-
let existing = "";
|
|
251
|
-
try {
|
|
252
|
-
existing = fs.readFileSync(cfgPath, "utf8");
|
|
253
|
-
}
|
|
254
|
-
catch {
|
|
255
|
-
existing = "";
|
|
256
|
-
}
|
|
257
|
-
// H1 — bloc mcp_servers (façade MCP CRM, Bearer clé Hermes) upserté après
|
|
258
|
-
// le bloc sandbox, idempotent, sans toucher la config utilisateur.
|
|
259
|
-
const mcpConfig = ctx.getHermesMcpServerConfig?.(opts.crmPort != null ? { crmPort: opts.crmPort } : undefined) || null;
|
|
260
|
-
fs.writeFileSync(cfgPath, upsertHermesMcpConfig(upsertHermesSandboxConfig(existing, paths.workspace), mcpConfig), "utf8");
|
|
261
|
-
if (mcpConfig) {
|
|
262
|
-
pushLog(`config: mcp_servers.${mcpConfig.serverName} → ${mcpConfig.url}`);
|
|
263
|
-
}
|
|
264
|
-
return { profileHome: paths.profileHome, workspace: paths.workspace };
|
|
265
|
-
}
|
|
266
|
-
function waitForHttpOk(url, opts = {}) {
|
|
267
|
-
const deadline = Date.now() + (opts.timeoutMs ?? 90000);
|
|
268
|
-
return new Promise((resolve) => {
|
|
269
|
-
const tryOnce = () => {
|
|
270
|
-
const req = http.get(url, { timeout: 2000, headers: opts.headers || {} }, (res) => {
|
|
271
|
-
const chunks = [];
|
|
272
|
-
res.on("data", (c) => chunks.push(c));
|
|
273
|
-
res.on("end", () => {
|
|
274
|
-
const body = Buffer.concat(chunks).toString("utf8");
|
|
275
|
-
if (res.statusCode && res.statusCode >= 200 && res.statusCode < 500) {
|
|
276
|
-
resolve({ ok: res.statusCode < 400, body, status: res.statusCode });
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
next();
|
|
280
|
-
});
|
|
281
|
-
});
|
|
282
|
-
req.on("error", () => next());
|
|
283
|
-
req.on("timeout", () => {
|
|
284
|
-
req.destroy();
|
|
285
|
-
next();
|
|
286
|
-
});
|
|
287
|
-
};
|
|
288
|
-
const next = () => {
|
|
289
|
-
if (Date.now() > deadline) {
|
|
290
|
-
resolve({ ok: false, body: "", status: null });
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
setTimeout(tryOnce, 500);
|
|
294
|
-
}
|
|
295
|
-
};
|
|
296
|
-
tryOnce();
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
function waitForHermesHealth(apiUrl, apiKey, timeoutMs = 90000) {
|
|
300
|
-
return waitForHttpOk(`${apiUrl}/health`, {
|
|
301
|
-
timeoutMs,
|
|
302
|
-
headers: { Authorization: `Bearer ${apiKey}` },
|
|
303
|
-
}).then((r) => {
|
|
304
|
-
if (!r.ok)
|
|
305
|
-
return { ok: false, version: null, detail: "health timeout" };
|
|
306
|
-
let version = null;
|
|
307
|
-
try {
|
|
308
|
-
const j = JSON.parse(r.body);
|
|
309
|
-
version = j.version || null;
|
|
310
|
-
}
|
|
311
|
-
catch {
|
|
312
|
-
/* ignore */
|
|
313
|
-
}
|
|
314
|
-
return { ok: true, version, detail: "ok" };
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
async function spawnWebui(opts) {
|
|
318
|
-
const agentDir = resolveHermesAgentDir(ctx);
|
|
319
|
-
const python = resolveHermesPython(agentDir);
|
|
320
|
-
const webuiDir = hermesWebuiInstallDir(ctx);
|
|
321
|
-
const serverPy = path.join(webuiDir, "server.py");
|
|
322
|
-
if (!python || !fs.existsSync(serverPy)) {
|
|
323
|
-
state.webuiStatus = "missing";
|
|
324
|
-
state.webuiError = "WebUI ou Python Hermes absent";
|
|
325
|
-
opts.log(state.webuiError);
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
const webuiPort = await findFreePort(HERMES_DESKTOP_WEBUI_PORT);
|
|
329
|
-
const webuiUrl = `http://127.0.0.1:${webuiPort}`;
|
|
330
|
-
const stateDir = path.join(ctx.userDataDir, "hermes-webui-state");
|
|
331
|
-
fs.mkdirSync(stateDir, { recursive: true });
|
|
332
|
-
// Mode serveur/flotte : le WebUI est exposé publiquement via le tunnel
|
|
333
|
-
// (hermes.{slug}.{domaine}) → protection par le mécanisme natif Hermes
|
|
334
|
-
// (HERMES_WEBUI_PASSWORD = superadmin flotte). Desktop loopback : auth off
|
|
335
|
-
// (gold — pas de prompt).
|
|
336
|
-
const webuiPassword = serverWebuiPassword();
|
|
337
|
-
if (!webuiPassword) {
|
|
338
|
-
clearGeneratedWebuiPassword(opts.home, stateDir, ctx.secretFilePrefix || ctx.manifest.brandId); // clearTempoflowGeneratedWebuiPassword gold
|
|
339
|
-
}
|
|
340
|
-
opts.log(`spawn WebUI ${serverPy} → ${webuiUrl} (${webuiPassword ? "auth superadmin flotte ACTIVE" : "auth loopback désactivée"})`);
|
|
341
|
-
const sand = hermesSandboxPaths(opts.home);
|
|
342
|
-
// Chat WebUI = runtime in-process (pas la gateway) → BYOK obligatoire ici aussi.
|
|
343
|
-
const llm = store.getLlmKeys();
|
|
344
|
-
const childEnv = applyOsSandboxEnv({
|
|
345
|
-
env: {
|
|
346
|
-
...process.env,
|
|
347
|
-
HERMES_HOME: opts.home,
|
|
348
|
-
HERMES_WEBUI_HOST: "127.0.0.1",
|
|
349
|
-
HERMES_WEBUI_PORT: String(webuiPort),
|
|
350
|
-
HERMES_WEBUI_GATEWAY_BASE_URL: opts.apiUrl,
|
|
351
|
-
HERMES_WEBUI_GATEWAY_API_KEY: opts.apiKey,
|
|
352
|
-
HERMES_WEBUI_STATE_DIR: stateDir,
|
|
353
|
-
HERMES_WEBUI_AGENT_DIR: agentDir || "",
|
|
354
|
-
HERMES_WEBUI_DISABLE_SELF_UPDATE: "1",
|
|
355
|
-
PYTHONUNBUFFERED: "1",
|
|
356
|
-
TERMINAL_CWD: sand.workspace,
|
|
357
|
-
},
|
|
358
|
-
profileHome: sand.profileHome,
|
|
359
|
-
userData: ctx.userDataDir,
|
|
360
|
-
// PATH confiné : venv Python Hermes + System32 — pas le PATH utilisateur.
|
|
361
|
-
toolDirs: hermesToolPathDirs(path.dirname(python)),
|
|
362
|
-
});
|
|
363
|
-
// Ne jamais propager un password hérité du process parent / anciens builds —
|
|
364
|
-
// sauf protection serveur explicite (superadmin flotte).
|
|
365
|
-
delete childEnv.HERMES_WEBUI_PASSWORD;
|
|
366
|
-
if (webuiPassword)
|
|
367
|
-
childEnv.HERMES_WEBUI_PASSWORD = webuiPassword;
|
|
368
|
-
delete childEnv.OPENAI_API_KEY;
|
|
369
|
-
delete childEnv.ANTHROPIC_API_KEY;
|
|
370
|
-
if (llm.openai)
|
|
371
|
-
childEnv.OPENAI_API_KEY = llm.openai;
|
|
372
|
-
if (llm.anthropic)
|
|
373
|
-
childEnv.ANTHROPIC_API_KEY = llm.anthropic;
|
|
374
|
-
const child = spawn(python, [serverPy], {
|
|
375
|
-
cwd: webuiDir,
|
|
376
|
-
env: childEnv,
|
|
377
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
378
|
-
windowsHide: true,
|
|
379
|
-
});
|
|
380
|
-
child.stdout?.on("data", (d) => d
|
|
381
|
-
.toString()
|
|
382
|
-
.split("\n")
|
|
383
|
-
.filter(Boolean)
|
|
384
|
-
.forEach((l) => opts.log(`webui: ${l}`)));
|
|
385
|
-
child.stderr?.on("data", (d) => d
|
|
386
|
-
.toString()
|
|
387
|
-
.split("\n")
|
|
388
|
-
.filter(Boolean)
|
|
389
|
-
.forEach((l) => opts.log(`webui stderr: ${l}`)));
|
|
390
|
-
child.on("exit", (code, signal) => {
|
|
391
|
-
opts.log(`webui exit code=${code} signal=${signal}`);
|
|
392
|
-
if (state.running?.webuiChild === child) {
|
|
393
|
-
state.running.webuiChild = null;
|
|
394
|
-
state.running.webuiUrl = null;
|
|
395
|
-
state.webuiStatus = "stopped";
|
|
396
|
-
}
|
|
397
|
-
});
|
|
398
|
-
// Login endpoint répond 401/400 sans cookie — prouve que le serveur écoute.
|
|
399
|
-
const probe = await waitForHttpOk(`${webuiUrl}/api/auth/login`, {
|
|
400
|
-
timeoutMs: 60000,
|
|
401
|
-
});
|
|
402
|
-
// POST would be needed for real login; GET often 405 — any TCP response = up
|
|
403
|
-
const up = await waitForHttpOk(`${webuiUrl}/`, { timeoutMs: 30000 });
|
|
404
|
-
if (!up.ok && !probe.status) {
|
|
405
|
-
try {
|
|
406
|
-
child.kill();
|
|
407
|
-
}
|
|
408
|
-
catch {
|
|
409
|
-
/* ignore */
|
|
410
|
-
}
|
|
411
|
-
state.webuiStatus = "error";
|
|
412
|
-
state.webuiError = "WebUI health timeout";
|
|
413
|
-
opts.log(state.webuiError);
|
|
414
|
-
return null;
|
|
415
|
-
}
|
|
416
|
-
state.webuiStatus = "running";
|
|
417
|
-
state.webuiError = null;
|
|
418
|
-
opts.log(`WebUI ready ${webuiUrl}`);
|
|
419
|
-
return { child, webuiUrl };
|
|
420
|
-
}
|
|
421
|
-
/**
|
|
422
|
-
* Démarre Hermes si applicable. Retourne null sans throw si skip / missing / erreur.
|
|
423
|
-
*/
|
|
424
|
-
async function startHermesImpl(opts) {
|
|
425
|
-
const hermesConfig = sanitizeHermesEmbedConfig(opts.hermesConfig ?? store.getHermesEmbedConfig());
|
|
426
|
-
if (!shouldSpawnEmbeddedHermes({
|
|
427
|
-
connectionMode: opts.connectionMode,
|
|
428
|
-
hermes: hermesConfig,
|
|
429
|
-
})) {
|
|
430
|
-
pushLog(opts.connectionMode === "remote"
|
|
431
|
-
? "skip spawn (client distant)"
|
|
432
|
-
: `skip spawn (mode=${hermesConfig.mode})`);
|
|
433
|
-
state.webuiStatus = "skipped";
|
|
434
|
-
return null;
|
|
435
|
-
}
|
|
436
|
-
if (hermesConfig.mode === "remote") {
|
|
437
|
-
pushLog(`mode remote → ${hermesConfig.remoteApiUrl || "(url manquante)"}`);
|
|
438
|
-
state.webuiStatus = "skipped";
|
|
439
|
-
return null;
|
|
440
|
-
}
|
|
441
|
-
const log = (line) => {
|
|
442
|
-
pushLog(line);
|
|
443
|
-
opts.onLog?.(line);
|
|
444
|
-
};
|
|
445
|
-
let bin = findHermesBinary();
|
|
446
|
-
// Honnêteté splash + télémétrie : distinguer installation réelle vs runtime
|
|
447
|
-
// déjà présent réutilisé (ex. userData non purgé par une désinstallation).
|
|
448
|
-
state.lastStartPath = bin ? "reuse" : "bootstrap";
|
|
449
|
-
if (!bin && opts.autoBootstrap !== false) {
|
|
450
|
-
state.installing = true;
|
|
451
|
-
log("runtime manquant — bootstrap automatique…");
|
|
452
|
-
try {
|
|
453
|
-
const boot = await ensureHermesRuntime(ctx, { onLog: log });
|
|
454
|
-
log(boot.detail);
|
|
455
|
-
bin = boot.binary || findHermesBinary();
|
|
456
|
-
if (!boot.ok && !bin) {
|
|
457
|
-
state.lastError = boot.detail;
|
|
458
|
-
state.installing = false;
|
|
459
|
-
return null;
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
finally {
|
|
463
|
-
state.installing = false;
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
else if (bin && opts.autoBootstrap !== false) {
|
|
467
|
-
// CLI déjà là : assurer quand même WebUI (léger si pin présent)
|
|
468
|
-
const agentDir = resolveHermesAgentDir(ctx);
|
|
469
|
-
const python = resolveHermesPython(agentDir);
|
|
470
|
-
if (python) {
|
|
471
|
-
state.installing = true;
|
|
472
|
-
try {
|
|
473
|
-
const w = await ensureHermesWebuiTree(ctx, { onLog: log });
|
|
474
|
-
if (!w.ok)
|
|
475
|
-
log(`WebUI bootstrap: ${w.detail}`);
|
|
476
|
-
}
|
|
477
|
-
finally {
|
|
478
|
-
state.installing = false;
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
if (!bin) {
|
|
483
|
-
state.lastError = "CLI Hermes introuvable (sandbox userData / bootstrap)";
|
|
484
|
-
log(state.lastError);
|
|
485
|
-
state.webuiStatus = "missing";
|
|
486
|
-
return null;
|
|
487
|
-
}
|
|
488
|
-
try {
|
|
489
|
-
const home = homeDir();
|
|
490
|
-
const apiPort = await findFreePort(HERMES_DESKTOP_API_PORT);
|
|
491
|
-
// Clé API gateway générée/silencieuse (Bearer Work) — jamais de prompt UI.
|
|
492
|
-
const apiKey = ensureApiKey(home);
|
|
493
|
-
clearGeneratedWebuiPassword(home, path.join(ctx.userDataDir, "hermes-webui-state"), ctx.secretFilePrefix || ctx.manifest.brandId);
|
|
494
|
-
const sand = await writeHermesHome({
|
|
495
|
-
home,
|
|
496
|
-
apiKey,
|
|
497
|
-
apiPort,
|
|
498
|
-
crmPort: opts.crmPort,
|
|
499
|
-
});
|
|
500
|
-
const apiUrl = `http://127.0.0.1:${apiPort}`;
|
|
501
|
-
log(`spawn ${bin} gateway run (home=${home}, workspace=${sand.workspace}, api=${apiUrl})`);
|
|
502
|
-
const bridgeEnv = (ctx.getHermesBridgeEnv?.(opts.crmPort != null ? { crmPort: opts.crmPort } : undefined) || {});
|
|
503
|
-
// BYOK TempoFlow → process Hermes (en plus du .env écrit par writeHermesHome).
|
|
504
|
-
const llm = store.getLlmKeys();
|
|
505
|
-
const productEnv = {
|
|
506
|
-
HERMES_HOME: home,
|
|
507
|
-
API_SERVER_ENABLED: "true",
|
|
508
|
-
API_SERVER_KEY: apiKey,
|
|
509
|
-
API_SERVER_PORT: String(apiPort),
|
|
510
|
-
API_SERVER_HOST: "127.0.0.1",
|
|
511
|
-
TERMINAL_CWD: sand.workspace,
|
|
512
|
-
PYTHONUNBUFFERED: "1",
|
|
513
|
-
...bridgeEnv,
|
|
514
|
-
};
|
|
515
|
-
if (llm.openai)
|
|
516
|
-
productEnv.OPENAI_API_KEY = llm.openai;
|
|
517
|
-
if (llm.anthropic)
|
|
518
|
-
productEnv.ANTHROPIC_API_KEY = llm.anthropic;
|
|
519
|
-
const mergedUser = mergeEmbedUserEnv({
|
|
520
|
-
service: "hermes",
|
|
521
|
-
systemEnv: productEnv,
|
|
522
|
-
userOverlay: store.getEmbedUserEnv("hermes"),
|
|
523
|
-
});
|
|
524
|
-
const gatewayEnv = applyOsSandboxEnv({
|
|
525
|
-
env: {
|
|
526
|
-
...process.env,
|
|
527
|
-
...mergedUser,
|
|
528
|
-
...productEnv,
|
|
529
|
-
},
|
|
530
|
-
profileHome: sand.profileHome,
|
|
531
|
-
userData: ctx.userDataDir,
|
|
532
|
-
// PATH confiné : CLI Hermes (venv) + Node/git TempoFlow + System32.
|
|
533
|
-
// Le terminal de l'agent ne résout AUCUN outil du PC hôte.
|
|
534
|
-
toolDirs: hermesToolPathDirs(path.dirname(bin)),
|
|
535
|
-
});
|
|
536
|
-
delete gatewayEnv.HERMES_WEBUI_PASSWORD;
|
|
537
|
-
// Ne jamais laisser une clé vide / héritée écraser le BYOK TempoFlow.
|
|
538
|
-
delete gatewayEnv.OPENAI_API_KEY;
|
|
539
|
-
delete gatewayEnv.ANTHROPIC_API_KEY;
|
|
540
|
-
if (llm.openai)
|
|
541
|
-
gatewayEnv.OPENAI_API_KEY = llm.openai;
|
|
542
|
-
if (llm.anthropic)
|
|
543
|
-
gatewayEnv.ANTHROPIC_API_KEY = llm.anthropic;
|
|
544
|
-
const child = spawn(bin, ["gateway", "run", "--accept-hooks"], {
|
|
545
|
-
cwd: sand.workspace,
|
|
546
|
-
env: gatewayEnv,
|
|
547
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
548
|
-
windowsHide: true,
|
|
549
|
-
});
|
|
550
|
-
const errTail = [];
|
|
551
|
-
child.stdout?.on("data", (d) => d
|
|
552
|
-
.toString()
|
|
553
|
-
.split("\n")
|
|
554
|
-
.filter(Boolean)
|
|
555
|
-
.forEach((l) => log(l)));
|
|
556
|
-
child.stderr?.on("data", (d) => d
|
|
557
|
-
.toString()
|
|
558
|
-
.split("\n")
|
|
559
|
-
.filter(Boolean)
|
|
560
|
-
.forEach((l) => {
|
|
561
|
-
errTail.push(l);
|
|
562
|
-
if (errTail.length > 30)
|
|
563
|
-
errTail.shift();
|
|
564
|
-
log(`stderr: ${l}`);
|
|
565
|
-
}));
|
|
566
|
-
const spawnErr = { current: null };
|
|
567
|
-
child.on("error", (e) => {
|
|
568
|
-
spawnErr.current = e;
|
|
569
|
-
log(`spawn error: ${e.message}`);
|
|
570
|
-
});
|
|
571
|
-
child.on("exit", (code, signal) => {
|
|
572
|
-
log(`exit code=${code} signal=${signal}`);
|
|
573
|
-
if (state.running?.child === child) {
|
|
574
|
-
state.running = null;
|
|
575
|
-
}
|
|
576
|
-
});
|
|
577
|
-
const health = await waitForHermesHealth(apiUrl, apiKey);
|
|
578
|
-
if (!health.ok) {
|
|
579
|
-
try {
|
|
580
|
-
child.kill();
|
|
581
|
-
}
|
|
582
|
-
catch {
|
|
583
|
-
/* ignore */
|
|
584
|
-
}
|
|
585
|
-
state.lastError =
|
|
586
|
-
spawnErr.current?.message ||
|
|
587
|
-
health.detail ||
|
|
588
|
-
(errTail.length ? errTail.slice(-5).join(" | ") : "démarrage Hermes échoué");
|
|
589
|
-
log(`échec health: ${state.lastError}`);
|
|
590
|
-
return null;
|
|
591
|
-
}
|
|
592
|
-
let webuiChild = null;
|
|
593
|
-
let webuiUrl = hermesConfig.remoteWebuiUrl || null;
|
|
594
|
-
const webui = await spawnWebui({
|
|
595
|
-
apiUrl,
|
|
596
|
-
apiKey,
|
|
597
|
-
home,
|
|
598
|
-
log,
|
|
599
|
-
});
|
|
600
|
-
if (webui) {
|
|
601
|
-
webuiChild = webui.child;
|
|
602
|
-
webuiUrl = webui.webuiUrl;
|
|
603
|
-
}
|
|
604
|
-
state.version = health.version;
|
|
605
|
-
state.lastError = null;
|
|
606
|
-
const running = {
|
|
607
|
-
apiUrl,
|
|
608
|
-
apiKey,
|
|
609
|
-
webuiUrl,
|
|
610
|
-
// Embedded loopback : pas de password WebUI (auth off) — évite le prompt.
|
|
611
|
-
webuiPassword: null,
|
|
612
|
-
homeDir: home,
|
|
613
|
-
child,
|
|
614
|
-
webuiChild,
|
|
615
|
-
stop: () => {
|
|
616
|
-
if (webuiChild) {
|
|
617
|
-
try {
|
|
618
|
-
webuiChild.kill();
|
|
619
|
-
}
|
|
620
|
-
catch {
|
|
621
|
-
/* already dead */
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
try {
|
|
625
|
-
child.kill();
|
|
626
|
-
}
|
|
627
|
-
catch {
|
|
628
|
-
/* already dead */
|
|
629
|
-
}
|
|
630
|
-
},
|
|
631
|
-
};
|
|
632
|
-
state.running = running;
|
|
633
|
-
log(`ready v${health.version || "?"} ${apiUrl}${webuiUrl ? ` webui=${webuiUrl}` : ""}`);
|
|
634
|
-
return running;
|
|
635
|
-
}
|
|
636
|
-
catch (e) {
|
|
637
|
-
state.lastError = e instanceof Error ? e.message : String(e);
|
|
638
|
-
log(`exception: ${state.lastError}`);
|
|
639
|
-
return null;
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
/**
|
|
643
|
-
* Démarrage sérialisé : un clic UI ou une propagation de configuration ne
|
|
644
|
-
* peuvent plus lancer deux gateways/WebUI en parallèle.
|
|
645
|
-
*/
|
|
646
|
-
function startHermes(opts) {
|
|
647
|
-
if (state.running)
|
|
648
|
-
return Promise.resolve(state.running);
|
|
649
|
-
if (startInFlight)
|
|
650
|
-
return startInFlight;
|
|
651
|
-
state.starting = true;
|
|
652
|
-
state.lastError = null;
|
|
653
|
-
state.webuiError = null;
|
|
654
|
-
const pending = startHermesImpl(opts).finally(() => {
|
|
655
|
-
state.starting = false;
|
|
656
|
-
if (startInFlight === pending)
|
|
657
|
-
startInFlight = null;
|
|
658
|
-
});
|
|
659
|
-
startInFlight = pending;
|
|
660
|
-
return pending;
|
|
661
|
-
}
|
|
662
|
-
function stopHermes() {
|
|
663
|
-
if (state.running) {
|
|
664
|
-
pushLog("stop");
|
|
665
|
-
state.running.stop();
|
|
666
|
-
state.running = null;
|
|
667
|
-
}
|
|
668
|
-
state.webuiStatus = state.webuiStatus === "skipped" ? "skipped" : "stopped";
|
|
669
|
-
}
|
|
670
|
-
function waitForChildExit(child, timeoutMs) {
|
|
671
|
-
if (child.exitCode !== null || child.signalCode !== null)
|
|
672
|
-
return Promise.resolve();
|
|
673
|
-
return new Promise((resolve) => {
|
|
674
|
-
let settled = false;
|
|
675
|
-
const done = () => {
|
|
676
|
-
if (settled)
|
|
677
|
-
return;
|
|
678
|
-
settled = true;
|
|
679
|
-
clearTimeout(timer);
|
|
680
|
-
child.removeListener("exit", done);
|
|
681
|
-
child.removeListener("close", done);
|
|
682
|
-
resolve();
|
|
683
|
-
};
|
|
684
|
-
const timer = setTimeout(done, timeoutMs);
|
|
685
|
-
child.once("exit", done);
|
|
686
|
-
child.once("close", done);
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
/**
|
|
690
|
-
* Arrêt utilisé avant un respawn. Attendre la libération des ports évite que
|
|
691
|
-
* le second boot choisisse un autre port pendant que l'ancien process sort.
|
|
692
|
-
*/
|
|
693
|
-
async function stopHermesAndWait(timeoutMs = 5000) {
|
|
694
|
-
const running = state.running;
|
|
695
|
-
if (!running)
|
|
696
|
-
return;
|
|
697
|
-
const children = [running.webuiChild, running.child].filter((child) => Boolean(child));
|
|
698
|
-
stopHermes();
|
|
699
|
-
await Promise.all(children.map((child) => waitForChildExit(child, timeoutMs)));
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Propage les clés BYOK TempoFlow → Hermes (.env + process).
|
|
703
|
-
* Appelé après Configuration → Clés IA (sinon seul Next redémarrait).
|
|
704
|
-
*/
|
|
705
|
-
async function reapplyHermesLlmKeys(opts) {
|
|
706
|
-
const log = (line) => {
|
|
707
|
-
pushLog(line);
|
|
708
|
-
opts.onLog?.(line);
|
|
709
|
-
};
|
|
710
|
-
if (opts.connectionMode !== "local") {
|
|
711
|
-
return { restarted: false, detail: "client distant — pas de Hermes local" };
|
|
712
|
-
}
|
|
713
|
-
if (!state.running) {
|
|
714
|
-
return {
|
|
715
|
-
restarted: false,
|
|
716
|
-
detail: "Hermes non démarré — clés prises au prochain boot",
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
const llm = store.getLlmKeys();
|
|
720
|
-
log(`BYOK → redémarrage Hermes (openai=${llm.openai ? "oui" : "non"}, anthropic=${llm.anthropic ? "oui" : "non"})`);
|
|
721
|
-
await stopHermesAndWait();
|
|
722
|
-
const started = await startHermes({
|
|
723
|
-
connectionMode: opts.connectionMode,
|
|
724
|
-
autoBootstrap: false,
|
|
725
|
-
crmPort: opts.crmPort,
|
|
726
|
-
onLog: opts.onLog,
|
|
727
|
-
});
|
|
728
|
-
return {
|
|
729
|
-
restarted: Boolean(started),
|
|
730
|
-
detail: started
|
|
731
|
-
? "Hermes redémarré avec clés BYOK TempoFlow"
|
|
732
|
-
: "échec restart Hermes après BYOK",
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
/**
|
|
736
|
-
* Réinjecte bridge n8n (+ CRM si crmPort) dans Hermes si manquant dans .env.
|
|
737
|
-
* Warm boot / déjà injecté → no-op.
|
|
738
|
-
*/
|
|
739
|
-
async function reapplyHermesBridge(opts) {
|
|
740
|
-
const log = (line) => {
|
|
741
|
-
pushLog(line);
|
|
742
|
-
opts.onLog?.(line);
|
|
743
|
-
};
|
|
744
|
-
const bridge = (ctx.getHermesBridgeEnv?.(opts.crmPort != null ? { crmPort: opts.crmPort } : undefined) || {});
|
|
745
|
-
if (!state.running) {
|
|
746
|
-
return { restarted: false, detail: "Hermes non démarré" };
|
|
747
|
-
}
|
|
748
|
-
const envPath = path.join(homeDir(), ".env");
|
|
749
|
-
let envBody = "";
|
|
750
|
-
try {
|
|
751
|
-
envBody = fs.readFileSync(envPath, "utf8");
|
|
752
|
-
}
|
|
753
|
-
catch {
|
|
754
|
-
envBody = "";
|
|
755
|
-
}
|
|
756
|
-
const missing = [];
|
|
757
|
-
if (bridge.N8N_API_KEY && !envBody.includes(`N8N_API_KEY=${bridge.N8N_API_KEY}`)) {
|
|
758
|
-
missing.push("N8N_API_KEY");
|
|
759
|
-
}
|
|
760
|
-
if (bridge.TEMPOFLOW_API_KEY &&
|
|
761
|
-
!envBody.includes(`TEMPOFLOW_API_KEY=${bridge.TEMPOFLOW_API_KEY}`)) {
|
|
762
|
-
missing.push("TEMPOFLOW_API_KEY");
|
|
763
|
-
}
|
|
764
|
-
if (bridge.TEMPOFLOW_API_URL &&
|
|
765
|
-
!envBody.includes(`TEMPOFLOW_API_URL=${bridge.TEMPOFLOW_API_URL}`)) {
|
|
766
|
-
missing.push("TEMPOFLOW_API_URL");
|
|
767
|
-
}
|
|
768
|
-
if (bridge.PLUGINS_API_URL &&
|
|
769
|
-
!envBody.includes(`PLUGINS_API_URL=${bridge.PLUGINS_API_URL}`)) {
|
|
770
|
-
missing.push("PLUGINS_API_URL");
|
|
771
|
-
}
|
|
772
|
-
if (bridge.TEMPOFLOW_PLUGINS_API_TOKEN &&
|
|
773
|
-
!envBody.includes(`TEMPOFLOW_PLUGINS_API_TOKEN=${bridge.TEMPOFLOW_PLUGINS_API_TOKEN}`)) {
|
|
774
|
-
missing.push("TEMPOFLOW_PLUGINS_API_TOKEN");
|
|
775
|
-
}
|
|
776
|
-
if (bridge.TEMPOFLOW_PLUGINS_DIR &&
|
|
777
|
-
!envBody.includes(`TEMPOFLOW_PLUGINS_DIR=${bridge.TEMPOFLOW_PLUGINS_DIR}`)) {
|
|
778
|
-
missing.push("TEMPOFLOW_PLUGINS_DIR");
|
|
779
|
-
}
|
|
780
|
-
// H1 — bloc mcp_servers attendu dans config.yaml (façade MCP CRM) : s'il
|
|
781
|
-
// manque ou pointe ailleurs, un restart réécrit le home (writeHermesHome).
|
|
782
|
-
const mcpCfg = ctx.getHermesMcpServerConfig?.(opts.crmPort != null ? { crmPort: opts.crmPort } : undefined) || null;
|
|
783
|
-
if (mcpCfg) {
|
|
784
|
-
let cfgBody = "";
|
|
785
|
-
try {
|
|
786
|
-
cfgBody = fs.readFileSync(path.join(homeDir(), "config.yaml"), "utf8");
|
|
787
|
-
}
|
|
788
|
-
catch {
|
|
789
|
-
cfgBody = "";
|
|
790
|
-
}
|
|
791
|
-
if (!cfgBody.includes("mcp_servers") ||
|
|
792
|
-
!cfgBody.includes(mcpCfg.url) ||
|
|
793
|
-
!cfgBody.includes(mcpCfg.bearerToken)) {
|
|
794
|
-
missing.push("MCP_SERVERS");
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
if (!missing.length && !opts.forceRestart) {
|
|
798
|
-
return { restarted: false, detail: "bridge déjà injecté" };
|
|
799
|
-
}
|
|
800
|
-
const why = opts.forceRestart
|
|
801
|
-
? opts.forceReason || "force"
|
|
802
|
-
: missing.join(", ");
|
|
803
|
-
log(`bridge → redémarrage Hermes (${why})`);
|
|
804
|
-
await stopHermesAndWait();
|
|
805
|
-
const started = await startHermes({
|
|
806
|
-
connectionMode: opts.connectionMode,
|
|
807
|
-
autoBootstrap: false,
|
|
808
|
-
crmPort: opts.crmPort,
|
|
809
|
-
onLog: opts.onLog,
|
|
810
|
-
});
|
|
811
|
-
return {
|
|
812
|
-
restarted: Boolean(started),
|
|
813
|
-
detail: started
|
|
814
|
-
? `Hermes redémarré (${why})`
|
|
815
|
-
: "échec restart Hermes après bridge",
|
|
816
|
-
};
|
|
817
|
-
}
|
|
818
|
-
function getRunningHermes() {
|
|
819
|
-
return state.running;
|
|
820
|
-
}
|
|
821
|
-
/**
|
|
822
|
-
* Env à fusionner dans startNextServer / restart.
|
|
823
|
-
* Couvre embedded running + mode remote avancé (URL stockée).
|
|
824
|
-
*/
|
|
825
|
-
function getHermesNextEnv(connectionMode) {
|
|
826
|
-
if (connectionMode !== "local")
|
|
827
|
-
return {};
|
|
828
|
-
const config = sanitizeHermesEmbedConfig(store.getHermesEmbedConfig());
|
|
829
|
-
const running = state.running;
|
|
830
|
-
if (running) {
|
|
831
|
-
return buildNextHermesEnv({
|
|
832
|
-
apiUrl: running.apiUrl,
|
|
833
|
-
apiKey: running.apiKey,
|
|
834
|
-
webuiUrl: running.webuiUrl,
|
|
835
|
-
webuiPassword: running.webuiPassword,
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
if (config.mode === "remote" && config.remoteApiUrl) {
|
|
839
|
-
const key = (process.env.HERMES_API_SERVER_KEY ||
|
|
840
|
-
process.env.TF2_HERMES_REMOTE_KEY ||
|
|
841
|
-
"").trim();
|
|
842
|
-
if (!key)
|
|
843
|
-
return {};
|
|
844
|
-
return buildNextHermesEnv({
|
|
845
|
-
apiUrl: config.remoteApiUrl,
|
|
846
|
-
apiKey: key,
|
|
847
|
-
webuiUrl: config.remoteWebuiUrl,
|
|
848
|
-
webuiPassword: (process.env.HERMES_WEBUI_PASSWORD || "").trim() || null,
|
|
849
|
-
});
|
|
850
|
-
}
|
|
851
|
-
return {
|
|
852
|
-
HERMES_API_URL: `http://127.0.0.1:${HERMES_DESKTOP_API_PORT}`,
|
|
853
|
-
HERMES_GATEWAY_URL: `http://127.0.0.1:${HERMES_DESKTOP_API_PORT}`,
|
|
854
|
-
HERMES_WEBUI_URL: `http://127.0.0.1:${HERMES_DESKTOP_WEBUI_PORT}`,
|
|
855
|
-
HERMES_KANBAN_URL: `http://127.0.0.1:${HERMES_DESKTOP_WEBUI_PORT}`,
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
function getHermesStatusPayload(connectionMode, opts) {
|
|
859
|
-
const config = sanitizeHermesEmbedConfig(store.getHermesEmbedConfig());
|
|
860
|
-
const binary = state.binaryPath || findHermesBinary();
|
|
861
|
-
let pub = hermesPublicStatus({
|
|
862
|
-
connectionMode,
|
|
863
|
-
config,
|
|
864
|
-
binaryFound: Boolean(binary),
|
|
865
|
-
running: Boolean(state.running),
|
|
866
|
-
apiUrl: state.running?.apiUrl || config.remoteApiUrl || null,
|
|
867
|
-
lastError: state.lastError,
|
|
868
|
-
version: state.version,
|
|
869
|
-
remoteCrmOrigin: opts?.remoteCrmOrigin,
|
|
870
|
-
tunnelRootDomain: ctx.manifest.tunnelRootDomain,
|
|
871
|
-
tunnelHostMode: (() => {
|
|
872
|
-
const env = String(process.env.CREEZIO_TUNNEL_FLAT_HOSTS || "").trim();
|
|
873
|
-
if (env === "1" || /^true$/i.test(env))
|
|
874
|
-
return "flat";
|
|
875
|
-
if (env === "0" || /^false$/i.test(env))
|
|
876
|
-
return "nested";
|
|
877
|
-
return ctx.manifest.tunnelHostMode;
|
|
878
|
-
})(),
|
|
879
|
-
productName: product(),
|
|
880
|
-
});
|
|
881
|
-
if (state.installing && pub.status === "missing") {
|
|
882
|
-
pub = {
|
|
883
|
-
...pub,
|
|
884
|
-
status: "installing",
|
|
885
|
-
detail: `Installation runtime en cours (${getBootstrapPhase()})…`,
|
|
886
|
-
};
|
|
887
|
-
}
|
|
888
|
-
if (state.starting && pub.status !== "running") {
|
|
889
|
-
pub = {
|
|
890
|
-
...pub,
|
|
891
|
-
status: "starting",
|
|
892
|
-
detail: "Démarrage du gateway et de la WebUI Hermes…",
|
|
893
|
-
};
|
|
894
|
-
}
|
|
895
|
-
const webuiUrl = connectionMode === "remote"
|
|
896
|
-
? pub.webuiUrl
|
|
897
|
-
: state.running?.webuiUrl || config.remoteWebuiUrl || null;
|
|
898
|
-
return {
|
|
899
|
-
...pub,
|
|
900
|
-
webuiUrl,
|
|
901
|
-
webuiStatus: connectionMode === "remote"
|
|
902
|
-
? webuiUrl
|
|
903
|
-
? "running"
|
|
904
|
-
: "skipped"
|
|
905
|
-
: config.mode === "remote" || config.mode === "off"
|
|
906
|
-
? "skipped"
|
|
907
|
-
: state.webuiStatus,
|
|
908
|
-
binaryPath: binary,
|
|
909
|
-
homeDir: state.running?.homeDir || null,
|
|
910
|
-
bootstrapPhase: getBootstrapPhase(),
|
|
911
|
-
bootstrapError: getBootstrapError() || state.webuiError,
|
|
912
|
-
installing: state.installing,
|
|
913
|
-
logs: state.logs.slice(-80),
|
|
914
|
-
};
|
|
915
|
-
}
|
|
916
|
-
function getHermesLogs() {
|
|
917
|
-
return state.logs.slice(-80);
|
|
918
|
-
}
|
|
919
|
-
/** Déclenché depuis l’UI Configuration (hôte local uniquement). */
|
|
920
|
-
async function ensureHermesRuntimeFromUi(opts) {
|
|
921
|
-
state.installing = true;
|
|
922
|
-
const log = (line) => {
|
|
923
|
-
pushLog(line);
|
|
924
|
-
opts?.onLog?.(line);
|
|
925
|
-
};
|
|
926
|
-
try {
|
|
927
|
-
const r = await ensureHermesRuntime(ctx, { onLog: log });
|
|
928
|
-
return {
|
|
929
|
-
ok: r.ok,
|
|
930
|
-
detail: r.detail,
|
|
931
|
-
binaryPath: r.binary,
|
|
932
|
-
webuiDir: r.webuiDir,
|
|
933
|
-
};
|
|
934
|
-
}
|
|
935
|
-
finally {
|
|
936
|
-
state.installing = false;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
/** Exposé pour tests. */
|
|
940
|
-
function __resetHermesStateForTests() {
|
|
941
|
-
state.running = null;
|
|
942
|
-
state.starting = false;
|
|
943
|
-
state.lastError = null;
|
|
944
|
-
state.version = null;
|
|
945
|
-
state.logs = [];
|
|
946
|
-
state.binaryPath = null;
|
|
947
|
-
state.webuiStatus = "stopped";
|
|
948
|
-
state.webuiError = null;
|
|
949
|
-
state.installing = false;
|
|
950
|
-
startInFlight = null;
|
|
951
|
-
}
|
|
952
|
-
// --- end inlined ---
|
|
953
|
-
return {
|
|
954
|
-
startHermes,
|
|
955
|
-
stopHermes,
|
|
956
|
-
stopHermesAndWait,
|
|
957
|
-
getRunningHermes,
|
|
958
|
-
getHermesStatusPayload,
|
|
959
|
-
getHermesNextEnv,
|
|
960
|
-
getHermesLogs,
|
|
961
|
-
ensureHermesRuntimeFromUi: async (uiOpts) => {
|
|
962
|
-
const r = await ensureHermesRuntimeFromUi(uiOpts);
|
|
963
|
-
return { ...r, phase: getBootstrapPhase() };
|
|
964
|
-
},
|
|
965
|
-
findHermesBinary,
|
|
966
|
-
getHermesLastStartPath,
|
|
967
|
-
reapplyHermesLlmKeys,
|
|
968
|
-
reapplyHermesBridge,
|
|
969
|
-
__resetForTests: __resetHermesStateForTests,
|
|
970
|
-
};
|
|
971
|
-
}
|
|
972
|
-
//# sourceMappingURL=launcher.js.map
|