@camstack/core 0.1.15 → 0.1.16
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/dist/addon/addon-api-factory.d.ts +36 -0
- package/dist/addon/addon-api-factory.d.ts.map +1 -0
- package/dist/addon-routes/addon-route-registry.d.ts +38 -0
- package/dist/addon-routes/addon-route-registry.d.ts.map +1 -0
- package/dist/auth/api-key-manager.d.ts +27 -0
- package/dist/auth/api-key-manager.d.ts.map +1 -0
- package/dist/auth/auth-manager.d.ts +47 -0
- package/dist/auth/auth-manager.d.ts.map +1 -0
- package/dist/auth/parse-record.d.ts +19 -0
- package/dist/auth/parse-record.d.ts.map +1 -0
- package/dist/auth/scoped-token-manager.d.ts +18 -0
- package/dist/auth/scoped-token-manager.d.ts.map +1 -0
- package/dist/auth/user-manager.d.ts +34 -0
- package/dist/auth/user-manager.d.ts.map +1 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +54 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts.map +1 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +223 -217
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js.map +1 -1
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +216 -7
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs.map +1 -1
- package/dist/builtins/addon-pages-aggregator/index.d.ts +2 -0
- package/dist/builtins/addon-pages-aggregator/index.d.ts.map +1 -0
- package/dist/builtins/addon-pages-aggregator/index.js +6 -221
- package/dist/builtins/addon-pages-aggregator/index.mjs +2 -9
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +33 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts.map +1 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +199 -197
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js.map +1 -1
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +192 -7
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs.map +1 -1
- package/dist/builtins/addon-widgets-aggregator/index.d.ts +2 -0
- package/dist/builtins/addon-widgets-aggregator/index.d.ts.map +1 -0
- package/dist/builtins/addon-widgets-aggregator/index.js +6 -201
- package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -9
- package/dist/builtins/alerts/alerts.addon.d.ts +82 -0
- package/dist/builtins/alerts/alerts.addon.d.ts.map +1 -0
- package/dist/builtins/alerts/alerts.addon.js +590 -430
- package/dist/builtins/alerts/alerts.addon.js.map +1 -1
- package/dist/builtins/alerts/alerts.addon.mjs +595 -7
- package/dist/builtins/alerts/alerts.addon.mjs.map +1 -1
- package/dist/builtins/alerts/index.d.ts +2 -0
- package/dist/builtins/alerts/index.d.ts.map +1 -0
- package/dist/builtins/alerts/index.js +3 -443
- package/dist/builtins/alerts/index.mjs +2 -8
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts +8 -0
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js +56 -0
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.js.map +1 -0
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs +50 -0
- package/dist/builtins/auth-orchestrator/auth-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/auth-orchestrator/index.d.ts +2 -0
- package/dist/builtins/auth-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/auth-orchestrator/index.js +7 -0
- package/dist/builtins/auth-orchestrator/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +148 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +7639 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js.map +1 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +7627 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +24 -0
- package/dist/builtins/backup-orchestrator/cron-helpers.d.ts.map +1 -0
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +73 -0
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts.map +1 -0
- package/dist/builtins/backup-orchestrator/download-helpers.d.ts +13 -0
- package/dist/builtins/backup-orchestrator/download-helpers.d.ts.map +1 -0
- package/dist/builtins/backup-orchestrator/index.d.ts +3 -0
- package/dist/builtins/backup-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/backup-orchestrator/index.js +7 -0
- package/dist/builtins/backup-orchestrator/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts +78 -0
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts.map +1 -0
- package/dist/builtins/console-logging/console-destination.d.ts +14 -0
- package/dist/builtins/console-logging/console-destination.d.ts.map +1 -0
- package/dist/builtins/console-logging/console-logging.addon.d.ts +26 -0
- package/dist/builtins/console-logging/console-logging.addon.d.ts.map +1 -0
- package/dist/builtins/console-logging/index.d.ts +4 -0
- package/dist/builtins/console-logging/index.d.ts.map +1 -0
- package/dist/builtins/console-logging/index.js +99 -235
- package/dist/builtins/console-logging/index.js.map +1 -1
- package/dist/builtins/console-logging/index.mjs +95 -9
- package/dist/builtins/console-logging/index.mjs.map +1 -1
- package/dist/builtins/device-manager/device-event-propagator.d.ts +27 -0
- package/dist/builtins/device-manager/device-event-propagator.d.ts.map +1 -0
- package/dist/builtins/device-manager/device-manager.addon.d.ts +259 -0
- package/dist/builtins/device-manager/device-manager.addon.d.ts.map +1 -0
- package/dist/builtins/device-manager/device-manager.addon.js +2125 -2127
- package/dist/builtins/device-manager/device-manager.addon.js.map +1 -1
- package/dist/builtins/device-manager/device-manager.addon.mjs +2145 -7
- package/dist/builtins/device-manager/device-manager.addon.mjs.map +1 -1
- package/dist/builtins/device-manager/index.d.ts +3 -0
- package/dist/builtins/device-manager/index.d.ts.map +1 -0
- package/dist/builtins/device-manager/index.js +6 -2156
- package/dist/builtins/device-manager/index.mjs +2 -10
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +45 -0
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts.map +1 -0
- package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +16 -0
- package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts.map +1 -0
- package/dist/builtins/hub-forwarder/index.d.ts +4 -0
- package/dist/builtins/hub-forwarder/index.d.ts.map +1 -0
- package/dist/builtins/hub-forwarder/index.js +150 -291
- package/dist/builtins/hub-forwarder/index.js.map +1 -1
- package/dist/builtins/hub-forwarder/index.mjs +145 -9
- package/dist/builtins/hub-forwarder/index.mjs.map +1 -1
- package/dist/builtins/local-auth/auth-schema.d.ts +12 -0
- package/dist/builtins/local-auth/auth-schema.d.ts.map +1 -0
- package/dist/builtins/local-auth/index.d.ts +2 -0
- package/dist/builtins/local-auth/index.d.ts.map +1 -0
- package/dist/builtins/local-auth/index.js +3 -623
- package/dist/builtins/local-auth/index.mjs +2 -8
- package/dist/builtins/local-auth/local-auth.addon.d.ts +17 -0
- package/dist/builtins/local-auth/local-auth.addon.d.ts.map +1 -0
- package/dist/builtins/local-auth/local-auth.addon.js +6861 -589
- package/dist/builtins/local-auth/local-auth.addon.js.map +1 -1
- package/dist/builtins/local-auth/local-auth.addon.mjs +6883 -7
- package/dist/builtins/local-auth/local-auth.addon.mjs.map +1 -1
- package/dist/builtins/local-network/index.d.ts +3 -0
- package/dist/builtins/local-network/index.d.ts.map +1 -0
- package/dist/builtins/local-network/index.js +9 -0
- package/dist/builtins/local-network/index.mjs +2 -0
- package/dist/builtins/local-network/local-network.addon.d.ts +102 -0
- package/dist/builtins/local-network/local-network.addon.d.ts.map +1 -0
- package/dist/builtins/local-network/local-network.addon.js +404 -0
- package/dist/builtins/local-network/local-network.addon.js.map +1 -0
- package/dist/builtins/local-network/local-network.addon.mjs +392 -0
- package/dist/builtins/local-network/local-network.addon.mjs.map +1 -0
- package/dist/builtins/mesh-orchestrator/index.d.ts +2 -0
- package/dist/builtins/mesh-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/mesh-orchestrator/index.js +7 -0
- package/dist/builtins/mesh-orchestrator/index.mjs +2 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts +9 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js +83 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.js.map +1 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs +77 -0
- package/dist/builtins/mesh-orchestrator/mesh-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/native-metrics/index.d.ts +3 -0
- package/dist/builtins/native-metrics/index.d.ts.map +1 -0
- package/dist/builtins/native-metrics/native-metrics-provider.d.ts +49 -0
- package/dist/builtins/native-metrics/native-metrics-provider.d.ts.map +1 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts +74 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts.map +1 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +887 -861
- package/dist/builtins/native-metrics/native-metrics.addon.js.map +1 -1
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -5
- package/dist/builtins/native-metrics/native-metrics.addon.mjs.map +1 -1
- package/dist/builtins/platform-probe/index.d.ts +12 -0
- package/dist/builtins/platform-probe/index.d.ts.map +1 -0
- package/dist/builtins/platform-probe/index.js +539 -0
- package/dist/builtins/platform-probe/index.js.map +1 -0
- package/dist/builtins/platform-probe/index.mjs +530 -0
- package/dist/builtins/platform-probe/index.mjs.map +1 -0
- package/dist/builtins/platform-probe/inference-config-resolver.d.ts +30 -0
- package/dist/builtins/platform-probe/inference-config-resolver.d.ts.map +1 -0
- package/dist/builtins/platform-probe/platform-scorer.d.ts +22 -0
- package/dist/builtins/platform-probe/platform-scorer.d.ts.map +1 -0
- package/dist/builtins/remote-access-orchestrator/index.d.ts +2 -0
- package/dist/builtins/remote-access-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/remote-access-orchestrator/index.js +7 -0
- package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +9 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +72 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js.map +1 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +66 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/snapshot/index.d.ts +3 -0
- package/dist/builtins/snapshot/index.d.ts.map +1 -0
- package/dist/builtins/snapshot/index.js +481 -491
- package/dist/builtins/snapshot/index.js.map +1 -1
- package/dist/builtins/snapshot/index.mjs +475 -464
- package/dist/builtins/snapshot/index.mjs.map +1 -1
- package/dist/builtins/snapshot/snapshot.addon.d.ts +121 -0
- package/dist/builtins/snapshot/snapshot.addon.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/config-store.d.ts +9 -0
- package/dist/builtins/sqlite-storage/config-store.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/device-store.d.ts +24 -0
- package/dist/builtins/sqlite-storage/device-store.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +87 -0
- package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +312 -56
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js.map +1 -1
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +305 -7
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs.map +1 -1
- package/dist/builtins/sqlite-storage/index.d.ts +12 -0
- package/dist/builtins/sqlite-storage/index.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/index.js +229 -1001
- package/dist/builtins/sqlite-storage/index.js.map +1 -1
- package/dist/builtins/sqlite-storage/index.mjs +268 -26
- package/dist/builtins/sqlite-storage/index.mjs.map +1 -1
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +28 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/settings-store.d.ts +40 -0
- package/dist/builtins/sqlite-storage/settings-store.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/sql-schema.d.ts +33 -0
- package/dist/builtins/sqlite-storage/sql-schema.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +94 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +15 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts.map +1 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +586 -653
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js.map +1 -1
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +582 -7
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs.map +1 -1
- package/dist/builtins/storage-orchestrator/index.d.ts +7 -0
- package/dist/builtins/storage-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/storage-orchestrator/index.js +9 -0
- package/dist/builtins/storage-orchestrator/index.mjs +2 -0
- package/dist/builtins/storage-orchestrator/location-store.d.ts +50 -0
- package/dist/builtins/storage-orchestrator/location-store.d.ts.map +1 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +60 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +755 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js.map +1 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +746 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +121 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts.map +1 -0
- package/dist/builtins/system-backup/system-backup.service.d.ts +138 -0
- package/dist/builtins/system-backup/system-backup.service.d.ts.map +1 -0
- package/dist/builtins/system-config/index.d.ts +2 -0
- package/dist/builtins/system-config/index.d.ts.map +1 -0
- package/dist/builtins/system-config/index.js +6 -188
- package/dist/builtins/system-config/index.mjs +2 -10
- package/dist/builtins/system-config/system-config.addon.d.ts +11 -0
- package/dist/builtins/system-config/system-config.addon.d.ts.map +1 -0
- package/dist/builtins/system-config/system-config.addon.js +227 -180
- package/dist/builtins/system-config/system-config.addon.js.map +1 -1
- package/dist/builtins/system-config/system-config.addon.mjs +226 -7
- package/dist/builtins/system-config/system-config.addon.mjs.map +1 -1
- package/dist/builtins/turn-orchestrator/index.d.ts +2 -0
- package/dist/builtins/turn-orchestrator/index.d.ts.map +1 -0
- package/dist/builtins/turn-orchestrator/index.js +7 -0
- package/dist/builtins/turn-orchestrator/index.mjs +2 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts +10 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.d.ts.map +1 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js +78 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.js.map +1 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs +72 -0
- package/dist/builtins/turn-orchestrator/turn-orchestrator.addon.mjs.map +1 -0
- package/dist/builtins/winston-logging/index.d.ts +4 -0
- package/dist/builtins/winston-logging/index.d.ts.map +1 -0
- package/dist/builtins/winston-logging/index.js +153 -300
- package/dist/builtins/winston-logging/index.js.map +1 -1
- package/dist/builtins/winston-logging/index.mjs +144 -9
- package/dist/builtins/winston-logging/index.mjs.map +1 -1
- package/dist/builtins/winston-logging/winston-destination.d.ts +22 -0
- package/dist/builtins/winston-logging/winston-destination.d.ts.map +1 -0
- package/dist/builtins/winston-logging/winston-logging.addon.d.ts +20 -0
- package/dist/builtins/winston-logging/winston-logging.addon.d.ts.map +1 -0
- package/dist/chunk-C13QxCFV.js +50 -0
- package/dist/chunk-hT5z_Zn9.mjs +35 -0
- package/dist/download/model-download-service.d.ts +42 -0
- package/dist/download/model-download-service.d.ts.map +1 -0
- package/dist/download/model-downloader.d.ts +32 -0
- package/dist/download/model-downloader.d.ts.map +1 -0
- package/dist/events/event-bus.d.ts +11 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/system-event-bus.d.ts +15 -0
- package/dist/events/system-event-bus.d.ts.map +1 -0
- package/dist/feature/feature-manager.d.ts +12 -0
- package/dist/feature/feature-manager.d.ts.map +1 -0
- package/dist/formatter-C-5An4Bl.mjs +164 -0
- package/dist/formatter-C-5An4Bl.mjs.map +1 -0
- package/dist/formatter-Dr_6NNZc.js +169 -0
- package/dist/formatter-Dr_6NNZc.js.map +1 -0
- package/dist/index.d.ts +76 -1696
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7780 -8035
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +7707 -2148
- package/dist/index.mjs.map +1 -1
- package/dist/lifecycle/lifecycle-state-machine.d.ts +29 -0
- package/dist/lifecycle/lifecycle-state-machine.d.ts.map +1 -0
- package/dist/logging/formatter.d.ts +31 -0
- package/dist/logging/formatter.d.ts.map +1 -0
- package/dist/logging/log-manager.d.ts +52 -0
- package/dist/logging/log-manager.d.ts.map +1 -0
- package/dist/logging/log-ring-buffer.d.ts +48 -0
- package/dist/logging/log-ring-buffer.d.ts.map +1 -0
- package/dist/logging/scoped-logger.d.ts +18 -0
- package/dist/logging/scoped-logger.d.ts.map +1 -0
- package/dist/network/network-quality.d.ts +12 -0
- package/dist/network/network-quality.d.ts.map +1 -0
- package/dist/notification/notification-service.d.ts +38 -0
- package/dist/notification/notification-service.d.ts.map +1 -0
- package/dist/notification/toast-service.d.ts +23 -0
- package/dist/notification/toast-service.d.ts.map +1 -0
- package/dist/pipeline/engine-manager-resolver.d.ts +16 -0
- package/dist/pipeline/engine-manager-resolver.d.ts.map +1 -0
- package/dist/pipeline/pipeline-runner.d.ts +9 -0
- package/dist/pipeline/pipeline-runner.d.ts.map +1 -0
- package/dist/pipeline/pipeline-validator.d.ts +14 -0
- package/dist/pipeline/pipeline-validator.d.ts.map +1 -0
- package/dist/process/resource-monitor.d.ts +12 -0
- package/dist/process/resource-monitor.d.ts.map +1 -0
- package/dist/python/python-env-manager.d.ts +13 -0
- package/dist/python/python-env-manager.d.ts.map +1 -0
- package/dist/repl/interfaces.d.ts +32 -0
- package/dist/repl/interfaces.d.ts.map +1 -0
- package/dist/repl/repl-engine.d.ts +9 -0
- package/dist/repl/repl-engine.d.ts.map +1 -0
- package/dist/resource-monitor-CmuWlmap.js +76 -0
- package/dist/resource-monitor-CmuWlmap.js.map +1 -0
- package/dist/resource-monitor-DcQdKGYU.mjs +59 -0
- package/dist/resource-monitor-DcQdKGYU.mjs.map +1 -0
- package/dist/storage/fs-storage-backend.d.ts +41 -0
- package/dist/storage/fs-storage-backend.d.ts.map +1 -0
- package/dist/storage/storage-location-manager.d.ts +24 -0
- package/dist/storage/storage-location-manager.d.ts.map +1 -0
- package/dist/storage/storage-manager.d.ts +77 -0
- package/dist/storage/storage-manager.d.ts.map +1 -0
- package/dist/tls/cert-manager.d.ts +27 -0
- package/dist/tls/cert-manager.d.ts.map +1 -0
- package/dist/tls/index.d.ts +2 -0
- package/dist/tls/index.d.ts.map +1 -0
- package/package.json +119 -23
- package/dist/builtins/addon-pages-aggregator/index.js.map +0 -1
- package/dist/builtins/addon-pages-aggregator/index.mjs.map +0 -1
- package/dist/builtins/addon-widgets-aggregator/index.js.map +0 -1
- package/dist/builtins/addon-widgets-aggregator/index.mjs.map +0 -1
- package/dist/builtins/alerts/index.js.map +0 -1
- package/dist/builtins/alerts/index.mjs.map +0 -1
- package/dist/builtins/device-manager/index.js.map +0 -1
- package/dist/builtins/device-manager/index.mjs.map +0 -1
- package/dist/builtins/local-auth/index.js.map +0 -1
- package/dist/builtins/local-auth/index.mjs.map +0 -1
- package/dist/builtins/local-backup/index.js +0 -173
- package/dist/builtins/local-backup/index.js.map +0 -1
- package/dist/builtins/local-backup/index.mjs +0 -10
- package/dist/builtins/local-backup/index.mjs.map +0 -1
- package/dist/builtins/system-config/index.js.map +0 -1
- package/dist/builtins/system-config/index.mjs.map +0 -1
- package/dist/chunk-2CIYKDRN.mjs +0 -1
- package/dist/chunk-2CIYKDRN.mjs.map +0 -1
- package/dist/chunk-2F76X6NL.mjs +0 -136
- package/dist/chunk-2F76X6NL.mjs.map +0 -1
- package/dist/chunk-2QUFBZ7M.mjs +0 -1
- package/dist/chunk-2QUFBZ7M.mjs.map +0 -1
- package/dist/chunk-3BK2Y7GY.mjs +0 -593
- package/dist/chunk-3BK2Y7GY.mjs.map +0 -1
- package/dist/chunk-4OOHFJHT.mjs +0 -421
- package/dist/chunk-4OOHFJHT.mjs.map +0 -1
- package/dist/chunk-4XHB7IHT.mjs +0 -809
- package/dist/chunk-4XHB7IHT.mjs.map +0 -1
- package/dist/chunk-6M2HSSTQ.mjs +0 -98
- package/dist/chunk-6M2HSSTQ.mjs.map +0 -1
- package/dist/chunk-7FI7SQS7.mjs +0 -135
- package/dist/chunk-7FI7SQS7.mjs.map +0 -1
- package/dist/chunk-ED57RCQE.mjs +0 -171
- package/dist/chunk-ED57RCQE.mjs.map +0 -1
- package/dist/chunk-FZN56HGQ.mjs +0 -626
- package/dist/chunk-FZN56HGQ.mjs.map +0 -1
- package/dist/chunk-GL4OOB25.mjs +0 -51
- package/dist/chunk-GL4OOB25.mjs.map +0 -1
- package/dist/chunk-KDG2NTDB.mjs +0 -137
- package/dist/chunk-KDG2NTDB.mjs.map +0 -1
- package/dist/chunk-NRBQWBDM.mjs +0 -191
- package/dist/chunk-NRBQWBDM.mjs.map +0 -1
- package/dist/chunk-O4V246GG.mjs +0 -2137
- package/dist/chunk-O4V246GG.mjs.map +0 -1
- package/dist/chunk-QT57H266.mjs +0 -163
- package/dist/chunk-QT57H266.mjs.map +0 -1
- package/dist/chunk-QX4RH25I.mjs +0 -141
- package/dist/chunk-QX4RH25I.mjs.map +0 -1
- package/dist/chunk-TB562PZX.mjs +0 -86
- package/dist/chunk-TB562PZX.mjs.map +0 -1
- package/dist/chunk-TDYPZXK5.mjs +0 -1
- package/dist/chunk-TDYPZXK5.mjs.map +0 -1
- package/dist/chunk-UJI4LN5P.mjs +0 -36
- package/dist/chunk-UJI4LN5P.mjs.map +0 -1
- package/dist/chunk-W6RTHQGP.mjs +0 -1
- package/dist/chunk-W6RTHQGP.mjs.map +0 -1
- package/dist/chunk-ZELBCPDC.mjs +0 -369
- package/dist/chunk-ZELBCPDC.mjs.map +0 -1
- package/dist/index.d.mts +0 -1696
- package/dist/resource-monitor-UZUGPIAU.mjs +0 -9
- package/dist/resource-monitor-UZUGPIAU.mjs.map +0 -1
- package/dist/storage-location-manager-HFNB3PCS.mjs +0 -7
- package/dist/storage-location-manager-HFNB3PCS.mjs.map +0 -1
|
@@ -1,898 +1,924 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __esm = (fn, res) => function __init() {
|
|
9
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
-
};
|
|
11
|
-
var __export = (target, all) => {
|
|
12
|
-
for (var name in all)
|
|
13
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
14
|
-
};
|
|
15
|
-
var __copyProps = (to, from, except, desc) => {
|
|
16
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
17
|
-
for (let key of __getOwnPropNames(from))
|
|
18
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
19
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
-
mod
|
|
30
|
-
));
|
|
31
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
32
|
-
|
|
33
|
-
// src/process/resource-monitor.ts
|
|
34
|
-
var resource_monitor_exports = {};
|
|
35
|
-
__export(resource_monitor_exports, {
|
|
36
|
-
getPidStats: () => getPidStats,
|
|
37
|
-
getSinglePidStats: () => getSinglePidStats
|
|
38
|
-
});
|
|
39
|
-
function execPsForPids(pids) {
|
|
40
|
-
return new Promise((resolve, reject) => {
|
|
41
|
-
(0, import_node_child_process.execFile)("ps", ["-o", "pid=,pcpu=,rss=", "-p", pids.join(",")], {
|
|
42
|
-
timeout: 5e3
|
|
43
|
-
}, (err, stdout) => {
|
|
44
|
-
if (err) return reject(err);
|
|
45
|
-
resolve(stdout);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function parsePsOutput(stdout) {
|
|
50
|
-
const result = /* @__PURE__ */ new Map();
|
|
51
|
-
for (const line of stdout.trim().split("\n")) {
|
|
52
|
-
const trimmed = line.trim();
|
|
53
|
-
if (!trimmed) continue;
|
|
54
|
-
const parts = trimmed.split(/\s+/);
|
|
55
|
-
if (parts.length < 3) continue;
|
|
56
|
-
const pid = parseInt(parts[0], 10);
|
|
57
|
-
const cpu = parseFloat(parts[1]);
|
|
58
|
-
const rssKb = parseInt(parts[2], 10);
|
|
59
|
-
if (isNaN(pid) || isNaN(cpu) || isNaN(rssKb)) continue;
|
|
60
|
-
result.set(pid, {
|
|
61
|
-
cpu: Math.round(cpu * 10) / 10,
|
|
62
|
-
memory: rssKb * 1024
|
|
63
|
-
// KB → bytes
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
async function getPidStats(pids) {
|
|
69
|
-
const pidArray = typeof pids === "number" ? [pids] : [...pids];
|
|
70
|
-
if (pidArray.length === 0) return /* @__PURE__ */ new Map();
|
|
71
|
-
try {
|
|
72
|
-
const stdout = await execPsForPids(pidArray);
|
|
73
|
-
return parsePsOutput(stdout);
|
|
74
|
-
} catch {
|
|
75
|
-
return /* @__PURE__ */ new Map();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
async function getSinglePidStats(pid) {
|
|
79
|
-
const stats = await getPidStats([pid]);
|
|
80
|
-
return stats.get(pid) ?? null;
|
|
81
|
-
}
|
|
82
|
-
var import_node_child_process;
|
|
83
|
-
var init_resource_monitor = __esm({
|
|
84
|
-
"src/process/resource-monitor.ts"() {
|
|
85
|
-
"use strict";
|
|
86
|
-
import_node_child_process = require("child_process");
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// src/builtins/native-metrics/native-metrics.addon.ts
|
|
91
|
-
var native_metrics_addon_exports = {};
|
|
92
|
-
__export(native_metrics_addon_exports, {
|
|
93
|
-
default: () => NativeMetricsAddon
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
94
4
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
var IS_DARWIN =
|
|
105
|
-
var IS_LINUX =
|
|
5
|
+
const require_chunk = require("../../chunk-C13QxCFV.js");
|
|
6
|
+
let node_fs = require("node:fs");
|
|
7
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
8
|
+
let node_child_process = require("node:child_process");
|
|
9
|
+
let node_util = require("node:util");
|
|
10
|
+
let _camstack_types = require("@camstack/types");
|
|
11
|
+
let node_os = require("node:os");
|
|
12
|
+
node_os = require_chunk.__toESM(node_os);
|
|
13
|
+
//#region src/builtins/native-metrics/native-metrics-provider.ts
|
|
14
|
+
var IS_DARWIN = node_os.platform() === "darwin";
|
|
15
|
+
var IS_LINUX = node_os.platform() === "linux";
|
|
106
16
|
var NativeMetricsProvider = class {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
swapTotalBytes
|
|
281
|
-
};
|
|
282
|
-
}
|
|
17
|
+
id = "native";
|
|
18
|
+
cachedSnapshot = null;
|
|
19
|
+
samplingTimer = null;
|
|
20
|
+
macMemTimer = null;
|
|
21
|
+
prevCpu;
|
|
22
|
+
diagnostics = null;
|
|
23
|
+
consecutiveSampleErrors = 0;
|
|
24
|
+
constructor() {
|
|
25
|
+
this.prevCpu = aggregateCpuTimes();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Optional diagnostics sink for sampling errors. The first failure and
|
|
29
|
+
* every Nth failure thereafter are reported so a permanently-broken
|
|
30
|
+
* collector doesn't spam logs but is still observable.
|
|
31
|
+
*/
|
|
32
|
+
setDiagnostics(diag) {
|
|
33
|
+
this.diagnostics = diag;
|
|
34
|
+
}
|
|
35
|
+
startSampling(intervalMs) {
|
|
36
|
+
if (IS_DARWIN) {
|
|
37
|
+
sampleMacMemory(this);
|
|
38
|
+
this.macMemTimer = setInterval(() => sampleMacMemory(this), 5e3);
|
|
39
|
+
if (this.macMemTimer.unref) this.macMemTimer.unref();
|
|
40
|
+
}
|
|
41
|
+
this.collectSnapshot().then((s) => {
|
|
42
|
+
this.cachedSnapshot = s;
|
|
43
|
+
this.consecutiveSampleErrors = 0;
|
|
44
|
+
}).catch((err) => this.reportSampleError(err));
|
|
45
|
+
this.samplingTimer = setInterval(() => {
|
|
46
|
+
this.collectSnapshot().then((s) => {
|
|
47
|
+
this.cachedSnapshot = s;
|
|
48
|
+
this.consecutiveSampleErrors = 0;
|
|
49
|
+
}).catch((err) => this.reportSampleError(err));
|
|
50
|
+
}, intervalMs);
|
|
51
|
+
if (this.samplingTimer.unref) this.samplingTimer.unref();
|
|
52
|
+
}
|
|
53
|
+
reportSampleError(err) {
|
|
54
|
+
this.consecutiveSampleErrors++;
|
|
55
|
+
if (!this.diagnostics) return;
|
|
56
|
+
if (!(this.consecutiveSampleErrors === 1 || this.consecutiveSampleErrors % 60 === 0)) return;
|
|
57
|
+
this.diagnostics.warn("metrics-provider sample failed", {
|
|
58
|
+
consecutiveErrors: this.consecutiveSampleErrors,
|
|
59
|
+
error: err instanceof Error ? err.message : String(err)
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
stopSampling() {
|
|
63
|
+
if (this.samplingTimer) {
|
|
64
|
+
clearInterval(this.samplingTimer);
|
|
65
|
+
this.samplingTimer = null;
|
|
66
|
+
}
|
|
67
|
+
if (this.macMemTimer) {
|
|
68
|
+
clearInterval(this.macMemTimer);
|
|
69
|
+
this.macMemTimer = null;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async collectSnapshot() {
|
|
73
|
+
const cpu = this.sampleCpu();
|
|
74
|
+
const memory = this.getMemoryInfo();
|
|
75
|
+
const processInfo = getProcessResources();
|
|
76
|
+
const [gpu, network, disk, cpuTemp] = await Promise.all([
|
|
77
|
+
getGpuInfoInternal().catch(() => null),
|
|
78
|
+
takeNetworkIoSnapshot(),
|
|
79
|
+
takeDiskIoSnapshot(),
|
|
80
|
+
getCpuTemperatureInternal().catch(() => null)
|
|
81
|
+
]);
|
|
82
|
+
const snapshot = {
|
|
83
|
+
cpu,
|
|
84
|
+
memory,
|
|
85
|
+
gpu,
|
|
86
|
+
network,
|
|
87
|
+
disk,
|
|
88
|
+
pressure: {
|
|
89
|
+
cpu: getPressure("cpu"),
|
|
90
|
+
memory: getPressure("memory"),
|
|
91
|
+
io: getPressure("io")
|
|
92
|
+
},
|
|
93
|
+
process: processInfo,
|
|
94
|
+
cpuTemperature: cpuTemp,
|
|
95
|
+
timestampMs: Date.now()
|
|
96
|
+
};
|
|
97
|
+
this.cachedSnapshot = snapshot;
|
|
98
|
+
return snapshot;
|
|
99
|
+
}
|
|
100
|
+
async getCached() {
|
|
101
|
+
return this.cachedSnapshot;
|
|
102
|
+
}
|
|
103
|
+
async getCurrent() {
|
|
104
|
+
const s = this.cachedSnapshot ?? await this.collectSnapshot();
|
|
105
|
+
const mb = (bytes) => Math.round(bytes / 1024 / 1024);
|
|
106
|
+
return {
|
|
107
|
+
cpuPercent: s.cpu.total,
|
|
108
|
+
memoryPercent: s.memory.percent,
|
|
109
|
+
memoryUsedMB: mb(s.memory.usedBytes),
|
|
110
|
+
memoryTotalMB: mb(s.memory.totalBytes),
|
|
111
|
+
temperature: s.cpuTemperature ?? void 0,
|
|
112
|
+
gpuPercent: s.gpu?.utilization,
|
|
113
|
+
gpuMemoryPercent: s.gpu && s.gpu.memoryTotalBytes > 0 ? Math.round(s.gpu.memoryUsedBytes / s.gpu.memoryTotalBytes * 1e3) / 10 : void 0
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
async getDiskSpace(input) {
|
|
117
|
+
return getDiskSpaceInternal(input.dirPath);
|
|
118
|
+
}
|
|
119
|
+
async getGpuInfo() {
|
|
120
|
+
return getGpuInfoInternal();
|
|
121
|
+
}
|
|
122
|
+
async getCpuTemperature() {
|
|
123
|
+
return getCpuTemperatureInternal();
|
|
124
|
+
}
|
|
125
|
+
async getProcessStats(input) {
|
|
126
|
+
const { getPidStats } = await Promise.resolve().then(() => require("../../resource-monitor-CmuWlmap.js")).then((n) => n.resource_monitor_exports);
|
|
127
|
+
const raw = await getPidStats(input.pids);
|
|
128
|
+
const result = [];
|
|
129
|
+
for (const [pid, s] of raw) result.push({
|
|
130
|
+
pid,
|
|
131
|
+
cpu: s.cpu,
|
|
132
|
+
memory: s.memory
|
|
133
|
+
});
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
sampleCpu() {
|
|
137
|
+
const curr = aggregateCpuTimes();
|
|
138
|
+
const prev = this.prevCpu;
|
|
139
|
+
this.prevCpu = curr;
|
|
140
|
+
const dUser = curr.user - prev.user;
|
|
141
|
+
const dNice = curr.nice - prev.nice;
|
|
142
|
+
const dSys = curr.sys - prev.sys;
|
|
143
|
+
const dIrq = curr.irq - prev.irq;
|
|
144
|
+
const dIdle = curr.idle - prev.idle;
|
|
145
|
+
const dTotal = dUser + dNice + dSys + dIrq + dIdle;
|
|
146
|
+
const pct = (v) => dTotal === 0 ? 0 : Math.round(v / dTotal * 1e3) / 10;
|
|
147
|
+
return {
|
|
148
|
+
total: pct(dUser + dNice + dSys + dIrq),
|
|
149
|
+
user: pct(dUser),
|
|
150
|
+
system: pct(dSys),
|
|
151
|
+
irq: pct(dIrq),
|
|
152
|
+
nice: pct(dNice),
|
|
153
|
+
loadAvg: node_os.loadavg(),
|
|
154
|
+
cores: node_os.cpus().length
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/** Cached macOS memory (set by sampleMacMemory timer). */
|
|
158
|
+
_cachedMacMem = null;
|
|
159
|
+
getMemoryInfo() {
|
|
160
|
+
const total = node_os.totalmem();
|
|
161
|
+
if (total === 0) return {
|
|
162
|
+
percent: 0,
|
|
163
|
+
totalBytes: 0,
|
|
164
|
+
usedBytes: 0,
|
|
165
|
+
availableBytes: 0,
|
|
166
|
+
swapUsedBytes: 0,
|
|
167
|
+
swapTotalBytes: 0
|
|
168
|
+
};
|
|
169
|
+
if (IS_DARWIN && this._cachedMacMem !== null) return this._cachedMacMem;
|
|
170
|
+
const free = node_os.freemem();
|
|
171
|
+
const used = total - free;
|
|
172
|
+
let swapUsedBytes = 0;
|
|
173
|
+
let swapTotalBytes = 0;
|
|
174
|
+
if (IS_LINUX) try {
|
|
175
|
+
const meminfo = node_fs.readFileSync("/proc/meminfo", "utf-8");
|
|
176
|
+
const swapTotal = parseInt(meminfo.match(/SwapTotal:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
|
|
177
|
+
const swapFree = parseInt(meminfo.match(/SwapFree:\s+(\d+)/)?.[1] ?? "0", 10) * 1024;
|
|
178
|
+
swapTotalBytes = swapTotal;
|
|
179
|
+
swapUsedBytes = swapTotal - swapFree;
|
|
180
|
+
} catch {}
|
|
181
|
+
return {
|
|
182
|
+
percent: Math.round((total - free) / total * 1e3) / 10,
|
|
183
|
+
totalBytes: total,
|
|
184
|
+
usedBytes: used,
|
|
185
|
+
availableBytes: free,
|
|
186
|
+
swapUsedBytes,
|
|
187
|
+
swapTotalBytes
|
|
188
|
+
};
|
|
189
|
+
}
|
|
283
190
|
};
|
|
284
191
|
function aggregateCpuTimes() {
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
192
|
+
const cpus = node_os.cpus();
|
|
193
|
+
let user = 0, nice = 0, sys = 0, irq = 0, idle = 0;
|
|
194
|
+
for (const cpu of cpus) {
|
|
195
|
+
user += cpu.times.user;
|
|
196
|
+
nice += cpu.times.nice;
|
|
197
|
+
sys += cpu.times.sys;
|
|
198
|
+
irq += cpu.times.irq;
|
|
199
|
+
idle += cpu.times.idle;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
user,
|
|
203
|
+
nice,
|
|
204
|
+
sys,
|
|
205
|
+
irq,
|
|
206
|
+
idle
|
|
207
|
+
};
|
|
295
208
|
}
|
|
296
209
|
function sampleMacMemory(provider) {
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
210
|
+
try {
|
|
211
|
+
const output = (0, node_child_process.execFileSync)("vm_stat", {
|
|
212
|
+
timeout: 2e3,
|
|
213
|
+
encoding: "utf-8"
|
|
214
|
+
});
|
|
215
|
+
const pageSize = 16384;
|
|
216
|
+
const parse = (label) => {
|
|
217
|
+
const match = output.match(new RegExp(`${label}:\\s+(\\d+)`));
|
|
218
|
+
return match ? parseInt(match[1], 10) * pageSize : 0;
|
|
219
|
+
};
|
|
220
|
+
const free = parse("Pages free");
|
|
221
|
+
const inactive = parse("Pages inactive");
|
|
222
|
+
const purgeable = parse("Pages purgeable");
|
|
223
|
+
const speculative = parse("Pages speculative");
|
|
224
|
+
const available = free + inactive + purgeable + speculative;
|
|
225
|
+
const total = node_os.totalmem();
|
|
226
|
+
const used = total - available;
|
|
227
|
+
let swapUsedBytes = 0;
|
|
228
|
+
let swapTotalBytes = 0;
|
|
229
|
+
try {
|
|
230
|
+
const swapOut = (0, node_child_process.execFileSync)("sysctl", ["-n", "vm.swapusage"], {
|
|
231
|
+
timeout: 2e3,
|
|
232
|
+
encoding: "utf-8"
|
|
233
|
+
});
|
|
234
|
+
const totalMatch = swapOut.match(/total\s*=\s*([\d.]+)M/);
|
|
235
|
+
const usedMatch = swapOut.match(/used\s*=\s*([\d.]+)M/);
|
|
236
|
+
if (totalMatch) swapTotalBytes = parseFloat(totalMatch[1]) * 1024 * 1024;
|
|
237
|
+
if (usedMatch) swapUsedBytes = parseFloat(usedMatch[1]) * 1024 * 1024;
|
|
238
|
+
} catch {}
|
|
239
|
+
provider._cachedMacMem = {
|
|
240
|
+
percent: Math.round(used / total * 1e3) / 10,
|
|
241
|
+
totalBytes: total,
|
|
242
|
+
usedBytes: used,
|
|
243
|
+
availableBytes: available,
|
|
244
|
+
swapUsedBytes,
|
|
245
|
+
swapTotalBytes
|
|
246
|
+
};
|
|
247
|
+
} catch {
|
|
248
|
+
provider._cachedMacMem = null;
|
|
249
|
+
}
|
|
332
250
|
}
|
|
333
251
|
function getDiskSpaceInternal(dirPath) {
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
252
|
+
return new Promise((resolve, reject) => {
|
|
253
|
+
node_fs.statfs(dirPath, (err, stats) => {
|
|
254
|
+
if (err) return reject(err);
|
|
255
|
+
const totalBytes = stats.blocks * stats.bsize;
|
|
256
|
+
const availableBytes = stats.bavail * stats.bsize;
|
|
257
|
+
const usedBytes = totalBytes - stats.bfree * stats.bsize;
|
|
258
|
+
resolve({
|
|
259
|
+
path: dirPath,
|
|
260
|
+
totalBytes,
|
|
261
|
+
usedBytes,
|
|
262
|
+
availableBytes,
|
|
263
|
+
percent: totalBytes > 0 ? Math.round(usedBytes / totalBytes * 1e3) / 10 : 0
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
349
267
|
}
|
|
350
268
|
async function takeDiskIoSnapshot() {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
269
|
+
const now = Date.now();
|
|
270
|
+
if (IS_LINUX) try {
|
|
271
|
+
const data = node_fs.readFileSync("/proc/diskstats", "utf-8");
|
|
272
|
+
let readOps = 0, readBytes = 0, writeOps = 0, writeBytes = 0;
|
|
273
|
+
for (const line of data.split("\n")) {
|
|
274
|
+
const parts = line.trim().split(/\s+/);
|
|
275
|
+
if (parts.length < 14) continue;
|
|
276
|
+
const devName = parts[2];
|
|
277
|
+
if (/\d+$/.test(devName) && !/^nvme\d+n\d+$/.test(devName)) continue;
|
|
278
|
+
readOps += parseInt(parts[3], 10) || 0;
|
|
279
|
+
readBytes += (parseInt(parts[5], 10) || 0) * 512;
|
|
280
|
+
writeOps += parseInt(parts[7], 10) || 0;
|
|
281
|
+
writeBytes += (parseInt(parts[9], 10) || 0) * 512;
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
readBytes,
|
|
285
|
+
writeBytes,
|
|
286
|
+
readOps,
|
|
287
|
+
writeOps,
|
|
288
|
+
timestampMs: now
|
|
289
|
+
};
|
|
290
|
+
} catch {}
|
|
291
|
+
return {
|
|
292
|
+
readBytes: 0,
|
|
293
|
+
writeBytes: 0,
|
|
294
|
+
readOps: 0,
|
|
295
|
+
writeOps: 0,
|
|
296
|
+
timestampMs: now
|
|
297
|
+
};
|
|
371
298
|
}
|
|
372
299
|
async function takeNetworkIoSnapshot() {
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
300
|
+
const now = Date.now();
|
|
301
|
+
if (IS_LINUX) try {
|
|
302
|
+
const data = node_fs.readFileSync("/proc/net/dev", "utf-8");
|
|
303
|
+
let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
|
|
304
|
+
for (const line of data.split("\n")) {
|
|
305
|
+
const match = line.match(/^\s*(\w+):\s+(.+)$/);
|
|
306
|
+
if (!match) continue;
|
|
307
|
+
if (match[1] === "lo") continue;
|
|
308
|
+
const cols = match[2].trim().split(/\s+/);
|
|
309
|
+
rxBytes += parseInt(cols[0], 10) || 0;
|
|
310
|
+
rxPackets += parseInt(cols[1], 10) || 0;
|
|
311
|
+
rxErrors += parseInt(cols[2], 10) || 0;
|
|
312
|
+
txBytes += parseInt(cols[8], 10) || 0;
|
|
313
|
+
txPackets += parseInt(cols[9], 10) || 0;
|
|
314
|
+
txErrors += parseInt(cols[10], 10) || 0;
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
rxBytes,
|
|
318
|
+
txBytes,
|
|
319
|
+
rxPackets,
|
|
320
|
+
txPackets,
|
|
321
|
+
rxErrors,
|
|
322
|
+
txErrors,
|
|
323
|
+
timestampMs: now
|
|
324
|
+
};
|
|
325
|
+
} catch {}
|
|
326
|
+
if (IS_DARWIN) try {
|
|
327
|
+
const stdout = await execAsync("netstat", ["-ib"]);
|
|
328
|
+
let rxBytes = 0, txBytes = 0, rxPackets = 0, txPackets = 0, rxErrors = 0, txErrors = 0;
|
|
329
|
+
for (const line of stdout.split("\n")) {
|
|
330
|
+
const parts = line.trim().split(/\s+/);
|
|
331
|
+
if (parts.length < 11) continue;
|
|
332
|
+
if (parts[0] === "lo0" || parts[0] === "Name") continue;
|
|
333
|
+
if (!parts[2]?.startsWith("Link#")) continue;
|
|
334
|
+
rxPackets += parseInt(parts[4], 10) || 0;
|
|
335
|
+
rxErrors += parseInt(parts[5], 10) || 0;
|
|
336
|
+
rxBytes += parseInt(parts[6], 10) || 0;
|
|
337
|
+
txPackets += parseInt(parts[7], 10) || 0;
|
|
338
|
+
txErrors += parseInt(parts[8], 10) || 0;
|
|
339
|
+
txBytes += parseInt(parts[9], 10) || 0;
|
|
340
|
+
}
|
|
341
|
+
return {
|
|
342
|
+
rxBytes,
|
|
343
|
+
txBytes,
|
|
344
|
+
rxPackets,
|
|
345
|
+
txPackets,
|
|
346
|
+
rxErrors,
|
|
347
|
+
txErrors,
|
|
348
|
+
timestampMs: now
|
|
349
|
+
};
|
|
350
|
+
} catch {}
|
|
351
|
+
return {
|
|
352
|
+
rxBytes: 0,
|
|
353
|
+
txBytes: 0,
|
|
354
|
+
rxPackets: 0,
|
|
355
|
+
txPackets: 0,
|
|
356
|
+
rxErrors: 0,
|
|
357
|
+
txErrors: 0,
|
|
358
|
+
timestampMs: now
|
|
359
|
+
};
|
|
415
360
|
}
|
|
416
361
|
async function getCpuTemperatureInternal() {
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
362
|
+
if (IS_LINUX) for (const p of ["/sys/class/thermal/thermal_zone0/temp", "/sys/class/hwmon/hwmon0/temp1_input"]) try {
|
|
363
|
+
const raw = node_fs.readFileSync(p, "utf-8").trim();
|
|
364
|
+
const millideg = parseInt(raw, 10);
|
|
365
|
+
if (!isNaN(millideg)) return Math.round(millideg / 100) / 10;
|
|
366
|
+
} catch {
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (IS_DARWIN) try {
|
|
370
|
+
const match = (await execAsync("sudo", [
|
|
371
|
+
"-n",
|
|
372
|
+
"powermetrics",
|
|
373
|
+
"--samplers",
|
|
374
|
+
"smc",
|
|
375
|
+
"-i",
|
|
376
|
+
"1",
|
|
377
|
+
"-n",
|
|
378
|
+
"1"
|
|
379
|
+
], 3e3)).match(/CPU die temperature:\s+([\d.]+)\s*C/);
|
|
380
|
+
if (match) return Math.round(parseFloat(match[1]) * 10) / 10;
|
|
381
|
+
} catch {}
|
|
382
|
+
return null;
|
|
438
383
|
}
|
|
439
384
|
async function getGpuInfoInternal() {
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
temperature: parseInt(parts[4], 10) || null
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
} catch {
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
return null;
|
|
385
|
+
if (IS_DARWIN) try {
|
|
386
|
+
const utilMatch = (await execAsync("ioreg", [
|
|
387
|
+
"-r",
|
|
388
|
+
"-d",
|
|
389
|
+
"1",
|
|
390
|
+
"-c",
|
|
391
|
+
"IOAccelerator"
|
|
392
|
+
])).match(/"GPU Core Utilization"\s*=\s*(\d+)/);
|
|
393
|
+
const util = utilMatch ? parseInt(utilMatch[1], 10) : 0;
|
|
394
|
+
const utilPct = util > 1e3 ? Math.round(util / 1e7) : util;
|
|
395
|
+
return {
|
|
396
|
+
utilization: Math.min(100, utilPct),
|
|
397
|
+
model: "Apple Silicon GPU",
|
|
398
|
+
memoryUsedBytes: 0,
|
|
399
|
+
memoryTotalBytes: 0,
|
|
400
|
+
temperature: null
|
|
401
|
+
};
|
|
402
|
+
} catch {}
|
|
403
|
+
if (IS_LINUX) try {
|
|
404
|
+
const parts = (await execAsync("nvidia-smi", ["--query-gpu=utilization.gpu,name,memory.used,memory.total,temperature.gpu", "--format=csv,noheader,nounits"])).trim().split(",").map((s) => s.trim());
|
|
405
|
+
if (parts.length >= 5) return {
|
|
406
|
+
utilization: parseInt(parts[0], 10) || 0,
|
|
407
|
+
model: parts[1] ?? "Unknown GPU",
|
|
408
|
+
memoryUsedBytes: (parseInt(parts[2], 10) || 0) * 1024 * 1024,
|
|
409
|
+
memoryTotalBytes: (parseInt(parts[3], 10) || 0) * 1024 * 1024,
|
|
410
|
+
temperature: parseInt(parts[4], 10) || null
|
|
411
|
+
};
|
|
412
|
+
} catch {}
|
|
413
|
+
return null;
|
|
476
414
|
}
|
|
477
415
|
function getProcessResources() {
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
activeHandles: (nodeProcess._getActiveHandles?.() ?? []).length,
|
|
497
|
-
activeRequests: (nodeProcess._getActiveRequests?.() ?? []).length
|
|
498
|
-
};
|
|
416
|
+
let openFds = 0;
|
|
417
|
+
let threadCount = 0;
|
|
418
|
+
if (IS_LINUX) {
|
|
419
|
+
try {
|
|
420
|
+
openFds = node_fs.readdirSync(`/proc/${process.pid}/fd`).length;
|
|
421
|
+
} catch {}
|
|
422
|
+
try {
|
|
423
|
+
const match = node_fs.readFileSync(`/proc/${process.pid}/status`, "utf-8").match(/Threads:\s+(\d+)/);
|
|
424
|
+
if (match) threadCount = parseInt(match[1], 10);
|
|
425
|
+
} catch {}
|
|
426
|
+
}
|
|
427
|
+
const nodeProcess = process;
|
|
428
|
+
return {
|
|
429
|
+
openFds,
|
|
430
|
+
threadCount,
|
|
431
|
+
activeHandles: (nodeProcess._getActiveHandles?.() ?? []).length,
|
|
432
|
+
activeRequests: (nodeProcess._getActiveRequests?.() ?? []).length
|
|
433
|
+
};
|
|
499
434
|
}
|
|
500
435
|
function getPressure(resource) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
436
|
+
if (!IS_LINUX) return null;
|
|
437
|
+
try {
|
|
438
|
+
const data = node_fs.readFileSync(`/proc/pressure/${resource}`, "utf-8");
|
|
439
|
+
const parseLine = (prefix) => {
|
|
440
|
+
const match = data.match(new RegExp(`${prefix} avg10=(\\d+\\.\\d+) avg60=(\\d+\\.\\d+) avg300=(\\d+\\.\\d+)`));
|
|
441
|
+
if (!match) return null;
|
|
442
|
+
return {
|
|
443
|
+
avg10: parseFloat(match[1]),
|
|
444
|
+
avg60: parseFloat(match[2]),
|
|
445
|
+
avg300: parseFloat(match[3])
|
|
446
|
+
};
|
|
447
|
+
};
|
|
448
|
+
const some = parseLine("some");
|
|
449
|
+
if (!some) return null;
|
|
450
|
+
return {
|
|
451
|
+
some,
|
|
452
|
+
full: parseLine("full")
|
|
453
|
+
};
|
|
454
|
+
} catch {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
515
457
|
}
|
|
516
458
|
function execAsync(cmd, args, timeoutMs = 5e3) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
459
|
+
return new Promise((resolve, reject) => {
|
|
460
|
+
(0, node_child_process.execFile)(cmd, args, { timeout: timeoutMs }, (err, stdout) => {
|
|
461
|
+
if (err) return reject(err);
|
|
462
|
+
resolve(stdout);
|
|
463
|
+
});
|
|
464
|
+
});
|
|
523
465
|
}
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
var execFileAsync = (0,
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/builtins/native-metrics/native-metrics.addon.ts
|
|
468
|
+
var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
469
|
+
/**
|
|
470
|
+
* Regex matching camstack-related command lines. We surface anything with
|
|
471
|
+
* an obvious camstack fingerprint so operators can spot stray inference
|
|
472
|
+
* pools, leaked tsx watchers, and zombie node workers in the Cluster →
|
|
473
|
+
* Agent → Processes tab.
|
|
474
|
+
*
|
|
475
|
+
* Patterns mirror `scripts/hunt-zombies.sh` — keep them in sync when
|
|
476
|
+
* adding a new long-lived subprocess.
|
|
477
|
+
*/
|
|
527
478
|
var CAMSTACK_CMD_RE = /(camstack|tsx\s+watch\s.*launcher\.ts|packages\/agent\/dist\/cli\.js|inference_pool\.py|bench-(inference-pool|nodeav)|node .*\/packages\/)/;
|
|
479
|
+
/**
|
|
480
|
+
* Boundary patterns: ancestry walks that pass through a process whose
|
|
481
|
+
* command line matches one of these are considered to be inside an
|
|
482
|
+
* "intentional camstack tree". Anything reachable by walking up the
|
|
483
|
+
* pid tree from such a boundary is `system` — not a ghost.
|
|
484
|
+
*
|
|
485
|
+
* The boundaries are:
|
|
486
|
+
* - `tsx watch .../launcher.ts` — hub launcher (npm run dev:server)
|
|
487
|
+
* - `node .../packages/agent/dist/cli.js` — agent CLI (dev-cluster, npm run dev:agent)
|
|
488
|
+
* - `concurrently` — dev-cluster orchestrator that runs hub + admin-ui + agents
|
|
489
|
+
* - `npm exec ` / `npm-cli.js` — npm wrappers driving the above
|
|
490
|
+
* - `vite` — admin-ui dev server (sibling of hub under concurrently)
|
|
491
|
+
*
|
|
492
|
+
* The classification logic (`classifyByAncestry`) walks each candidate
|
|
493
|
+
* pid up to ppid=1; if any ancestor matches this regex, the candidate
|
|
494
|
+
* is `system`. Reaching ppid=1 without crossing a boundary = `ghost`.
|
|
495
|
+
*/
|
|
528
496
|
var SUPERVISOR_BOUNDARY_RE = /(tsx\s+watch\s.*launcher\.ts|packages\/agent\/dist\/cli\.js|\.bin\/concurrently|\/concurrently\/dist|\bnpm-cli\.js\b|npm exec |\.bin\/vite|\/vite\/bin\/vite\.js|node_modules\/\.bin\/(vite|concurrently|tsup|rollup|esbuild|tsx)(\s|$))/;
|
|
497
|
+
/**
|
|
498
|
+
* Cadence for the per-node metric snapshot bus events. ~5 s matches
|
|
499
|
+
* the existing UI polling cadence (ProcessesTab, ProcessResources)
|
|
500
|
+
* and stays within the sampling interval so consumers always see a
|
|
501
|
+
* fresh-from-OS payload.
|
|
502
|
+
*/
|
|
529
503
|
var METRICS_SNAPSHOT_INTERVAL_MS = 5e3;
|
|
504
|
+
/**
|
|
505
|
+
* Force a metrics-snapshot emit at least every 60s even when the
|
|
506
|
+
* coarsened payload looks unchanged. Without this an idle node
|
|
507
|
+
* (steady CPU within ±5%, no process churn) goes silent on the
|
|
508
|
+
* bus and the UI's "node alive" chip can stale out.
|
|
509
|
+
*/
|
|
530
510
|
var METRICS_SNAPSHOT_HEARTBEAT_MS = 6e4;
|
|
511
|
+
/**
|
|
512
|
+
* Coarsen CPU/mem percentages to integer buckets before deduping.
|
|
513
|
+
* Without this every 5s tick differs by ±0.3% and the equality check
|
|
514
|
+
* always fails, so the snapshot fans out unconditionally.
|
|
515
|
+
*/
|
|
531
516
|
function coarsenResourcesSnapshot(snapshot) {
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
};
|
|
548
|
-
return JSON.stringify(round(snapshot));
|
|
517
|
+
if (!snapshot || typeof snapshot !== "object") return JSON.stringify(snapshot);
|
|
518
|
+
const round = (v) => {
|
|
519
|
+
if (typeof v === "number") {
|
|
520
|
+
if (v >= 0 && v <= 100) return Math.round(v / 5) * 5;
|
|
521
|
+
return Math.round(v / 1e5) * 1e5;
|
|
522
|
+
}
|
|
523
|
+
if (Array.isArray(v)) return v.map(round);
|
|
524
|
+
if (v && typeof v === "object") {
|
|
525
|
+
const out = {};
|
|
526
|
+
for (const [k, val] of Object.entries(v)) out[k] = round(val);
|
|
527
|
+
return out;
|
|
528
|
+
}
|
|
529
|
+
return v;
|
|
530
|
+
};
|
|
531
|
+
return JSON.stringify(round(snapshot));
|
|
549
532
|
}
|
|
533
|
+
/**
|
|
534
|
+
* Coarsen a process list before deduping — pid, addonId, state +
|
|
535
|
+
* bucketed cpu%. Drops cmdline / cwd / start time / uptime which
|
|
536
|
+
* change every tick on a process that's just running. The result
|
|
537
|
+
* is "process X has the same role and roughly the same load" =
|
|
538
|
+
* skip emit.
|
|
539
|
+
*/
|
|
550
540
|
function coarsenProcessList(processes) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
541
|
+
const summary = processes.filter((p) => !!p && typeof p === "object").map((p) => {
|
|
542
|
+
return [
|
|
543
|
+
p["pid"],
|
|
544
|
+
p["addonId"],
|
|
545
|
+
p["state"],
|
|
546
|
+
typeof p["cpuPercent"] === "number" ? Math.round(p["cpuPercent"] / 5) * 5 : null,
|
|
547
|
+
typeof p["memoryRss"] === "number" ? Math.round(p["memoryRss"] / (50 * 1024 * 1024)) : null
|
|
548
|
+
];
|
|
549
|
+
});
|
|
550
|
+
return JSON.stringify(summary);
|
|
560
551
|
}
|
|
561
552
|
function narrowWorkerState(state) {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
return "running";
|
|
571
|
-
}
|
|
553
|
+
switch (state) {
|
|
554
|
+
case "starting":
|
|
555
|
+
case "running":
|
|
556
|
+
case "stopping":
|
|
557
|
+
case "stopped":
|
|
558
|
+
case "crashed": return state;
|
|
559
|
+
default: return "running";
|
|
560
|
+
}
|
|
572
561
|
}
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
562
|
+
/**
|
|
563
|
+
* Native metrics — CPU, memory, disk usage sampling.
|
|
564
|
+
* Settings appear under Cluster → NodeDetail → Settings.
|
|
565
|
+
*/
|
|
566
|
+
var NativeMetricsAddon = class extends _camstack_types.BaseAddon {
|
|
567
|
+
provider = null;
|
|
568
|
+
startedAtMs = Date.now();
|
|
569
|
+
snapshotTimer = null;
|
|
570
|
+
/**
|
|
571
|
+
* Snapshot-equality cache for the resources + processes emit.
|
|
572
|
+
* Stores the coarsened JSON and timestamp; a tick where the
|
|
573
|
+
* coarsened payload matches the cache (and the heartbeat hasn't
|
|
574
|
+
* elapsed) is skipped.
|
|
575
|
+
*/
|
|
576
|
+
lastResourcesEmit = null;
|
|
577
|
+
lastProcessesEmit = null;
|
|
578
|
+
constructor() {
|
|
579
|
+
super({ samplingIntervalMs: 5e3 });
|
|
580
|
+
}
|
|
581
|
+
async onInitialize() {
|
|
582
|
+
const provider = new NativeMetricsProvider();
|
|
583
|
+
provider.setDiagnostics({ warn: (message, meta) => this.ctx.logger.warn(message, { meta: meta ?? {} }) });
|
|
584
|
+
provider.startSampling(this.config.samplingIntervalMs);
|
|
585
|
+
this.provider = provider;
|
|
586
|
+
this.startedAtMs = Date.now();
|
|
587
|
+
this.ctx.logger.info("Native metrics provider started", { meta: { intervalMs: this.config.samplingIntervalMs } });
|
|
588
|
+
const composed = {
|
|
589
|
+
collectSnapshot: () => provider.collectSnapshot(),
|
|
590
|
+
getCached: () => provider.getCached(),
|
|
591
|
+
getCurrent: () => provider.getCurrent(),
|
|
592
|
+
getDiskSpace: (params) => provider.getDiskSpace(params),
|
|
593
|
+
getGpuInfo: () => provider.getGpuInfo(),
|
|
594
|
+
getCpuTemperature: () => provider.getCpuTemperature(),
|
|
595
|
+
getProcessStats: (params) => provider.getProcessStats(params),
|
|
596
|
+
listAddonInstances: () => this.listAddonInstances(),
|
|
597
|
+
getAddonStats: (params) => this.getAddonStats(params.addonId),
|
|
598
|
+
listNodeProcesses: () => this.listNodeProcesses(),
|
|
599
|
+
killProcess: (params) => this.killProcess(params)
|
|
600
|
+
};
|
|
601
|
+
this.snapshotTimer = setInterval(() => this.emitMetricsSnapshots(), METRICS_SNAPSHOT_INTERVAL_MS);
|
|
602
|
+
return [{
|
|
603
|
+
capability: _camstack_types.metricsProviderCapability,
|
|
604
|
+
provider: composed
|
|
605
|
+
}];
|
|
606
|
+
}
|
|
607
|
+
async onShutdown() {
|
|
608
|
+
if (this.snapshotTimer) {
|
|
609
|
+
clearInterval(this.snapshotTimer);
|
|
610
|
+
this.snapshotTimer = null;
|
|
611
|
+
}
|
|
612
|
+
this.provider?.stopSampling();
|
|
613
|
+
this.provider = null;
|
|
614
|
+
}
|
|
615
|
+
/**
|
|
616
|
+
* Emit one `metrics.node-resources-snapshot` + one
|
|
617
|
+
* `metrics.node-processes-snapshot` for this node. UI consumers
|
|
618
|
+
* subscribe and read state directly from the payload.
|
|
619
|
+
*/
|
|
620
|
+
async emitMetricsSnapshots() {
|
|
621
|
+
const provider = this.provider;
|
|
622
|
+
const eventBus = this.ctx.eventBus;
|
|
623
|
+
if (!provider || !eventBus) return;
|
|
624
|
+
const rawNodeId = this.ctx.kernel.localNodeId ?? this.ctx.id;
|
|
625
|
+
const nodeId = rawNodeId.includes("/") ? rawNodeId.split("/")[0] : rawNodeId;
|
|
626
|
+
const timestamp = Date.now();
|
|
627
|
+
try {
|
|
628
|
+
const snapshot = await provider.getCached() ?? await provider.collectSnapshot();
|
|
629
|
+
const coarse = coarsenResourcesSnapshot(snapshot);
|
|
630
|
+
const prev = this.lastResourcesEmit;
|
|
631
|
+
const heartbeatDue = !prev || timestamp - prev.emittedAt >= METRICS_SNAPSHOT_HEARTBEAT_MS;
|
|
632
|
+
if (!prev || prev.coarse !== coarse || heartbeatDue) {
|
|
633
|
+
this.lastResourcesEmit = {
|
|
634
|
+
coarse,
|
|
635
|
+
emittedAt: timestamp
|
|
636
|
+
};
|
|
637
|
+
eventBus.emit((0, _camstack_types.createEvent)(_camstack_types.EventCategory.MetricsNodeResourcesSnapshot, {
|
|
638
|
+
type: "node",
|
|
639
|
+
id: nodeId,
|
|
640
|
+
nodeId
|
|
641
|
+
}, {
|
|
642
|
+
nodeId,
|
|
643
|
+
snapshot,
|
|
644
|
+
timestamp
|
|
645
|
+
}));
|
|
646
|
+
}
|
|
647
|
+
} catch {}
|
|
648
|
+
try {
|
|
649
|
+
const processes = await this.listNodeProcesses();
|
|
650
|
+
const coarse = coarsenProcessList(processes);
|
|
651
|
+
const prev = this.lastProcessesEmit;
|
|
652
|
+
const heartbeatDue = !prev || timestamp - prev.emittedAt >= METRICS_SNAPSHOT_HEARTBEAT_MS;
|
|
653
|
+
if (!prev || prev.coarse !== coarse || heartbeatDue) {
|
|
654
|
+
this.lastProcessesEmit = {
|
|
655
|
+
coarse,
|
|
656
|
+
emittedAt: timestamp
|
|
657
|
+
};
|
|
658
|
+
eventBus.emit((0, _camstack_types.createEvent)(_camstack_types.EventCategory.MetricsNodeProcessesSnapshot, {
|
|
659
|
+
type: "node",
|
|
660
|
+
id: nodeId,
|
|
661
|
+
nodeId
|
|
662
|
+
}, {
|
|
663
|
+
nodeId,
|
|
664
|
+
processes,
|
|
665
|
+
timestamp
|
|
666
|
+
}));
|
|
667
|
+
}
|
|
668
|
+
} catch {}
|
|
669
|
+
}
|
|
670
|
+
async onConfigChanged() {
|
|
671
|
+
this.provider?.stopSampling();
|
|
672
|
+
this.provider?.startSampling(this.config.samplingIntervalMs);
|
|
673
|
+
}
|
|
674
|
+
async listWorkerInstances() {
|
|
675
|
+
const broker = this.ctx.kernel.cluster?.broker;
|
|
676
|
+
if (!broker) return [];
|
|
677
|
+
try {
|
|
678
|
+
return await broker.call("$process.list");
|
|
679
|
+
} catch {
|
|
680
|
+
return [];
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
async listAddonInstances() {
|
|
684
|
+
const hubNodeId = (this.ctx.kernel.cluster?.broker)?.nodeID ?? "hub";
|
|
685
|
+
const uptimeSec = Math.max(0, Math.floor((Date.now() - this.startedAtMs) / 1e3));
|
|
686
|
+
const instances = [{
|
|
687
|
+
addonId: "$hub",
|
|
688
|
+
nodeId: hubNodeId,
|
|
689
|
+
role: "hub",
|
|
690
|
+
pid: process.pid,
|
|
691
|
+
state: "running",
|
|
692
|
+
uptimeSec
|
|
693
|
+
}];
|
|
694
|
+
const workers = await this.listWorkerInstances();
|
|
695
|
+
for (const w of workers) instances.push({
|
|
696
|
+
addonId: w.addonId,
|
|
697
|
+
nodeId: w.nodeId,
|
|
698
|
+
role: "worker",
|
|
699
|
+
pid: w.pid,
|
|
700
|
+
state: narrowWorkerState(w.state),
|
|
701
|
+
uptimeSec: w.uptimeSeconds
|
|
702
|
+
});
|
|
703
|
+
return instances;
|
|
704
|
+
}
|
|
705
|
+
async getAddonStats(addonId) {
|
|
706
|
+
const provider = this.provider;
|
|
707
|
+
if (!provider) return null;
|
|
708
|
+
if (addonId === "$hub") return (await provider.getProcessStats({ pids: [process.pid] }))[0] ?? null;
|
|
709
|
+
const target = (await this.listWorkerInstances()).find((w) => w.addonId === addonId);
|
|
710
|
+
if (!target) return null;
|
|
711
|
+
return (await provider.getProcessStats({ pids: [target.pid] }))[0] ?? null;
|
|
712
|
+
}
|
|
713
|
+
/**
|
|
714
|
+
* Walk the OS process table and classify each camstack-shaped process.
|
|
715
|
+
*
|
|
716
|
+
* Classification (ancestry-driven, NOT pattern-driven):
|
|
717
|
+
* - root — the current node's own pid (`process.pid`).
|
|
718
|
+
* - managed — pid is registered in the kernel's `$process.list`
|
|
719
|
+
* (forked addon worker spawned by this hub).
|
|
720
|
+
* - system — ancestry walk crosses a SUPERVISOR_BOUNDARY_RE match
|
|
721
|
+
* (tsx-watch launcher, agent CLI, concurrently, vite,
|
|
722
|
+
* npm exec wrapper). The process belongs to the dev
|
|
723
|
+
* tree even if not in `$process.list`. NEVER killable.
|
|
724
|
+
* - ghost — ancestry walk reaches `ppid=1` without crossing any
|
|
725
|
+
* supervisor boundary AND the parent isn't visible in
|
|
726
|
+
* `ps`. A truly orphaned camstack-shaped process. The
|
|
727
|
+
* ONLY classification that's eligible for kill.
|
|
728
|
+
*
|
|
729
|
+
* Old pattern-only ghost detection produced false positives: every
|
|
730
|
+
* monorepo-path process matched CAMSTACK_CMD_RE, ancestry walk
|
|
731
|
+
* stopping at ppid=hub returned false-positive ghosts whenever a
|
|
732
|
+
* concurrently sibling sat above hub. Ancestry-driven classification
|
|
733
|
+
* fixes that.
|
|
734
|
+
*/
|
|
735
|
+
async listNodeProcesses() {
|
|
736
|
+
const ps = await this.runPs();
|
|
737
|
+
if (ps.length === 0) return [];
|
|
738
|
+
const managedPids = /* @__PURE__ */ new Map();
|
|
739
|
+
const workers = await this.listWorkerInstances();
|
|
740
|
+
for (const w of workers) managedPids.set(w.pid, {
|
|
741
|
+
addonId: w.addonId,
|
|
742
|
+
nodeId: w.nodeId
|
|
743
|
+
});
|
|
744
|
+
const hubNodeId = this.ctx.kernel.cluster?.broker?.nodeID ?? "hub";
|
|
745
|
+
const selfPid = process.pid;
|
|
746
|
+
const psIndex = /* @__PURE__ */ new Map();
|
|
747
|
+
for (const p of ps) psIndex.set(p.pid, {
|
|
748
|
+
ppid: p.ppid,
|
|
749
|
+
command: p.command
|
|
750
|
+
});
|
|
751
|
+
/**
|
|
752
|
+
* Walk ancestry from `pid` up to ppid=1 (or until we leave the ps
|
|
753
|
+
* snapshot). Returns:
|
|
754
|
+
* - 'system' — crossed a SUPERVISOR_BOUNDARY_RE ancestor
|
|
755
|
+
* - 'ghost' — reached ppid=1 OR the parent isn't visible in ps
|
|
756
|
+
* without crossing a boundary
|
|
757
|
+
*
|
|
758
|
+
* `selfPid` itself is treated as a boundary (this node's own root).
|
|
759
|
+
*/
|
|
760
|
+
const classifyByAncestry = (startPid) => {
|
|
761
|
+
let cur = startPid;
|
|
762
|
+
for (let depth = 0; depth < 32; depth++) {
|
|
763
|
+
const node = psIndex.get(cur);
|
|
764
|
+
if (!node) return "ghost";
|
|
765
|
+
if (cur === selfPid) return "system";
|
|
766
|
+
if (SUPERVISOR_BOUNDARY_RE.test(node.command)) return "system";
|
|
767
|
+
if (node.ppid === 1) return "ghost";
|
|
768
|
+
if (node.ppid === selfPid) return "system";
|
|
769
|
+
cur = node.ppid;
|
|
770
|
+
}
|
|
771
|
+
return "system";
|
|
772
|
+
};
|
|
773
|
+
const out = [];
|
|
774
|
+
for (const p of ps) {
|
|
775
|
+
if (!CAMSTACK_CMD_RE.test(p.command)) continue;
|
|
776
|
+
const managed = managedPids.get(p.pid);
|
|
777
|
+
let classification;
|
|
778
|
+
if (p.pid === selfPid) classification = "root";
|
|
779
|
+
else if (managed) classification = "managed";
|
|
780
|
+
else classification = classifyByAncestry(p.pid);
|
|
781
|
+
const orphaned = classification === "ghost";
|
|
782
|
+
out.push({
|
|
783
|
+
pid: p.pid,
|
|
784
|
+
ppid: p.ppid,
|
|
785
|
+
pgid: p.pgid,
|
|
786
|
+
classification,
|
|
787
|
+
addonId: managed?.addonId ?? null,
|
|
788
|
+
nodeId: managed?.nodeId ?? (p.pid === selfPid ? hubNodeId : null),
|
|
789
|
+
command: p.command,
|
|
790
|
+
cpuPercent: p.cpuPercent,
|
|
791
|
+
memoryRssBytes: p.memoryRssBytes,
|
|
792
|
+
uptimeSec: p.uptimeSec,
|
|
793
|
+
orphaned
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
return out;
|
|
797
|
+
}
|
|
798
|
+
/**
|
|
799
|
+
* Send SIGTERM / SIGKILL to a pid. Refuses pids that don't appear in
|
|
800
|
+
* `listNodeProcesses()` to prevent arbitrary system kills — a dedicated
|
|
801
|
+
* admin-path for resurrected zombies, not a generic shell replacement.
|
|
802
|
+
*
|
|
803
|
+
* `root`-classified pids (the running launcher / agent CLI / hub itself)
|
|
804
|
+
* are also refused: killing them tears down the whole node and the
|
|
805
|
+
* operator's intent is almost always to nuke a leaked child, not the
|
|
806
|
+
* supervisor that keeps the rest alive. Process restart goes through
|
|
807
|
+
* the dedicated `$process.restart` action, not this kill API.
|
|
808
|
+
*/
|
|
809
|
+
async killProcess(input) {
|
|
810
|
+
const match = (await this.listNodeProcesses()).find((p) => p.pid === input.pid);
|
|
811
|
+
if (!match) return {
|
|
812
|
+
success: false,
|
|
813
|
+
reason: "pid not in node process table"
|
|
814
|
+
};
|
|
815
|
+
if (match.classification === "root" || match.classification === "system") {
|
|
816
|
+
this.ctx.logger.warn("Refused to kill protected process", { meta: {
|
|
817
|
+
pid: input.pid,
|
|
818
|
+
classification: match.classification,
|
|
819
|
+
addonId: match.addonId,
|
|
820
|
+
command: match.command
|
|
821
|
+
} });
|
|
822
|
+
return {
|
|
823
|
+
success: false,
|
|
824
|
+
reason: match.classification === "root" ? "cannot kill root (current node supervisor)" : "cannot kill system (intentional dev-tree ancestor — vite, concurrently, npm, etc.)"
|
|
825
|
+
};
|
|
826
|
+
}
|
|
827
|
+
const signal = input.force ? "SIGKILL" : "SIGTERM";
|
|
828
|
+
try {
|
|
829
|
+
process.kill(input.pid, signal);
|
|
830
|
+
this.ctx.logger.info("Killed node process", { meta: {
|
|
831
|
+
pid: input.pid,
|
|
832
|
+
signal,
|
|
833
|
+
classification: match.classification,
|
|
834
|
+
addonId: match.addonId
|
|
835
|
+
} });
|
|
836
|
+
return {
|
|
837
|
+
success: true,
|
|
838
|
+
signal
|
|
839
|
+
};
|
|
840
|
+
} catch (err) {
|
|
841
|
+
return {
|
|
842
|
+
success: false,
|
|
843
|
+
reason: err instanceof Error ? err.message : String(err),
|
|
844
|
+
signal
|
|
845
|
+
};
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
/** Raw `ps` scan returning every pid + command + resource stats. */
|
|
849
|
+
async runPs() {
|
|
850
|
+
try {
|
|
851
|
+
const { stdout } = await execFileAsync("ps", ["-eo", "pid=,ppid=,pgid=,pcpu=,rss=,etime=,command="], {
|
|
852
|
+
timeout: 5e3,
|
|
853
|
+
maxBuffer: 8 * 1024 * 1024
|
|
854
|
+
});
|
|
855
|
+
const lines = stdout.split("\n");
|
|
856
|
+
const rows = [];
|
|
857
|
+
for (const line of lines) {
|
|
858
|
+
const trimmed = line.trim();
|
|
859
|
+
if (!trimmed) continue;
|
|
860
|
+
const match = trimmed.match(/^(\d+)\s+(\d+)\s+(\d+)\s+([\d.]+)\s+(\d+)\s+(\S+)\s+(.+)$/);
|
|
861
|
+
if (!match) continue;
|
|
862
|
+
const [, pidS, ppidS, pgidS, cpuS, rssS, etimeS, command] = match;
|
|
863
|
+
rows.push({
|
|
864
|
+
pid: parseInt(pidS, 10),
|
|
865
|
+
ppid: parseInt(ppidS, 10),
|
|
866
|
+
pgid: parseInt(pgidS, 10),
|
|
867
|
+
cpuPercent: Math.round(parseFloat(cpuS) * 10) / 10,
|
|
868
|
+
memoryRssBytes: parseInt(rssS, 10) * 1024,
|
|
869
|
+
uptimeSec: parseEtime(etimeS),
|
|
870
|
+
command
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
return rows;
|
|
874
|
+
} catch (err) {
|
|
875
|
+
this.ctx.logger.warn("ps scan failed", { meta: { error: err instanceof Error ? err.message : String(err) } });
|
|
876
|
+
return [];
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
globalSettingsSchema() {
|
|
880
|
+
return this.schema({ sections: [{
|
|
881
|
+
id: "native-metrics-settings",
|
|
882
|
+
title: "System Metrics",
|
|
883
|
+
fields: [this.field({
|
|
884
|
+
type: "number",
|
|
885
|
+
key: "samplingIntervalMs",
|
|
886
|
+
label: "Sampling Interval",
|
|
887
|
+
description: "How often to collect system metrics",
|
|
888
|
+
min: 1e3,
|
|
889
|
+
max: 6e4,
|
|
890
|
+
step: 1e3,
|
|
891
|
+
default: 5e3,
|
|
892
|
+
unit: "ms"
|
|
893
|
+
})]
|
|
894
|
+
}] });
|
|
895
|
+
}
|
|
882
896
|
};
|
|
897
|
+
/**
|
|
898
|
+
* Parse `ps etime` format → seconds.
|
|
899
|
+
*
|
|
900
|
+
* Formats we handle:
|
|
901
|
+
* `MM:SS` (< 1h)
|
|
902
|
+
* `HH:MM:SS` (< 1d)
|
|
903
|
+
* `DD-HH:MM:SS` (>= 1d)
|
|
904
|
+
*/
|
|
883
905
|
function parseEtime(etime) {
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
906
|
+
const dashParts = etime.split("-");
|
|
907
|
+
let days = 0;
|
|
908
|
+
let hms = etime;
|
|
909
|
+
if (dashParts.length === 2) {
|
|
910
|
+
days = parseInt(dashParts[0], 10) || 0;
|
|
911
|
+
hms = dashParts[1];
|
|
912
|
+
}
|
|
913
|
+
const parts = hms.split(":").map((p) => parseInt(p, 10) || 0);
|
|
914
|
+
let hours = 0, minutes = 0, seconds = 0;
|
|
915
|
+
if (parts.length === 3) [hours, minutes, seconds] = parts;
|
|
916
|
+
else if (parts.length === 2) [minutes, seconds] = parts;
|
|
917
|
+
else if (parts.length === 1) [seconds] = parts;
|
|
918
|
+
return days * 86400 + hours * 3600 + minutes * 60 + seconds;
|
|
897
919
|
}
|
|
920
|
+
//#endregion
|
|
921
|
+
exports.NativeMetricsProvider = NativeMetricsProvider;
|
|
922
|
+
exports.default = NativeMetricsAddon;
|
|
923
|
+
|
|
898
924
|
//# sourceMappingURL=native-metrics.addon.js.map
|