pi-harness-runtime 1.1.220 → 1.1.222
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.
- package/harness/honcho-init.ts +29 -29
- package/index.ts +81 -22
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/e2e-tester/package.json +1 -1
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/package.json +1 -1
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
package/harness/honcho-init.ts
CHANGED
|
@@ -380,29 +380,29 @@ export async function initHoncho(options?: {
|
|
|
380
380
|
piEvents?: PiEvents;
|
|
381
381
|
}): Promise<HonchoMemory | null> {
|
|
382
382
|
if (_disposed) {
|
|
383
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
424
|
+
logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "mcp_config", phase: "completed" });
|
|
425
425
|
} catch (err) {
|
|
426
|
-
|
|
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
|
-
|
|
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
|
-
|
|
457
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
668
|
+
logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "dispose_registration", phase: "completed" });
|
|
669
669
|
} catch (err) {
|
|
670
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
744
|
+
logServiceEvent({ ts: new Date().toISOString(), level: "info", service: "honcho", operation: "lifecycle_hooks", phase: "completed" });
|
|
745
745
|
}
|
package/index.ts
CHANGED
|
@@ -121,6 +121,30 @@ async function getTaskContext(): Promise<{
|
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
// --- Harness Startup Widget Messages (used by init functions) -----------------
|
|
125
|
+
interface HarnessMessage {
|
|
126
|
+
id: string;
|
|
127
|
+
label: string;
|
|
128
|
+
text: string;
|
|
129
|
+
status: "wait" | "ok" | "err";
|
|
130
|
+
details?: string[]; // Multi-line fix instructions for errors
|
|
131
|
+
}
|
|
132
|
+
const harnessMessages: HarnessMessage[] = [];
|
|
133
|
+
const preSessionErrors: HarnessMessage[] = []; // Errors from init functions (before session_start)
|
|
134
|
+
|
|
135
|
+
function addHarnessMessage(label: string, text: string, status: "wait" | "ok" | "err" = "wait", details?: string[]) {
|
|
136
|
+
const id = `${label}-${Date.now()}`;
|
|
137
|
+
const msg: HarnessMessage = { id, label, text, status, details };
|
|
138
|
+
|
|
139
|
+
// If session hasn't started yet, store in preSessionErrors
|
|
140
|
+
// The session_start handler will merge these into harnessMessages
|
|
141
|
+
if (harnessMessages.length === 0) {
|
|
142
|
+
preSessionErrors.push(msg);
|
|
143
|
+
} else {
|
|
144
|
+
harnessMessages.push(msg);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
124
148
|
async function initAutoContinue(pi: ExtensionAPI): Promise<void> {
|
|
125
149
|
try {
|
|
126
150
|
// Check if Jev API key is available (env var or keys file)
|
|
@@ -506,6 +530,11 @@ async function initTelegram(pi: ExtensionAPI): Promise<void> {
|
|
|
506
530
|
logStartup("[pi-harness] 3. echo \"{token}\" > ~/.pi-harness-runtime/keys/telegram-bot-token.txt");
|
|
507
531
|
logStartup("[pi-harness] 4. echo \"{chat-id}\" > ~/.pi-harness-runtime/keys/telegram-chat-id.txt");
|
|
508
532
|
logStartup("[pi-harness] 5. Reload pi — then DM @PiHarnessRuntimeBot to verify");
|
|
533
|
+
addHarnessMessage("Telegram", "not configured", "err", [
|
|
534
|
+
"echo \"<TOKEN>\" > keys/telegram-bot-token.txt",
|
|
535
|
+
"echo \"<CHAT_ID>\" > keys/telegram-chat-id.txt",
|
|
536
|
+
"Then: pi restart",
|
|
537
|
+
]);
|
|
509
538
|
return;
|
|
510
539
|
}
|
|
511
540
|
|
|
@@ -610,12 +639,21 @@ async function initHoncho(pi: ExtensionAPI): Promise<void> {
|
|
|
610
639
|
logStartup("[pi-harness] Honcho not configured:");
|
|
611
640
|
logStartup("[pi-harness] Get key: https://app.honcho.dev/api-keys");
|
|
612
641
|
logStartup(`[pi-harness] Then: echo "{api-key}" > ~/.pi-harness-runtime/keys/honcho-api-key.txt`);
|
|
642
|
+
addHarnessMessage("Honcho", "API key missing", "err", [
|
|
643
|
+
"Get key: https://app.honcho.dev/api-keys",
|
|
644
|
+
"echo \"<KEY>\" > keys/honcho-api-key.txt",
|
|
645
|
+
"Then: pi restart",
|
|
646
|
+
]);
|
|
613
647
|
return;
|
|
614
648
|
}
|
|
615
649
|
|
|
616
650
|
const apiKey = readFileSync(keyPath, "utf8").trim();
|
|
617
651
|
if (!apiKey) {
|
|
618
652
|
logStartup("[pi-harness] Honcho: API key is empty — skipping");
|
|
653
|
+
addHarnessMessage("Honcho", "API key empty", "err", [
|
|
654
|
+
"echo \"<KEY>\" > keys/honcho-api-key.txt",
|
|
655
|
+
"Then: pi restart",
|
|
656
|
+
]);
|
|
619
657
|
return;
|
|
620
658
|
}
|
|
621
659
|
|
|
@@ -635,6 +673,10 @@ async function initHoncho(pi: ExtensionAPI): Promise<void> {
|
|
|
635
673
|
}
|
|
636
674
|
} catch (err) {
|
|
637
675
|
logStartup("[pi-harness] Honcho: init failed:", err instanceof Error ? err.message : String(err));
|
|
676
|
+
addHarnessMessage("Honcho", "init failed", "err", [
|
|
677
|
+
err instanceof Error ? err.message : String(err),
|
|
678
|
+
"Check keys/honcho-api-key.txt",
|
|
679
|
+
]);
|
|
638
680
|
}
|
|
639
681
|
}
|
|
640
682
|
|
|
@@ -719,15 +761,15 @@ function initLangChain(pi: {
|
|
|
719
761
|
handler: async (_args: string, _ctx: unknown) => {
|
|
720
762
|
const allModels = listAllModels();
|
|
721
763
|
if (allModels.length === 0) {
|
|
722
|
-
|
|
723
|
-
|
|
764
|
+
logToFile("[pi-harness]", "/langchain-config: no models found in ~/.pi/agent/models-store.json");
|
|
765
|
+
logToFile("[pi-harness]", " Configure models first via /model in pi");
|
|
724
766
|
return;
|
|
725
767
|
}
|
|
726
768
|
|
|
727
769
|
// Print available models
|
|
728
|
-
|
|
770
|
+
logToFile("[pi-harness]", "Available models:");
|
|
729
771
|
for (const m of allModels) {
|
|
730
|
-
|
|
772
|
+
logToFile("[pi-harness]", ` [${m.index}] ${m.provider}/${m.id}`);
|
|
731
773
|
}
|
|
732
774
|
|
|
733
775
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -755,7 +797,7 @@ function initLangChain(pi: {
|
|
|
755
797
|
}
|
|
756
798
|
|
|
757
799
|
if (!plannerSpec || !coderSpec || !reviewerSpec) {
|
|
758
|
-
|
|
800
|
+
logToFile("[pi-harness]", "/langchain-config: all three roles must be selected");
|
|
759
801
|
return;
|
|
760
802
|
}
|
|
761
803
|
|
|
@@ -767,20 +809,20 @@ function initLangChain(pi: {
|
|
|
767
809
|
};
|
|
768
810
|
writeFileSync(roleConfigPath, JSON.stringify(config, null, 2), "utf8");
|
|
769
811
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
812
|
+
logToFile("[pi-harness]", "LangChain role config saved:");
|
|
813
|
+
logToFile("[pi-harness]", ` planner: ${plannerSpec}`);
|
|
814
|
+
logToFile("[pi-harness]", ` coder: ${coderSpec}`);
|
|
815
|
+
logToFile("[pi-harness]", ` reviewer: ${reviewerSpec}`);
|
|
774
816
|
|
|
775
817
|
// Also prompt for API keys if missing
|
|
776
818
|
if (!existsSync(`${keysDir}/planner-api-key.txt`)) {
|
|
777
|
-
|
|
819
|
+
logToFile("[pi-harness]", ` planner-api-key.txt missing. echo "{key}" > ${keysDir}/planner-api-key.txt`);
|
|
778
820
|
}
|
|
779
821
|
if (!existsSync(`${keysDir}/reviewer-api-key.txt`)) {
|
|
780
|
-
|
|
822
|
+
logToFile("[pi-harness]", ` reviewer-api-key.txt missing. echo "{key}" > ${keysDir}/reviewer-api-key.txt`);
|
|
781
823
|
}
|
|
782
824
|
if (!existsSync(`${keysDir}/coder-api-key.txt`)) {
|
|
783
|
-
|
|
825
|
+
logToFile("[pi-harness]", ` coder-api-key.txt missing. echo "{key}" > ${keysDir}/coder-api-key.txt`);
|
|
784
826
|
}
|
|
785
827
|
},
|
|
786
828
|
});
|
|
@@ -807,13 +849,13 @@ function initLangChain(pi: {
|
|
|
807
849
|
const coderKeyExists = existsSync(`${keysDir}/coder-api-key.txt`);
|
|
808
850
|
|
|
809
851
|
if (!activeConfig) {
|
|
810
|
-
|
|
852
|
+
logToFile("[pi-harness]", "/langchain not configured — run /langchain-config");
|
|
811
853
|
} else if (!plannerKeyExists || !reviewerKeyExists || !coderKeyExists) {
|
|
812
854
|
const missingKeys: string[] = [];
|
|
813
855
|
if (!plannerKeyExists) missingKeys.push("planner-api-key.txt");
|
|
814
856
|
if (!reviewerKeyExists) missingKeys.push("reviewer-api-key.txt");
|
|
815
857
|
if (!coderKeyExists) missingKeys.push("coder-api-key.txt");
|
|
816
|
-
|
|
858
|
+
logToFile("[pi-harness]", `/langchain missing API keys: ${missingKeys.join(", ")}`);
|
|
817
859
|
} else {
|
|
818
860
|
logStartup(`[pi-harness] /langchain ready (${activeConfig.planner.id} + ${activeConfig.coder.id} + ${activeConfig.reviewer.id})`);
|
|
819
861
|
}
|
|
@@ -823,14 +865,14 @@ function initLangChain(pi: {
|
|
|
823
865
|
prompt: "Describe the feature or task for the LangChain loop to implement.",
|
|
824
866
|
handler: async (request: string) => {
|
|
825
867
|
if (!request.trim()) {
|
|
826
|
-
|
|
827
|
-
|
|
868
|
+
logToFile("[pi-harness]", "/langchain requires a request.");
|
|
869
|
+
logToFile("[pi-harness]", " Example: /langchain implement user auth module");
|
|
828
870
|
return;
|
|
829
871
|
}
|
|
830
872
|
|
|
831
873
|
const cfg = loadActiveConfig();
|
|
832
874
|
if (!cfg) {
|
|
833
|
-
|
|
875
|
+
logToFile("[pi-harness]", "/langchain: not configured. Run /langchain-config first.");
|
|
834
876
|
return;
|
|
835
877
|
}
|
|
836
878
|
|
|
@@ -857,7 +899,7 @@ function initLangChain(pi: {
|
|
|
857
899
|
stdio: "inherit",
|
|
858
900
|
});
|
|
859
901
|
proc.on("exit", (code: number | null) => {
|
|
860
|
-
if (code !== 0)
|
|
902
|
+
if (code !== 0) logToFile("[pi-harness]", `/langchain exited with code ${code}`);
|
|
861
903
|
});
|
|
862
904
|
},
|
|
863
905
|
});
|
|
@@ -1875,7 +1917,7 @@ Run \`bd ready\` to see current bd issues.
|
|
|
1875
1917
|
!content.includes("bd ready") &&
|
|
1876
1918
|
!content.includes("TODO UPDATE")
|
|
1877
1919
|
) {
|
|
1878
|
-
|
|
1920
|
+
logToFile(TODO_BUILD_REMINDER.trim());
|
|
1879
1921
|
}
|
|
1880
1922
|
});
|
|
1881
1923
|
|
|
@@ -2447,7 +2489,7 @@ Run \`bd ready\` to see current bd issues.
|
|
|
2447
2489
|
mirrorStore,
|
|
2448
2490
|
currentSession.machine,
|
|
2449
2491
|
);
|
|
2450
|
-
|
|
2492
|
+
logToFile("[GLM countdown]", `Started - will auto-resume at ${resetAt}`);
|
|
2451
2493
|
}
|
|
2452
2494
|
|
|
2453
2495
|
if (!suppressErrors) {
|
|
@@ -3033,6 +3075,7 @@ Run \`bd ready\` to see current bd issues.
|
|
|
3033
3075
|
label: string;
|
|
3034
3076
|
text: string;
|
|
3035
3077
|
status: "wait" | "ok" | "err";
|
|
3078
|
+
details?: string[]; // Multi-line fix instructions for errors
|
|
3036
3079
|
}
|
|
3037
3080
|
const harnessMessages: HarnessMessage[] = [];
|
|
3038
3081
|
let startupVisible = true;
|
|
@@ -3040,9 +3083,9 @@ Run \`bd ready\` to see current bd issues.
|
|
|
3040
3083
|
let harnessWidgetRegistered = false;
|
|
3041
3084
|
let sessionGeneration = 0;
|
|
3042
3085
|
|
|
3043
|
-
function addHarnessMessage(label: string, text: string, status: "wait" | "ok" | "err" = "wait") {
|
|
3086
|
+
function addHarnessMessage(label: string, text: string, status: "wait" | "ok" | "err" = "wait", details?: string[]) {
|
|
3044
3087
|
const id = `${label}-${Date.now()}`;
|
|
3045
|
-
harnessMessages.push({ id, label, text, status });
|
|
3088
|
+
harnessMessages.push({ id, label, text, status, details });
|
|
3046
3089
|
harnessTUI?.requestRender();
|
|
3047
3090
|
}
|
|
3048
3091
|
|
|
@@ -3066,6 +3109,14 @@ Run \`bd ready\` to see current bd issues.
|
|
|
3066
3109
|
let text = `${treeChar} ${marker} ${msg.label}: ${msg.text}`;
|
|
3067
3110
|
text = truncateToWidth(text, width);
|
|
3068
3111
|
lines.push(text);
|
|
3112
|
+
|
|
3113
|
+
// Add fix instructions for errors (indented)
|
|
3114
|
+
if (msg.status === "err" && msg.details && msg.details.length > 0) {
|
|
3115
|
+
for (const detail of msg.details) {
|
|
3116
|
+
const detailLine = `${isLast ? " " : "│ "} Fix: ${detail}`;
|
|
3117
|
+
lines.push(truncateToWidth(detailLine, width));
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3069
3120
|
}
|
|
3070
3121
|
|
|
3071
3122
|
// Trailing spacer for breathing room (like Todos)
|
|
@@ -3109,6 +3160,14 @@ Run \`bd ready\` to see current bd issues.
|
|
|
3109
3160
|
{ placement: "aboveEditor" }, // Like Todos!
|
|
3110
3161
|
);
|
|
3111
3162
|
harnessWidgetRegistered = true;
|
|
3163
|
+
|
|
3164
|
+
// Merge pre-session errors into harnessMessages
|
|
3165
|
+
for (const err of preSessionErrors) {
|
|
3166
|
+
harnessMessages.push(err);
|
|
3167
|
+
}
|
|
3168
|
+
preSessionErrors.length = 0; // Clear pre-session errors
|
|
3169
|
+
|
|
3170
|
+
harnessTUI?.requestRender(); // Show widget with error messages
|
|
3112
3171
|
} else {
|
|
3113
3172
|
harnessTUI?.requestRender();
|
|
3114
3173
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pi-harness/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.222",
|
|
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",
|