pi-harness-runtime 1.1.375 → 1.1.377

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 (129) 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/client.d.ts +56 -35
  77. package/packages/relay/dist/client.js +278 -71
  78. package/packages/relay/dist/index.d.ts +12 -5
  79. package/packages/relay/dist/index.js +12 -4
  80. package/packages/relay/dist/server.d.ts +58 -20
  81. package/packages/relay/dist/server.js +344 -49
  82. package/packages/relay/dist/types.d.ts +137 -1
  83. package/packages/relay/dist/types.js +21 -2
  84. package/packages/relay/dist/ws-server.d.ts +48 -0
  85. package/packages/relay/dist/ws-server.js +130 -0
  86. package/packages/relay/package.json +1 -1
  87. package/packages/relay/src/client.ts +375 -81
  88. package/packages/relay/src/index.ts +42 -5
  89. package/packages/relay/src/server.ts +452 -54
  90. package/packages/relay/src/types.ts +174 -1
  91. package/packages/relay/src/ws-server.ts +165 -0
  92. package/packages/release-manager/package.json +1 -1
  93. package/packages/requirement-compiler/package.json +1 -1
  94. package/packages/runtime/package.json +1 -1
  95. package/packages/scheduler/package.json +1 -1
  96. package/packages/scheduler-adapter/package.json +1 -1
  97. package/packages/session/package.json +1 -1
  98. package/packages/session-api/package.json +1 -1
  99. package/packages/session-export/package.json +1 -1
  100. package/packages/shared-context/package.json +1 -1
  101. package/packages/skill-mcp-client/package.json +1 -1
  102. package/packages/skill-registry/package.json +1 -1
  103. package/packages/skills/package.json +1 -1
  104. package/packages/sprint-planner/package.json +1 -1
  105. package/packages/subscription-engine/package.json +1 -1
  106. package/packages/task-compiler/package.json +1 -1
  107. package/packages/telegram/package.json +1 -1
  108. package/packages/tencentdb-memory/package.json +1 -1
  109. package/packages/tencentdb-sync/package.json +1 -1
  110. package/packages/test-data-generator/package.json +1 -1
  111. package/packages/test-generator/package.json +1 -1
  112. package/packages/todo-bd-sync/package.json +1 -1
  113. package/packages/token-estimation/package.json +1 -1
  114. package/packages/token-optimizer/package.json +1 -1
  115. package/packages/trajectory/package.json +1 -1
  116. package/packages/tui/package.json +1 -1
  117. package/packages/types/package.json +1 -1
  118. package/packages/voice-api/package.json +1 -1
  119. package/packages/webmcp-tester/package.json +1 -1
  120. package/packages/wiki/package.json +1 -1
  121. package/packages/workflow-events/package.json +1 -1
  122. package/packages/workspace-scanner/package.json +1 -1
  123. package/packages/worktree/package.json +1 -1
  124. package/packages/write-review/package.json +1 -1
  125. package/scripts/relay-client.ts +184 -0
  126. package/scripts/sync-callback-queue.ts +57 -0
  127. package/scripts/telegram-callback-processor.ts +16 -0
  128. package/scripts/unified-webhook-server.ts +160 -145
  129. package/scripts/ws-server.ts +81 -0
@@ -0,0 +1,184 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Real-time Callback Relay Client - Two-way streaming
4
+ *
5
+ * Uses the relay package's typed streaming protocol:
6
+ * - Snapshot + Live event pattern (t3code style)
7
+ * - Connection state machine with automatic reconnection
8
+ * - Typed message handling
9
+ *
10
+ * Usage:
11
+ * RELAY_WS_URL=wss://webhook.bunchee.online:8444 \
12
+ * RELAY_AUTH_TOKEN=change-me-in-production \
13
+ * bun run scripts/relay-client.ts
14
+ */
15
+
16
+ import { readFileSync, writeFileSync, existsSync } from "fs";
17
+ import { join } from "path";
18
+ import { homedir } from "os";
19
+ import { RelayClient } from "../packages/relay/src/client";
20
+ import type { CallbackPayload, SnapshotMessage } from "../packages/relay/src/types";
21
+
22
+ // Configuration
23
+ const RELAY_WS_URL = process.env.RELAY_WS_URL || "wss://webhook.bunchee.online:8444";
24
+ const RELAY_AUTH_TOKEN = process.env.RELAY_AUTH_TOKEN || "change-me-in-production";
25
+ const JOB_PIPE_FILE = join(homedir(), ".pi-harness-runtime", "job-commands.jsonl");
26
+
27
+ // ============================================================================
28
+ // Telegram Integration
29
+ // ============================================================================
30
+
31
+ function loadKeys() {
32
+ const keysDir = join(homedir(), ".pi-harness-runtime", "keys");
33
+ return {
34
+ telegramBotToken: readFileSync(join(keysDir, "telegram-bot-token.txt"), "utf8").trim(),
35
+ telegramAllowedUsers: readFileSync(join(keysDir, "telegram-allowed-users.txt"), "utf8").trim(),
36
+ };
37
+ }
38
+
39
+ function writeToJobPipe(command: { command: string; jobId: string; userId: number; timestamp: string }): void {
40
+ const line = JSON.stringify(command) + "\n";
41
+ writeFileSync(JOB_PIPE_FILE, line, { flag: "a" });
42
+ console.log(`[Client] Wrote to job pipe: ${command.command} ${command.jobId}`);
43
+ }
44
+
45
+ async function sendTelegramMessage(chatId: number, text: string): Promise<void> {
46
+ const keys = loadKeys();
47
+ await fetch(`https://api.telegram.org/bot${keys.telegramBotToken}/sendMessage`, {
48
+ method: "POST",
49
+ headers: { "Content-Type": "application/json" },
50
+ body: JSON.stringify({ chat_id: chatId, text }),
51
+ });
52
+ }
53
+
54
+ // ============================================================================
55
+ // Callback Processing
56
+ // ============================================================================
57
+
58
+ async function processCallback(callback: CallbackPayload): Promise<void> {
59
+ console.log(`[Client] Processing: ${callback.type} - ${callback.action} ${callback.targetId}`);
60
+
61
+ switch (callback.action) {
62
+ case "approve":
63
+ writeToJobPipe({
64
+ command: "resume",
65
+ jobId: callback.targetId,
66
+ userId: callback.userId,
67
+ timestamp: new Date().toISOString(),
68
+ });
69
+ await sendTelegramMessage(callback.userId, `Approved! Job ${callback.targetId} will resume.`);
70
+ break;
71
+
72
+ case "reject":
73
+ writeToJobPipe({
74
+ command: "cancel",
75
+ jobId: callback.targetId,
76
+ userId: callback.userId,
77
+ timestamp: new Date().toISOString(),
78
+ });
79
+ await sendTelegramMessage(callback.userId, `Rejected. Job ${callback.targetId} cancelled.`);
80
+ break;
81
+
82
+ case "sayhi":
83
+ await sendTelegramMessage(
84
+ callback.userId,
85
+ "Hi! Two-way streaming communication working!"
86
+ );
87
+ break;
88
+
89
+ default:
90
+ console.log(`[Client] Unknown action: ${callback.action}`);
91
+ }
92
+ }
93
+
94
+ // ============================================================================
95
+ // Main
96
+ // ============================================================================
97
+
98
+ async function main() {
99
+ console.log("===========================================");
100
+ console.log("Real-time Callback Relay Client - Streaming v2");
101
+ console.log("===========================================");
102
+ console.log(`Server: ${RELAY_WS_URL}`);
103
+ console.log("===========================================");
104
+
105
+ // Create client with typed callbacks
106
+ const client = new RelayClient(
107
+ {
108
+ serverUrl: RELAY_WS_URL,
109
+ token: RELAY_AUTH_TOKEN,
110
+ keepAlive: 30000,
111
+ },
112
+ {
113
+ onConnected: (sessionId) => {
114
+ console.log(`[Client] Connected! Session: ${sessionId}`);
115
+ },
116
+
117
+ onDisconnected: () => {
118
+ console.log("[Client] Disconnected");
119
+ },
120
+
121
+ onSnapshot: (snapshot: SnapshotMessage["payload"]) => {
122
+ console.log(`[Client] Snapshot received:`);
123
+ console.log(` - Session: ${snapshot.sessionId}`);
124
+ console.log(` - Version: ${snapshot.serverVersion}`);
125
+ console.log(` - Connected clients: ${snapshot.connectedClients}`);
126
+ console.log(` - Recent callbacks: ${snapshot.recentCallbacks.length}`);
127
+
128
+ // Process any recent callbacks from snapshot
129
+ for (const callback of snapshot.recentCallbacks) {
130
+ processCallback(callback).catch(console.error);
131
+ }
132
+ },
133
+
134
+ onSynchronized: () => {
135
+ console.log("[Client] Synchronized - receiving live events");
136
+ },
137
+
138
+ onCallback: (callback: CallbackPayload) => {
139
+ console.log(`[Client] Live callback: ${callback.action} ${callback.targetId}`);
140
+ processCallback(callback).catch(console.error);
141
+ },
142
+
143
+ onStatus: (status) => {
144
+ console.log(`[Client] Status [${status.kind}]: ${status.code} - ${status.message}`);
145
+ },
146
+
147
+ onError: (error) => {
148
+ console.error("[Client] Error:", error.message);
149
+ },
150
+
151
+ onStateChange: (change) => {
152
+ const prev = change.previous.state;
153
+ const curr = change.current.state;
154
+ if (prev !== curr) {
155
+ console.log(`[Client] State: ${prev} → ${curr}`);
156
+ }
157
+ },
158
+ }
159
+ );
160
+
161
+ // Handle graceful shutdown
162
+ const shutdown = () => {
163
+ console.log("\nShutting down...");
164
+ client.disconnect();
165
+ process.exit(0);
166
+ };
167
+
168
+ process.on("SIGINT", shutdown);
169
+ process.on("SIGTERM", shutdown);
170
+
171
+ // Connect
172
+ try {
173
+ await client.connect();
174
+ console.log("[Client] Connection established!");
175
+
176
+ // Keep running
177
+ await new Promise(() => {});
178
+ } catch (err) {
179
+ console.error("[Client] Failed to connect:", err);
180
+ process.exit(1);
181
+ }
182
+ }
183
+
184
+ main();
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Syncs callback queue from VPS to local for processing.
4
+ * Run this alongside telegram-callback-processor.ts
5
+ *
6
+ * Usage:
7
+ * bun run scripts/sync-callback-queue.ts
8
+ *
9
+ * Or set up a cron job:
10
+ * * * * * * bun /home/frappe/pi-harness-runtime/scripts/sync-callback-queue.ts
11
+ */
12
+
13
+ import { execSync } from "child_process";
14
+ import { readFileSync, writeFileSync, existsSync } from "fs";
15
+ import { join } from "path";
16
+
17
+ const VPS_HOST = process.env.VPS_HOST || "frappe@217.216.37.251";
18
+ const VPS_QUEUE = "/home/frappe/.pi-harness-runtime/callback-queue.jsonl";
19
+ const LOCAL_QUEUE = join(process.env.HOME || "/home/frappe", ".pi-harness-runtime", "callback-queue.jsonl");
20
+
21
+ function syncQueue(): number {
22
+ try {
23
+ // SSH to get VPS queue content
24
+ const vpsQueueContent = execSync(`ssh -o BatchMode=yes ${VPS_HOST} "cat ${VPS_QUEUE}"`, { encoding: "utf8" });
25
+
26
+ if (!vpsQueueContent.trim()) {
27
+ return 0; // Nothing to sync
28
+ }
29
+
30
+ // Append to local queue
31
+ const existing = existsSync(LOCAL_QUEUE) ? readFileSync(LOCAL_QUEUE, "utf8") : "";
32
+ const newQueue = existing + vpsQueueContent;
33
+ writeFileSync(LOCAL_QUEUE, newQueue);
34
+
35
+ // Clear VPS queue
36
+ execSync(`ssh -o BatchMode=yes ${VPS_HOST} "truncate -s 0 ${VPS_QUEUE}"`);
37
+
38
+ const count = vpsQueueContent.split("\n").filter(l => l.trim()).length;
39
+ if (count > 0) {
40
+ console.log(`[Sync] Synced ${count} callback(s) from VPS`);
41
+ }
42
+ return count;
43
+ } catch (err) {
44
+ console.error("[Sync] Error:", err);
45
+ return 0;
46
+ }
47
+ }
48
+
49
+ // Run once and exit (for cron) unless --watch is passed
50
+ const isWatch = process.argv.includes("--watch");
51
+
52
+ if (isWatch) {
53
+ console.log("[Sync] Watching VPS queue every 500ms...");
54
+ setInterval(syncQueue, 500);
55
+ } else {
56
+ syncQueue();
57
+ }
@@ -89,6 +89,22 @@ export async function processCallbacks(): Promise<number> {
89
89
  break;
90
90
  }
91
91
 
92
+ case "sayhi": {
93
+ console.log(`👋 SAYHI: ${item.targetId} from @${item.username || item.userId}`);
94
+ // Send greeting response via Telegram
95
+ const botToken = process.env.TELEGRAM_BOT_TOKEN || readFileSync(join(process.env.HOME || "", ".pi-harness-runtime", "keys", "telegram-bot-token.txt"), "utf-8").trim();
96
+ const chatId = item.userId;
97
+ await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
98
+ method: "POST",
99
+ headers: { "Content-Type": "application/json" },
100
+ body: JSON.stringify({
101
+ chat_id: chatId,
102
+ text: "👋 Hi! Two-way communication is working! Click buttons to interact."
103
+ })
104
+ });
105
+ break;
106
+ }
107
+
92
108
  default: {
93
109
  console.log(`❓ UNKNOWN: ${item.action}_${item.targetId}`);
94
110
  if (onUnknown) {