@kb-labs/gateway-runtime-server 0.4.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # TODO
package/dist/cli.js CHANGED
@@ -24,6 +24,7 @@ var RuntimeServer = class {
24
24
  this.client = new GatewayClient(clientOpts);
25
25
  this.client.registerHandler("execution", (call) => this.handleExecution(call));
26
26
  }
27
+ opts;
27
28
  client;
28
29
  hostId = null;
29
30
  async start() {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime-server.ts","../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * @module @kb-labs/gateway-runtime-server\n *\n * RuntimeServer — plugin execution host that connects to Gateway as a Host Agent.\n *\n * Connects via WS, registers as adapter 'execution', and handles:\n * call { adapter: 'execution', method: 'execute', args: [RemoteExecutionRequest] }\n * → runInProcess(request)\n * → chunk { data: result } + result { done: true }\n *\n * Used for isolation: strict — runs inside a container alongside the workspace.\n *\n * Design doc: docs/architecture/execution-isolation.md\n * Architecture decision: WS/Gateway transport instead of TCP (see ADR context).\n */\n\nimport * as path from 'node:path';\nimport { GatewayClient } from '@kb-labs/host-agent-core';\nimport type { GatewayClientOptions } from '@kb-labs/host-agent-core';\nimport type { CapabilityCall } from '@kb-labs/host-agent-contracts';\nimport { runInProcess } from '@kb-labs/plugin-runtime';\nimport { noopUI } from '@kb-labs/plugin-contracts';\n\n/**\n * Minimal execution request as received from RemoteBackend via Gateway dispatch.\n */\ninterface RemoteExecutionRequest {\n executionId: string;\n handlerRef: string; // absolute path inside container, e.g. /workspace/dist/handler.js\n pluginRoot: string; // base dir, e.g. /workspace\n input: unknown;\n descriptor: unknown;\n timeoutMs?: number;\n context?: unknown;\n}\n\nexport interface RuntimeServerOptions {\n /** WebSocket URL of the Gateway, e.g. http://localhost:4000 */\n gatewayUrl: string;\n /** Access token for WS auth */\n getAccessToken: () => string;\n /** Called when refresh is needed (reconnect path) */\n onTokenExpired?: () => Promise<void>;\n /** Agent version string */\n agentVersion?: string;\n /**\n * Platform services for runInProcess.\n * If omitted, a minimal noop platform is used (for container environments\n * where full platform is not available).\n */\n platform?: unknown;\n}\n\nexport class RuntimeServer {\n private readonly client: GatewayClient;\n private hostId: string | null = null;\n\n constructor(private readonly opts: RuntimeServerOptions) {\n const clientOpts: GatewayClientOptions = {\n gatewayUrl: opts.gatewayUrl,\n agentVersion: opts.agentVersion ?? '0.1.0',\n getAccessToken: opts.getAccessToken,\n onTokenExpired: opts.onTokenExpired,\n capabilities: ['execution'],\n onConnected: (hId, sessionId) => {\n this.hostId = hId;\n console.log(`[runtime-server] Connected to Gateway: hostId=${hId} session=${sessionId}`);\n },\n onDisconnected: () => {\n console.log('[runtime-server] Disconnected from Gateway, reconnecting...');\n },\n };\n\n this.client = new GatewayClient(clientOpts);\n this.client.registerHandler('execution', (call) => this.handleExecution(call));\n }\n\n async start(): Promise<void> {\n await this.client.connect();\n }\n\n stop(): void {\n this.client.stop();\n }\n\n /** The hostId assigned by Gateway after handshake (null before connected) */\n getHostId(): string | null {\n return this.hostId;\n }\n\n private async handleExecution(call: CapabilityCall): Promise<unknown> {\n if (call.method !== 'execute') {\n throw new Error(`Unknown execution method: ${call.method}`);\n }\n\n const request = call.args[0] as RemoteExecutionRequest | undefined;\n if (!request || !request.handlerRef || !request.pluginRoot) {\n throw new Error('Missing required fields: handlerRef, pluginRoot');\n }\n\n return this.executeHandler(request);\n }\n\n private async executeHandler(request: RemoteExecutionRequest): Promise<unknown> {\n // Resolve absolute handler path\n const hashIndex = request.handlerRef.indexOf('#');\n const relPath = hashIndex > 0 ? request.handlerRef.slice(0, hashIndex) : request.handlerRef;\n\n // handlerRef may be absolute (/workspace/...) or relative to pluginRoot\n const handlerPath = relPath.startsWith('/')\n ? relPath\n : path.resolve(request.pluginRoot, relPath);\n\n const platform = this.opts.platform ?? createNoopPlatform();\n\n const runResult = await runInProcess({\n descriptor: request.descriptor as Parameters<typeof runInProcess>[0]['descriptor'],\n platform: platform as Parameters<typeof runInProcess>[0]['platform'],\n ui: noopUI,\n handlerPath,\n input: request.input,\n cwd: request.pluginRoot,\n });\n\n return runResult.data;\n }\n}\n\n/**\n * Minimal noop platform for container environments.\n * Logger writes to stdout, cache is a no-op.\n * Production use should pass real platform services.\n */\nfunction createNoopPlatform(): unknown {\n return {\n logger: {\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({}),\n }),\n },\n cache: {\n get: async () => null,\n set: async () => {},\n delete: async () => {},\n clear: async () => {},\n },\n config: {},\n shell: {\n exec: async () => { throw new Error('shell.exec not available in runtime-server noop platform'); },\n },\n };\n}\n","/**\n * @module @kb-labs/gateway-runtime-server/cli\n *\n * CLI entry point for the runtime server.\n * Run inside an isolation: strict container to handle remote plugin execution.\n *\n * Required env vars:\n * GATEWAY_WS_URL — WebSocket URL of the Gateway (e.g. ws://gateway:4000)\n * RUNTIME_HOST_ID — Deterministic hostId assigned by workflow-daemon (e.g. runtime-abc123)\n * GATEWAY_TOKEN — Bearer token for WS auth\n */\n\nimport { RuntimeServer } from './runtime-server.js';\n\nconst gatewayUrl = process.env['GATEWAY_WS_URL'];\nconst hostId = process.env['RUNTIME_HOST_ID'];\nconst token = process.env['GATEWAY_TOKEN'];\n\nif (!gatewayUrl) {\n process.stderr.write('[runtime-server] FATAL: GATEWAY_WS_URL is required\\n');\n process.exit(1);\n}\nif (!hostId) {\n process.stderr.write('[runtime-server] FATAL: RUNTIME_HOST_ID is required\\n');\n process.exit(1);\n}\nif (!token) {\n process.stderr.write('[runtime-server] FATAL: GATEWAY_TOKEN is required\\n');\n process.exit(1);\n}\n\nconst server = new RuntimeServer({\n gatewayUrl,\n getAccessToken: () => token,\n agentVersion: '0.1.0',\n});\n\nprocess.on('SIGTERM', () => {\n server.stop();\n process.exit(0);\n});\n\nprocess.on('SIGINT', () => {\n server.stop();\n process.exit(0);\n});\n\nserver.start().catch((err: unknown) => {\n process.stderr.write(`[runtime-server] Failed to start: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../src/runtime-server.ts","../src/cli.ts"],"names":[],"mappings":"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","file":"cli.js","sourcesContent":["/**\n * @module @kb-labs/gateway-runtime-server\n *\n * RuntimeServer — plugin execution host that connects to Gateway as a Host Agent.\n *\n * Connects via WS, registers as adapter 'execution', and handles:\n * call { adapter: 'execution', method: 'execute', args: [RemoteExecutionRequest] }\n * → runInProcess(request)\n * → chunk { data: result } + result { done: true }\n *\n * Used for isolation: strict — runs inside a container alongside the workspace.\n *\n * Design doc: docs/architecture/execution-isolation.md\n * Architecture decision: WS/Gateway transport instead of TCP (see ADR context).\n */\n\nimport * as path from 'node:path';\nimport { GatewayClient } from '@kb-labs/host-agent-core';\nimport type { GatewayClientOptions } from '@kb-labs/host-agent-core';\nimport type { CapabilityCall } from '@kb-labs/host-agent-contracts';\nimport { runInProcess } from '@kb-labs/plugin-runtime';\nimport { noopUI } from '@kb-labs/plugin-contracts';\n\n/**\n * Minimal execution request as received from RemoteBackend via Gateway dispatch.\n */\ninterface RemoteExecutionRequest {\n executionId: string;\n handlerRef: string; // absolute path inside container, e.g. /workspace/dist/handler.js\n pluginRoot: string; // base dir, e.g. /workspace\n input: unknown;\n descriptor: unknown;\n timeoutMs?: number;\n context?: unknown;\n}\n\nexport interface RuntimeServerOptions {\n /** WebSocket URL of the Gateway, e.g. http://localhost:4000 */\n gatewayUrl: string;\n /** Access token for WS auth */\n getAccessToken: () => string;\n /** Called when refresh is needed (reconnect path) */\n onTokenExpired?: () => Promise<void>;\n /** Agent version string */\n agentVersion?: string;\n /**\n * Platform services for runInProcess.\n * If omitted, a minimal noop platform is used (for container environments\n * where full platform is not available).\n */\n platform?: unknown;\n}\n\nexport class RuntimeServer {\n private readonly client: GatewayClient;\n private hostId: string | null = null;\n\n constructor(private readonly opts: RuntimeServerOptions) {\n const clientOpts: GatewayClientOptions = {\n gatewayUrl: opts.gatewayUrl,\n agentVersion: opts.agentVersion ?? '0.1.0',\n getAccessToken: opts.getAccessToken,\n onTokenExpired: opts.onTokenExpired,\n capabilities: ['execution'],\n onConnected: (hId, sessionId) => {\n this.hostId = hId;\n console.log(`[runtime-server] Connected to Gateway: hostId=${hId} session=${sessionId}`);\n },\n onDisconnected: () => {\n console.log('[runtime-server] Disconnected from Gateway, reconnecting...');\n },\n };\n\n this.client = new GatewayClient(clientOpts);\n this.client.registerHandler('execution', (call) => this.handleExecution(call));\n }\n\n async start(): Promise<void> {\n await this.client.connect();\n }\n\n stop(): void {\n this.client.stop();\n }\n\n /** The hostId assigned by Gateway after handshake (null before connected) */\n getHostId(): string | null {\n return this.hostId;\n }\n\n private async handleExecution(call: CapabilityCall): Promise<unknown> {\n if (call.method !== 'execute') {\n throw new Error(`Unknown execution method: ${call.method}`);\n }\n\n const request = call.args[0] as RemoteExecutionRequest | undefined;\n if (!request || !request.handlerRef || !request.pluginRoot) {\n throw new Error('Missing required fields: handlerRef, pluginRoot');\n }\n\n return this.executeHandler(request);\n }\n\n private async executeHandler(request: RemoteExecutionRequest): Promise<unknown> {\n // Resolve absolute handler path\n const hashIndex = request.handlerRef.indexOf('#');\n const relPath = hashIndex > 0 ? request.handlerRef.slice(0, hashIndex) : request.handlerRef;\n\n // handlerRef may be absolute (/workspace/...) or relative to pluginRoot\n const handlerPath = relPath.startsWith('/')\n ? relPath\n : path.resolve(request.pluginRoot, relPath);\n\n const platform = this.opts.platform ?? createNoopPlatform();\n\n const runResult = await runInProcess({\n descriptor: request.descriptor as Parameters<typeof runInProcess>[0]['descriptor'],\n platform: platform as Parameters<typeof runInProcess>[0]['platform'],\n ui: noopUI,\n handlerPath,\n input: request.input,\n cwd: request.pluginRoot,\n });\n\n return runResult.data;\n }\n}\n\n/**\n * Minimal noop platform for container environments.\n * Logger writes to stdout, cache is a no-op.\n * Production use should pass real platform services.\n */\nfunction createNoopPlatform(): unknown {\n return {\n logger: {\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({}),\n }),\n },\n cache: {\n get: async () => null,\n set: async () => {},\n delete: async () => {},\n clear: async () => {},\n },\n config: {},\n shell: {\n exec: async () => { throw new Error('shell.exec not available in runtime-server noop platform'); },\n },\n };\n}\n","/**\n * @module @kb-labs/gateway-runtime-server/cli\n *\n * CLI entry point for the runtime server.\n * Run inside an isolation: strict container to handle remote plugin execution.\n *\n * Required env vars:\n * GATEWAY_WS_URL — WebSocket URL of the Gateway (e.g. ws://gateway:4000)\n * RUNTIME_HOST_ID — Deterministic hostId assigned by workflow-daemon (e.g. runtime-abc123)\n * GATEWAY_TOKEN — Bearer token for WS auth\n */\n\nimport { RuntimeServer } from './runtime-server.js';\n\nconst gatewayUrl = process.env['GATEWAY_WS_URL'];\nconst hostId = process.env['RUNTIME_HOST_ID'];\nconst token = process.env['GATEWAY_TOKEN'];\n\nif (!gatewayUrl) {\n process.stderr.write('[runtime-server] FATAL: GATEWAY_WS_URL is required\\n');\n process.exit(1);\n}\nif (!hostId) {\n process.stderr.write('[runtime-server] FATAL: RUNTIME_HOST_ID is required\\n');\n process.exit(1);\n}\nif (!token) {\n process.stderr.write('[runtime-server] FATAL: GATEWAY_TOKEN is required\\n');\n process.exit(1);\n}\n\nconst server = new RuntimeServer({\n gatewayUrl,\n getAccessToken: () => token,\n agentVersion: '0.1.0',\n});\n\nprocess.on('SIGTERM', () => {\n server.stop();\n process.exit(0);\n});\n\nprocess.on('SIGINT', () => {\n server.stop();\n process.exit(0);\n});\n\nserver.start().catch((err: unknown) => {\n process.stderr.write(`[runtime-server] Failed to start: ${err instanceof Error ? err.message : String(err)}\\n`);\n process.exit(1);\n});\n"]}
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ var RuntimeServer = class {
24
24
  this.client = new GatewayClient(clientOpts);
25
25
  this.client.registerHandler("execution", (call) => this.handleExecution(call));
26
26
  }
27
+ opts;
27
28
  client;
28
29
  hostId = null;
29
30
  async start() {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/runtime-server.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/gateway-runtime-server\n *\n * RuntimeServer — plugin execution host that connects to Gateway as a Host Agent.\n *\n * Connects via WS, registers as adapter 'execution', and handles:\n * call { adapter: 'execution', method: 'execute', args: [RemoteExecutionRequest] }\n * → runInProcess(request)\n * → chunk { data: result } + result { done: true }\n *\n * Used for isolation: strict — runs inside a container alongside the workspace.\n *\n * Design doc: docs/architecture/execution-isolation.md\n * Architecture decision: WS/Gateway transport instead of TCP (see ADR context).\n */\n\nimport * as path from 'node:path';\nimport { GatewayClient } from '@kb-labs/host-agent-core';\nimport type { GatewayClientOptions } from '@kb-labs/host-agent-core';\nimport type { CapabilityCall } from '@kb-labs/host-agent-contracts';\nimport { runInProcess } from '@kb-labs/plugin-runtime';\nimport { noopUI } from '@kb-labs/plugin-contracts';\n\n/**\n * Minimal execution request as received from RemoteBackend via Gateway dispatch.\n */\ninterface RemoteExecutionRequest {\n executionId: string;\n handlerRef: string; // absolute path inside container, e.g. /workspace/dist/handler.js\n pluginRoot: string; // base dir, e.g. /workspace\n input: unknown;\n descriptor: unknown;\n timeoutMs?: number;\n context?: unknown;\n}\n\nexport interface RuntimeServerOptions {\n /** WebSocket URL of the Gateway, e.g. http://localhost:4000 */\n gatewayUrl: string;\n /** Access token for WS auth */\n getAccessToken: () => string;\n /** Called when refresh is needed (reconnect path) */\n onTokenExpired?: () => Promise<void>;\n /** Agent version string */\n agentVersion?: string;\n /**\n * Platform services for runInProcess.\n * If omitted, a minimal noop platform is used (for container environments\n * where full platform is not available).\n */\n platform?: unknown;\n}\n\nexport class RuntimeServer {\n private readonly client: GatewayClient;\n private hostId: string | null = null;\n\n constructor(private readonly opts: RuntimeServerOptions) {\n const clientOpts: GatewayClientOptions = {\n gatewayUrl: opts.gatewayUrl,\n agentVersion: opts.agentVersion ?? '0.1.0',\n getAccessToken: opts.getAccessToken,\n onTokenExpired: opts.onTokenExpired,\n capabilities: ['execution'],\n onConnected: (hId, sessionId) => {\n this.hostId = hId;\n console.log(`[runtime-server] Connected to Gateway: hostId=${hId} session=${sessionId}`);\n },\n onDisconnected: () => {\n console.log('[runtime-server] Disconnected from Gateway, reconnecting...');\n },\n };\n\n this.client = new GatewayClient(clientOpts);\n this.client.registerHandler('execution', (call) => this.handleExecution(call));\n }\n\n async start(): Promise<void> {\n await this.client.connect();\n }\n\n stop(): void {\n this.client.stop();\n }\n\n /** The hostId assigned by Gateway after handshake (null before connected) */\n getHostId(): string | null {\n return this.hostId;\n }\n\n private async handleExecution(call: CapabilityCall): Promise<unknown> {\n if (call.method !== 'execute') {\n throw new Error(`Unknown execution method: ${call.method}`);\n }\n\n const request = call.args[0] as RemoteExecutionRequest | undefined;\n if (!request || !request.handlerRef || !request.pluginRoot) {\n throw new Error('Missing required fields: handlerRef, pluginRoot');\n }\n\n return this.executeHandler(request);\n }\n\n private async executeHandler(request: RemoteExecutionRequest): Promise<unknown> {\n // Resolve absolute handler path\n const hashIndex = request.handlerRef.indexOf('#');\n const relPath = hashIndex > 0 ? request.handlerRef.slice(0, hashIndex) : request.handlerRef;\n\n // handlerRef may be absolute (/workspace/...) or relative to pluginRoot\n const handlerPath = relPath.startsWith('/')\n ? relPath\n : path.resolve(request.pluginRoot, relPath);\n\n const platform = this.opts.platform ?? createNoopPlatform();\n\n const runResult = await runInProcess({\n descriptor: request.descriptor as Parameters<typeof runInProcess>[0]['descriptor'],\n platform: platform as Parameters<typeof runInProcess>[0]['platform'],\n ui: noopUI,\n handlerPath,\n input: request.input,\n cwd: request.pluginRoot,\n });\n\n return runResult.data;\n }\n}\n\n/**\n * Minimal noop platform for container environments.\n * Logger writes to stdout, cache is a no-op.\n * Production use should pass real platform services.\n */\nfunction createNoopPlatform(): unknown {\n return {\n logger: {\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({}),\n }),\n },\n cache: {\n get: async () => null,\n set: async () => {},\n delete: async () => {},\n clear: async () => {},\n },\n config: {},\n shell: {\n exec: async () => { throw new Error('shell.exec not available in runtime-server noop platform'); },\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/runtime-server.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/gateway-runtime-server\n *\n * RuntimeServer — plugin execution host that connects to Gateway as a Host Agent.\n *\n * Connects via WS, registers as adapter 'execution', and handles:\n * call { adapter: 'execution', method: 'execute', args: [RemoteExecutionRequest] }\n * → runInProcess(request)\n * → chunk { data: result } + result { done: true }\n *\n * Used for isolation: strict — runs inside a container alongside the workspace.\n *\n * Design doc: docs/architecture/execution-isolation.md\n * Architecture decision: WS/Gateway transport instead of TCP (see ADR context).\n */\n\nimport * as path from 'node:path';\nimport { GatewayClient } from '@kb-labs/host-agent-core';\nimport type { GatewayClientOptions } from '@kb-labs/host-agent-core';\nimport type { CapabilityCall } from '@kb-labs/host-agent-contracts';\nimport { runInProcess } from '@kb-labs/plugin-runtime';\nimport { noopUI } from '@kb-labs/plugin-contracts';\n\n/**\n * Minimal execution request as received from RemoteBackend via Gateway dispatch.\n */\ninterface RemoteExecutionRequest {\n executionId: string;\n handlerRef: string; // absolute path inside container, e.g. /workspace/dist/handler.js\n pluginRoot: string; // base dir, e.g. /workspace\n input: unknown;\n descriptor: unknown;\n timeoutMs?: number;\n context?: unknown;\n}\n\nexport interface RuntimeServerOptions {\n /** WebSocket URL of the Gateway, e.g. http://localhost:4000 */\n gatewayUrl: string;\n /** Access token for WS auth */\n getAccessToken: () => string;\n /** Called when refresh is needed (reconnect path) */\n onTokenExpired?: () => Promise<void>;\n /** Agent version string */\n agentVersion?: string;\n /**\n * Platform services for runInProcess.\n * If omitted, a minimal noop platform is used (for container environments\n * where full platform is not available).\n */\n platform?: unknown;\n}\n\nexport class RuntimeServer {\n private readonly client: GatewayClient;\n private hostId: string | null = null;\n\n constructor(private readonly opts: RuntimeServerOptions) {\n const clientOpts: GatewayClientOptions = {\n gatewayUrl: opts.gatewayUrl,\n agentVersion: opts.agentVersion ?? '0.1.0',\n getAccessToken: opts.getAccessToken,\n onTokenExpired: opts.onTokenExpired,\n capabilities: ['execution'],\n onConnected: (hId, sessionId) => {\n this.hostId = hId;\n console.log(`[runtime-server] Connected to Gateway: hostId=${hId} session=${sessionId}`);\n },\n onDisconnected: () => {\n console.log('[runtime-server] Disconnected from Gateway, reconnecting...');\n },\n };\n\n this.client = new GatewayClient(clientOpts);\n this.client.registerHandler('execution', (call) => this.handleExecution(call));\n }\n\n async start(): Promise<void> {\n await this.client.connect();\n }\n\n stop(): void {\n this.client.stop();\n }\n\n /** The hostId assigned by Gateway after handshake (null before connected) */\n getHostId(): string | null {\n return this.hostId;\n }\n\n private async handleExecution(call: CapabilityCall): Promise<unknown> {\n if (call.method !== 'execute') {\n throw new Error(`Unknown execution method: ${call.method}`);\n }\n\n const request = call.args[0] as RemoteExecutionRequest | undefined;\n if (!request || !request.handlerRef || !request.pluginRoot) {\n throw new Error('Missing required fields: handlerRef, pluginRoot');\n }\n\n return this.executeHandler(request);\n }\n\n private async executeHandler(request: RemoteExecutionRequest): Promise<unknown> {\n // Resolve absolute handler path\n const hashIndex = request.handlerRef.indexOf('#');\n const relPath = hashIndex > 0 ? request.handlerRef.slice(0, hashIndex) : request.handlerRef;\n\n // handlerRef may be absolute (/workspace/...) or relative to pluginRoot\n const handlerPath = relPath.startsWith('/')\n ? relPath\n : path.resolve(request.pluginRoot, relPath);\n\n const platform = this.opts.platform ?? createNoopPlatform();\n\n const runResult = await runInProcess({\n descriptor: request.descriptor as Parameters<typeof runInProcess>[0]['descriptor'],\n platform: platform as Parameters<typeof runInProcess>[0]['platform'],\n ui: noopUI,\n handlerPath,\n input: request.input,\n cwd: request.pluginRoot,\n });\n\n return runResult.data;\n }\n}\n\n/**\n * Minimal noop platform for container environments.\n * Logger writes to stdout, cache is a no-op.\n * Production use should pass real platform services.\n */\nfunction createNoopPlatform(): unknown {\n return {\n logger: {\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({\n info: (msg: string, meta?: unknown) => console.log('[handler]', msg, meta ?? ''),\n warn: (msg: string, meta?: unknown) => console.warn('[handler]', msg, meta ?? ''),\n error: (msg: string, meta?: unknown) => console.error('[handler]', msg, meta ?? ''),\n debug: () => {},\n child: () => ({}),\n }),\n },\n cache: {\n get: async () => null,\n set: async () => {},\n delete: async () => {},\n clear: async () => {},\n },\n config: {},\n shell: {\n exec: async () => { throw new Error('shell.exec not available in runtime-server noop platform'); },\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,12 +1,24 @@
1
1
  {
2
- "name": "@kb-labs/gateway-runtime-server",
3
- "version": "0.4.0",
4
- "type": "module",
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
7
2
  "bin": {
8
3
  "kb-runtime-server": "./dist/cli.js"
9
4
  },
5
+ "dependencies": {
6
+ "@kb-labs/host-agent-contracts": "^2.6.0",
7
+ "@kb-labs/host-agent-core": "^2.6.0",
8
+ "@kb-labs/plugin-contracts": "^2.6.0",
9
+ "@kb-labs/plugin-runtime": "^2.6.0"
10
+ },
11
+ "devDependencies": {
12
+ "@kb-labs/devkit": "workspace:*",
13
+ "@types/node": "^22.0.0",
14
+ "tsup": "^8.5.0",
15
+ "typescript": "^5",
16
+ "vitest": "^3.2.4"
17
+ },
18
+ "engines": {
19
+ "node": ">=20.0.0",
20
+ "pnpm": ">=9.0.0"
21
+ },
10
22
  "exports": {
11
23
  ".": {
12
24
  "import": "./dist/index.js",
@@ -16,29 +28,22 @@
16
28
  "files": [
17
29
  "dist"
18
30
  ],
19
- "sideEffects": false,
31
+ "main": "./dist/index.js",
32
+ "name": "@kb-labs/gateway-runtime-server",
20
33
  "scripts": {
21
- "clean": "rimraf dist",
22
34
  "build": "tsup",
35
+ "build:docker": "DOCKER_BUILD=1 tsup",
36
+ "clean": "rimraf dist",
23
37
  "dev": "tsup --watch",
24
- "type-check": "tsc --noEmit",
38
+ "docker:build": "pnpm run build:docker && docker build -t kb-runtime-server:local .",
25
39
  "lint": "eslint .",
26
40
  "lint:fix": "eslint . --fix",
27
41
  "test": "vitest run -c ../../vitest.config.ts",
28
42
  "test:watch": "vitest -c ../../vitest.config.ts",
29
- "build:docker": "DOCKER_BUILD=1 tsup",
30
- "docker:build": "pnpm run build:docker && docker build -t kb-runtime-server:local ."
31
- },
32
- "dependencies": {
33
- "@kb-labs/host-agent-core": "^0.2.0",
34
- "@kb-labs/host-agent-contracts": "^0.2.0",
35
- "@kb-labs/plugin-runtime": "^1.4.0",
36
- "@kb-labs/plugin-contracts": "^1.4.0"
43
+ "type-check": "tsc --noEmit"
37
44
  },
38
- "devDependencies": {
39
- "@kb-labs/devkit": "link:../../../kb-labs-devkit",
40
- "@types/node": "^22.0.0",
41
- "tsup": "^8.5.0",
42
- "vitest": "^3.2.4"
43
- }
45
+ "sideEffects": false,
46
+ "type": "module",
47
+ "types": "./dist/index.d.ts",
48
+ "version": "2.6.0"
44
49
  }