pi-harness-runtime 1.1.152 → 1.1.153

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 (110) hide show
  1. package/harness/langchain/graph.ts +9 -9
  2. package/harness/langchain/{jev-logger.ts → planner-logger.ts} +25 -24
  3. package/harness/service-diagnostics.ts +217 -0
  4. package/index.ts +30 -6
  5. package/package.json +1 -1
  6. package/packages/a2a-adapter/package.json +1 -1
  7. package/packages/agent-policy/package.json +1 -1
  8. package/packages/architecture-generator/package.json +1 -1
  9. package/packages/auth/package.json +1 -1
  10. package/packages/autonomous-refactor/package.json +1 -1
  11. package/packages/autonomous-runtime/package.json +1 -1
  12. package/packages/cache-strategy/package.json +1 -1
  13. package/packages/capability-registry/package.json +1 -1
  14. package/packages/checkpoint/package.json +1 -1
  15. package/packages/cli-plugin-sdk/package.json +1 -1
  16. package/packages/clipboard/package.json +1 -1
  17. package/packages/clipboard-plugin/package.json +1 -1
  18. package/packages/code-generation/package.json +1 -1
  19. package/packages/code-review/package.json +1 -1
  20. package/packages/codex-adapter/package.json +1 -1
  21. package/packages/codex-watcher/package.json +1 -1
  22. package/packages/config-capture/package.json +1 -1
  23. package/packages/context-compiler/package.json +1 -1
  24. package/packages/context-discovery/package.json +1 -1
  25. package/packages/context-manager/package.json +1 -1
  26. package/packages/cookie-sanitizer/package.json +1 -1
  27. package/packages/cost-optimizer/package.json +1 -1
  28. package/packages/dependency-analyzer/package.json +1 -1
  29. package/packages/django-plugin/package.json +1 -1
  30. package/packages/doc-generator/package.json +1 -1
  31. package/packages/evaluation-engine/package.json +1 -1
  32. package/packages/evaluation-runner/package.json +1 -1
  33. package/packages/event-bus/package.json +1 -1
  34. package/packages/event-store/package.json +1 -1
  35. package/packages/experience-replay/package.json +1 -1
  36. package/packages/feedback-collector/package.json +1 -1
  37. package/packages/file-copy-helper/package.json +1 -1
  38. package/packages/framework-detector/package.json +1 -1
  39. package/packages/framework-plugin-sdk/package.json +1 -1
  40. package/packages/frappe-plugin/package.json +1 -1
  41. package/packages/generic-web-plugin/package.json +1 -1
  42. package/packages/health-monitor/package.json +1 -1
  43. package/packages/intent-analyzer/package.json +1 -1
  44. package/packages/jev-judge/package.json +1 -1
  45. package/packages/knowledge-graph/package.json +1 -1
  46. package/packages/knowledge-retrieval/package.json +1 -1
  47. package/packages/laravel-plugin/package.json +1 -1
  48. package/packages/learning-engine/package.json +1 -1
  49. package/packages/mcp-adapter/package.json +1 -1
  50. package/packages/memory-engine/package.json +1 -1
  51. package/packages/milestone-manager/package.json +1 -1
  52. package/packages/model-registry/package.json +1 -1
  53. package/packages/nextjs-plugin/package.json +1 -1
  54. package/packages/notification/package.json +1 -1
  55. package/packages/observability/package.json +1 -1
  56. package/packages/okf-indexer/package.json +1 -1
  57. package/packages/paperclip-integration/package.json +1 -1
  58. package/packages/performance-optimizer/package.json +1 -1
  59. package/packages/privilege-broker/package.json +1 -1
  60. package/packages/project-analyzer/package.json +1 -1
  61. package/packages/project-bootstrap/package.json +1 -1
  62. package/packages/projection-engine/package.json +1 -1
  63. package/packages/prompt-compiler/package.json +1 -1
  64. package/packages/prompt-versioning/package.json +1 -1
  65. package/packages/provider-adapter-sdk/package.json +1 -1
  66. package/packages/provider-router/package.json +1 -1
  67. package/packages/provider-selector/package.json +1 -1
  68. package/packages/providers/package.json +1 -1
  69. package/packages/qdrant-skills/dist/client.d.ts.map +1 -1
  70. package/packages/qdrant-skills/dist/client.js +4 -3
  71. package/packages/qdrant-skills/dist/client.js.map +1 -1
  72. package/packages/qdrant-skills/package.json +1 -1
  73. package/packages/qdrant-skills/src/client.ts +14 -17
  74. package/packages/quota-manager/package.json +1 -1
  75. package/packages/rate-limiter/package.json +1 -1
  76. package/packages/react-vite-plugin/package.json +1 -1
  77. package/packages/release-manager/package.json +1 -1
  78. package/packages/requirement-compiler/package.json +1 -1
  79. package/packages/runtime/package.json +1 -1
  80. package/packages/scheduler/package.json +1 -1
  81. package/packages/scheduler-adapter/package.json +1 -1
  82. package/packages/session/package.json +1 -1
  83. package/packages/session-api/package.json +1 -1
  84. package/packages/session-export/package.json +1 -1
  85. package/packages/shared-context/package.json +1 -1
  86. package/packages/skill-mcp-client/package.json +1 -1
  87. package/packages/skill-registry/package.json +1 -1
  88. package/packages/skills/dist/loader.d.ts +9 -2
  89. package/packages/skills/dist/loader.d.ts.map +1 -1
  90. package/packages/skills/dist/loader.js +24 -7
  91. package/packages/skills/dist/loader.js.map +1 -1
  92. package/packages/skills/package.json +1 -1
  93. package/packages/skills/src/loader.ts +27 -7
  94. package/packages/sprint-planner/package.json +1 -1
  95. package/packages/subscription-engine/package.json +1 -1
  96. package/packages/task-compiler/package.json +1 -1
  97. package/packages/tencentdb-memory/package.json +1 -1
  98. package/packages/tencentdb-sync/package.json +1 -1
  99. package/packages/test-data-generator/package.json +1 -1
  100. package/packages/test-generator/package.json +1 -1
  101. package/packages/todo-bd-sync/package.json +1 -1
  102. package/packages/token-estimation/package.json +1 -1
  103. package/packages/token-optimizer/package.json +1 -1
  104. package/packages/trajectory/package.json +1 -1
  105. package/packages/tui/package.json +1 -1
  106. package/packages/types/package.json +1 -1
  107. package/packages/workflow-events/package.json +1 -1
  108. package/packages/workspace-scanner/package.json +1 -1
  109. package/packages/worktree/package.json +1 -1
  110. package/packages/write-review/package.json +1 -1
@@ -457,22 +457,22 @@ export async function buildRealLoopDeps(
457
457
  });
458
458
  const planOutput = lastMessage(plannerResponse) ?? "";
459
459
 
460
- // Import and use Jev logger (async - logs to file + Telegram)
460
+ // Import and use planner logger (async - logs to file + Telegram)
461
461
  try {
462
- const { logJevDecision, parseJevDecision } = await import("./jev-logger.js");
463
- const jevDecision = parseJevDecision(planOutput);
464
- setJevProvider(jevDecision.provider);
465
- await logJevDecision({
462
+ const { logPlannerDecision, parsePlannerDecision } = await import("./planner-logger.js");
463
+ const plannerDecision = parsePlannerDecision(planOutput);
464
+ setJevProvider(plannerDecision.provider);
465
+ await logPlannerDecision({
466
466
  timestamp: new Date().toISOString(),
467
467
  request,
468
- provider: jevDecision.provider,
469
- reason: jevDecision.reason,
470
- userInput: jevDecision.userInput,
468
+ provider: plannerDecision.provider,
469
+ reason: plannerDecision.reason,
470
+ userInput: plannerDecision.userInput,
471
471
  escalate: false,
472
472
  raw: planOutput,
473
473
  });
474
474
  } catch (logErr) {
475
- console.error("[JEV] Logger error:", (logErr as Error).message);
475
+ console.error("[PLANNER] Logger error:", (logErr as Error).message);
476
476
  }
477
477
 
478
478
  return planOutput;
@@ -1,20 +1,21 @@
1
1
  /**
2
- * Jev Logger - Exclusive logging for Jev's decisions
2
+ * Planner Logger - Logs LangChain planner decisions
3
3
  *
4
- * Logs all Jev decisions:
4
+ * Logs planner output:
5
5
  * - Provider selection (minimax vs gpt)
6
6
  * - User input decisions
7
7
  * - Escalation triggers
8
8
  * - Reasoning
9
9
  *
10
- * Sends to both file and Telegram for real-time monitoring.
10
+ * NOTE: This logs the LangChain planner's output, not TypeSafe Jev service calls.
11
+ * The TypeSafe Jev service is tracked separately in the auto-continue system.
11
12
  */
12
13
 
13
14
  import { mkdirSync, appendFileSync, existsSync } from "node:fs";
14
15
  import { join } from "node:path";
15
16
  import { homedir } from "node:os";
16
17
 
17
- export interface JevDecision {
18
+ export interface PlannerDecision {
18
19
  timestamp: string;
19
20
  request: string;
20
21
  provider: "minimax" | "gpt";
@@ -27,12 +28,12 @@ export interface JevDecision {
27
28
  escalateReason?: string;
28
29
  }
29
30
 
30
- export interface JevLogEntry extends JevDecision {
31
+ export interface PlannerLogEntry extends PlannerDecision {
31
32
  raw?: string; // Raw planner output for debugging
32
33
  }
33
34
 
34
35
  const LOG_DIR = join(homedir(), ".pi-harness-runtime", "logs");
35
- const LOG_FILE = join(LOG_DIR, "jev.log");
36
+ const LOG_FILE = join(LOG_DIR, "planner.log");
36
37
 
37
38
  // Telegram config (loaded from environment)
38
39
  let TELEGRAM_BOT_TOKEN: string | undefined;
@@ -54,20 +55,20 @@ function ensureLogDir(): void {
54
55
  /**
55
56
  * Format decision for file log (detailed, multi-line)
56
57
  */
57
- function formatFileLog(entry: JevLogEntry): string {
58
+ function formatFileLog(entry: PlannerLogEntry): string {
58
59
  const lines = [
59
60
  `═══════════════════════════════════════════════════════════════`,
60
- `[JEV] ${entry.timestamp}`,
61
+ `[PLANNER] ${entry.timestamp}`,
61
62
  `═══════════════════════════════════════════════════════════════`,
62
63
  ``,
63
64
  `## Request`,
64
65
  `${entry.request}`,
65
66
  ``,
66
- `## Jev Provider Decision`,
67
+ `## Provider Decision`,
67
68
  `Provider: ${entry.provider.toUpperCase()}`,
68
69
  `Reason: ${entry.reason}`,
69
70
  ``,
70
- `## Jev User Input Decision`,
71
+ `## User Input Decision`,
71
72
  `Type: ${entry.userInput?.type ?? "none (proceed automatically)"}`,
72
73
  entry.userInput?.question ? `Question: ${entry.userInput.question}` : ``,
73
74
  ``,
@@ -92,12 +93,12 @@ function formatFileLog(entry: JevLogEntry): string {
92
93
  /**
93
94
  * Format decision for Telegram (compact, single message)
94
95
  */
95
- function formatTelegramMessage(entry: JevLogEntry): string {
96
+ function formatTelegramMessage(entry: PlannerLogEntry): string {
96
97
  const providerIcon = entry.provider === "gpt" ? "🤖" : "⚡";
97
98
  const escalateIcon = entry.escalate ? " ↑ ESCALATE" : "";
98
99
 
99
100
  const parts = [
100
- `${providerIcon} *JEV DECISION*`,
101
+ `${providerIcon} *PLANNER DECISION*`,
101
102
  `\n*Provider:* ${entry.provider.toUpperCase()}${escalateIcon}`,
102
103
  `\n*Reason:* ${entry.reason}`,
103
104
  ];
@@ -125,16 +126,16 @@ async function sendToTelegram(message: string): Promise<void> {
125
126
  TELEGRAM_CHAT_ID = process.env.TELEGRAM_CHAT_ID ?? TELEGRAM_CHAT_ID;
126
127
 
127
128
  if (!TELEGRAM_BOT_TOKEN || !TELEGRAM_CHAT_ID) {
128
- console.log("[JEV] Telegram not configured - skipping");
129
+ console.log("[PLANNER] Telegram not configured - skipping");
129
130
  return;
130
131
  }
131
132
 
132
- console.log(`[JEV] Telegram sending: ${TELEGRAM_BOT_TOKEN?.slice(0, 10)}... to ${TELEGRAM_CHAT_ID}`);
133
+ console.log(`[PLANNER] Telegram sending: ${TELEGRAM_BOT_TOKEN?.slice(0, 10)}... to ${TELEGRAM_CHAT_ID}`);
133
134
  telegramQueue.push(message);
134
135
 
135
136
  // Process queue sequentially
136
137
  if (telegramSending) {
137
- console.log("[JEV] Telegram already sending, queued");
138
+ console.log("[PLANNER] Telegram already sending, queued");
138
139
  return;
139
140
  }
140
141
  telegramSending = true;
@@ -156,12 +157,12 @@ async function sendToTelegram(message: string): Promise<void> {
156
157
  );
157
158
 
158
159
  if (!response.ok) {
159
- console.error(`[JEV] Telegram send failed: ${response.status}`);
160
+ console.error(`[PLANNER] Telegram send failed: ${response.status}`);
160
161
  } else {
161
- console.log("[JEV] Telegram sent successfully");
162
+ console.log("[PLANNER] Telegram sent successfully");
162
163
  }
163
164
  } catch (err) {
164
- console.error(`[JEV] Telegram error:`, err);
165
+ console.error(`[PLANNER] Telegram error:`, err);
165
166
  }
166
167
  // Rate limit: 1 message per second
167
168
  await new Promise((resolve) => setTimeout(resolve, 1000));
@@ -170,7 +171,7 @@ async function sendToTelegram(message: string): Promise<void> {
170
171
  telegramSending = false;
171
172
  }
172
173
 
173
- export async function logJevDecision(decision: JevLogEntry): Promise<void> {
174
+ export async function logPlannerDecision(decision: PlannerLogEntry): Promise<void> {
174
175
  ensureLogDir();
175
176
 
176
177
  // Always log to file (sync)
@@ -182,25 +183,25 @@ export async function logJevDecision(decision: JevLogEntry): Promise<void> {
182
183
  const telegramMsg = formatTelegramMessage(decision);
183
184
  // Fire-and-forget: don't await, let it run in background
184
185
  sendToTelegram(telegramMsg).catch((err) => {
185
- console.error("[JEV] Failed to send Telegram notification:", err);
186
+ console.error("[PLANNER] Failed to send Telegram notification:", err);
186
187
  });
187
188
  // Also await briefly for testing, then let process exit handle it
188
189
  await new Promise((resolve) => setTimeout(resolve, 100));
189
190
  }
190
191
 
191
192
  /**
192
- * Parse Jev's decision from planner output
193
+ * Parse planner's decision from output
193
194
  * Looks for [JEVO] and [USER_INPUT] markers
194
195
  */
195
- export function parseJevDecision(planOutput: string): {
196
+ export function parsePlannerDecision(planOutput: string): {
196
197
  provider: "minimax" | "gpt";
197
198
  reason: string;
198
- userInput: JevDecision["userInput"];
199
+ userInput: PlannerDecision["userInput"];
199
200
  } {
200
201
  const result: {
201
202
  provider: "minimax" | "gpt";
202
203
  reason: string;
203
- userInput: JevDecision["userInput"];
204
+ userInput: PlannerDecision["userInput"];
204
205
  } = {
205
206
  provider: "minimax",
206
207
  reason: "default (no explicit decision)",
@@ -0,0 +1,217 @@
1
+ /**
2
+ * Service Diagnostics - Structured logging for harness services
3
+ *
4
+ * Logs service events to ~/.pi-harness-runtime/logs/services.jsonl
5
+ * with structured data for observability.
6
+ */
7
+
8
+ import { appendFileSync, existsSync, mkdirSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { homedir } from "node:os";
11
+
12
+ export type ServiceLevel = "info" | "warn" | "error" | "debug";
13
+ export type ServiceName = "jev" | "honcho" | "qdrant";
14
+
15
+ export interface ServiceEvent {
16
+ ts: string;
17
+ level: ServiceLevel;
18
+ service: ServiceName;
19
+ operation: string;
20
+ phase: "start" | "completed" | "failed";
21
+ sessionId?: string;
22
+ requestId?: string;
23
+ durationMs?: number;
24
+ [key: string]: unknown;
25
+ }
26
+
27
+ const LOG_DIR = join(homedir(), ".pi-harness-runtime", "logs");
28
+ const LOG_FILE = join(LOG_DIR, "services.jsonl");
29
+ let _initialized = false;
30
+
31
+ function ensureLogDir(): void {
32
+ if (_initialized) return;
33
+ if (!existsSync(LOG_DIR)) {
34
+ mkdirSync(LOG_DIR, { recursive: true });
35
+ }
36
+ _initialized = true;
37
+ }
38
+
39
+ /**
40
+ * Log a structured service event.
41
+ * Sensitive fields (keys, tokens, full content) are never logged.
42
+ */
43
+ export function logServiceEvent(event: ServiceEvent): void {
44
+ ensureLogDir();
45
+
46
+ // Redact sensitive fields
47
+ const safeEvent = redactSensitive(event);
48
+
49
+ try {
50
+ appendFileSync(LOG_FILE, JSON.stringify(safeEvent) + "\n");
51
+ } catch {
52
+ // Silently fail if logging fails - don't crash the service
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Redact sensitive fields from event data.
58
+ * Never log: apiKey, token, secret, chatId, content, vectors, embeddings
59
+ */
60
+ function redactSensitive(event: ServiceEvent): Record<string, unknown> {
61
+ const sensitiveKeys = [
62
+ "apiKey",
63
+ "token",
64
+ "secret",
65
+ "bearerToken",
66
+ "chatId",
67
+ "content",
68
+ "vectors",
69
+ "embeddings",
70
+ "prompt",
71
+ "messages",
72
+ "raw",
73
+ ];
74
+
75
+ const result: Record<string, unknown> = { ...event };
76
+
77
+ for (const key of Object.keys(result)) {
78
+ if (sensitiveKeys.some((sk) => key.toLowerCase().includes(sk.toLowerCase()))) {
79
+ result[key] = "[REDACTED]";
80
+ }
81
+ }
82
+
83
+ return result;
84
+ }
85
+
86
+ /**
87
+ * Create a service status tracker.
88
+ */
89
+ export class ServiceStatus {
90
+ private _configured = false;
91
+ private _initialized = false;
92
+ private _connected = false;
93
+ private _lastSuccessAt: string | null = null;
94
+ private _lastFailureAt: string | null = null;
95
+ private _lastErrorCode: string | null = null;
96
+ private _requests = 0;
97
+ private _successes = 0;
98
+ private _failures = 0;
99
+ private _featureEnabled = false;
100
+ private _service: ServiceName;
101
+
102
+ constructor(service: ServiceName) {
103
+ this._service = service;
104
+ }
105
+
106
+ get configured() { return this._configured; }
107
+ get initialized() { return this._initialized; }
108
+ get connected() { return this._connected; }
109
+ get lastSuccessAt() { return this._lastSuccessAt; }
110
+ get lastFailureAt() { return this._lastFailureAt; }
111
+ get lastErrorCode() { return this._lastErrorCode; }
112
+ get requests() { return this._requests; }
113
+ get successes() { return this._successes; }
114
+ get failures() { return this._failures; }
115
+ get featureEnabled() { return this._featureEnabled; }
116
+
117
+ setConfigured(v: boolean): this {
118
+ this._configured = v;
119
+ logServiceEvent({
120
+ ts: new Date().toISOString(),
121
+ level: "info",
122
+ service: this._service,
123
+ operation: "config_checked",
124
+ phase: "completed",
125
+ configured: v,
126
+ });
127
+ return this;
128
+ }
129
+
130
+ setInitialized(v: boolean): this {
131
+ this._initialized = v;
132
+ if (v) {
133
+ logServiceEvent({
134
+ ts: new Date().toISOString(),
135
+ level: "info",
136
+ service: this._service,
137
+ operation: "initialized",
138
+ phase: "completed",
139
+ });
140
+ }
141
+ return this;
142
+ }
143
+
144
+ setConnected(v: boolean): this {
145
+ this._connected = v;
146
+ logServiceEvent({
147
+ ts: new Date().toISOString(),
148
+ level: "info",
149
+ service: this._service,
150
+ operation: "connected",
151
+ phase: v ? "completed" : "failed",
152
+ connected: v,
153
+ });
154
+ return this;
155
+ }
156
+
157
+ setFeatureEnabled(v: boolean): this {
158
+ this._featureEnabled = v;
159
+ return this;
160
+ }
161
+
162
+ recordSuccess(operation: string, durationMs?: number, extra?: Record<string, unknown>): void {
163
+ this._requests++;
164
+ this._successes++;
165
+ this._lastSuccessAt = new Date().toISOString();
166
+ logServiceEvent({
167
+ ts: new Date().toISOString(),
168
+ level: "info",
169
+ service: this._service,
170
+ operation,
171
+ phase: "completed",
172
+ durationMs,
173
+ requests: this._requests,
174
+ successes: this._successes,
175
+ ...extra,
176
+ });
177
+ }
178
+
179
+ recordFailure(operation: string, errorCode: string, extra?: Record<string, unknown>): void {
180
+ this._requests++;
181
+ this._failures++;
182
+ this._lastFailureAt = new Date().toISOString();
183
+ this._lastErrorCode = errorCode;
184
+ logServiceEvent({
185
+ ts: new Date().toISOString(),
186
+ level: "error",
187
+ service: this._service,
188
+ operation,
189
+ phase: "failed",
190
+ errorCode,
191
+ requests: this._requests,
192
+ failures: this._failures,
193
+ ...extra,
194
+ });
195
+ }
196
+
197
+ toJSON(): Record<string, unknown> {
198
+ return {
199
+ service: this._service,
200
+ configured: this._configured,
201
+ initialized: this._initialized,
202
+ connected: this._connected,
203
+ lastSuccessAt: this._lastSuccessAt,
204
+ lastFailureAt: this._lastFailureAt,
205
+ lastErrorCode: this._lastErrorCode,
206
+ requests: this._requests,
207
+ successes: this._successes,
208
+ failures: this._failures,
209
+ featureEnabled: this._featureEnabled,
210
+ };
211
+ }
212
+ }
213
+
214
+ // Export service status instances
215
+ export const jevStatus = new ServiceStatus("jev");
216
+ export const honchoStatus = new ServiceStatus("honcho");
217
+ export const qdrantStatus = new ServiceStatus("qdrant");
package/index.ts CHANGED
@@ -103,6 +103,11 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
103
103
  return;
104
104
  }
105
105
 
106
+ // Resolve the actual API key: env takes priority, file is fallback
107
+ const resolvedApiKey = process.env.TYPESAFE_API_KEY ||
108
+ process.env.OPENROUTER_API_KEY ||
109
+ readFileSync(`${keysDir}/jev-api-key.txt`, "utf8").trim();
110
+
106
111
  const mod = await import("./packages/jev-judge/src/auto-continue.js");
107
112
 
108
113
  // Track waiting state
@@ -111,10 +116,22 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
111
116
 
112
117
  // Detect when agent asks for continuation
113
118
  pi.on("message_end", async (event) => {
114
- const msg = event.message as { role?: string; content?: string } | undefined;
119
+ const msg = event.message as { role?: string; content?: string | Array<{ type?: string; text?: string }> } | undefined;
115
120
  if (!msg || msg.role !== "assistant") return;
116
121
 
117
- const content = typeof msg.content === "string" ? msg.content : "";
122
+ // Extract text from array content (TextContent blocks) or legacy string
123
+ let content = "";
124
+ if (typeof msg.content === "string") {
125
+ content = msg.content;
126
+ } else if (Array.isArray(msg.content)) {
127
+ // Extract text from TextContent blocks only; ignore thinking/tool calls
128
+ content = msg.content
129
+ .filter((block): block is { type: "text"; text: string } =>
130
+ block.type === "text" && typeof block.text === "string"
131
+ )
132
+ .map(block => block.text)
133
+ .join("\n");
134
+ }
118
135
  const hasContinuation = /continue|proceed|next phase|next step/i.test(content);
119
136
 
120
137
  if (hasContinuation && !waitingForUserSince) {
@@ -154,7 +171,7 @@ async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
154
171
 
155
172
  try {
156
173
  const judge = new mod.AutoContinueJudge({
157
- apiKey: process.env.TYPESAFE_API_KEY || process.env.OPENROUTER_API_KEY!,
174
+ apiKey: resolvedApiKey,
158
175
  proceedThreshold: 0.7,
159
176
  maxWaitMinutes: 30,
160
177
  });
@@ -336,7 +353,7 @@ async function initHoncho(pi: { events: { emit(name: string, data: unknown): voi
336
353
  const keyPath = `${home}/.pi-harness-runtime/keys/honcho-api-key.txt`;
337
354
 
338
355
  if (!existsSync(keyPath)) {
339
- logStartup("[pi-harness] Honcho memory not configured:");
356
+ logStartup("[pi-harness] Honcho not configured:");
340
357
  logStartup("[pi-harness] Get key: https://app.honcho.dev/api-keys");
341
358
  logStartup(`[pi-harness] Then: echo "{api-key}" > ~/.pi-harness-runtime/keys/honcho-api-key.txt`);
342
359
  return;
@@ -356,12 +373,19 @@ async function initHoncho(pi: { events: { emit(name: string, data: unknown): voi
356
373
  name: "honcho",
357
374
  definition: {
358
375
  url: "https://mcp.honcho.dev",
359
- auth: { header: `Bearer ${apiKey}` },
376
+ auth: "bearer" as const,
377
+ bearerToken: apiKey,
360
378
  },
361
379
  };
380
+
381
+ // Emit registration request — pi-mcp-adapter will respond with
382
+ // pi-mcp-adapter:runtime-register-result event on completion
362
383
  pi.events.emit("pi-mcp-adapter:runtime-register:v1", request);
384
+ console.log("[honcho] MCP registration emitted (awaiting adapter ack)");
363
385
  });
364
- logStartup("[pi-harness] Honcho memory ready (peer/user memory via mcp.honcho.dev)");
386
+
387
+ // Report pending state — actual memory active requires explicit lifecycle
388
+ logStartup("[pi-harness] Honcho registered (awaiting adapter connection)");
365
389
  } catch (err) {
366
390
  logStartup("[pi-harness] Honcho: init failed:", err instanceof Error ? err.message : String(err));
367
391
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
4
4
  "description": "Auto-capture API-fetched configuration values to AGENTS.md",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.152",
3
+ "version": "1.1.153",
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.152",
3
+ "version": "1.1.153",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {