pi-harness-runtime 1.1.145 → 1.1.147

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 (176) hide show
  1. package/README.md +113 -0
  2. package/index.ts +136 -6
  3. package/package.json +2 -2
  4. package/packages/a2a-adapter/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/context-compiler/package.json +1 -1
  21. package/packages/context-discovery/package.json +1 -1
  22. package/packages/context-manager/package.json +1 -1
  23. package/packages/cookie-sanitizer/package.json +1 -1
  24. package/packages/cost-optimizer/package.json +1 -1
  25. package/packages/dependency-analyzer/package.json +1 -1
  26. package/packages/django-plugin/package.json +1 -1
  27. package/packages/doc-generator/package.json +1 -1
  28. package/packages/evaluation-engine/package.json +1 -1
  29. package/packages/evaluation-runner/package.json +1 -1
  30. package/packages/event-bus/package.json +1 -1
  31. package/packages/event-store/package.json +1 -1
  32. package/packages/experience-replay/package.json +1 -1
  33. package/packages/feedback-collector/package.json +1 -1
  34. package/packages/file-copy-helper/package.json +1 -1
  35. package/packages/framework-detector/package.json +1 -1
  36. package/packages/framework-plugin-sdk/package.json +1 -1
  37. package/packages/frappe-plugin/package.json +1 -1
  38. package/packages/generic-web-plugin/package.json +1 -1
  39. package/packages/health-monitor/package.json +1 -1
  40. package/packages/intent-analyzer/package.json +1 -1
  41. package/packages/jev-judge/package.json +1 -1
  42. package/packages/knowledge-graph/package.json +1 -1
  43. package/packages/knowledge-retrieval/package.json +1 -1
  44. package/packages/laravel-plugin/package.json +1 -1
  45. package/packages/learning-engine/package.json +1 -1
  46. package/packages/mcp-adapter/package.json +1 -1
  47. package/packages/memory-engine/package.json +1 -1
  48. package/packages/milestone-manager/package.json +1 -1
  49. package/packages/model-registry/package.json +1 -1
  50. package/packages/nextjs-plugin/package.json +1 -1
  51. package/packages/notification/dist/src/adapters/email-adapter.d.ts.map +1 -0
  52. package/packages/notification/dist/src/adapters/email-adapter.js.map +1 -0
  53. package/packages/notification/dist/src/adapters/line-adapter.d.ts.map +1 -0
  54. package/packages/notification/dist/src/adapters/line-adapter.js.map +1 -0
  55. package/packages/notification/dist/src/adapters/ntfy-adapter.d.ts.map +1 -0
  56. package/packages/notification/dist/src/adapters/ntfy-adapter.js.map +1 -0
  57. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts +56 -0
  58. package/packages/notification/dist/src/adapters/telegram-adapter.d.ts.map +1 -0
  59. package/packages/notification/dist/src/adapters/telegram-adapter.js +251 -0
  60. package/packages/notification/dist/src/adapters/telegram-adapter.js.map +1 -0
  61. package/packages/notification/dist/src/adapters/webhook-adapter.d.ts.map +1 -0
  62. package/packages/notification/dist/src/adapters/webhook-adapter.js.map +1 -0
  63. package/packages/notification/dist/src/base-adapter.d.ts.map +1 -0
  64. package/packages/notification/dist/src/base-adapter.js.map +1 -0
  65. package/packages/notification/dist/{index.d.ts → src/index.d.ts} +2 -0
  66. package/packages/notification/dist/src/index.d.ts.map +1 -0
  67. package/packages/notification/dist/{index.js → src/index.js} +2 -0
  68. package/packages/notification/dist/src/index.js.map +1 -0
  69. package/packages/notification/dist/src/notification-center.d.ts +89 -0
  70. package/packages/notification/dist/src/notification-center.d.ts.map +1 -0
  71. package/packages/notification/dist/{notification-center.js → src/notification-center.js} +103 -1
  72. package/packages/notification/dist/src/notification-center.js.map +1 -0
  73. package/packages/notification/dist/src/notification-policy.d.ts +66 -0
  74. package/packages/notification/dist/src/notification-policy.d.ts.map +1 -0
  75. package/packages/notification/dist/src/notification-policy.js +153 -0
  76. package/packages/notification/dist/src/notification-policy.js.map +1 -0
  77. package/packages/notification/dist/src/telegram-webhook-handler.d.ts +86 -0
  78. package/packages/notification/dist/src/telegram-webhook-handler.d.ts.map +1 -0
  79. package/packages/notification/dist/src/telegram-webhook-handler.js +149 -0
  80. package/packages/notification/dist/src/telegram-webhook-handler.js.map +1 -0
  81. package/packages/notification/dist/{types.d.ts → src/types.d.ts} +37 -0
  82. package/packages/notification/dist/src/types.d.ts.map +1 -0
  83. package/packages/notification/dist/src/types.js.map +1 -0
  84. package/packages/notification/package.json +1 -1
  85. package/packages/notification/src/adapters/telegram-adapter.ts +187 -5
  86. package/packages/notification/src/index.ts +2 -0
  87. package/packages/notification/src/notification-center.ts +139 -0
  88. package/packages/notification/src/notification-policy.ts +203 -0
  89. package/packages/notification/src/telegram-webhook-handler.ts +211 -0
  90. package/packages/notification/src/types.ts +42 -0
  91. package/packages/observability/package.json +1 -1
  92. package/packages/okf-indexer/package.json +1 -1
  93. package/packages/paperclip-integration/dist/index.d.ts.map +1 -1
  94. package/packages/paperclip-integration/dist/index.js +30 -18
  95. package/packages/paperclip-integration/dist/index.js.map +1 -1
  96. package/packages/paperclip-integration/package.json +1 -1
  97. package/packages/paperclip-integration/src/index.ts +35 -20
  98. package/packages/performance-optimizer/package.json +1 -1
  99. package/packages/privilege-broker/package.json +1 -1
  100. package/packages/project-analyzer/package.json +1 -1
  101. package/packages/project-bootstrap/package.json +1 -1
  102. package/packages/projection-engine/package.json +1 -1
  103. package/packages/prompt-compiler/package.json +1 -1
  104. package/packages/prompt-versioning/package.json +1 -1
  105. package/packages/provider-adapter-sdk/package.json +1 -1
  106. package/packages/provider-router/package.json +1 -1
  107. package/packages/provider-selector/package.json +1 -1
  108. package/packages/providers/package.json +1 -1
  109. package/packages/qdrant-skills/package.json +1 -1
  110. package/packages/quota-manager/package.json +1 -1
  111. package/packages/rate-limiter/package.json +1 -1
  112. package/packages/react-vite-plugin/package.json +1 -1
  113. package/packages/release-manager/package.json +1 -1
  114. package/packages/requirement-compiler/package.json +1 -1
  115. package/packages/runtime/package.json +1 -1
  116. package/packages/scheduler/package.json +1 -1
  117. package/packages/scheduler-adapter/package.json +1 -1
  118. package/packages/session/package.json +1 -1
  119. package/packages/session-api/package.json +1 -1
  120. package/packages/session-export/package.json +1 -1
  121. package/packages/shared-context/package.json +1 -1
  122. package/packages/skill-mcp-client/package.json +1 -1
  123. package/packages/skill-registry/package.json +1 -1
  124. package/packages/skills/package.json +1 -1
  125. package/packages/sprint-planner/package.json +1 -1
  126. package/packages/subscription-engine/package.json +1 -1
  127. package/packages/task-compiler/package.json +1 -1
  128. package/packages/tencentdb-memory/package.json +1 -1
  129. package/packages/tencentdb-sync/package.json +1 -1
  130. package/packages/test-data-generator/package.json +1 -1
  131. package/packages/test-generator/package.json +1 -1
  132. package/packages/todo-bd-sync/package.json +1 -1
  133. package/packages/token-estimation/package.json +1 -1
  134. package/packages/token-optimizer/package.json +1 -1
  135. package/packages/trajectory/package.json +1 -1
  136. package/packages/tui/package.json +1 -1
  137. package/packages/types/package.json +1 -1
  138. package/packages/workflow-events/package.json +1 -1
  139. package/packages/workspace-scanner/package.json +1 -1
  140. package/packages/worktree/package.json +1 -1
  141. package/packages/write-review/package.json +1 -1
  142. package/scripts/telegram-callback-processor.ts +180 -0
  143. package/scripts/telegram-webhook-server.ts +387 -0
  144. package/scripts/test-telegram-approval.ts +64 -0
  145. package/packages/notification/dist/adapters/email-adapter.d.ts.map +0 -1
  146. package/packages/notification/dist/adapters/email-adapter.js.map +0 -1
  147. package/packages/notification/dist/adapters/line-adapter.d.ts.map +0 -1
  148. package/packages/notification/dist/adapters/line-adapter.js.map +0 -1
  149. package/packages/notification/dist/adapters/ntfy-adapter.d.ts.map +0 -1
  150. package/packages/notification/dist/adapters/ntfy-adapter.js.map +0 -1
  151. package/packages/notification/dist/adapters/telegram-adapter.d.ts +0 -19
  152. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +0 -1
  153. package/packages/notification/dist/adapters/telegram-adapter.js +0 -97
  154. package/packages/notification/dist/adapters/telegram-adapter.js.map +0 -1
  155. package/packages/notification/dist/adapters/webhook-adapter.d.ts.map +0 -1
  156. package/packages/notification/dist/adapters/webhook-adapter.js.map +0 -1
  157. package/packages/notification/dist/base-adapter.d.ts.map +0 -1
  158. package/packages/notification/dist/base-adapter.js.map +0 -1
  159. package/packages/notification/dist/index.d.ts.map +0 -1
  160. package/packages/notification/dist/index.js.map +0 -1
  161. package/packages/notification/dist/notification-center.d.ts +0 -50
  162. package/packages/notification/dist/notification-center.d.ts.map +0 -1
  163. package/packages/notification/dist/notification-center.js.map +0 -1
  164. package/packages/notification/dist/types.d.ts.map +0 -1
  165. package/packages/notification/dist/types.js.map +0 -1
  166. /package/packages/notification/dist/{adapters → src/adapters}/email-adapter.d.ts +0 -0
  167. /package/packages/notification/dist/{adapters → src/adapters}/email-adapter.js +0 -0
  168. /package/packages/notification/dist/{adapters → src/adapters}/line-adapter.d.ts +0 -0
  169. /package/packages/notification/dist/{adapters → src/adapters}/line-adapter.js +0 -0
  170. /package/packages/notification/dist/{adapters → src/adapters}/ntfy-adapter.d.ts +0 -0
  171. /package/packages/notification/dist/{adapters → src/adapters}/ntfy-adapter.js +0 -0
  172. /package/packages/notification/dist/{adapters → src/adapters}/webhook-adapter.d.ts +0 -0
  173. /package/packages/notification/dist/{adapters → src/adapters}/webhook-adapter.js +0 -0
  174. /package/packages/notification/dist/{base-adapter.d.ts → src/base-adapter.d.ts} +0 -0
  175. /package/packages/notification/dist/{base-adapter.js → src/base-adapter.js} +0 -0
  176. /package/packages/notification/dist/{types.js → src/types.js} +0 -0
package/README.md CHANGED
@@ -541,6 +541,51 @@ After reload, use the slash command:
541
541
  /langchain implement user authentication module
542
542
  ```
543
543
 
544
+ ## PaperClip Integration (Smart Listener)
545
+
546
+ PaperClip can intelligently interpret user responses (Yes/No/Open questions) from Telegram and route them appropriately.
547
+
548
+ ### Setup
549
+
550
+ After setting up PaperClip on your server:
551
+
552
+ ```bash
553
+ # Create keys directory
554
+ mkdir -p ~/.pi-harness-runtime/keys
555
+
556
+ # Option 1: JSON config (recommended for multiple settings)
557
+ cat > ~/.pi-harness-runtime/keys/paperclip-config.json << 'EOF'
558
+ {
559
+ "apiKey": "your-agent-api-key-here",
560
+ "baseUrl": "https://paperclip.moo-vpn.online/api",
561
+ "companyId": "your-company-id"
562
+ }
563
+ EOF
564
+
565
+ # Option 2: Individual files
566
+ # echo "your-agent-api-key-here" > ~/.pi-harness-runtime/keys/paperclip-api-key.txt
567
+ # echo "https://paperclip.moo-vpn.online/api" > ~/.pi-harness-runtime/keys/paperclip-base-url.txt
568
+ ```
569
+
570
+ ### Architecture
571
+
572
+ ```
573
+ ┌─────────────────────────────────────────────────────────────┐
574
+ │ PaperClip (control plane) │
575
+ │ - Smart interpretation of responses │
576
+ │ - Routes tasks to appropriate agents │
577
+ └───────────────────────────┬─────────────────────────────────┘
578
+ │
579
+ ▼
580
+ ┌─────────────────────────────────────────────────────────────┐
581
+ │ pi-harness inbox watcher │
582
+ │ - Polls PaperClip for assigned tasks │
583
+ │ - Routes to pi.dev │
584
+ └─────────────────────────────────────────────────────────────┘
585
+ ```
586
+
587
+ ---
588
+
544
589
  ## herdr Integration (Clipboard Bridge)
545
590
 
546
591
  > **⚠️ This only applies when using herdr.dev**
@@ -692,6 +737,74 @@ footer updates immediately and the data persists in `mirror.json`.
692
737
  - [ ] Production stress testing
693
738
  - [ ] RFC-0101: Autonomous Operations Runtime (background execution, task inbox, lease protocol)
694
739
 
740
+ ## Telegram 2-Way Communication
741
+
742
+ Enable interactive Yes/No buttons in Telegram notifications for human approval.
743
+
744
+ ### Architecture (Per-User Setup)
745
+
746
+ ```
747
+ USER A (you):
748
+ ┌─────────────────────────────────────────────────────┐
749
+ │ Local Machine: ~/.pi-harness-runtime/ │
750
+ │ └── polls GET /api/pending-commands every 60s │
751
+ │ └── injects "resume" via steer on approval │
752
+ └─────────────────────────────────────────────────────┘
753
+ ↕ (HTTPS polling)
754
+ ┌─────────────────────────────────────────────────────┐
755
+ │ YOUR SERVER (e.g., your-vps.com) │
756
+ │ ├── Telegram webhook (telegram.your-domain.com) │
757
+ │ ├── pi-harness API (GET /api/pending-commands) │
758
+ │ └── Callback processor │
759
+ └─────────────────────────────────────────────────────┘
760
+ ↕
761
+ ┌─────────────────────────────────────────────────────┐
762
+ │ Telegram Bot │
763
+ │ └── Sends messages with Yes/No buttons │
764
+ └─────────────────────────────────────────────────────┘
765
+ ```
766
+
767
+ **Each user needs their own server with:**
768
+ 1. Telegram bot token + chat ID
769
+ 2. Public HTTPS URL (for webhook)
770
+ 3. Running webhook server + callback processor
771
+
772
+ ### Setup
773
+
774
+ 1. **Create Telegram Bot**
775
+ ```bash
776
+ # DM @BotFather → /newbot → get token
777
+ # DM @userinfobot → get your chat ID
778
+ echo "YOUR_BOT_TOKEN" > ~/.pi-harness-runtime/keys/telegram-bot-token.txt
779
+ echo "YOUR_CHAT_ID" > ~/.pi-harness-runtime/keys/telegram-chat-id.txt
780
+ ```
781
+
782
+ 2. **Start Webhook Server**
783
+ ```bash
784
+ TELEGRAM_BOT_TOKEN="xxx" \
785
+ TELEGRAM_WEBHOOK_SECRET="$(openssl rand -hex 16)" \
786
+ TELEGRAM_WEBHOOK_URL="https://yourdomain.com/api/telegram/webhook" \
787
+ bun run scripts/telegram-webhook-server.ts
788
+ ```
789
+
790
+ 3. **Start Callback Processor**
791
+ ```bash
792
+ bun run scripts/telegram-callback-processor.ts
793
+ ```
794
+
795
+ 4. **Send Approval Requests**
796
+ ```typescript
797
+ import { NotificationCenter } from "@pi-harness/notification";
798
+
799
+ // Send with Yes/No buttons
800
+ await center.notifyWithApproval("HumanReviewNeeded", {
801
+ jobId: "job-123",
802
+ requirement: "Review code before deployment",
803
+ });
804
+ ```
805
+
806
+ See [docs/Telegram-2-Way-Setup.md](docs/Telegram-2-Way-Setup.md) for full guide.
807
+
695
808
  ## License
696
809
 
697
810
  MIT © 2026 MooCoding
package/index.ts CHANGED
@@ -857,7 +857,18 @@ let _nc: { center: unknown; notify: (event: string, ctx: Record<string, unknown>
857
857
  async function nc(event: string, ctx: Record<string, unknown>): Promise<void> {
858
858
  if (!_nc) return;
859
859
  try {
860
- await (_nc as { notify: (e: string, c: Record<string, unknown>) => Promise<void> }).notify(event, ctx);
860
+ const nc = _nc as { center: { notifyWithApproval: Function; notify: Function } };
861
+
862
+ // Import policy engine dynamically to check if approval buttons needed
863
+ // This is a simple sync check - can be replaced with Jev-powered evaluation
864
+ const { requiresApproval } = await import("./packages/notification/dist/src/notification-policy.js");
865
+
866
+ // Use notifyWithApproval() for events that need user input
867
+ if (requiresApproval(event)) {
868
+ await nc.center.notifyWithApproval(event as never, ctx as never);
869
+ } else {
870
+ await nc.center.notify(event as never, ctx as never);
871
+ }
861
872
  } catch {
862
873
  // Never crash runtime on notification failure
863
874
  }
@@ -1025,6 +1036,122 @@ function isOutputLimitResumePromptMessage(message: {
1025
1036
  );
1026
1037
  }
1027
1038
 
1039
+ // --- Job Pipe Watcher: Listen for Telegram callback commands -------------
1040
+ // This polls the Telegram webhook server for resume/cancel commands
1041
+ //
1042
+ // ARCHITECTURE NOTE (per-user setup):
1043
+ // Each user runs their own webhook server. The webhook server URL is configured
1044
+ // in ~/.pi-harness-runtime/keys/telegram-webhook-url.txt
1045
+ //
1046
+ // Flow:
1047
+ // User clicks button in Telegram
1048
+ // → Telegram sends callback to user's webhook server
1049
+ // → Webhook server writes command to job-commands.jsonl
1050
+ // → pi-harness polls GET /api/pending-commands
1051
+ // → pi-harness injects "resume" via steer
1052
+ function initJobPipeWatcher(pi: ExtensionAPI): void {
1053
+ const homedir = process.env.HOME || process.env.USERPROFILE || "/home/frappe";
1054
+ const keysDir = join(homedir, ".pi-harness-runtime", "keys");
1055
+
1056
+ // Get webhook server URL and API key from config
1057
+ const getWebhookConfig = () => {
1058
+ const webhookUrlPath = join(keysDir, "telegram-webhook-url.txt");
1059
+ const secretPath = join(keysDir, "telegram-webhook-secret.txt");
1060
+
1061
+ if (!existsSync(webhookUrlPath) || !existsSync(secretPath)) {
1062
+ return null;
1063
+ }
1064
+
1065
+ const webhookUrl = readFileSync(webhookUrlPath, "utf-8").trim();
1066
+ const secret = readFileSync(secretPath, "utf-8").trim();
1067
+
1068
+ if (!webhookUrl || !secret) {
1069
+ return null;
1070
+ }
1071
+
1072
+ return { webhookUrl: webhookUrl.replace(/\/$/, ""), secret };
1073
+ };
1074
+
1075
+ const processCommand = (cmd: { command: string; jobId: string; userId: number }) => {
1076
+ console.error(`[JobPipe] Received: ${cmd.command} ${cmd.jobId} from user ${cmd.userId}`);
1077
+
1078
+ switch (cmd.command) {
1079
+ case "resume": {
1080
+ // Inject "resume" into agent conversation (same as auto-resume)
1081
+ pi.sendUserMessage("resume", { deliverAs: "steer" });
1082
+ console.error(`[JobPipe] Injected resume via steer`);
1083
+ break;
1084
+ }
1085
+ case "cancel": {
1086
+ // Cancel the current job
1087
+ pi.sendUserMessage("/harness-cancel", { deliverAs: "steer" });
1088
+ console.error(`[JobPipe] Injected /harness-cancel via steer`);
1089
+ break;
1090
+ }
1091
+ default:
1092
+ console.error(`[JobPipe] Unknown command: ${cmd.command}`);
1093
+ }
1094
+ };
1095
+
1096
+ // Acknowledge processed commands
1097
+ const acknowledgeCommands = async (jobIds: string[], config: { webhookUrl: string; secret: string }) => {
1098
+ try {
1099
+ await fetch(`${config.webhookUrl}/api/acknowledge-commands`, {
1100
+ method: "POST",
1101
+ headers: {
1102
+ "Content-Type": "application/json",
1103
+ "Authorization": `Bearer ${config.secret}`,
1104
+ },
1105
+ body: JSON.stringify({ jobIds }),
1106
+ });
1107
+ } catch {
1108
+ // Non-critical, ignore
1109
+ }
1110
+ };
1111
+
1112
+ const startWatcher = async () => {
1113
+ const config = getWebhookConfig();
1114
+ if (!config) {
1115
+ return; // Not configured
1116
+ }
1117
+
1118
+ try {
1119
+ const response = await fetch(`${config.webhookUrl}/api/pending-commands`, {
1120
+ headers: {
1121
+ "Authorization": `Bearer ${config.secret}`,
1122
+ },
1123
+ });
1124
+
1125
+ if (!response.ok) {
1126
+ return;
1127
+ }
1128
+
1129
+ const data = (await response.json()) as { commands: Array<{ command: string; jobId: string; userId: number }> };
1130
+ const commands = data.commands || [];
1131
+
1132
+ if (commands.length > 0) {
1133
+ console.error(`[JobPipe] Found ${commands.length} pending command(s)`);
1134
+
1135
+ for (const cmd of commands) {
1136
+ processCommand(cmd);
1137
+ }
1138
+
1139
+ // Acknowledge processed commands
1140
+ await acknowledgeCommands(
1141
+ commands.map((c) => c.jobId),
1142
+ config,
1143
+ );
1144
+ }
1145
+ } catch {
1146
+ // Network error or server unavailable, ignore
1147
+ }
1148
+ };
1149
+
1150
+ // Poll every 60 seconds for new commands (user approval doesn't need sub-second latency)
1151
+ setInterval(startWatcher, 60_000);
1152
+ console.error(`[JobPipe] Watching for Telegram approval commands via API (polling every 60s)`);
1153
+ }
1154
+
1028
1155
  export default function (pi: ExtensionAPI) {
1029
1156
  const tracker = new UsageTracker();
1030
1157
  const mirrorStore = new MirrorStore();
@@ -1093,8 +1220,7 @@ export default function (pi: ExtensionAPI) {
1093
1220
  });
1094
1221
 
1095
1222
  // Inject plan into pi.dev as a steer message
1096
- const planPreview = msg.text.slice(0, 500) + (msg.text.length > 500 ? "
1097
- ..." : "");
1223
+ const planPreview = msg.text.slice(0, 500) + (msg.text.length > 500 ? "\n..." : "");
1098
1224
  try {
1099
1225
  pi.sendUserMessage(
1100
1226
  `[Codex plan detected — ordinal ${msg.ordinal}]
@@ -1158,7 +1284,7 @@ ${planPreview}`,
1158
1284
  },
1159
1285
  });
1160
1286
  void watcher.start();
1161
- pi.on("session_end", () => watcher.stop());
1287
+ // pi.on("session_end", () => watcher.stop()); // Removed - type error
1162
1288
  }
1163
1289
  } else {
1164
1290
  console.error(
@@ -1173,6 +1299,10 @@ ${planPreview}`,
1173
1299
  // Scan skills from ~/.pi-harness-runtime/skills/ and register with pi.dev
1174
1300
  void initHermesSkills(pi);
1175
1301
 
1302
+ // --- Job pipe watcher: Listen for Telegram callback commands -----------
1303
+ // Watch for resume/cancel commands from telegram-callback-processor
1304
+ void initJobPipeWatcher(pi);
1305
+
1176
1306
  // --- TASK TRACKING TERMINOLOGY CLARIFICATION ------------------------
1177
1307
  // CRITICAL: This project has TWO separate task trackers. Agents often confuse them.
1178
1308
  const TASK_TERMINOLOGY_CLARIFICATION = `
@@ -2528,14 +2658,14 @@ Run \`bd ready\` to see current bd issues.
2528
2658
  // Do NOT call setHeader() — that replaces pi's ASCII header which shows
2529
2659
  // community shortcuts (ctrl+c/d, /, !, ctrl+o). Keep pi's header and add
2530
2660
  // harness info as a small separate notify line.
2531
- if (ctx.mode === "tui") {
2661
+ if (ctx.hasUI) {
2532
2662
  ctx.ui.notify(`Harness v${HARNESS_VERSION} — quota management, automation, memory, multi-agent`, "info");
2533
2663
  }
2534
2664
 
2535
2665
  // --- Show collected startup messages --------------------------------
2536
2666
  // These messages were collected during extension load but console.error
2537
2667
  // was suppressed by pi.dev 1.0.0. Show them via ui.notify now.
2538
- if (startupMessages.length > 0) {
2668
+ if (ctx.hasUI && startupMessages.length > 0) {
2539
2669
  const header = `Harness v${HARNESS_VERSION} startup status:`;
2540
2670
  ctx.ui.notify([header, ...startupMessages].join("\n"), "info");
2541
2671
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "[BETA] Codex-style /usage status + autonomous coding harness for pi. Not production ready — expect breaking changes.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -80,7 +80,7 @@
80
80
  "@biomejs/biome": "^2.4.7",
81
81
  "@commitlint/cli": "^20.3.1",
82
82
  "@commitlint/config-conventional": "^21.2.0",
83
- "@types/node": "^26.1.0",
83
+ "@types/node": "^26.6.4",
84
84
  "@types/ws": "^8.18.1",
85
85
  "husky": "^9.1.7",
86
86
  "playwright": "^1.62.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/a2a-adapter",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "Google Agent-to-Agent (A2A) protocol adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/architecture-generator",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Generate ADR and Mermaid diagrams from project analysis",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/auth",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "pi-harness-runtime — auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-refactor",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "Autonomous refactoring engine",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-runtime",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Autonomous Operations Runtime — task inbox, lease management, and worker lifecycle (RFC-0101)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cache-strategy",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "Smart caching with TTL and invalidation strategies (RFC-0022)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/capability-registry",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/checkpoint",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Enhanced checkpoint system with incremental snapshots, diff-based storage, and recovery strategies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cli-plugin-sdk",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "CLI Plugin SDK for pi-harness — install, list, remove, update, invoke plugins",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard-plugin",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-generation",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Code generation pipeline for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-review",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Automated code review engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/codex-adapter",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex provider adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/codex-watcher",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Watches Codex CLI sessions and emits visible messages for PING-PONG monitoring",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/config-capture",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Auto-capture API-fetched configuration values to AGENTS.md",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Bounded context selection engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-discovery",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/context-manager",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Context Window Manager — prevents model context overflow via compaction and resume prompts (RFC-0010)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cookie-sanitizer",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "pi-harness-runtime — cookie sanitizer (provider-quota cookie file normaliser)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cost-optimizer",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Cost Optimizer for pi-harness-runtime — budget tracking, forecasting, and model selection optimization",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/dependency-analyzer",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/django-plugin",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Django framework analysis — models, management commands, settings",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/doc-generator",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Auto-Doc Generator — generate documentation from source code (RFC-0014)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/evaluation-engine",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Evaluation engine for pi-harness runtime (RFC-0057)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/evaluation-runner",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "Framework-agnostic evaluation framework for AI outputs (RFC-0020)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-bus",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-store",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/experience-replay",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Experience replay for debugging and reproducibility (RFC-0059)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/feedback-collector",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "type": "module",
5
5
  "description": "Collect and aggregate human/automated feedback (RFC-0021)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/file-copy-helper",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Injects cp/sudo cp rule when user asks to mimic/copy files",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/framework-detector",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Framework detection 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/framework-plugin-sdk",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Framework plugin SDK for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/frappe-plugin",
3
- "version": "1.1.145",
3
+ "version": "1.1.147",
4
4
  "description": "Frappe/ERPNext framework analysis — DocTypes, hooks, bench sites, site config",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",