pi-harness-runtime 1.1.190 → 1.1.192

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 (125) hide show
  1. package/index.ts +9 -3
  2. package/package.json +1 -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/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/e2e-tester/package.json +1 -1
  29. package/packages/evaluation-engine/package.json +1 -1
  30. package/packages/evaluation-runner/package.json +1 -1
  31. package/packages/event-bus/package.json +1 -1
  32. package/packages/event-store/package.json +1 -1
  33. package/packages/experience-replay/package.json +1 -1
  34. package/packages/feedback-collector/package.json +1 -1
  35. package/packages/file-copy-helper/package.json +1 -1
  36. package/packages/framework-detector/package.json +1 -1
  37. package/packages/framework-plugin-sdk/package.json +1 -1
  38. package/packages/frappe-plugin/package.json +1 -1
  39. package/packages/generic-web-plugin/package.json +1 -1
  40. package/packages/health-monitor/package.json +1 -1
  41. package/packages/intent-analyzer/package.json +1 -1
  42. package/packages/jev-judge/package.json +1 -1
  43. package/packages/knowledge-graph/package.json +1 -1
  44. package/packages/knowledge-retrieval/package.json +1 -1
  45. package/packages/laravel-plugin/package.json +1 -1
  46. package/packages/learning-engine/package.json +1 -1
  47. package/packages/mcp-adapter/package.json +1 -1
  48. package/packages/memory-engine/package.json +1 -1
  49. package/packages/milestone-manager/package.json +1 -1
  50. package/packages/model-registry/package.json +1 -1
  51. package/packages/nextjs-plugin/package.json +1 -1
  52. package/packages/notification/dist/adapters/telegram-adapter.d.ts.map +1 -1
  53. package/packages/notification/dist/adapters/telegram-adapter.js +12 -5
  54. package/packages/notification/dist/adapters/telegram-adapter.js.map +1 -1
  55. package/packages/notification/dist/base-adapter.d.ts +14 -0
  56. package/packages/notification/dist/base-adapter.d.ts.map +1 -1
  57. package/packages/notification/dist/base-adapter.js +13 -0
  58. package/packages/notification/dist/base-adapter.js.map +1 -1
  59. package/packages/notification/dist/conversation-bridge.d.ts +93 -0
  60. package/packages/notification/dist/conversation-bridge.d.ts.map +1 -0
  61. package/packages/notification/dist/conversation-bridge.js +294 -0
  62. package/packages/notification/dist/conversation-bridge.js.map +1 -0
  63. package/packages/notification/dist/index.d.ts +1 -0
  64. package/packages/notification/dist/index.d.ts.map +1 -1
  65. package/packages/notification/dist/index.js +1 -0
  66. package/packages/notification/dist/index.js.map +1 -1
  67. package/packages/notification/dist/notification-center.d.ts +5 -0
  68. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  69. package/packages/notification/dist/notification-center.js +12 -0
  70. package/packages/notification/dist/notification-center.js.map +1 -1
  71. package/packages/notification/package.json +1 -1
  72. package/packages/notification/src/adapters/telegram-adapter.ts +16 -5
  73. package/packages/notification/src/base-adapter.ts +23 -1
  74. package/packages/notification/src/conversation-bridge.ts +385 -0
  75. package/packages/notification/src/index.ts +4 -0
  76. package/packages/notification/src/notification-center.ts +13 -0
  77. package/packages/observability/package.json +1 -1
  78. package/packages/okf-indexer/package.json +1 -1
  79. package/packages/paperclip-integration/package.json +1 -1
  80. package/packages/performance-optimizer/package.json +1 -1
  81. package/packages/privilege-broker/package.json +1 -1
  82. package/packages/project-analyzer/package.json +1 -1
  83. package/packages/project-bootstrap/package.json +1 -1
  84. package/packages/projection-engine/package.json +1 -1
  85. package/packages/prompt-compiler/package.json +1 -1
  86. package/packages/prompt-versioning/package.json +1 -1
  87. package/packages/provider-adapter-sdk/package.json +1 -1
  88. package/packages/provider-router/package.json +1 -1
  89. package/packages/provider-selector/package.json +1 -1
  90. package/packages/providers/package.json +1 -1
  91. package/packages/qdrant-skills/package.json +1 -1
  92. package/packages/quota-manager/package.json +1 -1
  93. package/packages/rate-limiter/package.json +1 -1
  94. package/packages/react-vite-plugin/package.json +1 -1
  95. package/packages/release-manager/package.json +1 -1
  96. package/packages/requirement-compiler/package.json +1 -1
  97. package/packages/runtime/package.json +1 -1
  98. package/packages/scheduler/package.json +1 -1
  99. package/packages/scheduler-adapter/package.json +1 -1
  100. package/packages/session/package.json +1 -1
  101. package/packages/session-api/package.json +1 -1
  102. package/packages/session-export/package.json +1 -1
  103. package/packages/shared-context/package.json +1 -1
  104. package/packages/skill-mcp-client/package.json +1 -1
  105. package/packages/skill-registry/package.json +1 -1
  106. package/packages/skills/package.json +1 -1
  107. package/packages/sprint-planner/package.json +1 -1
  108. package/packages/subscription-engine/package.json +1 -1
  109. package/packages/task-compiler/package.json +1 -1
  110. package/packages/telegram/package.json +1 -1
  111. package/packages/tencentdb-memory/package.json +1 -1
  112. package/packages/tencentdb-sync/package.json +1 -1
  113. package/packages/test-data-generator/package.json +1 -1
  114. package/packages/test-generator/package.json +1 -1
  115. package/packages/todo-bd-sync/package.json +1 -1
  116. package/packages/token-estimation/package.json +1 -1
  117. package/packages/token-optimizer/package.json +1 -1
  118. package/packages/trajectory/package.json +1 -1
  119. package/packages/tui/package.json +1 -1
  120. package/packages/types/package.json +1 -1
  121. package/packages/webmcp-tester/package.json +1 -1
  122. package/packages/workflow-events/package.json +1 -1
  123. package/packages/workspace-scanner/package.json +1 -1
  124. package/packages/worktree/package.json +1 -1
  125. package/packages/write-review/package.json +1 -1
@@ -69,17 +69,28 @@ return this._botUsername;
69
69
  const response = await fetch(
70
70
  `https://api.telegram.org/bot${cfg.botToken}/getMe`,
71
71
  );
72
- if (!response.ok) return false;
72
+ if (!response.ok) {
73
+ console.warn(`[TelegramAdapter] getMe failed: HTTP ${response.status}`);
74
+ return false;
75
+ }
73
76
  const data = (await response.json()) as { ok: boolean; result?: { username?: string } };
74
- if (data.ok && data.result?.username) {
75
- this._botUsername = data.result.username;
77
+ if (!data.ok || !data.result?.username) {
78
+ console.warn(`[TelegramAdapter] getMe returned ok=false`);
79
+ return false;
76
80
  }
81
+
82
+ this._botUsername = data.result.username;
83
+ this.markHealthy(); // Mark as healthy after successful getMe
84
+ console.log(`[TelegramAdapter] Bot @${this._botUsername} verified successfully`);
85
+
77
86
  // Start polling for callback queries if handler is registered
78
87
  if (this._callbackHandler) {
79
88
  this.startPolling();
80
89
  }
81
- return data.ok;
82
- } catch {
90
+
91
+ return true;
92
+ } catch (err) {
93
+ console.error(`[TelegramAdapter] Initialize failed:`, err);
83
94
  return false;
84
95
  }
85
96
  }
@@ -28,9 +28,17 @@ export interface ChannelAdapter {
28
28
  * Check if the adapter is properly configured
29
29
  */
30
30
  isConfigured(): boolean;
31
+
32
+ /**
33
+ * Check if the adapter is healthy (initialized and working)
34
+ * Returns true if initialized successfully, false otherwise
35
+ */
36
+ isHealthy(): boolean;
31
37
  }
32
38
 
33
- export abstract class BaseChannelAdapter implements ChannelAdapter {
39
+ export abstract class BaseChannelAdapter implements ChannelAdapter {
40
+ protected _healthy = false;
41
+
34
42
  abstract readonly id: string;
35
43
  abstract readonly type: string;
36
44
 
@@ -43,6 +51,20 @@ export abstract class BaseChannelAdapter implements ChannelAdapter {
43
51
  return this.config.enabled;
44
52
  }
45
53
 
54
+ /**
55
+ * Default health check - subclasses should override for actual health verification
56
+ */
57
+ isHealthy(): boolean {
58
+ return this._healthy;
59
+ }
60
+
61
+ /**
62
+ * Mark adapter as healthy (called after successful initialize)
63
+ */
64
+ protected markHealthy(): void {
65
+ this._healthy = true;
66
+ }
67
+
46
68
  /**
47
69
  * Redact sensitive data from payload before sending
48
70
  */
@@ -0,0 +1,385 @@
1
+ /**
2
+ * Telegram Conversation Bridge
3
+ *
4
+ * Sends assistant responses and tool activity to Telegram.
5
+ * Hooks into Pi lifecycle events to capture:
6
+ * - message_end: Final assistant responses
7
+ * - agent_end: When agent finishes a turn
8
+ * - agent_settled: When agent fully settles
9
+ *
10
+ * Features:
11
+ * - Deduplication across events
12
+ * - Safe formatting
13
+ * - Delivery status tracking
14
+ */
15
+
16
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
17
+ import type { NotificationCenter } from "./notification-center.js";
18
+ import type { NotificationPayload } from "./types.js";
19
+
20
+ /**
21
+ * Configuration for the conversation bridge
22
+ */
23
+ export interface ConversationBridgeConfig {
24
+ /** Whether to send assistant final responses */
25
+ sendAssistantResponses: boolean;
26
+ /** Whether to send tool summaries */
27
+ sendToolSummaries: boolean;
28
+ /** Max message length before chunking */
29
+ maxMessageLength: number;
30
+ /** Minimum confidence to send a message */
31
+ minConfidence: number;
32
+ }
33
+
34
+ /**
35
+ * Pending message to prevent duplicate sends
36
+ */
37
+ interface PendingMessage {
38
+ messageId: string;
39
+ content: string;
40
+ timestamp: number;
41
+ events: Set<string>; // Events that triggered this message
42
+ }
43
+
44
+ /**
45
+ * Conversation Bridge
46
+ *
47
+ * Bridges Pi conversation events to Telegram notifications.
48
+ */
49
+ export class ConversationBridge {
50
+ private pi: ExtensionAPI;
51
+ private center: NotificationCenter;
52
+ private config: ConversationBridgeConfig;
53
+ private pendingMessages: Map<string, PendingMessage> = new Map();
54
+ private deliveredMessageIds: Set<string> = new Set();
55
+ private sessionStartTime: number = Date.now();
56
+ private lastMessageId: string | null = null;
57
+
58
+ constructor(
59
+ pi: ExtensionAPI,
60
+ center: NotificationCenter,
61
+ config: Partial<ConversationBridgeConfig> = {},
62
+ ) {
63
+ this.pi = pi;
64
+ this.center = center;
65
+ this.config = {
66
+ sendAssistantResponses: true,
67
+ sendToolSummaries: true,
68
+ maxMessageLength: 4000,
69
+ minConfidence: 0.5,
70
+ ...config,
71
+ };
72
+ }
73
+
74
+ /**
75
+ * Register all lifecycle hooks
76
+ */
77
+ register(): void {
78
+ console.log("[ConversationBridge] Registering lifecycle hooks...");
79
+
80
+ // Session start - reset state
81
+ this.pi.on("session_start", () => {
82
+ this.reset();
83
+ console.log("[ConversationBridge] Session started");
84
+ });
85
+
86
+ // Session compact - flush pending messages
87
+ this.pi.on("session_compact", (event) => {
88
+ console.log(
89
+ `[ConversationBridge] Compaction: ${event.reason} (willRetry=${event.willRetry})`,
90
+ );
91
+ this.flushPendingMessages();
92
+ });
93
+
94
+ // Session shutdown - cleanup
95
+ this.pi.on("session_shutdown", () => {
96
+ console.log("[ConversationBridge] Session shutting down");
97
+ this.flushPendingMessages();
98
+ this.stop();
99
+ });
100
+
101
+ // Message start - track new message
102
+ this.pi.on("message_start", (event) => {
103
+ const msg = event.message as { id?: string; role?: string };
104
+ if (msg?.role === "assistant" && msg?.id) {
105
+ this.lastMessageId = msg.id;
106
+ }
107
+ });
108
+
109
+ // Message end - capture final assistant response
110
+ this.pi.on("message_end", (event) => {
111
+ const msg = event.message as { id?: string; role?: string; content?: unknown };
112
+ if (msg?.role !== "assistant") return;
113
+
114
+ const content = this.extractMessageContent(msg);
115
+ if (!content || content.length < 10) return; // Skip empty/too short
116
+
117
+ const messageId = msg.id ?? `msg-${Date.now()}`;
118
+
119
+ // Deduplicate
120
+ if (this.deliveredMessageIds.has(messageId)) {
121
+ console.log(`[ConversationBridge] Skipping duplicate: ${messageId}`);
122
+ return;
123
+ }
124
+
125
+ // Check if already pending
126
+ let pending = this.pendingMessages.get(messageId);
127
+ if (!pending) {
128
+ pending = {
129
+ messageId,
130
+ content,
131
+ timestamp: Date.now(),
132
+ events: new Set(),
133
+ };
134
+ this.pendingMessages.set(messageId, pending);
135
+ }
136
+ pending.events.add("message_end");
137
+
138
+ console.log(
139
+ `[ConversationBridge] Assistant message captured: ${messageId.substring(0, 20)}...`,
140
+ );
141
+ });
142
+
143
+ // Tool execution end - capture tool summaries
144
+ if (this.config.sendToolSummaries) {
145
+ this.pi.on("tool_execution_end", (event) => {
146
+ const summary = this.formatToolSummary(event);
147
+ if (summary) {
148
+ this.sendToolSummary(summary);
149
+ }
150
+ });
151
+ }
152
+
153
+ // Agent settled - finalize and send pending messages
154
+ this.pi.on("agent_settled", () => {
155
+ console.log("[ConversationBridge] Agent settled, finalizing messages...");
156
+ this.finalizePendingMessages();
157
+ });
158
+
159
+ console.log("[ConversationBridge] Lifecycle hooks registered");
160
+ }
161
+
162
+ /**
163
+ * Extract text content from a message
164
+ */
165
+ private extractMessageContent(
166
+ msg: { content?: unknown },
167
+ ): string | null {
168
+ if (!msg.content) return null;
169
+
170
+ // Array of content parts
171
+ if (Array.isArray(msg.content)) {
172
+ const texts: string[] = [];
173
+ for (const part of msg.content) {
174
+ if (
175
+ part &&
176
+ typeof part === "object" &&
177
+ "type" in part &&
178
+ part.type === "text" &&
179
+ "text" in part
180
+ ) {
181
+ texts.push(String(part.text));
182
+ }
183
+ }
184
+ return texts.join("\n\n");
185
+ }
186
+
187
+ // Simple string
188
+ if (typeof msg.content === "string") {
189
+ return msg.content;
190
+ }
191
+
192
+ return null;
193
+ }
194
+
195
+ /**
196
+ * Format a tool execution summary
197
+ */
198
+ private formatToolSummary(event: {
199
+ toolName: string;
200
+ result?: unknown;
201
+ isError: boolean;
202
+ }): string {
203
+ const status = event.isError ? "FAILED" : "DONE";
204
+ const resultPreview = this.truncate(
205
+ JSON.stringify(event.result ?? ""),
206
+ 100,
207
+ );
208
+ return `[Tool] ${event.toolName}: ${status}${resultPreview ? ` - ${resultPreview}` : ""}`;
209
+ }
210
+
211
+ /**
212
+ * Send a tool summary to Telegram
213
+ */
214
+ private async sendToolSummary(summary: string): Promise<void> {
215
+ if (!this.center.hasHealthyChannels()) return;
216
+
217
+ const payload: NotificationPayload = {
218
+ event: "CodexSessionStarted", // Reusing existing event
219
+ jobId: `tool-${Date.now()}`,
220
+ timestamp: new Date().toISOString(),
221
+ title: "Tool Executed",
222
+ message: summary,
223
+ };
224
+
225
+ try {
226
+ const results = await this.center.notify("CodexSessionStarted", {
227
+ jobId: payload.jobId,
228
+ requirement: payload.message,
229
+ });
230
+
231
+ for (const result of results) {
232
+ if (result.success) {
233
+ console.log(`[ConversationBridge] Tool summary sent`);
234
+ } else {
235
+ console.warn(`[ConversationBridge] Tool summary failed: ${result.error}`);
236
+ }
237
+ }
238
+ } catch (err) {
239
+ console.error("[ConversationBridge] Failed to send tool summary:", err);
240
+ }
241
+ }
242
+
243
+ /**
244
+ * Finalize and send pending messages (called on agent_settled)
245
+ */
246
+ private async finalizePendingMessages(): Promise<void> {
247
+ for (const [messageId, pending] of this.pendingMessages) {
248
+ if (this.deliveredMessageIds.has(messageId)) continue;
249
+
250
+ // Send the message
251
+ await this.sendAssistantResponse(pending.content, messageId);
252
+ this.deliveredMessageIds.add(messageId);
253
+ this.pendingMessages.delete(messageId);
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Flush pending messages without sending (on compaction)
259
+ */
260
+ private flushPendingMessages(): void {
261
+ console.log(
262
+ `[ConversationBridge] Flushing ${this.pendingMessages.size} pending messages`,
263
+ );
264
+ this.pendingMessages.clear();
265
+ }
266
+
267
+ /**
268
+ * Send an assistant response to Telegram
269
+ */
270
+ private async sendAssistantResponse(
271
+ content: string,
272
+ messageId: string,
273
+ ): Promise<void> {
274
+ if (!this.center.hasHealthyChannels()) {
275
+ console.log("[ConversationBridge] No healthy channels, skipping");
276
+ return;
277
+ }
278
+
279
+ // Chunk if too long
280
+ const chunks = this.chunkMessage(content);
281
+
282
+ for (let i = 0; i < chunks.length; i++) {
283
+ const chunk = chunks[i];
284
+ const chunkSuffix = chunks.length > 1 ? ` [${i + 1}/${chunks.length}]` : "";
285
+
286
+ const payload: NotificationPayload = {
287
+ event: "CodexSessionStarted", // Reusing event type
288
+ jobId: `msg-${messageId}`,
289
+ timestamp: new Date().toISOString(),
290
+ title: "Assistant Response",
291
+ message: chunk + chunkSuffix,
292
+ };
293
+
294
+ try {
295
+ const results = await this.center.notify("CodexSessionStarted", {
296
+ jobId: payload.jobId,
297
+ requirement: payload.message,
298
+ });
299
+
300
+ for (const result of results) {
301
+ if (result.success) {
302
+ console.log(
303
+ `[ConversationBridge] Response chunk ${i + 1}/${chunks.length} sent`,
304
+ );
305
+ } else {
306
+ console.warn(
307
+ `[ConversationBridge] Response chunk failed: ${result.error}`,
308
+ );
309
+ }
310
+ }
311
+ } catch (err) {
312
+ console.error("[ConversationBridge] Failed to send response:", err);
313
+ }
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Chunk a message into smaller parts
319
+ */
320
+ private chunkMessage(message: string): string[] {
321
+ if (message.length <= this.config.maxMessageLength) {
322
+ return [message];
323
+ }
324
+
325
+ const chunks: string[] = [];
326
+ const sentences = message.match(/[^.!?]+[.!?]+/g) || [message];
327
+ let currentChunk = "";
328
+
329
+ for (const sentence of sentences) {
330
+ if ((currentChunk + sentence).length > this.config.maxMessageLength) {
331
+ if (currentChunk) {
332
+ chunks.push(currentChunk.trim());
333
+ }
334
+ currentChunk = sentence;
335
+ } else {
336
+ currentChunk += sentence;
337
+ }
338
+ }
339
+
340
+ if (currentChunk) {
341
+ chunks.push(currentChunk.trim());
342
+ }
343
+
344
+ return chunks;
345
+ }
346
+
347
+ /**
348
+ * Truncate a string
349
+ */
350
+ private truncate(str: string, maxLen: number): string {
351
+ if (str.length <= maxLen) return str;
352
+ return str.substring(0, maxLen - 3) + "...";
353
+ }
354
+
355
+ /**
356
+ * Reset state for new session
357
+ */
358
+ private reset(): void {
359
+ this.pendingMessages.clear();
360
+ this.deliveredMessageIds.clear();
361
+ this.lastMessageId = null;
362
+ this.sessionStartTime = Date.now();
363
+ }
364
+
365
+ /**
366
+ * Stop the bridge (cleanup)
367
+ */
368
+ stop(): void {
369
+ console.log("[ConversationBridge] Stopped");
370
+ // Cleanup will happen on shutdown
371
+ }
372
+ }
373
+
374
+ /**
375
+ * Create and register a conversation bridge
376
+ */
377
+ export function createConversationBridge(
378
+ pi: ExtensionAPI,
379
+ center: NotificationCenter,
380
+ config?: Partial<ConversationBridgeConfig>,
381
+ ): ConversationBridge {
382
+ const bridge = new ConversationBridge(pi, center, config);
383
+ bridge.register();
384
+ return bridge;
385
+ }
@@ -22,3 +22,7 @@ export {
22
22
  filterTelegramContent,
23
23
  getSafeNotificationLog,
24
24
  } from "./telegram-content-filter.js";
25
+ export {
26
+ ConversationBridge,
27
+ createConversationBridge,
28
+ } from "./conversation-bridge.js";
@@ -235,6 +235,19 @@ export class NotificationCenter {
235
235
  return this.adapters.size > 0;
236
236
  }
237
237
 
238
+ /**
239
+ * Check if any adapter is healthy (initialized and working)
240
+ * Unlike hasChannels(), this verifies actual health, not just config
241
+ */
242
+ hasHealthyChannels(): boolean {
243
+ for (const [, adapter] of this.adapters) {
244
+ if (adapter.isHealthy()) {
245
+ return true;
246
+ }
247
+ }
248
+ return false;
249
+ }
250
+
238
251
  /**
239
252
  * List all configured channels
240
253
  */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/observability",
3
- "version": "1.1.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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/privilege-broker",
3
- "version": "1.1.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
4
4
  "description": "React/Vite framework analysis — components, config, TypeScript setup",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/release-manager",
3
- "version": "1.1.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
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.190",
3
+ "version": "1.1.192",
4
4
  "description": "pi-harness-runtime — runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",