pi-harness-runtime 0.9.21 → 0.9.25
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/CHANGELOG.md +24 -0
- package/footer-status.ts +84 -44
- package/harness/auto-quota-resume.ts +15 -12
- package/harness/e2e/minimax-quota-scraper.ts +9 -9
- package/harness/e2e/openai-quota-scraper.ts +442 -0
- package/harness/loop-runtime.ts +11 -7
- package/index.ts +170 -53
- package/package.json +2 -2
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/auth/dist/minimax-browser-auth.d.ts +89 -0
- package/packages/auth/dist/minimax-browser-auth.d.ts.map +1 -0
- package/packages/auth/dist/minimax-browser-auth.js +890 -0
- package/packages/auth/dist/minimax-browser-auth.js.map +1 -0
- package/packages/auth/dist/run-minimax-auth.d.ts +19 -0
- package/packages/auth/dist/run-minimax-auth.d.ts.map +1 -0
- package/packages/auth/dist/run-minimax-auth.js +112 -0
- package/packages/auth/dist/run-minimax-auth.js.map +1 -0
- package/packages/auth/package.json +1 -1
- package/packages/auth/tsconfig.json +9 -0
- 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/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/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/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/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/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/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/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/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/dist/provider-id.d.ts +5 -0
- package/packages/providers/dist/provider-id.d.ts.map +1 -1
- package/packages/providers/dist/provider-id.js +6 -1
- package/packages/providers/dist/provider-id.js.map +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/providers/src/provider-id.ts +6 -1
- package/packages/quota-manager/dist/tui-usage-monitor.d.ts.map +1 -1
- package/packages/quota-manager/dist/tui-usage-monitor.js +0 -6
- package/packages/quota-manager/dist/tui-usage-monitor.js.map +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/quota-manager/src/tui-usage-monitor.ts +0 -21
- 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-registry/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/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/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/dependency-analyzer/dist/analyzer.d.ts +0 -17
- package/packages/dependency-analyzer/dist/analyzer.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/analyzer.js +0 -106
- package/packages/dependency-analyzer/dist/analyzer.js.map +0 -1
- package/packages/dependency-analyzer/dist/imports.d.ts +0 -12
- package/packages/dependency-analyzer/dist/imports.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/imports.js +0 -73
- package/packages/dependency-analyzer/dist/imports.js.map +0 -1
- package/packages/dependency-analyzer/dist/index.d.ts +0 -4
- package/packages/dependency-analyzer/dist/index.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/index.js +0 -3
- package/packages/dependency-analyzer/dist/index.js.map +0 -1
- package/packages/dependency-analyzer/dist/test/analyzer.test.js +0 -37
- package/packages/dependency-analyzer/dist/types.d.ts +0 -28
- package/packages/dependency-analyzer/dist/types.d.ts.map +0 -1
- package/packages/dependency-analyzer/dist/types.js +0 -5
- package/packages/dependency-analyzer/dist/types.js.map +0 -1
- package/packages/intent-analyzer/dist/analyzer.d.ts +0 -13
- package/packages/intent-analyzer/dist/analyzer.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/analyzer.js +0 -72
- package/packages/intent-analyzer/dist/analyzer.js.map +0 -1
- package/packages/intent-analyzer/dist/index.d.ts +0 -3
- package/packages/intent-analyzer/dist/index.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/index.js +0 -2
- package/packages/intent-analyzer/dist/index.js.map +0 -1
- package/packages/intent-analyzer/dist/test/analyzer.test.js +0 -56
- package/packages/intent-analyzer/dist/types.d.ts +0 -26
- package/packages/intent-analyzer/dist/types.d.ts.map +0 -1
- package/packages/intent-analyzer/dist/types.js +0 -7
- package/packages/intent-analyzer/dist/types.js.map +0 -1
- package/packages/workspace-scanner/dist/detect.d.ts +0 -3
- package/packages/workspace-scanner/dist/detect.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/detect.js +0 -58
- package/packages/workspace-scanner/dist/detect.js.map +0 -1
- package/packages/workspace-scanner/dist/git.d.ts +0 -7
- package/packages/workspace-scanner/dist/git.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/git.js +0 -75
- package/packages/workspace-scanner/dist/git.js.map +0 -1
- package/packages/workspace-scanner/dist/index.d.ts +0 -5
- package/packages/workspace-scanner/dist/index.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/index.js +0 -4
- package/packages/workspace-scanner/dist/index.js.map +0 -1
- package/packages/workspace-scanner/dist/scanner.d.ts +0 -11
- package/packages/workspace-scanner/dist/scanner.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/scanner.js +0 -46
- package/packages/workspace-scanner/dist/scanner.js.map +0 -1
- package/packages/workspace-scanner/dist/test/scanner.test.js +0 -34
- package/packages/workspace-scanner/dist/types.d.ts +0 -35
- package/packages/workspace-scanner/dist/types.d.ts.map +0 -1
- package/packages/workspace-scanner/dist/types.js +0 -5
- package/packages/workspace-scanner/dist/types.js.map +0 -1
package/index.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type {
|
|
|
22
22
|
import { UsageTracker } from "./tracker.ts";
|
|
23
23
|
import { MirrorStore, type MirrorRecord } from "./mirror.ts";
|
|
24
24
|
import { MiniMaxQuotaScraper } from "./harness/e2e/minimax-quota-scraper.js";
|
|
25
|
+
import { OpenAIQuotaScraper } from "./harness/e2e/openai-quota-scraper.js";
|
|
25
26
|
import { parseMiniMaxQuotaText } from "./harness/e2e/minimax-quota-parser.js";
|
|
26
27
|
import {
|
|
27
28
|
CookieWatcher,
|
|
@@ -64,9 +65,49 @@ import {
|
|
|
64
65
|
} from "./harness/blackboard.ts";
|
|
65
66
|
import { scheduleAutoResume, cancelAutoResume } from "./harness/index.js";
|
|
66
67
|
import { homedir } from "node:os";
|
|
67
|
-
import { existsSync, mkdirSync } from "node:fs";
|
|
68
|
+
import { appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
68
69
|
import { join } from "node:path";
|
|
69
70
|
|
|
71
|
+
// ─── Debug log → file instead of TUI ─────────────────────────────────
|
|
72
|
+
const DEBUG_LOG_DIR = join(homedir(), ".pi", "harness-logs");
|
|
73
|
+
const DEBUG_LOG_PATH = join(DEBUG_LOG_DIR, "harness-debug.log");
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
if (!existsSync(DEBUG_LOG_DIR)) mkdirSync(DEBUG_LOG_DIR, { recursive: true });
|
|
77
|
+
} catch { /* non-fatal */ }
|
|
78
|
+
|
|
79
|
+
// Write harness runtime logs to file only (NOT to TUI stdout)
|
|
80
|
+
function _debugLog(...args: unknown[]): void {
|
|
81
|
+
try {
|
|
82
|
+
const line =
|
|
83
|
+
new Date().toISOString() +
|
|
84
|
+
" " +
|
|
85
|
+
args.map((a) => (typeof a === "object" ? JSON.stringify(a) : String(a))).join(" ");
|
|
86
|
+
appendFileSync(DEBUG_LOG_PATH, line + "\n");
|
|
87
|
+
} catch {
|
|
88
|
+
// non-fatal
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ─── Selective console override — harness DEBUG → file only ────────
|
|
93
|
+
// Real errors (no [DEBUG prefix) still print to TUI so you notice problems.
|
|
94
|
+
const _origLog = console.log.bind(console);
|
|
95
|
+
const _origError = console.error.bind(console);
|
|
96
|
+
|
|
97
|
+
console.log = (...args: unknown[]) => {
|
|
98
|
+
_origLog(...args);
|
|
99
|
+
_debugLog(...args);
|
|
100
|
+
};
|
|
101
|
+
console.error = (...args: unknown[]) => {
|
|
102
|
+
const first = String(args[0] ?? "");
|
|
103
|
+
if (first.startsWith("[DEBUG")) {
|
|
104
|
+
_debugLog(...args);
|
|
105
|
+
} else {
|
|
106
|
+
_origError(...args);
|
|
107
|
+
_debugLog(...args);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
|
|
70
111
|
// ─── Harness Runtime State ────────────────────────────────────────────
|
|
71
112
|
const HARNESS_ROOT_DIR = join(homedir(), ".pi", "harness");
|
|
72
113
|
|
|
@@ -175,7 +216,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
175
216
|
if (event.message.role !== "assistant") return;
|
|
176
217
|
|
|
177
218
|
// DEBUG: Log model ID
|
|
178
|
-
console.log("[DEBUG message_end] ctx.model?.id =", ctx.model?.id);
|
|
179
219
|
|
|
180
220
|
const m = event.message as {
|
|
181
221
|
role?: string;
|
|
@@ -224,14 +264,13 @@ export default function (pi: ExtensionAPI) {
|
|
|
224
264
|
try {
|
|
225
265
|
const text = readMessageText(event.message);
|
|
226
266
|
if (text) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
);
|
|
267
|
+
// "[DEBUG message_end] Processing TUI text (first 200 chars):",
|
|
268
|
+
// text.substring(0, 200),
|
|
269
|
+
// );
|
|
231
270
|
tuiMonitor.processMessage(text);
|
|
232
271
|
}
|
|
233
272
|
} catch (e) {
|
|
234
|
-
console.error("[DEBUG message_end] TUI processMessage error:", e);
|
|
273
|
+
// console.error("[DEBUG message_end] TUI processMessage error:", e);
|
|
235
274
|
}
|
|
236
275
|
});
|
|
237
276
|
|
|
@@ -243,6 +282,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
243
282
|
? new MiniMaxQuotaScraper({ cookieFile: process.env.QUOTA_COOKIE_FILE })
|
|
244
283
|
: new MiniMaxQuotaScraper();
|
|
245
284
|
|
|
285
|
+
// ─── Smart quota fetch for OpenAI status ─────────────────────────
|
|
286
|
+
const OPENAI_REFRESH_MIN_INTERVAL_MS = 5 * 60 * 1000; // 5 minutes
|
|
287
|
+
const _openaiQuotaScraper = new OpenAIQuotaScraper();
|
|
288
|
+
let lastOpenAIQuotaFetchAt = 0;
|
|
289
|
+
|
|
246
290
|
// ─── Cookie sanitizer integration ────────────────────────────────────
|
|
247
291
|
// The drop folder is the user-facing, forgiving input. The canonical
|
|
248
292
|
// cache (`~/.config/minimax-cookies.txt`) is the runtime-owned,
|
|
@@ -275,10 +319,9 @@ export default function (pi: ExtensionAPI) {
|
|
|
275
319
|
const tuiMonitor = new TUIUsageMonitor({ quotaManager });
|
|
276
320
|
|
|
277
321
|
tuiMonitor.on("signal", (signal: TUIUsageSignal) => {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
);
|
|
322
|
+
// "[DEBUG tuiMonitor signal] Received signal:",
|
|
323
|
+
// JSON.stringify(signal),
|
|
324
|
+
// );
|
|
282
325
|
try {
|
|
283
326
|
writeMirrorRecord(signal.provider as ProviderId, {
|
|
284
327
|
synced_at: signal.timestamp,
|
|
@@ -360,12 +403,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
360
403
|
provider: ProviderId,
|
|
361
404
|
record: Omit<import("./mirror.js").ProviderMirrorRecord, "provider">,
|
|
362
405
|
): void {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
);
|
|
406
|
+
// "[DEBUG writeMirrorRecord] Writing record for provider:",
|
|
407
|
+
// provider,
|
|
408
|
+
// "record:",
|
|
409
|
+
// JSON.stringify(record),
|
|
410
|
+
// );
|
|
369
411
|
mirrorStore.writeProvider(provider, { ...record, provider });
|
|
370
412
|
if (footerStatusCtx) {
|
|
371
413
|
refreshFooterStatus(
|
|
@@ -399,12 +441,11 @@ export default function (pi: ExtensionAPI) {
|
|
|
399
441
|
/** Set the active provider; triggers a footer refresh. */
|
|
400
442
|
function noteActiveProvider(modelId: string | null | undefined): void {
|
|
401
443
|
const p = providerFromModelId(modelId);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
);
|
|
444
|
+
// "[DEBUG noteActiveProvider] modelId =",
|
|
445
|
+
// modelId,
|
|
446
|
+
// "-> provider =",
|
|
447
|
+
// p,
|
|
448
|
+
// );
|
|
408
449
|
if (p !== lastActiveProvider) {
|
|
409
450
|
lastActiveProvider = p;
|
|
410
451
|
if (footerStatusCtx) {
|
|
@@ -535,40 +576,120 @@ export default function (pi: ExtensionAPI) {
|
|
|
535
576
|
}
|
|
536
577
|
}
|
|
537
578
|
|
|
579
|
+
/**
|
|
580
|
+
* Auto-fetch OpenAI quota via ChatGPT Codex analytics.
|
|
581
|
+
* GPT has WEEKLY-ONLY limits (no 5h window).
|
|
582
|
+
*/
|
|
583
|
+
async function autoFetchOpenAIQuota(options?: {
|
|
584
|
+
suppressErrors?: boolean;
|
|
585
|
+
}): Promise<boolean> {
|
|
586
|
+
const suppressErrors = options?.suppressErrors === true;
|
|
587
|
+
|
|
588
|
+
try {
|
|
589
|
+
// Try direct API first (faster)
|
|
590
|
+
const directResult = await _openaiQuotaScraper.scrapeDirect();
|
|
591
|
+
if (directResult) {
|
|
592
|
+
writeMirrorRecord("openai", {
|
|
593
|
+
synced_at: directResult.scrapedAt,
|
|
594
|
+
source: "scrape",
|
|
595
|
+
weekly_used_pct: directResult.weeklyUsedPct,
|
|
596
|
+
weekly_resets_at: directResult.weeklyResetsAt,
|
|
597
|
+
weekly_resets_at_epoch: directResult.weeklyResetsAtEpoch,
|
|
598
|
+
// No 5h window for GPT - set to undefined
|
|
599
|
+
h5_used_pct: undefined,
|
|
600
|
+
});
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Fall back to browser scrape
|
|
605
|
+
const data = await _openaiQuotaScraper.scrape();
|
|
606
|
+
writeMirrorRecord("openai", {
|
|
607
|
+
synced_at: data.scrapedAt,
|
|
608
|
+
source: "scrape",
|
|
609
|
+
weekly_used_pct: data.weeklyUsedPct,
|
|
610
|
+
weekly_resets_at: data.weeklyResetsAt,
|
|
611
|
+
weekly_resets_at_epoch: data.weeklyResetsAtEpoch,
|
|
612
|
+
// No 5h window for GPT - set to undefined
|
|
613
|
+
h5_used_pct: undefined,
|
|
614
|
+
});
|
|
615
|
+
return true;
|
|
616
|
+
} catch (error) {
|
|
617
|
+
if (!suppressErrors) {
|
|
618
|
+
console.error(
|
|
619
|
+
"[pi-harness] OpenAI quota auto-fetch skipped:",
|
|
620
|
+
error instanceof Error ? error.message : String(error),
|
|
621
|
+
);
|
|
622
|
+
}
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
538
627
|
async function maybeAutoFetchQuota(
|
|
539
628
|
modelId: string | null | undefined,
|
|
540
629
|
): Promise<void> {
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
630
|
+
const provider = providerFromModelId(modelId);
|
|
631
|
+
|
|
632
|
+
// MiniMax path
|
|
633
|
+
if (provider === "minimax") {
|
|
634
|
+
if (quotaAutoFetchInFlight) return;
|
|
635
|
+
|
|
636
|
+
const nowMs = Date.now();
|
|
637
|
+
if (nowMs - lastQuotaAutoFetchAt < MINIMAX_REFRESH_MIN_INTERVAL_MS) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
const mirror = mirrorStore.read();
|
|
642
|
+
const freshness = mirrorStore.freshness(mirror, nowMs);
|
|
643
|
+
const shouldFetchBaseline = !mirror || freshness === "expired";
|
|
644
|
+
const usageSinceSync = getMiniMaxUsageSince(
|
|
645
|
+
mirror?.synced_at ? Date.parse(mirror.synced_at) : 0,
|
|
646
|
+
);
|
|
647
|
+
const shouldFetchFromUsage =
|
|
648
|
+
usageSinceSync.tokens >= MINIMAX_REFRESH_TOKEN_THRESHOLD ||
|
|
649
|
+
usageSinceSync.requests >= MINIMAX_REFRESH_REQUEST_THRESHOLD ||
|
|
650
|
+
(freshness === "stale" && usageSinceSync.requests > 0);
|
|
651
|
+
|
|
652
|
+
if (!shouldFetchBaseline && !shouldFetchFromUsage) {
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
544
655
|
|
|
545
|
-
|
|
546
|
-
|
|
656
|
+
quotaAutoFetchInFlight = true;
|
|
657
|
+
lastQuotaAutoFetchAt = nowMs;
|
|
658
|
+
try {
|
|
659
|
+
await autoFetchQuota({ suppressErrors: true });
|
|
660
|
+
} finally {
|
|
661
|
+
quotaAutoFetchInFlight = false;
|
|
662
|
+
}
|
|
547
663
|
return;
|
|
548
664
|
}
|
|
549
665
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
usageSinceSync.requests >= MINIMAX_REFRESH_REQUEST_THRESHOLD ||
|
|
559
|
-
(freshness === "stale" && usageSinceSync.requests > 0);
|
|
666
|
+
// OpenAI path (GPT has weekly-only limits, no 5h window)
|
|
667
|
+
if (provider === "openai") {
|
|
668
|
+
if (quotaAutoFetchInFlight) return;
|
|
669
|
+
|
|
670
|
+
const nowMs = Date.now();
|
|
671
|
+
if (nowMs - lastOpenAIQuotaFetchAt < OPENAI_REFRESH_MIN_INTERVAL_MS) {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
560
674
|
|
|
561
|
-
|
|
675
|
+
// Check if OpenAI cookie file exists
|
|
676
|
+
const openaiCookieFile = join(homedir(), ".config", "openai-cookies.txt");
|
|
677
|
+
if (!existsSync(openaiCookieFile)) {
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
quotaAutoFetchInFlight = true;
|
|
682
|
+
lastOpenAIQuotaFetchAt = nowMs;
|
|
683
|
+
try {
|
|
684
|
+
await autoFetchOpenAIQuota({ suppressErrors: true });
|
|
685
|
+
} finally {
|
|
686
|
+
quotaAutoFetchInFlight = false;
|
|
687
|
+
}
|
|
562
688
|
return;
|
|
563
689
|
}
|
|
564
690
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
try {
|
|
568
|
-
await autoFetchQuota({ suppressErrors: true });
|
|
569
|
-
} finally {
|
|
570
|
-
quotaAutoFetchInFlight = false;
|
|
571
|
-
}
|
|
691
|
+
// Other providers (GLM, Anthropic, etc.) - TUI signal path only for now
|
|
692
|
+
return;
|
|
572
693
|
}
|
|
573
694
|
|
|
574
695
|
// ─── /usage — show full status ───────────────────────────────────────
|
|
@@ -978,7 +1099,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
978
1099
|
});
|
|
979
1100
|
|
|
980
1101
|
pi.on("turn_end", (_event, ctx) => {
|
|
981
|
-
console.log("[DEBUG turn_end] ctx.model?.id =", ctx.model?.id);
|
|
982
1102
|
noteActiveProvider(ctx.model?.id ?? null);
|
|
983
1103
|
footerStatusCtx = ctx;
|
|
984
1104
|
refreshFooterStatus(
|
|
@@ -1119,14 +1239,11 @@ function refreshFooterStatus(
|
|
|
1119
1239
|
const nowMs = Date.now();
|
|
1120
1240
|
const local = aggregateWindows(tracker.all());
|
|
1121
1241
|
const provider = getActiveProvider();
|
|
1122
|
-
console.log("[DEBUG refreshFooterStatus] provider =", provider);
|
|
1123
1242
|
const mirror = provider ? mirrorStore.readProvider(provider) : null;
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
);
|
|
1243
|
+
// "[DEBUG refreshFooterStatus] mirror =",
|
|
1244
|
+
// mirror ? JSON.stringify(mirror) : null,
|
|
1245
|
+
// );
|
|
1128
1246
|
const freshness = mirrorStore.freshness(mirror, nowMs);
|
|
1129
|
-
console.log("[DEBUG refreshFooterStatus] freshness =", freshness);
|
|
1130
1247
|
ctx.ui.setStatus(
|
|
1131
1248
|
"harness-runtime",
|
|
1132
1249
|
buildFooterStatusValue(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-harness-runtime",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.25",
|
|
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": {
|
|
@@ -80,7 +80,7 @@
|
|
|
80
80
|
"@types/node": "^26.1.0",
|
|
81
81
|
"@types/ws": "^8.18.1",
|
|
82
82
|
"husky": "^9.1.7",
|
|
83
|
-
"playwright": "^1.
|
|
83
|
+
"playwright": "^1.62.0",
|
|
84
84
|
"standard-version": "^9.5.0"
|
|
85
85
|
},
|
|
86
86
|
"workspaces": [
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* minimax-browser-auth.ts
|
|
3
|
+
*
|
|
4
|
+
* MiniMax browser authentication using a real Chrome profile.
|
|
5
|
+
*
|
|
6
|
+
* SECURITY RULES:
|
|
7
|
+
* - Human owns authentication. Agent never receives credentials.
|
|
8
|
+
* - No username, password, raw cookies, or session tokens stored.
|
|
9
|
+
* - Real Chrome owns the login flow via a persistent profile.
|
|
10
|
+
* - Profile is stored at ~/.pi-harness-runtime/browser-profiles/minimax/
|
|
11
|
+
*/
|
|
12
|
+
export interface MinimaxAuthStatus {
|
|
13
|
+
provider: "minimax";
|
|
14
|
+
authenticated: boolean;
|
|
15
|
+
checked_at: string;
|
|
16
|
+
page_url: string;
|
|
17
|
+
detected_text_sample: string | null;
|
|
18
|
+
profile_path: string;
|
|
19
|
+
usage_lines?: string[];
|
|
20
|
+
error_message?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MinimaxBrowserAuthConfig {
|
|
23
|
+
profilePath?: string;
|
|
24
|
+
statusPath?: string;
|
|
25
|
+
targetUrl?: string;
|
|
26
|
+
chromeExecutablePath?: string;
|
|
27
|
+
authTimeoutMs?: number;
|
|
28
|
+
headless?: boolean;
|
|
29
|
+
cdpPort?: number;
|
|
30
|
+
/** Suppress console output for background/runtime-driven scrapes. */
|
|
31
|
+
quiet?: boolean;
|
|
32
|
+
/** Override live session detection — used by tests to bypass real daemon. */
|
|
33
|
+
forceNoLiveSession?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare function getRuntimeDir(): string;
|
|
36
|
+
export declare function getProfileDir(): string;
|
|
37
|
+
export declare function getStatusPath(): string;
|
|
38
|
+
export interface MinimaxLiveBrowserSession {
|
|
39
|
+
profile_path: string;
|
|
40
|
+
target_url: string;
|
|
41
|
+
chrome_path: string;
|
|
42
|
+
debugging_port: number;
|
|
43
|
+
pid: number;
|
|
44
|
+
started_at: string;
|
|
45
|
+
}
|
|
46
|
+
export declare function getLiveSessionPath(): string;
|
|
47
|
+
export declare function saveAuthStatus(status: MinimaxAuthStatus, config?: MinimaxBrowserAuthConfig): void;
|
|
48
|
+
export declare function loadLiveBrowserSession(liveSessionPath?: string): MinimaxLiveBrowserSession | null;
|
|
49
|
+
export declare function detectUsagePage(bodyText: string): {
|
|
50
|
+
detected: boolean;
|
|
51
|
+
sample: string | null;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Manual authentication flow: launches real Chrome so Google login works,
|
|
55
|
+
* waits for user to sign in, then confirms at the TTY.
|
|
56
|
+
*/
|
|
57
|
+
export declare function authenticateWithPersistentBrowser(config?: MinimaxBrowserAuthConfig): Promise<MinimaxAuthStatus>;
|
|
58
|
+
/**
|
|
59
|
+
* Extract usage-relevant lines from page body text.
|
|
60
|
+
* Splits on newlines AND HTML tag boundaries, then filters for keywords.
|
|
61
|
+
*/
|
|
62
|
+
export declare function extractUsageLines(bodyText: string): string[];
|
|
63
|
+
/**
|
|
64
|
+
* Scrape usage data by attaching to a live browser session (via Node CDP).
|
|
65
|
+
* Writes attach script to a temp .js file to avoid shell escaping issues.
|
|
66
|
+
*/
|
|
67
|
+
export declare function scrapeViaLiveBrowserSession(config?: MinimaxBrowserAuthConfig): Promise<MinimaxAuthStatus>;
|
|
68
|
+
/**
|
|
69
|
+
* Start a persistent browser daemon (keep-open mode).
|
|
70
|
+
* Launches real Chrome with --remote-debugging-port and saves session.
|
|
71
|
+
*/
|
|
72
|
+
export declare function startPersistentBrowserDaemon(config?: MinimaxBrowserAuthConfig): Promise<MinimaxLiveBrowserSession>;
|
|
73
|
+
/**
|
|
74
|
+
* Stop the persistent browser daemon.
|
|
75
|
+
*/
|
|
76
|
+
export declare function stopPersistentBrowserDaemon(_config?: MinimaxBrowserAuthConfig): Promise<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Get active live browser session info.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getActiveLiveBrowserSession(): MinimaxLiveBrowserSession | null;
|
|
81
|
+
/**
|
|
82
|
+
* Scrape usage data. Tries live session first, falls back to headless Playwright.
|
|
83
|
+
*/
|
|
84
|
+
export declare function scrapeWithExistingProfile(config?: MinimaxBrowserAuthConfig): Promise<MinimaxAuthStatus>;
|
|
85
|
+
/**
|
|
86
|
+
* Check auth status.
|
|
87
|
+
*/
|
|
88
|
+
export declare function checkAuthStatus(config?: MinimaxBrowserAuthConfig): Promise<MinimaxAuthStatus>;
|
|
89
|
+
//# sourceMappingURL=minimax-browser-auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"minimax-browser-auth.d.ts","sourceRoot":"","sources":["../src/minimax-browser-auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAsBH,MAAM,WAAW,iBAAiB;IACjC,QAAQ,EAAE,SAAS,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6EAA6E;IAC7E,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAiBD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,MAAM,WAAW,yBAAyB;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAWD,wBAAgB,cAAc,CAC7B,MAAM,EAAE,iBAAiB,EACzB,MAAM,CAAC,EAAE,wBAAwB,GAC/B,IAAI,CAIN;AA2BD,wBAAgB,sBAAsB,CACrC,eAAe,CAAC,EAAE,MAAM,GACtB,yBAAyB,GAAG,IAAI,CAUlC;AASD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG;IAClD,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB,CASA;AAgND;;;GAGG;AACH,wBAAsB,iCAAiC,CACtD,MAAM,GAAE,wBAA6B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAqK5B;AA+CD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAiC5D;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAChD,MAAM,GAAE,wBAA6B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAwI5B;AAED;;;GAGG;AACH,wBAAsB,4BAA4B,CACjD,MAAM,GAAE,wBAA6B,GACnC,OAAO,CAAC,yBAAyB,CAAC,CA0CpC;AAED;;GAEG;AACH,wBAAsB,2BAA2B,CAChD,OAAO,GAAE,wBAA6B,GACpC,OAAO,CAAC,OAAO,CAAC,CA+ClB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,yBAAyB,GAAG,IAAI,CAE9E;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC9C,MAAM,GAAE,wBAA6B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAuJ5B;AAED;;GAEG;AACH,wBAAsB,eAAe,CACpC,MAAM,GAAE,wBAA6B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAoD5B"}
|