pi-harness-runtime 1.1.404 → 1.1.405

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 (158) hide show
  1. package/index.ts +275 -1
  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/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/logging/package.json +1 -1
  52. package/packages/mcp-adapter/package.json +1 -1
  53. package/packages/memory-engine/package.json +1 -1
  54. package/packages/milestone-manager/package.json +1 -1
  55. package/packages/model-registry/package.json +1 -1
  56. package/packages/nextjs-plugin/package.json +1 -1
  57. package/packages/notification/dist/adapters/line-adapter.d.ts.map +1 -1
  58. package/packages/notification/dist/adapters/line-adapter.js +6 -1
  59. package/packages/notification/dist/adapters/line-adapter.js.map +1 -1
  60. package/packages/notification/dist/notification-center.d.ts.map +1 -1
  61. package/packages/notification/dist/notification-center.js +32 -0
  62. package/packages/notification/dist/notification-center.js.map +1 -1
  63. package/packages/notification/dist/telegram-webhook-handler.d.ts +7 -0
  64. package/packages/notification/dist/telegram-webhook-handler.d.ts.map +1 -1
  65. package/packages/notification/dist/telegram-webhook-handler.js +7 -0
  66. package/packages/notification/dist/telegram-webhook-handler.js.map +1 -1
  67. package/packages/notification/dist/types.d.ts +1 -1
  68. package/packages/notification/dist/types.d.ts.map +1 -1
  69. package/packages/notification/package.json +1 -1
  70. package/packages/notification/src/adapters/line-adapter.ts +7 -1
  71. package/packages/notification/src/notification-center.ts +30 -0
  72. package/packages/notification/src/telegram-webhook-handler.ts +7 -0
  73. package/packages/notification/src/types.ts +1 -0
  74. package/packages/notification/test/notification.test.ts +31 -28
  75. package/packages/notification/test/tooling-proposal-payload.test.ts +212 -0
  76. package/packages/observability/package.json +1 -1
  77. package/packages/okf-indexer/package.json +1 -1
  78. package/packages/paperclip-integration/package.json +1 -1
  79. package/packages/performance-optimizer/package.json +1 -1
  80. package/packages/permission-mode/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/relay/package.json +1 -1
  96. package/packages/release-manager/package.json +1 -1
  97. package/packages/requirement-compiler/package.json +1 -1
  98. package/packages/runtime/package.json +1 -1
  99. package/packages/scheduler/package.json +1 -1
  100. package/packages/scheduler-adapter/package.json +1 -1
  101. package/packages/session/package.json +1 -1
  102. package/packages/session-api/package.json +1 -1
  103. package/packages/session-export/package.json +1 -1
  104. package/packages/shared-context/package.json +1 -1
  105. package/packages/skill-mcp-client/package.json +1 -1
  106. package/packages/skill-registry/package.json +1 -1
  107. package/packages/skills/package.json +1 -1
  108. package/packages/sprint-planner/package.json +1 -1
  109. package/packages/subscription-engine/package.json +1 -1
  110. package/packages/task-compiler/package.json +1 -1
  111. package/packages/telegram/package.json +1 -1
  112. package/packages/tencentdb-memory/package.json +1 -1
  113. package/packages/tencentdb-sync/package.json +1 -1
  114. package/packages/test-data-generator/package.json +1 -1
  115. package/packages/test-generator/package.json +1 -1
  116. package/packages/todo-bd-sync/package.json +1 -1
  117. package/packages/token-estimation/package.json +1 -1
  118. package/packages/token-optimizer/package.json +1 -1
  119. package/packages/tooling-preference/dist/detect.d.ts +62 -0
  120. package/packages/tooling-preference/dist/detect.d.ts.map +1 -0
  121. package/packages/tooling-preference/dist/detect.js +209 -0
  122. package/packages/tooling-preference/dist/detect.js.map +1 -0
  123. package/packages/tooling-preference/dist/index.d.ts +13 -0
  124. package/packages/tooling-preference/dist/index.d.ts.map +1 -0
  125. package/packages/tooling-preference/dist/index.js +13 -0
  126. package/packages/tooling-preference/dist/index.js.map +1 -0
  127. package/packages/tooling-preference/dist/proposal.d.ts +70 -0
  128. package/packages/tooling-preference/dist/proposal.d.ts.map +1 -0
  129. package/packages/tooling-preference/dist/proposal.js +137 -0
  130. package/packages/tooling-preference/dist/proposal.js.map +1 -0
  131. package/packages/tooling-preference/dist/registry.d.ts +50 -0
  132. package/packages/tooling-preference/dist/registry.d.ts.map +1 -0
  133. package/packages/tooling-preference/dist/registry.js +53 -0
  134. package/packages/tooling-preference/dist/registry.js.map +1 -0
  135. package/packages/tooling-preference/dist/store.d.ts +61 -0
  136. package/packages/tooling-preference/dist/store.d.ts.map +1 -0
  137. package/packages/tooling-preference/dist/store.js +129 -0
  138. package/packages/tooling-preference/dist/store.js.map +1 -0
  139. package/packages/tooling-preference/package.json +21 -0
  140. package/packages/tooling-preference/src/detect.ts +251 -0
  141. package/packages/tooling-preference/src/index.ts +44 -0
  142. package/packages/tooling-preference/src/proposal.ts +173 -0
  143. package/packages/tooling-preference/src/registry.ts +79 -0
  144. package/packages/tooling-preference/src/store.ts +162 -0
  145. package/packages/tooling-preference/tests/detect.test.ts +188 -0
  146. package/packages/tooling-preference/tests/proposal.test.ts +107 -0
  147. package/packages/tooling-preference/tests/registry.test.ts +51 -0
  148. package/packages/tooling-preference/tests/store.test.ts +99 -0
  149. package/packages/trajectory/package.json +1 -1
  150. package/packages/tui/package.json +1 -1
  151. package/packages/types/package.json +1 -1
  152. package/packages/voice-api/package.json +1 -1
  153. package/packages/webmcp-tester/package.json +1 -1
  154. package/packages/wiki/package.json +1 -1
  155. package/packages/workflow-events/package.json +1 -1
  156. package/packages/workspace-scanner/package.json +1 -1
  157. package/packages/worktree/package.json +1 -1
  158. package/packages/write-review/package.json +1 -1
package/index.ts CHANGED
@@ -296,6 +296,240 @@ function waitBelongsToRequest(requestId: string | undefined): boolean {
296
296
  return active === requestId;
297
297
  }
298
298
 
299
+ // --- tooling-preference: the Biome proposal ---------------------------------
300
+ //
301
+ // The proposal ("use Biome.js instead of ESLint and Prettier") is a decision
302
+ // of its own. It never travels through the task-approval path: a "No" here
303
+ // must not pause the work and a "Yes" must not resume a pending question.
304
+
305
+ /** The proposals of this session - the first answer wins. */
306
+ interface ToolingProposalRequest {
307
+ requestId: string;
308
+ workspaceRoot: string;
309
+ userKey: string;
310
+ }
311
+
312
+ interface ToolingProposalRegistry {
313
+ register(request: ToolingProposalRequest): boolean;
314
+ claim(
315
+ requestId: string,
316
+ choice: "yes" | "no",
317
+ channel?: string,
318
+ ): {
319
+ request: ToolingProposalRequest;
320
+ resolution: {
321
+ choice: "yes" | "no";
322
+ preference: "prefer_biome" | "use_project_tools";
323
+ channel?: string;
324
+ };
325
+ } | null;
326
+ }
327
+
328
+ interface ToolingProposalStore {
329
+ read(
330
+ userKey: string,
331
+ workspaceRoot: string,
332
+ ): { decision?: "prefer_biome" | "use_project_tools"; askedAt?: string } | undefined;
333
+ markAsked(userKey: string, workspaceRoot: string, requestId: string): void;
334
+ recordDecision(
335
+ userKey: string,
336
+ workspaceRoot: string,
337
+ decision: "prefer_biome" | "use_project_tools",
338
+ requestId: string,
339
+ channel?: string,
340
+ ): void;
341
+ }
342
+
343
+ let _toolingRegistry: ToolingProposalRegistry | null = null;
344
+ let _toolingStore: ToolingProposalStore | null = null;
345
+ /** The identity of the person the notifications reach (never logged). */
346
+ let _toolingIdentity = "";
347
+ /**
348
+ * The identity of the person the notifications reach.
349
+ *
350
+ * It is read from the channel key files, so a LINE-only setup is recognized
351
+ * too. The value is hashed before it is stored and never reaches a log.
352
+ */
353
+ function readToolingIdentity(): string {
354
+ if (_toolingIdentity) return _toolingIdentity;
355
+ const home = process.env.HOME || process.env.USERPROFILE || "";
356
+ if (!home) return "";
357
+ const keysDir = `${home}/.pi-harness-runtime/keys`;
358
+ for (const name of ["telegram-chat-id.txt", "line-user-id.txt"]) {
359
+ try {
360
+ const value = readFileSync(`${keysDir}/${name}`, "utf8").trim();
361
+ if (value) {
362
+ _toolingIdentity = value;
363
+ return value;
364
+ }
365
+ } catch {
366
+ // The key file is optional - the channel may not be configured.
367
+ }
368
+ }
369
+ return "";
370
+ }
371
+ /** The running extension API - the relay path has no `pi` of its own. */
372
+ let _extensionApi: ExtensionAPI | null = null;
373
+ /** How long an unanswered proposal stays quiet before it is offered again. */
374
+ const TOOLING_PROPOSAL_COOLDOWN_MS = 30 * 24 * 60 * 60 * 1000;
375
+
376
+ /**
377
+ * Load the tooling preference package and watch for the session start.
378
+ *
379
+ * The proposal is offered once per workspace: the answer is stored, and a
380
+ * workspace that already uses Biome is never asked at all.
381
+ */
382
+ async function initToolingPreference(pi: ExtensionAPI): Promise<void> {
383
+ try {
384
+ const mod = await import("./packages/tooling-preference/dist/index.js");
385
+ _toolingRegistry = new mod.ToolingRequestRegistry();
386
+ _toolingStore = new mod.ToolingPreferenceStore(
387
+ mod.ToolingPreferenceStore.defaultFilePath(),
388
+ );
389
+ } catch (error) {
390
+ logToFile("[ToolingPreference]", `package unavailable: ${oneLineError(error)}`);
391
+ return;
392
+ }
393
+
394
+ pi.on("session_start", () => {
395
+ void offerToolingPreference();
396
+ });
397
+ }
398
+
399
+ /**
400
+ * Offer the tooling proposal for the workspace of this session.
401
+ *
402
+ * The proposal never blocks: it is a message with two buttons, and the work
403
+ * continues while the user decides.
404
+ */
405
+ async function offerToolingPreference(): Promise<void> {
406
+ const registry = _toolingRegistry;
407
+ const store = _toolingStore;
408
+ const center = _nc?.center as NcCenter | undefined;
409
+ if (!registry || !store || !center?.notifyWithButtons) return;
410
+
411
+ let workspaceRoot: string;
412
+ try {
413
+ workspaceRoot = realpathSync(process.cwd());
414
+ } catch {
415
+ return;
416
+ }
417
+
418
+ try {
419
+ const mod = await import("./packages/tooling-preference/dist/index.js");
420
+ const userKey = mod.buildToolingUserKey(readToolingIdentity());
421
+ const record = store.read(userKey, workspaceRoot);
422
+ if (!mod.shouldAskAgain(record, TOOLING_PROPOSAL_COOLDOWN_MS)) return;
423
+
424
+ const context = mod.detectToolingContext(workspaceRoot);
425
+ const eligibility = mod.evaluateBiomeProposalEligibility(context);
426
+ if (!eligibility.eligible) {
427
+ logToFile("[ToolingPreference]", `no proposal: ${eligibility.reason}`);
428
+ return;
429
+ }
430
+
431
+ const requestId = mod.buildToolingRequestId(userKey, workspaceRoot);
432
+ if (!registry.register({ requestId, workspaceRoot, userKey })) return;
433
+
434
+ await center.notifyWithButtons(
435
+ "ToolingPreferenceProposal",
436
+ {
437
+ jobId: requestId,
438
+ questionId: requestId,
439
+ requirement: mod.buildToolingProposalMessage(context),
440
+ taskTitle: "Biome.js proposal",
441
+ },
442
+ mod.buildToolingButtons(requestId),
443
+ { additionalDetails: { _actionPrompt: "Use Biome.js in this workspace?" } },
444
+ );
445
+ store.markAsked(userKey, workspaceRoot, requestId);
446
+ logToFile("[ToolingPreference]", `proposal sent (${requestId})`);
447
+ } catch (error) {
448
+ logToFile("[ToolingPreference]", `proposal failed: ${oneLineError(error)}`);
449
+ }
450
+ }
451
+
452
+ /**
453
+ * Apply the answer of the user to the tooling proposal.
454
+ *
455
+ * The first answer wins: a second click finds nothing and changes nothing.
456
+ */
457
+ async function resolveToolingPreference(
458
+ targetId: string,
459
+ channel: "telegram" | "line",
460
+ pi: ExtensionAPI | null,
461
+ ): Promise<{ applied: boolean; reason: string }> {
462
+ const registry = _toolingRegistry;
463
+ const store = _toolingStore;
464
+ if (!registry || !store) {
465
+ return { applied: false, reason: "no proposal is open" };
466
+ }
467
+
468
+ let target: { choice: "yes" | "no"; requestId: string } | null = null;
469
+ try {
470
+ const mod = await import("./packages/tooling-preference/dist/index.js");
471
+ target = mod.parseToolingTarget(targetId);
472
+ } catch (error) {
473
+ logToFile("[ToolingPreference]", `package unavailable: ${oneLineError(error)}`);
474
+ return { applied: false, reason: "the proposal cannot be read" };
475
+ }
476
+ if (!target) {
477
+ return { applied: false, reason: "the button does not belong to a proposal" };
478
+ }
479
+
480
+ const claimed = registry.claim(target.requestId, target.choice, channel);
481
+ if (!claimed) {
482
+ return { applied: false, reason: "the proposal was already answered" };
483
+ }
484
+
485
+ store.recordDecision(
486
+ claimed.request.userKey,
487
+ claimed.request.workspaceRoot,
488
+ claimed.resolution.preference,
489
+ target.requestId,
490
+ channel,
491
+ );
492
+ logToFile(
493
+ "[ToolingPreference]",
494
+ `${channel} answered the proposal: ${claimed.resolution.preference}`,
495
+ );
496
+
497
+ if (claimed.resolution.choice === "yes" && pi) {
498
+ await startBiomeImplementation(claimed.request.workspaceRoot, channel, pi);
499
+ }
500
+ return {
501
+ applied: true,
502
+ reason:
503
+ claimed.resolution.choice === "yes"
504
+ ? "Biome.js will be implemented"
505
+ : "the current tools stay",
506
+ };
507
+ }
508
+
509
+ /**
510
+ * Start the Biome implementation after a "Yes".
511
+ *
512
+ * The harness does not change the repository itself: the agent does the
513
+ * work, so the change stays reviewable in the session.
514
+ */
515
+ async function startBiomeImplementation(
516
+ workspaceRoot: string,
517
+ channel: string,
518
+ pi: ExtensionAPI,
519
+ ): Promise<void> {
520
+ try {
521
+ const mod = await import("./packages/tooling-preference/dist/index.js");
522
+ const context = mod.detectToolingContext(workspaceRoot);
523
+ await pi.sendUserMessage(
524
+ mod.buildToolingImplementationPrompt(context, workspaceRoot),
525
+ { deliverAs: "steer" },
526
+ );
527
+ logToFile("[ToolingPreference]", `agent asked to implement Biome (${channel})`);
528
+ } catch (error) {
529
+ logToFile("[ToolingPreference]", `steer failed: ${oneLineError(error)}`);
530
+ }
531
+ }
532
+
299
533
  async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
300
534
  addHarnessMessage("Jev", "initializing", "wait");
301
535
  try {
@@ -1656,6 +1890,10 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
1656
1890
  const lineAccessToken = hasLineCredentials ? readFileSync(lineTokenPath, "utf8").trim() : null;
1657
1891
  const lineUserId = hasLineCredentials ? readFileSync(lineUserIdPath, "utf8").trim() : null;
1658
1892
 
1893
+ // The identity of the person the notifications reach. It is hashed
1894
+ // before it is stored and never reaches a log file.
1895
+ _toolingIdentity = chatId || lineUserId || "";
1896
+
1659
1897
  if (!botToken || !chatId) {
1660
1898
  logStartup("[pi-harness] Telegram: bot token or chat ID is empty — skipping");
1661
1899
  const emptyFixes = keyFileFixesOrFallback("Telegram", ["bot token", "chat id"]);
@@ -1782,6 +2020,21 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
1782
2020
  }
1783
2021
 
1784
2022
  switch (parsed.action) {
2023
+ case CallbackActions.TOOLING_PREFERENCE: {
2024
+ // The proposal is a decision of its own: it never resolves a
2025
+ // pending question and it never pauses the work.
2026
+ const result = await resolveToolingPreference(
2027
+ parsed.targetId,
2028
+ "telegram",
2029
+ pi,
2030
+ );
2031
+ await acknowledge(
2032
+ result.applied
2033
+ ? `Saved - ${result.reason}`
2034
+ : `Stale button - ${result.reason}`,
2035
+ );
2036
+ break;
2037
+ }
1785
2038
  case CallbackActions.APPROVE: {
1786
2039
  // The user clicked Continue. The request ID in the
1787
2040
  // callback data is the canonical one, so the click
@@ -2268,7 +2521,21 @@ async function initRelayStream(): Promise<void> {
2268
2521
  // A LINE postback is the same decision as a Telegram button
2269
2522
  // click: one resolver, the same canonical request ID.
2270
2523
  if (callback.type === "line_callback") {
2271
- applyChannelApproval(callback.action, callback.targetId, "line");
2524
+ if (
2525
+ callback.action === "biome" ||
2526
+ callback.action.startsWith("biome_")
2527
+ ) {
2528
+ // The tooling proposal is a decision of its own: it never
2529
+ // resolves a pending question and it never pauses the
2530
+ // work. The postback data may arrive split or as one
2531
+ // string - both carry the choice and the request ID.
2532
+ const raw = callback.action.startsWith("biome_")
2533
+ ? callback.action.slice("biome_".length)
2534
+ : callback.targetId;
2535
+ await resolveToolingPreference(raw, "line", _extensionApi);
2536
+ } else {
2537
+ applyChannelApproval(callback.action, callback.targetId, "line");
2538
+ }
2272
2539
  }
2273
2540
 
2274
2541
  // Forward Telegram callbacks to the adapter
@@ -3621,6 +3888,9 @@ export default async function (pi: ExtensionAPI) {
3621
3888
  const tracker = new UsageTracker();
3622
3889
  const mirrorStore = new MirrorStore();
3623
3890
  ensureHarnessDir();
3891
+ // The relay path has no `pi` of its own - the extension API is kept
3892
+ // here so every path can reach the agent.
3893
+ _extensionApi = pi;
3624
3894
 
3625
3895
  // --- central-logging: ship structured logs to R2 / the webhook server ---
3626
3896
  // The pipeline is opt-in by configuration, never by code: without R2
@@ -3675,6 +3945,10 @@ export default async function (pi: ExtensionAPI) {
3675
3945
  // Collect promise so we can wait for initialization before showing startup notification
3676
3946
  asyncInitPromises.push(initQdrant());
3677
3947
 
3948
+ // --- tooling-preference: offer Biome.js instead of ESLint/Prettier ------
3949
+ // The proposal is a decision of its own: it never pauses the work.
3950
+ void initToolingPreference(pi);
3951
+
3678
3952
  // --- telegram-notifications: Telegram bot for harness event notifications ----
3679
3953
  // Collect promise so we can wait for initialization before showing startup notification
3680
3954
  asyncInitPromises.push(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/a2a-adapter",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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/agent-policy",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "description": "Agent policy runtime for pi-harness - enforces mandatory rule delivery and mutation gating",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/architecture-generator",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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-harness/connection-runtime",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "type": "module",
5
5
  "description": "Connection management with jittered exponential backoff for pi-harness",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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/contracts",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "type": "module",
5
5
  "description": "RPC schema definitions for pi-harness runtime",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cookie-sanitizer",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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": "@moocoding/durable-review",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "description": "SQLite-backed durable reviewer using @earendil-works/pi-durable",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/e2e-tester",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "description": "WebMCP-powered E2E testing for pi-harness - natural language test scenarios",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/event-sink",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
4
4
  "type": "module",
5
5
  "description": "Atomic event sourcing with SQLite transactions for pi-harness",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/event-store",
3
- "version": "1.1.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
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.404",
3
+ "version": "1.1.405",
4
4
  "type": "module",
5
5
  "description": "Collect and aggregate human/automated feedback (RFC-0021)",
6
6
  "main": "dist/index.js",