@runtimescope/collector 0.9.2 → 0.9.3

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.
@@ -10,8 +10,9 @@ import {
10
10
  SessionManager,
11
11
  SqliteStore,
12
12
  isSqliteAvailable,
13
+ migrateProjectIds,
13
14
  resolveTlsConfig
14
- } from "./chunk-GENCCHYK.js";
15
+ } from "./chunk-MM44DN7Y.js";
15
16
  import "./chunk-UP2VWCW5.js";
16
17
 
17
18
  // src/standalone.ts
@@ -95,8 +96,21 @@ async function main() {
95
96
  const pmDbPath = join(projectManager.rootDir, "pm.db");
96
97
  pmStore = new PmStore({ dbPath: pmDbPath });
97
98
  discovery = new ProjectDiscovery(pmStore, projectManager);
99
+ collector.setPmStore(pmStore);
98
100
  discovery.discoverAll().then((result) => {
99
101
  console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);
102
+ projectManager.rebuildAppIndex(pmStore);
103
+ try {
104
+ const migrationResult = migrateProjectIds(projectManager, pmStore);
105
+ if (migrationResult.unified > 0) {
106
+ console.error(`[RuntimeScope] Unified ${migrationResult.unified} project IDs`);
107
+ for (const detail of migrationResult.details) {
108
+ console.error(`[RuntimeScope] ${detail}`);
109
+ }
110
+ projectManager.rebuildAppIndex(pmStore);
111
+ }
112
+ } catch {
113
+ }
100
114
  }).catch((err) => {
101
115
  console.error("[RuntimeScope] PM discovery error:", err.message);
102
116
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/standalone.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// ============================================================\n// RuntimeScope Standalone Collector\n// Runs CollectorServer + HttpServer as a standalone service\n// without MCP, Playwright, or ProcessMonitor.\n//\n// Usage:\n// node dist/standalone.js\n// npx @runtimescope/collector\n// docker run runtimescope\n// ============================================================\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { CollectorServer } from './server.js';\nimport { HttpServer } from './http-server.js';\nimport { ProjectManager } from './project-manager.js';\nimport { PmStore } from './pm/pm-store.js';\nimport { ProjectDiscovery } from './pm/project-discovery.js';\nimport { SessionManager } from './session-manager.js';\nimport { SqliteStore } from './sqlite-store.js';\nimport { isSqliteAvailable } from './sqlite-check.js';\nimport { AuthManager } from './auth.js';\nimport { Redactor } from './redactor.js';\nimport { resolveTlsConfig } from './tls.js';\n\nconst HOST = process.env.RUNTIMESCOPE_HOST ?? '127.0.0.1';\n// Same default ports as MCP server — only one should run at a time\nconst COLLECTOR_PORT = parseInt(process.env.RUNTIMESCOPE_PORT ?? '9090', 10);\nconst HTTP_PORT = parseInt(process.env.RUNTIMESCOPE_HTTP_PORT ?? '9091', 10);\nconst BUFFER_SIZE = parseInt(process.env.RUNTIMESCOPE_BUFFER_SIZE ?? '10000', 10);\nconst RETENTION_DAYS = parseInt(process.env.RUNTIMESCOPE_RETENTION_DAYS ?? '30', 10);\n\nasync function main() {\n console.error('[RuntimeScope] Starting standalone collector...');\n\n // 1. Initialize project management + config\n const projectManager = new ProjectManager();\n projectManager.ensureGlobalDir();\n const globalConfig = projectManager.getGlobalConfig();\n\n // 2. Security: auth, TLS, redaction, CORS\n const authManager = new AuthManager({\n enabled: globalConfig.auth?.enabled ?? false,\n apiKeys: globalConfig.auth?.apiKeys ?? [],\n });\n\n const tlsConfig = resolveTlsConfig() ?? globalConfig.tls ?? undefined;\n\n const redactor = new Redactor({\n enabled: globalConfig.redaction?.enabled ?? false,\n useBuiltIn: true,\n rules: globalConfig.redaction?.rules?.map(r => ({\n name: r.name,\n pattern: new RegExp(r.pattern, 'gi'),\n replacement: r.replacement,\n })),\n });\n\n const corsOrigins = process.env.RUNTIMESCOPE_CORS_ORIGINS?.split(',').map(s => s.trim())\n ?? globalConfig.corsOrigins;\n\n if (authManager.isEnabled()) {\n console.error(`[RuntimeScope] Auth enabled (${globalConfig.auth?.apiKeys?.length ?? 0} API keys)`);\n }\n if (tlsConfig) {\n console.error(`[RuntimeScope] TLS enabled (cert: ${tlsConfig.certPath})`);\n }\n if (redactor.isEnabled()) {\n console.error('[RuntimeScope] Payload redaction enabled');\n }\n\n // 3. Start collector WebSocket server\n const collector = new CollectorServer({\n bufferSize: BUFFER_SIZE,\n projectManager,\n authManager,\n rateLimits: globalConfig.rateLimits,\n tls: tlsConfig,\n });\n await collector.start({ port: COLLECTOR_PORT, host: HOST, maxRetries: 5, retryDelayMs: 1000 });\n\n const store = collector.getStore();\n\n // Wire redactor for defense-in-depth\n if (redactor.isEnabled()) {\n store.setRedactor(redactor);\n }\n\n // 4. Session management — auto-snapshot on disconnect\n const sqliteStores = collector.getSqliteStores();\n const sessionManager = new SessionManager(projectManager, sqliteStores, store);\n\n collector.onDisconnect((sessionId, projectName) => {\n try {\n sessionManager.createSnapshot(sessionId, projectName);\n console.error(`[RuntimeScope] Session ${sessionId} metrics saved`);\n } catch {\n // Non-fatal\n }\n });\n\n // 5. Retention pruning (only if SQLite is available)\n if (isSqliteAvailable()) {\n const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1000;\n for (const projectName of projectManager.listProjects()) {\n const dbPath = projectManager.getProjectDbPath(projectName);\n if (existsSync(dbPath)) {\n try {\n const tempStore = new SqliteStore({ dbPath });\n const deleted = tempStore.deleteOldEvents(cutoffMs);\n if (deleted > 0) {\n console.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from \"${projectName}\"`);\n }\n tempStore.close();\n } catch {\n // Non-fatal\n }\n }\n }\n }\n\n // 6. Project Management layer (requires SQLite)\n let pmStore: PmStore | undefined;\n let discovery: ProjectDiscovery | undefined;\n\n if (isSqliteAvailable()) {\n const pmDbPath = join(projectManager.rootDir, 'pm.db');\n pmStore = new PmStore({ dbPath: pmDbPath });\n discovery = new ProjectDiscovery(pmStore, projectManager);\n\n // Run discovery in background (non-blocking)\n discovery.discoverAll().then((result) => {\n console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);\n }).catch((err) => {\n console.error('[RuntimeScope] PM discovery error:', (err as Error).message);\n });\n }\n\n // 7. Start HTTP API server (with POST /api/events + PM routes)\n const httpServer = new HttpServer(store, undefined, {\n authManager,\n allowedOrigins: corsOrigins,\n rateLimiter: collector.getRateLimiter(),\n pmStore,\n discovery,\n projectManager,\n getConnectedSessions: () => collector.getConnectedSessions(),\n });\n\n try {\n await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });\n } catch (err) {\n console.error('[RuntimeScope] HTTP API failed to start:', (err as Error).message);\n }\n\n // Push session connect/disconnect to dashboard in real-time\n collector.onConnect((sessionId, projectName, projectId) => {\n httpServer.broadcastSessionChange('session_connected', sessionId, projectName);\n // Auto-link SDK appName to PM project\n if (pmStore) {\n try { pmStore.autoLinkApp(projectName, projectId); } catch { /* non-fatal */ }\n }\n });\n collector.onDisconnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_disconnected', sessionId, projectName);\n });\n\n // 7. Startup summary\n const proto = tlsConfig ? 'wss' : 'ws';\n const httpProto = tlsConfig ? 'https' : 'http';\n console.error(`[RuntimeScope] Standalone collector ready`);\n console.error(`[RuntimeScope] WebSocket: ${proto}://${HOST}:${COLLECTOR_PORT}`);\n console.error(`[RuntimeScope] HTTP API: ${httpProto}://${HOST}:${HTTP_PORT}`);\n console.error(`[RuntimeScope] Health: ${httpProto}://${HOST}:${HTTP_PORT}/api/health`);\n console.error(`[RuntimeScope] Ingest: POST ${httpProto}://${HOST}:${HTTP_PORT}/api/events`);\n\n // 8. Graceful shutdown\n let shuttingDown = false;\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.error('[RuntimeScope] Shutting down...');\n\n await httpServer.stop();\n collector.stop();\n pmStore?.close();\n\n process.exit(0);\n };\n\n process.on('SIGINT', () => { shutdown(); });\n process.on('SIGTERM', () => { shutdown(); });\n}\n\nmain().catch((err) => {\n console.error('[RuntimeScope] Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/standalone.ts"],"sourcesContent":["#!/usr/bin/env node\n\n// ============================================================\n// RuntimeScope Standalone Collector\n// Runs CollectorServer + HttpServer as a standalone service\n// without MCP, Playwright, or ProcessMonitor.\n//\n// Usage:\n// node dist/standalone.js\n// npx @runtimescope/collector\n// docker run runtimescope\n// ============================================================\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { CollectorServer } from './server.js';\nimport { HttpServer } from './http-server.js';\nimport { ProjectManager } from './project-manager.js';\nimport { PmStore } from './pm/pm-store.js';\nimport { ProjectDiscovery } from './pm/project-discovery.js';\nimport { SessionManager } from './session-manager.js';\nimport { SqliteStore } from './sqlite-store.js';\nimport { isSqliteAvailable } from './sqlite-check.js';\nimport { AuthManager } from './auth.js';\nimport { Redactor } from './redactor.js';\nimport { resolveTlsConfig } from './tls.js';\nimport { migrateProjectIds } from './project-config.js';\n\nconst HOST = process.env.RUNTIMESCOPE_HOST ?? '127.0.0.1';\n// Same default ports as MCP server — only one should run at a time\nconst COLLECTOR_PORT = parseInt(process.env.RUNTIMESCOPE_PORT ?? '9090', 10);\nconst HTTP_PORT = parseInt(process.env.RUNTIMESCOPE_HTTP_PORT ?? '9091', 10);\nconst BUFFER_SIZE = parseInt(process.env.RUNTIMESCOPE_BUFFER_SIZE ?? '10000', 10);\nconst RETENTION_DAYS = parseInt(process.env.RUNTIMESCOPE_RETENTION_DAYS ?? '30', 10);\n\nasync function main() {\n console.error('[RuntimeScope] Starting standalone collector...');\n\n // 1. Initialize project management + config\n const projectManager = new ProjectManager();\n projectManager.ensureGlobalDir();\n const globalConfig = projectManager.getGlobalConfig();\n\n // 2. Security: auth, TLS, redaction, CORS\n const authManager = new AuthManager({\n enabled: globalConfig.auth?.enabled ?? false,\n apiKeys: globalConfig.auth?.apiKeys ?? [],\n });\n\n const tlsConfig = resolveTlsConfig() ?? globalConfig.tls ?? undefined;\n\n const redactor = new Redactor({\n enabled: globalConfig.redaction?.enabled ?? false,\n useBuiltIn: true,\n rules: globalConfig.redaction?.rules?.map(r => ({\n name: r.name,\n pattern: new RegExp(r.pattern, 'gi'),\n replacement: r.replacement,\n })),\n });\n\n const corsOrigins = process.env.RUNTIMESCOPE_CORS_ORIGINS?.split(',').map(s => s.trim())\n ?? globalConfig.corsOrigins;\n\n if (authManager.isEnabled()) {\n console.error(`[RuntimeScope] Auth enabled (${globalConfig.auth?.apiKeys?.length ?? 0} API keys)`);\n }\n if (tlsConfig) {\n console.error(`[RuntimeScope] TLS enabled (cert: ${tlsConfig.certPath})`);\n }\n if (redactor.isEnabled()) {\n console.error('[RuntimeScope] Payload redaction enabled');\n }\n\n // 3. Start collector WebSocket server\n const collector = new CollectorServer({\n bufferSize: BUFFER_SIZE,\n projectManager,\n authManager,\n rateLimits: globalConfig.rateLimits,\n tls: tlsConfig,\n });\n await collector.start({ port: COLLECTOR_PORT, host: HOST, maxRetries: 5, retryDelayMs: 1000 });\n\n const store = collector.getStore();\n\n // Wire redactor for defense-in-depth\n if (redactor.isEnabled()) {\n store.setRedactor(redactor);\n }\n\n // 4. Session management — auto-snapshot on disconnect\n const sqliteStores = collector.getSqliteStores();\n const sessionManager = new SessionManager(projectManager, sqliteStores, store);\n\n collector.onDisconnect((sessionId, projectName) => {\n try {\n sessionManager.createSnapshot(sessionId, projectName);\n console.error(`[RuntimeScope] Session ${sessionId} metrics saved`);\n } catch {\n // Non-fatal\n }\n });\n\n // 5. Retention pruning (only if SQLite is available)\n if (isSqliteAvailable()) {\n const cutoffMs = Date.now() - RETENTION_DAYS * 24 * 60 * 60 * 1000;\n for (const projectName of projectManager.listProjects()) {\n const dbPath = projectManager.getProjectDbPath(projectName);\n if (existsSync(dbPath)) {\n try {\n const tempStore = new SqliteStore({ dbPath });\n const deleted = tempStore.deleteOldEvents(cutoffMs);\n if (deleted > 0) {\n console.error(`[RuntimeScope] Pruned ${deleted} events older than ${RETENTION_DAYS}d from \"${projectName}\"`);\n }\n tempStore.close();\n } catch {\n // Non-fatal\n }\n }\n }\n }\n\n // 6. Project Management layer (requires SQLite)\n let pmStore: PmStore | undefined;\n let discovery: ProjectDiscovery | undefined;\n\n if (isSqliteAvailable()) {\n const pmDbPath = join(projectManager.rootDir, 'pm.db');\n pmStore = new PmStore({ dbPath: pmDbPath });\n discovery = new ProjectDiscovery(pmStore, projectManager);\n\n // Wire PM store into collector so handshake can resolve projectIds\n collector.setPmStore(pmStore);\n\n // Run discovery in background (non-blocking)\n discovery.discoverAll().then((result) => {\n console.error(`[RuntimeScope] PM: ${result.projectsDiscovered} projects, ${result.sessionsDiscovered} sessions discovered`);\n\n // Rebuild app index after discovery completes\n projectManager.rebuildAppIndex(pmStore);\n\n // Migrate project IDs — unify multi-app projects\n try {\n const migrationResult = migrateProjectIds(projectManager, pmStore);\n if (migrationResult.unified > 0) {\n console.error(`[RuntimeScope] Unified ${migrationResult.unified} project IDs`);\n for (const detail of migrationResult.details) {\n console.error(`[RuntimeScope] ${detail}`);\n }\n // Rebuild the app index after migration\n projectManager.rebuildAppIndex(pmStore);\n }\n } catch { /* non-fatal */ }\n }).catch((err) => {\n console.error('[RuntimeScope] PM discovery error:', (err as Error).message);\n });\n }\n\n // 7. Start HTTP API server (with POST /api/events + PM routes)\n const httpServer = new HttpServer(store, undefined, {\n authManager,\n allowedOrigins: corsOrigins,\n rateLimiter: collector.getRateLimiter(),\n pmStore,\n discovery,\n projectManager,\n getConnectedSessions: () => collector.getConnectedSessions(),\n });\n\n try {\n await httpServer.start({ port: HTTP_PORT, host: HOST, tls: tlsConfig });\n } catch (err) {\n console.error('[RuntimeScope] HTTP API failed to start:', (err as Error).message);\n }\n\n // Push session connect/disconnect to dashboard in real-time\n collector.onConnect((sessionId, projectName, projectId) => {\n httpServer.broadcastSessionChange('session_connected', sessionId, projectName);\n // Auto-link SDK appName to PM project\n if (pmStore) {\n try { pmStore.autoLinkApp(projectName, projectId); } catch { /* non-fatal */ }\n }\n });\n collector.onDisconnect((sessionId, projectName) => {\n httpServer.broadcastSessionChange('session_disconnected', sessionId, projectName);\n });\n\n // 7. Startup summary\n const proto = tlsConfig ? 'wss' : 'ws';\n const httpProto = tlsConfig ? 'https' : 'http';\n console.error(`[RuntimeScope] Standalone collector ready`);\n console.error(`[RuntimeScope] WebSocket: ${proto}://${HOST}:${COLLECTOR_PORT}`);\n console.error(`[RuntimeScope] HTTP API: ${httpProto}://${HOST}:${HTTP_PORT}`);\n console.error(`[RuntimeScope] Health: ${httpProto}://${HOST}:${HTTP_PORT}/api/health`);\n console.error(`[RuntimeScope] Ingest: POST ${httpProto}://${HOST}:${HTTP_PORT}/api/events`);\n\n // 8. Graceful shutdown\n let shuttingDown = false;\n const shutdown = async () => {\n if (shuttingDown) return;\n shuttingDown = true;\n console.error('[RuntimeScope] Shutting down...');\n\n await httpServer.stop();\n collector.stop();\n pmStore?.close();\n\n process.exit(0);\n };\n\n process.on('SIGINT', () => { shutdown(); });\n process.on('SIGTERM', () => { shutdown(); });\n}\n\nmain().catch((err) => {\n console.error('[RuntimeScope] Fatal error:', err);\n process.exit(1);\n});\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runtimescope/collector",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Event collector and persistence layer for RuntimeScope",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",