pi-harness-runtime 1.1.375 → 1.1.376

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +68 -39
  2. package/package.json +2 -1
  3. package/packages/a2a-adapter/package.json +1 -1
  4. package/packages/agent-policy/package.json +1 -1
  5. package/packages/architecture-generator/package.json +1 -1
  6. package/packages/auth/package.json +1 -1
  7. package/packages/autonomous-refactor/package.json +1 -1
  8. package/packages/autonomous-runtime/package.json +1 -1
  9. package/packages/cache-strategy/package.json +1 -1
  10. package/packages/capability-registry/package.json +1 -1
  11. package/packages/checkpoint/package.json +1 -1
  12. package/packages/cli-plugin-sdk/package.json +1 -1
  13. package/packages/clipboard/package.json +1 -1
  14. package/packages/clipboard-plugin/package.json +1 -1
  15. package/packages/code-generation/package.json +1 -1
  16. package/packages/code-review/package.json +1 -1
  17. package/packages/codex-adapter/package.json +1 -1
  18. package/packages/codex-watcher/package.json +1 -1
  19. package/packages/config-capture/package.json +1 -1
  20. package/packages/connection-runtime/package.json +1 -1
  21. package/packages/context-compiler/package.json +1 -1
  22. package/packages/context-discovery/package.json +1 -1
  23. package/packages/context-manager/package.json +1 -1
  24. package/packages/contracts/package.json +1 -1
  25. package/packages/cookie-sanitizer/package.json +1 -1
  26. package/packages/cost-optimizer/package.json +1 -1
  27. package/packages/dependency-analyzer/package.json +1 -1
  28. package/packages/django-plugin/package.json +1 -1
  29. package/packages/doc-generator/package.json +1 -1
  30. package/packages/durable-review/package.json +1 -1
  31. package/packages/e2e-tester/package.json +1 -1
  32. package/packages/evaluation-engine/package.json +1 -1
  33. package/packages/evaluation-runner/package.json +1 -1
  34. package/packages/event-bus/package.json +1 -1
  35. package/packages/event-sink/package.json +1 -1
  36. package/packages/event-store/package.json +1 -1
  37. package/packages/experience-replay/package.json +1 -1
  38. package/packages/feedback-collector/package.json +1 -1
  39. package/packages/file-copy-helper/package.json +1 -1
  40. package/packages/framework-detector/package.json +1 -1
  41. package/packages/framework-plugin-sdk/package.json +1 -1
  42. package/packages/frappe-plugin/package.json +1 -1
  43. package/packages/generic-web-plugin/package.json +1 -1
  44. package/packages/health-monitor/package.json +1 -1
  45. package/packages/intent-analyzer/package.json +1 -1
  46. package/packages/jev-judge/package.json +1 -1
  47. package/packages/knowledge-graph/package.json +1 -1
  48. package/packages/knowledge-retrieval/package.json +1 -1
  49. package/packages/laravel-plugin/package.json +1 -1
  50. package/packages/learning-engine/package.json +1 -1
  51. package/packages/mcp-adapter/package.json +1 -1
  52. package/packages/memory-engine/package.json +1 -1
  53. package/packages/milestone-manager/package.json +1 -1
  54. package/packages/model-registry/package.json +1 -1
  55. package/packages/nextjs-plugin/package.json +1 -1
  56. package/packages/notification/package.json +1 -1
  57. package/packages/observability/package.json +1 -1
  58. package/packages/okf-indexer/package.json +1 -1
  59. package/packages/paperclip-integration/package.json +1 -1
  60. package/packages/performance-optimizer/package.json +1 -1
  61. package/packages/permission-mode/package.json +1 -1
  62. package/packages/privilege-broker/package.json +1 -1
  63. package/packages/project-analyzer/package.json +1 -1
  64. package/packages/project-bootstrap/package.json +1 -1
  65. package/packages/projection-engine/package.json +1 -1
  66. package/packages/prompt-compiler/package.json +1 -1
  67. package/packages/prompt-versioning/package.json +1 -1
  68. package/packages/provider-adapter-sdk/package.json +1 -1
  69. package/packages/provider-router/package.json +1 -1
  70. package/packages/provider-selector/package.json +1 -1
  71. package/packages/providers/package.json +1 -1
  72. package/packages/qdrant-skills/package.json +1 -1
  73. package/packages/quota-manager/package.json +1 -1
  74. package/packages/rate-limiter/package.json +1 -1
  75. package/packages/react-vite-plugin/package.json +1 -1
  76. package/packages/relay/dist/ws-server.d.ts +48 -0
  77. package/packages/relay/dist/ws-server.js +130 -0
  78. package/packages/relay/package.json +1 -1
  79. package/packages/relay/src/ws-server.ts +165 -0
  80. package/packages/release-manager/package.json +1 -1
  81. package/packages/requirement-compiler/package.json +1 -1
  82. package/packages/runtime/package.json +1 -1
  83. package/packages/scheduler/package.json +1 -1
  84. package/packages/scheduler-adapter/package.json +1 -1
  85. package/packages/session/package.json +1 -1
  86. package/packages/session-api/package.json +1 -1
  87. package/packages/session-export/package.json +1 -1
  88. package/packages/shared-context/package.json +1 -1
  89. package/packages/skill-mcp-client/package.json +1 -1
  90. package/packages/skill-registry/package.json +1 -1
  91. package/packages/skills/package.json +1 -1
  92. package/packages/sprint-planner/package.json +1 -1
  93. package/packages/subscription-engine/package.json +1 -1
  94. package/packages/task-compiler/package.json +1 -1
  95. package/packages/telegram/package.json +1 -1
  96. package/packages/tencentdb-memory/package.json +1 -1
  97. package/packages/tencentdb-sync/package.json +1 -1
  98. package/packages/test-data-generator/package.json +1 -1
  99. package/packages/test-generator/package.json +1 -1
  100. package/packages/todo-bd-sync/package.json +1 -1
  101. package/packages/token-estimation/package.json +1 -1
  102. package/packages/token-optimizer/package.json +1 -1
  103. package/packages/trajectory/package.json +1 -1
  104. package/packages/tui/package.json +1 -1
  105. package/packages/types/package.json +1 -1
  106. package/packages/voice-api/package.json +1 -1
  107. package/packages/webmcp-tester/package.json +1 -1
  108. package/packages/wiki/package.json +1 -1
  109. package/packages/workflow-events/package.json +1 -1
  110. package/packages/workspace-scanner/package.json +1 -1
  111. package/packages/worktree/package.json +1 -1
  112. package/packages/write-review/package.json +1 -1
  113. package/scripts/relay-client.ts +175 -0
  114. package/scripts/sync-callback-queue.ts +57 -0
  115. package/scripts/telegram-callback-processor.ts +16 -0
  116. package/scripts/unified-webhook-server.ts +142 -129
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/milestone-manager",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Track milestones and alerts when items are at risk",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/model-registry",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Model Registry for pi-harness-runtime — centralized model metadata with pricing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/nextjs-plugin",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Next.js framework detection and analysis for pi-harness-runtime (RFC-0062)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/notification",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — notification",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/observability",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Comprehensive observability system with structured logging, tracing, metrics, and alerting",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/okf-indexer",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "OKF document indexer for SKILL.md files (RFC-0106)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/paperclip-integration",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Paperclip API integration: poll agent inbox, route tasks to pi.dev, Telegram alerts",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/performance-optimizer",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Performance optimization analyzer for pi-harness runtime (RFC-0056)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/permission-mode",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "description": "Runtime permission modes for pi-harness - Supervised/Auto/Full-access",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/privilege-broker",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Privilege Broker — capability registry and command executor for autonomous runtime (RFC-0101 §7)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/project-analyzer",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Project analysis system for pi-harness-runtime - detects frameworks, rules, and project structure",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/project-bootstrap",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Project scaffolding from typed ProjectSpec",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/projection-engine",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/prompt-compiler",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Deterministic prompt compiler for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/prompt-versioning",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "description": "Version control for prompts with rollback support (RFC-0019)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/provider-adapter-sdk",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "SDK for building, testing, and registering AI provider adapters",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/provider-router",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Enhanced Provider Router for pi-harness-runtime — intelligent routing with capabilities, costs, and quotas",
5
5
  "type": "module",
6
6
  "main": "./dist/provider-router.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/provider-selector",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Multi-Provider Selector — route requests by cost, quality, and latency (RFC-0012)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/providers",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — providers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/qdrant-skills",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Qdrant vector search integration for Hermes-style skill system",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/quota-manager",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — quota-manager",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/rate-limiter",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "description": "Rate limiting with token bucket algorithm (RFC-0023)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/react-vite-plugin",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "React/Vite framework analysis — components, config, TypeScript setup",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,48 @@
1
+ /**
2
+ * WebSocket Relay Server - Pushes callbacks to connected clients in real-time
3
+ *
4
+ * Architecture:
5
+ * Telegram/LINE → Webhook → This Server → WebSocket → Local Client
6
+ *
7
+ * No file queue needed - real-time streaming!
8
+ */
9
+ export interface RelayMessage {
10
+ type: "callback" | "ping" | "pong" | "auth";
11
+ payload: unknown;
12
+ }
13
+ export interface CallbackPayload {
14
+ type: "telegram_callback" | "line_callback";
15
+ action: string;
16
+ targetId: string;
17
+ userId: number;
18
+ username?: string;
19
+ messageId?: number;
20
+ timestamp: string;
21
+ }
22
+ /**
23
+ * WebSocket Relay Server
24
+ */
25
+ export declare class WsRelayServer {
26
+ private server;
27
+ private wss;
28
+ private clients;
29
+ private port;
30
+ private running;
31
+ constructor(port?: number);
32
+ /**
33
+ * Start the WebSocket server
34
+ */
35
+ start(): Promise<void>;
36
+ private handleMessage;
37
+ /**
38
+ * Broadcast callback to all connected clients
39
+ */
40
+ broadcastCallback(callback: CallbackPayload): void;
41
+ /**
42
+ * Stop the server
43
+ */
44
+ stop(): Promise<void>;
45
+ isRunning(): boolean;
46
+ getClientCount(): number;
47
+ }
48
+ export declare function getRelayServer(): WsRelayServer;
@@ -0,0 +1,130 @@
1
+ /**
2
+ * WebSocket Relay Server - Pushes callbacks to connected clients in real-time
3
+ *
4
+ * Architecture:
5
+ * Telegram/LINE → Webhook → This Server → WebSocket → Local Client
6
+ *
7
+ * No file queue needed - real-time streaming!
8
+ */
9
+ import { createServer } from "node:http";
10
+ import { WebSocketServer, WebSocket } from "ws";
11
+ import { randomUUID } from "node:crypto";
12
+ const AUTH_TOKEN = process.env.RELAY_AUTH_TOKEN || "change-me-in-production";
13
+ /**
14
+ * WebSocket Relay Server
15
+ */
16
+ export class WsRelayServer {
17
+ server = null;
18
+ wss = null;
19
+ clients = new Map();
20
+ port;
21
+ running = false;
22
+ constructor(port = 8444) {
23
+ this.port = port;
24
+ }
25
+ /**
26
+ * Start the WebSocket server
27
+ */
28
+ async start() {
29
+ if (this.running)
30
+ return;
31
+ this.server = createServer();
32
+ this.wss = new WebSocketServer({ server: this.server });
33
+ this.wss.on("connection", (ws, req) => {
34
+ const clientId = randomUUID();
35
+ console.log(`[WsRelay] Client connected: ${clientId} from ${req.socket.remoteAddress}`);
36
+ // Don't auth yet - just accept connection
37
+ // Client will send auth message
38
+ ws.on("message", (data) => {
39
+ try {
40
+ const msg = JSON.parse(data.toString());
41
+ this.handleMessage(ws, clientId, msg);
42
+ }
43
+ catch (err) {
44
+ console.error("[WsRelay] Invalid message:", err);
45
+ }
46
+ });
47
+ ws.on("close", () => {
48
+ this.clients.delete(clientId);
49
+ console.log(`[WsRelay] Client disconnected: ${clientId}`);
50
+ });
51
+ ws.on("error", (err) => {
52
+ console.error(`[WsRelay] Client error: ${clientId}`, err);
53
+ this.clients.delete(clientId);
54
+ });
55
+ // Send welcome
56
+ ws.send(JSON.stringify({ type: "connected", payload: { clientId } }));
57
+ });
58
+ return new Promise((resolve) => {
59
+ this.server.listen(this.port, () => {
60
+ this.running = true;
61
+ console.log(`[WsRelay] Server started on port ${this.port}`);
62
+ resolve();
63
+ });
64
+ });
65
+ }
66
+ handleMessage(ws, clientId, msg) {
67
+ switch (msg.type) {
68
+ case "auth":
69
+ if (msg.payload === AUTH_TOKEN) {
70
+ this.clients.set(clientId, ws);
71
+ ws.send(JSON.stringify({ type: "auth", payload: { success: true } }));
72
+ console.log(`[WsRelay] Client authenticated: ${clientId}`);
73
+ }
74
+ else {
75
+ ws.send(JSON.stringify({ type: "auth", payload: { success: false, error: "Invalid token" } }));
76
+ ws.close();
77
+ }
78
+ break;
79
+ case "ping":
80
+ ws.send(JSON.stringify({ type: "pong", payload: {} }));
81
+ break;
82
+ }
83
+ }
84
+ /**
85
+ * Broadcast callback to all connected clients
86
+ */
87
+ broadcastCallback(callback) {
88
+ const msg = JSON.stringify({ type: "callback", payload: callback });
89
+ let count = 0;
90
+ for (const [clientId, ws] of this.clients) {
91
+ if (ws.readyState === WebSocket.OPEN) {
92
+ ws.send(msg);
93
+ count++;
94
+ }
95
+ }
96
+ console.log(`[WsRelay] Broadcast callback to ${count} client(s): ${callback.action} ${callback.targetId}`);
97
+ }
98
+ /**
99
+ * Stop the server
100
+ */
101
+ async stop() {
102
+ if (!this.running)
103
+ return;
104
+ for (const ws of this.clients.values()) {
105
+ ws.close();
106
+ }
107
+ this.clients.clear();
108
+ return new Promise((resolve) => {
109
+ this.server.close(() => {
110
+ this.running = false;
111
+ console.log("[WsRelay] Server stopped");
112
+ resolve();
113
+ });
114
+ });
115
+ }
116
+ isRunning() {
117
+ return this.running;
118
+ }
119
+ getClientCount() {
120
+ return this.clients.size;
121
+ }
122
+ }
123
+ // Export singleton for use in unified webhook server
124
+ let singleton = null;
125
+ export function getRelayServer() {
126
+ if (!singleton) {
127
+ singleton = new WsRelayServer();
128
+ }
129
+ return singleton;
130
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/relay",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "description": "Cloud relay for remote access - T3 Connect style for pi-harness",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,165 @@
1
+ /**
2
+ * WebSocket Relay Server - Pushes callbacks to connected clients in real-time
3
+ *
4
+ * Architecture:
5
+ * Telegram/LINE → Webhook → This Server → WebSocket → Local Client
6
+ *
7
+ * No file queue needed - real-time streaming!
8
+ */
9
+
10
+ import { createServer, IncomingMessage, ServerResponse, Server } from "node:http";
11
+ import { WebSocketServer, WebSocket } from "ws";
12
+ import { randomUUID } from "node:crypto";
13
+
14
+ export interface RelayMessage {
15
+ type: "callback" | "ping" | "pong" | "auth";
16
+ payload: unknown;
17
+ }
18
+
19
+ export interface CallbackPayload {
20
+ type: "telegram_callback" | "line_callback";
21
+ action: string;
22
+ targetId: string;
23
+ userId: number;
24
+ username?: string;
25
+ messageId?: number;
26
+ timestamp: string;
27
+ }
28
+
29
+ const AUTH_TOKEN = process.env.RELAY_AUTH_TOKEN || "change-me-in-production";
30
+
31
+ /**
32
+ * WebSocket Relay Server
33
+ */
34
+ export class WsRelayServer {
35
+ private server: Server | null = null;
36
+ private wss: WebSocketServer | null = null;
37
+ private clients = new Map<string, WebSocket>();
38
+ private port: number;
39
+ private running = false;
40
+
41
+ constructor(port = 8444) {
42
+ this.port = port;
43
+ }
44
+
45
+ /**
46
+ * Start the WebSocket server
47
+ */
48
+ async start(): Promise<void> {
49
+ if (this.running) return;
50
+
51
+ this.server = createServer();
52
+ this.wss = new WebSocketServer({ server: this.server });
53
+
54
+ this.wss.on("connection", (ws: WebSocket, req: IncomingMessage) => {
55
+ const clientId = randomUUID();
56
+ console.log(`[WsRelay] Client connected: ${clientId} from ${req.socket.remoteAddress}`);
57
+
58
+ // Don't auth yet - just accept connection
59
+ // Client will send auth message
60
+ ws.on("message", (data: Buffer) => {
61
+ try {
62
+ const msg = JSON.parse(data.toString()) as RelayMessage;
63
+ this.handleMessage(ws, clientId, msg);
64
+ } catch (err) {
65
+ console.error("[WsRelay] Invalid message:", err);
66
+ }
67
+ });
68
+
69
+ ws.on("close", () => {
70
+ this.clients.delete(clientId);
71
+ console.log(`[WsRelay] Client disconnected: ${clientId}`);
72
+ });
73
+
74
+ ws.on("error", (err) => {
75
+ console.error(`[WsRelay] Client error: ${clientId}`, err);
76
+ this.clients.delete(clientId);
77
+ });
78
+
79
+ // Send welcome
80
+ ws.send(JSON.stringify({ type: "connected", payload: { clientId } }));
81
+ });
82
+
83
+ return new Promise((resolve) => {
84
+ this.server!.listen(this.port, () => {
85
+ this.running = true;
86
+ console.log(`[WsRelay] Server started on port ${this.port}`);
87
+ resolve();
88
+ });
89
+ });
90
+ }
91
+
92
+ private handleMessage(ws: WebSocket, clientId: string, msg: RelayMessage): void {
93
+ switch (msg.type) {
94
+ case "auth":
95
+ if (msg.payload === AUTH_TOKEN) {
96
+ this.clients.set(clientId, ws);
97
+ ws.send(JSON.stringify({ type: "auth", payload: { success: true } }));
98
+ console.log(`[WsRelay] Client authenticated: ${clientId}`);
99
+ } else {
100
+ ws.send(JSON.stringify({ type: "auth", payload: { success: false, error: "Invalid token" } }));
101
+ ws.close();
102
+ }
103
+ break;
104
+
105
+ case "ping":
106
+ ws.send(JSON.stringify({ type: "pong", payload: {} }));
107
+ break;
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Broadcast callback to all connected clients
113
+ */
114
+ broadcastCallback(callback: CallbackPayload): void {
115
+ const msg = JSON.stringify({ type: "callback", payload: callback });
116
+ let count = 0;
117
+
118
+ for (const [clientId, ws] of this.clients) {
119
+ if (ws.readyState === WebSocket.OPEN) {
120
+ ws.send(msg);
121
+ count++;
122
+ }
123
+ }
124
+
125
+ console.log(`[WsRelay] Broadcast callback to ${count} client(s): ${callback.action} ${callback.targetId}`);
126
+ }
127
+
128
+ /**
129
+ * Stop the server
130
+ */
131
+ async stop(): Promise<void> {
132
+ if (!this.running) return;
133
+
134
+ for (const ws of this.clients.values()) {
135
+ ws.close();
136
+ }
137
+ this.clients.clear();
138
+
139
+ return new Promise((resolve) => {
140
+ this.server!.close(() => {
141
+ this.running = false;
142
+ console.log("[WsRelay] Server stopped");
143
+ resolve();
144
+ });
145
+ });
146
+ }
147
+
148
+ isRunning(): boolean {
149
+ return this.running;
150
+ }
151
+
152
+ getClientCount(): number {
153
+ return this.clients.size;
154
+ }
155
+ }
156
+
157
+ // Export singleton for use in unified webhook server
158
+ let singleton: WsRelayServer | null = null;
159
+
160
+ export function getRelayServer(): WsRelayServer {
161
+ if (!singleton) {
162
+ singleton = new WsRelayServer();
163
+ }
164
+ return singleton;
165
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/release-manager",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "description": "Release management for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/requirement-compiler",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Compiles raw requirements into validated CompiledRequirement with ambiguity detection and risk tagging",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/runtime",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/scheduler",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — scheduler",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/scheduler-adapter",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Scheduler Adapter — cron, systemd, launchd, internal adapters for autonomous runtime (RFC-0101 §6)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "Session management system for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-api",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/session-export",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/shared-context",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "pi-harness-runtime — shared-context",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/skill-mcp-client",
3
- "version": "1.1.375",
3
+ "version": "1.1.376",
4
4
  "description": "MCP client for Skills SaaS backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",