pi-harness-runtime 1.1.219 → 1.1.221

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 (102) hide show
  1. package/harness/honcho-init.ts +29 -29
  2. package/index.ts +47 -57
  3. package/package.json +1 -1
  4. package/packages/a2a-adapter/package.json +1 -1
  5. package/packages/agent-policy/package.json +1 -1
  6. package/packages/architecture-generator/package.json +1 -1
  7. package/packages/auth/package.json +1 -1
  8. package/packages/autonomous-refactor/package.json +1 -1
  9. package/packages/autonomous-runtime/package.json +1 -1
  10. package/packages/cache-strategy/package.json +1 -1
  11. package/packages/capability-registry/package.json +1 -1
  12. package/packages/checkpoint/package.json +1 -1
  13. package/packages/cli-plugin-sdk/package.json +1 -1
  14. package/packages/clipboard/package.json +1 -1
  15. package/packages/clipboard-plugin/package.json +1 -1
  16. package/packages/code-generation/package.json +1 -1
  17. package/packages/code-review/package.json +1 -1
  18. package/packages/codex-adapter/package.json +1 -1
  19. package/packages/codex-watcher/package.json +1 -1
  20. package/packages/config-capture/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/cookie-sanitizer/package.json +1 -1
  25. package/packages/cost-optimizer/package.json +1 -1
  26. package/packages/dependency-analyzer/package.json +1 -1
  27. package/packages/django-plugin/package.json +1 -1
  28. package/packages/doc-generator/package.json +1 -1
  29. package/packages/e2e-tester/package.json +1 -1
  30. package/packages/evaluation-engine/package.json +1 -1
  31. package/packages/evaluation-runner/package.json +1 -1
  32. package/packages/event-bus/package.json +1 -1
  33. package/packages/event-store/package.json +1 -1
  34. package/packages/experience-replay/package.json +1 -1
  35. package/packages/feedback-collector/package.json +1 -1
  36. package/packages/file-copy-helper/package.json +1 -1
  37. package/packages/framework-detector/package.json +1 -1
  38. package/packages/framework-plugin-sdk/package.json +1 -1
  39. package/packages/frappe-plugin/package.json +1 -1
  40. package/packages/generic-web-plugin/package.json +1 -1
  41. package/packages/health-monitor/package.json +1 -1
  42. package/packages/intent-analyzer/package.json +1 -1
  43. package/packages/jev-judge/package.json +1 -1
  44. package/packages/knowledge-graph/package.json +1 -1
  45. package/packages/knowledge-retrieval/package.json +1 -1
  46. package/packages/laravel-plugin/package.json +1 -1
  47. package/packages/learning-engine/package.json +1 -1
  48. package/packages/mcp-adapter/package.json +1 -1
  49. package/packages/memory-engine/package.json +1 -1
  50. package/packages/milestone-manager/package.json +1 -1
  51. package/packages/model-registry/package.json +1 -1
  52. package/packages/nextjs-plugin/package.json +1 -1
  53. package/packages/notification/package.json +1 -1
  54. package/packages/observability/package.json +1 -1
  55. package/packages/okf-indexer/package.json +1 -1
  56. package/packages/paperclip-integration/package.json +1 -1
  57. package/packages/performance-optimizer/package.json +1 -1
  58. package/packages/privilege-broker/package.json +1 -1
  59. package/packages/project-analyzer/package.json +1 -1
  60. package/packages/project-bootstrap/package.json +1 -1
  61. package/packages/projection-engine/package.json +1 -1
  62. package/packages/prompt-compiler/package.json +1 -1
  63. package/packages/prompt-versioning/package.json +1 -1
  64. package/packages/provider-adapter-sdk/package.json +1 -1
  65. package/packages/provider-router/package.json +1 -1
  66. package/packages/provider-selector/package.json +1 -1
  67. package/packages/providers/package.json +1 -1
  68. package/packages/qdrant-skills/package.json +1 -1
  69. package/packages/quota-manager/package.json +1 -1
  70. package/packages/rate-limiter/package.json +1 -1
  71. package/packages/react-vite-plugin/package.json +1 -1
  72. package/packages/release-manager/package.json +1 -1
  73. package/packages/requirement-compiler/package.json +1 -1
  74. package/packages/runtime/package.json +1 -1
  75. package/packages/scheduler/package.json +1 -1
  76. package/packages/scheduler-adapter/package.json +1 -1
  77. package/packages/session/package.json +1 -1
  78. package/packages/session-api/package.json +1 -1
  79. package/packages/session-export/package.json +1 -1
  80. package/packages/shared-context/package.json +1 -1
  81. package/packages/skill-mcp-client/package.json +1 -1
  82. package/packages/skill-registry/package.json +1 -1
  83. package/packages/skills/package.json +1 -1
  84. package/packages/sprint-planner/package.json +1 -1
  85. package/packages/subscription-engine/package.json +1 -1
  86. package/packages/task-compiler/package.json +1 -1
  87. package/packages/telegram/package.json +1 -1
  88. package/packages/tencentdb-memory/package.json +1 -1
  89. package/packages/tencentdb-sync/package.json +1 -1
  90. package/packages/test-data-generator/package.json +1 -1
  91. package/packages/test-generator/package.json +1 -1
  92. package/packages/todo-bd-sync/package.json +1 -1
  93. package/packages/token-estimation/package.json +1 -1
  94. package/packages/token-optimizer/package.json +1 -1
  95. package/packages/trajectory/package.json +1 -1
  96. package/packages/tui/package.json +1 -1
  97. package/packages/types/package.json +1 -1
  98. package/packages/webmcp-tester/package.json +1 -1
  99. package/packages/workflow-events/package.json +1 -1
  100. package/packages/workspace-scanner/package.json +1 -1
  101. package/packages/worktree/package.json +1 -1
  102. package/packages/write-review/package.json +1 -1
@@ -380,29 +380,29 @@ export async function initHoncho(options?: {
380
380
  piEvents?: PiEvents;
381
381
  }): Promise<HonchoMemory | null> {
382
382
  if (_disposed) {
383
- console.error("[honcho] Integration has been disposed, cannot reinitialize");
383
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "dispose", phase: "failed", reason: "integration has been disposed, cannot reinitialize" });
384
384
  return null;
385
385
  }
386
386
 
387
387
  // Allow retry if previous init failed
388
388
  if (_initialized && _initSucceeded) {
389
- console.debug("[honcho] Already initialized, returning existing instance");
389
+ logServiceEvent({ ts: new Date().toISOString(), level: "debug", service: "honcho", operation: "init", phase: "completed", reason: "already initialized, returning existing instance" });
390
390
  return _honchoMemory;
391
391
  }
392
392
 
393
393
  // Reset state if retrying
394
394
  if (_initialized && !_initSucceeded) {
395
- console.info("[honcho] Retrying initialization...");
395
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "init", phase: "start", reason: "retrying initialization" });
396
396
  }
397
397
  _initialized = true;
398
398
  _initSucceeded = false;
399
399
 
400
- console.info("[honcho] Initializing Honcho MCP integration...");
400
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "init", phase: "start" });
401
401
 
402
402
  // Load API key
403
403
  const key = options?.apiKey ?? loadHonchoApiKey();
404
404
  if (!key) {
405
- console.error("[honcho] No API key found. Run: echo \"YOUR_KEY\" > ~/.pi-harness-runtime/keys/honcho-api-key.txt");
405
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "init", phase: "failed", reason: "No API key found", helpUrl: "https://app.honcho.dev" });
406
406
  honchoStatus.setConfigured(false);
407
407
  honchoStatus.recordFailure("init", "no_key", { error: "No API key" });
408
408
  return null;
@@ -421,9 +421,9 @@ export async function initHoncho(options?: {
421
421
  // Write MCP config for the adapter to pick up
422
422
  try {
423
423
  writeHonchoMcpConfig(key);
424
- console.info("[honcho] MCP config written");
424
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "mcp_config", phase: "completed" });
425
425
  } catch (err) {
426
- console.warn("[honcho] Failed to write MCP config:", err);
426
+ logServiceEvent({ ts: new Date().toISOString(), level: "warn", service: "honcho", operation: "mcp_config", phase: "failed", reason: err instanceof Error ? err.message : String(err) });
427
427
  // Continue anyway - adapter may use its own config
428
428
  }
429
429
 
@@ -431,7 +431,7 @@ export async function initHoncho(options?: {
431
431
  const piEvents = options?.piEvents ?? (globalThis as { pi?: { events?: PiEvents } }).pi?.events;
432
432
 
433
433
  if (!piEvents) {
434
- console.error("[honcho] pi.events not available - MCP adapter may not be installed");
434
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "init", phase: "failed", reason: "pi.events not available" });
435
435
  honchoStatus.recordFailure("init", "adapter_missing", { error: "pi.events not available" });
436
436
  return null;
437
437
  }
@@ -453,8 +453,8 @@ export async function initHoncho(options?: {
453
453
 
454
454
  // Read result immediately after emit
455
455
  if (request.result === undefined) {
456
- console.error("[honcho] MCP adapter not responding to registration");
457
- console.error("[honcho] Install: pi install npm:pi-mcp-adapter");
456
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "mcp_register", phase: "failed", reason: "MCP adapter not responding" });
457
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "mcp_register", phase: "failed", helpUrl: "pi install npm:pi-mcp-adapter" });
458
458
  honchoStatus.recordFailure("init", "no_listener", { error: "No adapter responded" });
459
459
  return null;
460
460
  }
@@ -464,17 +464,17 @@ export async function initHoncho(options?: {
464
464
 
465
465
  // Check for duplicate name - an existing server may already be registered
466
466
  if (errorMsg.includes("already") || errorMsg.includes("duplicate")) {
467
- console.warn(`[honcho] Server already registered (duplicate name), continuing...`);
467
+ logServiceEvent({ ts: new Date().toISOString(), level: "warn", service: "honcho", operation: "mcp_register", phase: "completed", reason: "server already registered (duplicate name)" });
468
468
  // Continue with memory initialization - the existing server should work
469
469
  } else {
470
- console.error(`[honcho] Registration failed: ${errorMsg}`);
470
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "mcp_register", phase: "failed", reason: errorMsg });
471
471
  honchoStatus.recordFailure("init", "registration_rejected", { error: errorMsg });
472
472
  return null;
473
473
  }
474
474
  } else {
475
475
  // Registration accepted - store handle for disposal
476
476
  _honchoRegistration = request.result.registration;
477
- console.info("[honcho] MCP server registered");
477
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "mcp_register", phase: "completed" });
478
478
  }
479
479
 
480
480
  // Create memory instance
@@ -488,43 +488,43 @@ export async function initHoncho(options?: {
488
488
  const userName = options?.userName ?? "pi-user";
489
489
  const sessionId = options?.sessionId ?? `pi-session-${Date.now()}`;
490
490
 
491
- console.info("[honcho] Establishing workspace/peer identity...");
491
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "identity", phase: "start" });
492
492
 
493
493
  // Step 1: Create/get workspace
494
494
  const workspaceId = await ensureWorkspace(workspaceName);
495
495
  if (!workspaceId) {
496
- console.error("[honcho] Failed to create workspace");
496
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "create_workspace", phase: "failed" });
497
497
  honchoStatus.recordFailure("init", "workspace_failed", {});
498
498
  return _honchoMemory; // Return instance but mark as not ready
499
499
  }
500
- console.info(`[honcho] Workspace: ${workspaceId}`);
500
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "create_workspace", phase: "completed", workspaceId });
501
501
 
502
502
  // Step 2: Create/get user peer
503
503
  const userPeerId = await ensureUserPeer(workspaceId, userName);
504
504
  if (!userPeerId) {
505
- console.error("[honcho] Failed to create user peer");
505
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "create_user_peer", phase: "failed" });
506
506
  honchoStatus.recordFailure("init", "user_peer_failed", {});
507
507
  return _honchoMemory;
508
508
  }
509
- console.info(`[honcho] User peer: ${userPeerId}`);
509
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "create_user_peer", phase: "completed", userPeerId });
510
510
 
511
511
  // Step 3: Create/get assistant peer
512
512
  const assistantPeerId = await ensureAssistantPeer(workspaceId, assistantName);
513
513
  if (!assistantPeerId) {
514
- console.error("[honcho] Failed to create assistant peer");
514
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "create_assistant_peer", phase: "failed" });
515
515
  honchoStatus.recordFailure("init", "assistant_peer_failed", {});
516
516
  return _honchoMemory;
517
517
  }
518
- console.info(`[honcho] Assistant peer: ${assistantPeerId}`);
518
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "create_assistant_peer", phase: "completed", assistantPeerId });
519
519
 
520
520
  // Step 4: Create/get session
521
521
  const honchoSessionId = await ensureSession(workspaceId, userPeerId, assistantPeerId, sessionId);
522
522
  if (!honchoSessionId) {
523
- console.error("[honcho] Failed to create session");
523
+ logServiceEvent({ ts: new Date().toISOString(), level: "error", service: "honcho", operation: "create_session", phase: "failed" });
524
524
  honchoStatus.recordFailure("init", "session_failed", {});
525
525
  return _honchoMemory;
526
526
  }
527
- console.info(`[honcho] Session: ${honchoSessionId}`);
527
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "create_session", phase: "completed", honchoSessionId });
528
528
 
529
529
  // Store identity
530
530
  _identity = {
@@ -540,7 +540,7 @@ export async function initHoncho(options?: {
540
540
  _honchoMemory.setWorkspace(workspaceId);
541
541
  _honchoMemory.setSession(honchoSessionId);
542
542
 
543
- console.info("[honcho] Memory ready");
543
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "memory_init", phase: "completed" });
544
544
  honchoStatus.recordSuccess("init", undefined, {
545
545
  workspaceId,
546
546
  userPeerId,
@@ -650,7 +650,7 @@ export async function shutdownHoncho(): Promise<void> {
650
650
  }
651
651
 
652
652
  _disposed = true;
653
- console.info("[honcho] Shutting down...");
653
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "shutdown", phase: "start" });
654
654
 
655
655
  // Dispose memory instance
656
656
  if (_honchoMemory) {
@@ -665,15 +665,15 @@ export async function shutdownHoncho(): Promise<void> {
665
665
  if (_honchoRegistration) {
666
666
  try {
667
667
  await _honchoRegistration.dispose();
668
- console.info("[honcho] Registration disposed");
668
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "dispose_registration", phase: "completed" });
669
669
  } catch (err) {
670
- console.warn("[honcho] Failed to dispose registration:", err);
670
+ logServiceEvent({ ts: new Date().toISOString(), level: "warn", service: "honcho", operation: "dispose_registration", phase: "failed", reason: err instanceof Error ? err.message : String(err) });
671
671
  }
672
672
  _honchoRegistration = null;
673
673
  }
674
674
 
675
675
  _initialized = false;
676
- console.info("[honcho] Shutdown complete");
676
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "shutdown", phase: "completed" });
677
677
  }
678
678
 
679
679
  /**
@@ -704,7 +704,7 @@ export function registerHonchoLifecycle(
704
704
  ): void {
705
705
  // Initialize at session start
706
706
  pi.on("session_start", async () => {
707
- console.info("[honcho] Session started, initializing...");
707
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "session_start", phase: "start" });
708
708
  await initHoncho();
709
709
  });
710
710
 
@@ -741,5 +741,5 @@ export function registerHonchoLifecycle(
741
741
  }
742
742
  });
743
743
 
744
- console.info("[honcho] Lifecycle hooks registered");
744
+ logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "lifecycle_hooks", phase: "completed" });
745
745
  }
package/index.ts CHANGED
@@ -140,9 +140,7 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
140
140
  readFileSync(`${keysDir}/jev-api-key.txt`, "utf8").trim().length > 10;
141
141
 
142
142
  if (!hasEnvKey && !hasFileKey) {
143
- console.error(
144
- "[auto-continue] No Jev API key found. Set TYPESAFE_API_KEY run: echo \"{api_key}\" > ~/.pi-harness-runtime/keys/jev-api-key.txt"
145
- );
143
+ logToFile("[auto-continue]", "No Jev API key found. Set TYPESAFE_API_KEY run: echo \"{api_key}\" > ~/.pi-harness-runtime/keys/jev-api-key.txt");
146
144
  return;
147
145
  }
148
146
 
@@ -721,15 +719,15 @@ function initLangChain(pi: {
721
719
  handler: async (_args: string, _ctx: unknown) => {
722
720
  const allModels = listAllModels();
723
721
  if (allModels.length === 0) {
724
- console.error("[pi-harness] /langchain-config: no models found in ~/.pi/agent/models-store.json");
725
- console.error("[pi-harness] Configure models first via /model in pi");
722
+ logToFile("[pi-harness]", "/langchain-config: no models found in ~/.pi/agent/models-store.json");
723
+ logToFile("[pi-harness]", " Configure models first via /model in pi");
726
724
  return;
727
725
  }
728
726
 
729
727
  // Print available models
730
- console.error("[pi-harness] Available models:");
728
+ logToFile("[pi-harness]", "Available models:");
731
729
  for (const m of allModels) {
732
- console.error(` [${m.index}] ${m.provider}/${m.id}`);
730
+ logToFile("[pi-harness]", ` [${m.index}] ${m.provider}/${m.id}`);
733
731
  }
734
732
 
735
733
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
@@ -757,7 +755,7 @@ function initLangChain(pi: {
757
755
  }
758
756
 
759
757
  if (!plannerSpec || !coderSpec || !reviewerSpec) {
760
- console.error("[pi-harness] /langchain-config: all three roles must be selected");
758
+ logToFile("[pi-harness]", "/langchain-config: all three roles must be selected");
761
759
  return;
762
760
  }
763
761
 
@@ -769,20 +767,20 @@ function initLangChain(pi: {
769
767
  };
770
768
  writeFileSync(roleConfigPath, JSON.stringify(config, null, 2), "utf8");
771
769
 
772
- console.error("[pi-harness] LangChain role config saved:");
773
- console.error(`[pi-harness] planner: ${plannerSpec}`);
774
- console.error(`[pi-harness] coder: ${coderSpec}`);
775
- console.error(`[pi-harness] reviewer: ${reviewerSpec}`);
770
+ logToFile("[pi-harness]", "LangChain role config saved:");
771
+ logToFile("[pi-harness]", ` planner: ${plannerSpec}`);
772
+ logToFile("[pi-harness]", ` coder: ${coderSpec}`);
773
+ logToFile("[pi-harness]", ` reviewer: ${reviewerSpec}`);
776
774
 
777
775
  // Also prompt for API keys if missing
778
776
  if (!existsSync(`${keysDir}/planner-api-key.txt`)) {
779
- console.error(`[pi-harness] planner-api-key.txt missing. echo "{key}" > ${keysDir}/planner-api-key.txt`);
777
+ logToFile("[pi-harness]", ` planner-api-key.txt missing. echo "{key}" > ${keysDir}/planner-api-key.txt`);
780
778
  }
781
779
  if (!existsSync(`${keysDir}/reviewer-api-key.txt`)) {
782
- console.error(`[pi-harness] reviewer-api-key.txt missing. echo "{key}" > ${keysDir}/reviewer-api-key.txt`);
780
+ logToFile("[pi-harness]", ` reviewer-api-key.txt missing. echo "{key}" > ${keysDir}/reviewer-api-key.txt`);
783
781
  }
784
782
  if (!existsSync(`${keysDir}/coder-api-key.txt`)) {
785
- console.error(`[pi-harness] coder-api-key.txt missing. echo "{key}" > ${keysDir}/coder-api-key.txt`);
783
+ logToFile("[pi-harness]", ` coder-api-key.txt missing. echo "{key}" > ${keysDir}/coder-api-key.txt`);
786
784
  }
787
785
  },
788
786
  });
@@ -809,13 +807,13 @@ function initLangChain(pi: {
809
807
  const coderKeyExists = existsSync(`${keysDir}/coder-api-key.txt`);
810
808
 
811
809
  if (!activeConfig) {
812
- console.error("[pi-harness] /langchain not configured — run /langchain-config");
810
+ logToFile("[pi-harness]", "/langchain not configured — run /langchain-config");
813
811
  } else if (!plannerKeyExists || !reviewerKeyExists || !coderKeyExists) {
814
812
  const missingKeys: string[] = [];
815
813
  if (!plannerKeyExists) missingKeys.push("planner-api-key.txt");
816
814
  if (!reviewerKeyExists) missingKeys.push("reviewer-api-key.txt");
817
815
  if (!coderKeyExists) missingKeys.push("coder-api-key.txt");
818
- console.error(`[pi-harness] /langchain missing API keys: ${missingKeys.join(", ")}`);
816
+ logToFile("[pi-harness]", `/langchain missing API keys: ${missingKeys.join(", ")}`);
819
817
  } else {
820
818
  logStartup(`[pi-harness] /langchain ready (${activeConfig.planner.id} + ${activeConfig.coder.id} + ${activeConfig.reviewer.id})`);
821
819
  }
@@ -825,14 +823,14 @@ function initLangChain(pi: {
825
823
  prompt: "Describe the feature or task for the LangChain loop to implement.",
826
824
  handler: async (request: string) => {
827
825
  if (!request.trim()) {
828
- console.error("[pi-harness] /langchain requires a request.");
829
- console.error("[pi-harness] Example: /langchain implement user auth module");
826
+ logToFile("[pi-harness]", "/langchain requires a request.");
827
+ logToFile("[pi-harness]", " Example: /langchain implement user auth module");
830
828
  return;
831
829
  }
832
830
 
833
831
  const cfg = loadActiveConfig();
834
832
  if (!cfg) {
835
- console.error("[pi-harness] /langchain: not configured. Run /langchain-config first.");
833
+ logToFile("[pi-harness]", "/langchain: not configured. Run /langchain-config first.");
836
834
  return;
837
835
  }
838
836
 
@@ -859,7 +857,7 @@ function initLangChain(pi: {
859
857
  stdio: "inherit",
860
858
  });
861
859
  proc.on("exit", (code: number | null) => {
862
- if (code !== 0) console.error(`[pi-harness] /langchain exited with code ${code}`);
860
+ if (code !== 0) logToFile("[pi-harness]", `/langchain exited with code ${code}`);
863
861
  });
864
862
  },
865
863
  });
@@ -888,12 +886,8 @@ function initMoocodingSyncHint(): void {
888
886
  if (benchEntries.length === 0) return;
889
887
 
890
888
  const targetPath = join(homedir(), ".pi-harness-runtime", "skills");
891
- console.error(
892
- `[pi-harness] ${benchEntries.length} moocoding skill(s) found in frappe-bench`
893
- );
894
- console.error(
895
- `[pi-harness] Run /sync-skills --from ${benchPath} --to ${targetPath}`
896
- );
889
+ logToFile("[pi-harness]", `${benchEntries.length} moocoding skill(s) found in frappe-bench`);
890
+ logToFile("[pi-harness]", `Run /sync-skills --from ${benchPath} --to ${targetPath}`);
897
891
  } catch {
898
892
  // Non-fatal — ignore errors
899
893
  }
@@ -1582,7 +1576,7 @@ export default function (pi: ExtensionAPI) {
1582
1576
  maxIdlePolls: Infinity,
1583
1577
  onSessionChange: (session) => {
1584
1578
  if (session) {
1585
- console.error(`[codex] Session started: ${session.threadName}`);
1579
+ logToFile("[codex]", `Session started: ${session.threadName}`);
1586
1580
  nc("CodexSessionStarted", {
1587
1581
  requirement: session.threadName || "Codex session",
1588
1582
  taskTitle: session.id,
@@ -1673,9 +1667,7 @@ ${planPreview}`,
1673
1667
  // pi.on("session_end", () => watcher.stop()); // Removed - type error
1674
1668
  }
1675
1669
  } else {
1676
- console.error(
1677
- "[paperclip] Not configured. Set PAPERCLIP_API_KEY or write API key to ~/.pi-harness-runtime/keys/paperclip-api-key.txt",
1678
- );
1670
+ logToFile("[paperclip]", "Not configured. Set PAPERCLIP_API_KEY or write API key to ~/.pi-harness-runtime/keys/paperclip-api-key.txt");
1679
1671
  }
1680
1672
 
1681
1673
  // --- loop-completions: Watch daemon completions → agent TUI todos --------
@@ -1883,7 +1875,7 @@ Run \`bd ready\` to see current bd issues.
1883
1875
  !content.includes("bd ready") &&
1884
1876
  !content.includes("TODO UPDATE")
1885
1877
  ) {
1886
- console.log(TODO_BUILD_REMINDER.trim());
1878
+ logToFile(TODO_BUILD_REMINDER.trim());
1887
1879
  }
1888
1880
  });
1889
1881
 
@@ -1935,13 +1927,13 @@ Run \`bd ready\` to see current bd issues.
1935
1927
  )
1936
1928
  ) {
1937
1929
  providerOverloadResumeAttempts += 1;
1938
- console.error(`[pi-harness] Scheduling provider overload resume #${providerOverloadResumeAttempts}`);
1930
+ logToFile("[pi-harness]", `Scheduling provider overload resume #${providerOverloadResumeAttempts}`);
1939
1931
  scheduleProviderOverloadResume(() => ctx.hasPendingMessages());
1940
1932
  } else if (m.stopReason === "stop") {
1941
1933
  outputLimitResumeAttempts = 0;
1942
1934
  pendingOutputLimitResumeAfterSettled = false;
1943
1935
  if (providerOverloadResumeAttempts > 0) {
1944
- console.error(`[pi-harness] Counter reset (stopReason=stop), was=${providerOverloadResumeAttempts}`);
1936
+ logToFile("[pi-harness]", `Counter reset (stopReason=stop), was=${providerOverloadResumeAttempts}`);
1945
1937
  }
1946
1938
  providerOverloadResumeAttempts = 0;
1947
1939
  clearProviderOverloadResume();
@@ -2055,8 +2047,7 @@ Run \`bd ready\` to see current bd issues.
2055
2047
  resets_at: signal.resetsAt,
2056
2048
  });
2057
2049
  } catch (e) {
2058
- console.error(
2059
- "[pi-harness] tui-signal write failed:",
2050
+ logToFile("[pi-harness] tui-signal write failed:",
2060
2051
  e instanceof Error ? e.message : String(e),
2061
2052
  );
2062
2053
  }
@@ -2099,7 +2090,7 @@ Run \`bd ready\` to see current bd issues.
2099
2090
  } catch (e) {
2100
2091
  const msg = e instanceof Error ? e.message : String(e);
2101
2092
  if (msg.includes("ENOSPC")) {
2102
- console.error(
2093
+ logToFile(
2103
2094
  "[pi-harness] cookie-sanitizer watcher: ENOSPC — " +
2104
2095
  "inotify watcher limit reached.\n" +
2105
2096
  "Fix (once, as root):\n" +
@@ -2108,7 +2099,7 @@ Run \`bd ready\` to see current bd issues.
2108
2099
  "Drop folder sync still works — polling will resume automatically.",
2109
2100
  );
2110
2101
  } else {
2111
- console.error("[pi-harness] cookie-sanitizer watcher failed to start:", msg);
2102
+ logToFile("[pi-harness] cookie-sanitizer watcher failed to start:", msg);
2112
2103
  }
2113
2104
  }
2114
2105
 
@@ -2287,8 +2278,9 @@ Run \`bd ready\` to see current bd issues.
2287
2278
  };
2288
2279
  } catch (error) {
2289
2280
  if (!suppressErrors) {
2290
- console.error(
2291
- "[pi-harness] Browser-profile quota fetch skipped:",
2281
+ logToFile(
2282
+ "[pi-harness]",
2283
+ "Browser-profile quota fetch skipped:",
2292
2284
  error instanceof Error ? error.message : String(error),
2293
2285
  );
2294
2286
  }
@@ -2333,8 +2325,9 @@ Run \`bd ready\` to see current bd issues.
2333
2325
  return true;
2334
2326
  } catch (error) {
2335
2327
  if (!suppressErrors) {
2336
- console.error(
2337
- "[pi-harness] Quota auto-fetch skipped:",
2328
+ logToFile(
2329
+ "[pi-harness]",
2330
+ "Quota auto-fetch skipped:",
2338
2331
  error instanceof Error ? error.message : String(error),
2339
2332
  );
2340
2333
  }
@@ -2381,8 +2374,9 @@ Run \`bd ready\` to see current bd issues.
2381
2374
  return true;
2382
2375
  } catch (error) {
2383
2376
  if (!suppressErrors) {
2384
- console.error(
2385
- "[pi-harness] OpenAI quota auto-fetch skipped:",
2377
+ logToFile(
2378
+ "[pi-harness]",
2379
+ "OpenAI quota auto-fetch skipped:",
2386
2380
  error instanceof Error ? error.message : String(error),
2387
2381
  );
2388
2382
  }
@@ -2403,7 +2397,7 @@ Run \`bd ready\` to see current bd issues.
2403
2397
  const data = await _glmQuotaScraper.fetchUsage();
2404
2398
  if (!data) {
2405
2399
  if (!suppressErrors) {
2406
- console.error("[pi-harness] GLM quota auto-fetch: no data returned");
2400
+ logToFile("[pi-harness]", "GLM quota auto-fetch: no data returned");
2407
2401
  }
2408
2402
  return false;
2409
2403
  }
@@ -2453,23 +2447,20 @@ Run \`bd ready\` to see current bd issues.
2453
2447
  mirrorStore,
2454
2448
  currentSession.machine,
2455
2449
  );
2456
- console.log(`[GLM countdown] Started - will auto-resume at ${resetAt}`);
2450
+ logToFile("[GLM countdown]", `Started - will auto-resume at ${resetAt}`);
2457
2451
  }
2458
2452
 
2459
2453
  if (!suppressErrors) {
2460
2454
  const resetTime = resetAt
2461
2455
  ? `resets at ${new Date(resetAt).toLocaleString()}`
2462
2456
  : "resets soon";
2463
- console.error(`[pi-harness] GLM 5h quota exhausted! ${resetTime}`);
2457
+ logToFile("[pi-harness]", `GLM 5h quota exhausted! ${resetTime}`);
2464
2458
  }
2465
2459
  return true;
2466
2460
  }
2467
2461
 
2468
2462
  if (!suppressErrors) {
2469
- console.error(
2470
- "[pi-harness] GLM quota auto-fetch skipped:",
2471
- errorMsg,
2472
- );
2463
+ logToFile("[pi-harness]", "GLM quota auto-fetch skipped:", errorMsg);
2473
2464
  }
2474
2465
  return false;
2475
2466
  }
@@ -3303,8 +3294,9 @@ Run \`bd ready\` to see current bd issues.
3303
3294
  error: reason,
3304
3295
  });
3305
3296
  } catch (error) {
3306
- console.error(
3307
- `[pi-harness] Failed to queue ${reason} auto-resume:`,
3297
+ logToFile(
3298
+ "[pi-harness]",
3299
+ `Failed to queue ${reason} auto-resume:`,
3308
3300
  error instanceof Error ? error.message : String(error),
3309
3301
  );
3310
3302
  }
@@ -3317,9 +3309,7 @@ Run \`bd ready\` to see current bd issues.
3317
3309
  if (consecutiveCompactFailures >= MAX_PROACTIVE_COMPACT_FAILURES) {
3318
3310
  if (!proactiveCompactCircuitReported) {
3319
3311
  proactiveCompactCircuitReported = true;
3320
- console.error(
3321
- `[pi-harness] Proactive compact disabled after ${consecutiveCompactFailures} consecutive failures`,
3322
- );
3312
+ logToFile("[pi-harness]", `Proactive compact disabled after ${consecutiveCompactFailures} consecutive failures`);
3323
3313
  }
3324
3314
  return;
3325
3315
  }
@@ -3354,7 +3344,7 @@ Run \`bd ready\` to see current bd issues.
3354
3344
  onError: (error) => {
3355
3345
  proactiveCompactInFlight = false;
3356
3346
  consecutiveCompactFailures += 1;
3357
- console.error("[pi-harness] Proactive compact failed:", error.message);
3347
+ logToFile("[pi-harness]", "Proactive compact failed:", error.message);
3358
3348
  },
3359
3349
  };
3360
3350
  ctx.compact(compactOptions);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
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.219",
3
+ "version": "1.1.221",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex provider adapter for pi-harness",
6
6
  "main": "dist/index.js",