pi-harness-runtime 1.1.80 → 1.1.82

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 (116) hide show
  1. package/harness/browser-scrapers/base-browser-scraper.d.ts +91 -0
  2. package/harness/browser-scrapers/chrome-profile-manager.d.ts +80 -0
  3. package/harness/browser-scrapers/codex-browser-scraper.d.ts +60 -0
  4. package/harness/browser-scrapers/index.d.ts +29 -0
  5. package/harness/browser-scrapers/zai-browser-scraper.d.ts +79 -0
  6. package/harness/e2e/browser-scrapers/base-browser-scraper.d.ts +92 -0
  7. package/harness/e2e/browser-scrapers/base-browser-scraper.ts +244 -0
  8. package/harness/e2e/browser-scrapers/chrome-profile-manager.d.ts +81 -0
  9. package/harness/e2e/browser-scrapers/chrome-profile-manager.ts +297 -0
  10. package/harness/e2e/browser-scrapers/codex-browser-scraper.d.ts +61 -0
  11. package/harness/e2e/browser-scrapers/codex-browser-scraper.ts +343 -0
  12. package/harness/e2e/browser-scrapers/index.d.ts +30 -0
  13. package/harness/e2e/browser-scrapers/index.ts +48 -0
  14. package/harness/e2e/browser-scrapers/zai-browser-scraper.d.ts +80 -0
  15. package/harness/e2e/browser-scrapers/zai-browser-scraper.ts +392 -0
  16. package/harness/e2e/glm-quota-scraper.ts +106 -15
  17. package/harness/e2e/index.ts +29 -0
  18. package/harness/e2e/unified-quota-manager.ts +364 -0
  19. package/index.ts +72 -11
  20. package/mirror.ts +32 -28
  21. package/package.json +1 -1
  22. package/packages/a2a-adapter/package.json +1 -1
  23. package/packages/architecture-generator/package.json +1 -1
  24. package/packages/auth/package.json +1 -1
  25. package/packages/autonomous-refactor/package.json +1 -1
  26. package/packages/autonomous-runtime/package.json +1 -1
  27. package/packages/cache-strategy/package.json +1 -1
  28. package/packages/capability-registry/package.json +1 -1
  29. package/packages/checkpoint/package.json +1 -1
  30. package/packages/cli-plugin-sdk/package.json +1 -1
  31. package/packages/clipboard/package.json +1 -1
  32. package/packages/clipboard-plugin/package.json +1 -1
  33. package/packages/code-generation/package.json +1 -1
  34. package/packages/code-review/package.json +1 -1
  35. package/packages/codex-adapter/package.json +1 -1
  36. package/packages/config-capture/package.json +1 -1
  37. package/packages/context-compiler/package.json +1 -1
  38. package/packages/context-discovery/package.json +1 -1
  39. package/packages/context-manager/package.json +1 -1
  40. package/packages/cookie-sanitizer/package.json +1 -1
  41. package/packages/cost-optimizer/package.json +1 -1
  42. package/packages/dependency-analyzer/package.json +1 -1
  43. package/packages/django-plugin/package.json +1 -1
  44. package/packages/doc-generator/package.json +1 -1
  45. package/packages/evaluation-engine/package.json +1 -1
  46. package/packages/evaluation-runner/package.json +1 -1
  47. package/packages/event-bus/package.json +1 -1
  48. package/packages/event-store/package.json +1 -1
  49. package/packages/experience-replay/package.json +1 -1
  50. package/packages/feedback-collector/package.json +1 -1
  51. package/packages/file-copy-helper/package.json +1 -1
  52. package/packages/framework-detector/package.json +1 -1
  53. package/packages/framework-plugin-sdk/package.json +1 -1
  54. package/packages/frappe-plugin/package.json +1 -1
  55. package/packages/generic-web-plugin/package.json +1 -1
  56. package/packages/health-monitor/package.json +1 -1
  57. package/packages/intent-analyzer/package.json +1 -1
  58. package/packages/jev-judge/package.json +1 -1
  59. package/packages/knowledge-graph/package.json +1 -1
  60. package/packages/knowledge-retrieval/package.json +1 -1
  61. package/packages/laravel-plugin/package.json +1 -1
  62. package/packages/learning-engine/package.json +1 -1
  63. package/packages/mcp-adapter/package.json +1 -1
  64. package/packages/memory-engine/package.json +1 -1
  65. package/packages/milestone-manager/package.json +1 -1
  66. package/packages/model-registry/package.json +1 -1
  67. package/packages/nextjs-plugin/package.json +1 -1
  68. package/packages/notification/package.json +1 -1
  69. package/packages/observability/package.json +1 -1
  70. package/packages/okf-indexer/package.json +1 -1
  71. package/packages/performance-optimizer/package.json +1 -1
  72. package/packages/privilege-broker/package.json +1 -1
  73. package/packages/project-analyzer/package.json +1 -1
  74. package/packages/project-bootstrap/package.json +1 -1
  75. package/packages/projection-engine/package.json +1 -1
  76. package/packages/prompt-compiler/package.json +1 -1
  77. package/packages/prompt-versioning/package.json +1 -1
  78. package/packages/provider-adapter-sdk/package.json +1 -1
  79. package/packages/provider-router/package.json +1 -1
  80. package/packages/provider-selector/package.json +1 -1
  81. package/packages/providers/dist/provider-id.d.ts.map +1 -1
  82. package/packages/providers/dist/provider-id.js +1 -2
  83. package/packages/providers/dist/provider-id.js.map +1 -1
  84. package/packages/providers/package.json +1 -1
  85. package/packages/providers/src/provider-id.ts +1 -2
  86. package/packages/quota-manager/package.json +1 -1
  87. package/packages/rate-limiter/package.json +1 -1
  88. package/packages/react-vite-plugin/package.json +1 -1
  89. package/packages/release-manager/package.json +1 -1
  90. package/packages/requirement-compiler/package.json +1 -1
  91. package/packages/runtime/package.json +1 -1
  92. package/packages/scheduler/package.json +1 -1
  93. package/packages/scheduler-adapter/package.json +1 -1
  94. package/packages/session/package.json +1 -1
  95. package/packages/session-api/package.json +1 -1
  96. package/packages/session-export/package.json +1 -1
  97. package/packages/shared-context/package.json +1 -1
  98. package/packages/skill-mcp-client/package.json +1 -1
  99. package/packages/skill-registry/package.json +1 -1
  100. package/packages/sprint-planner/package.json +1 -1
  101. package/packages/subscription-engine/package.json +1 -1
  102. package/packages/task-compiler/package.json +1 -1
  103. package/packages/tencentdb-memory/package.json +1 -1
  104. package/packages/tencentdb-sync/package.json +1 -1
  105. package/packages/test-data-generator/package.json +1 -1
  106. package/packages/test-generator/package.json +1 -1
  107. package/packages/todo-bd-sync/package.json +1 -1
  108. package/packages/token-estimation/package.json +1 -1
  109. package/packages/token-optimizer/package.json +1 -1
  110. package/packages/trajectory/package.json +1 -1
  111. package/packages/tui/package.json +1 -1
  112. package/packages/types/package.json +1 -1
  113. package/packages/workflow-events/package.json +1 -1
  114. package/packages/workspace-scanner/package.json +1 -1
  115. package/packages/worktree/package.json +1 -1
  116. package/packages/write-review/package.json +1 -1
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Chrome Profile Manager — Browser-based quota scraping via Playwright
3
+ *
4
+ * Key concepts from google-flow-mcp:
5
+ * - Uses Playwright to connect to existing Chrome profile with stored cookies
6
+ * - Maintains persistent session across runs
7
+ * - Bypasses anti-bot measures by launching Chrome directly
8
+ *
9
+ * This enables scraping JavaScript-rendered pages that require authentication:
10
+ * - chatgpt.com/codex/cloud/settings/analytics
11
+ * - z.ai/manage-apikey/coding-plan/personal/usage
12
+ * - etc.
13
+ */
14
+ export interface ChromeProfileConfig {
15
+ /** Provider name (e.g., "codex", "z-ai") */
16
+ provider: string;
17
+ /** Path to Chrome user data directory (auto-detected if not provided) */
18
+ userDataDir?: string;
19
+ /** Profile directory name within userDataDir */
20
+ profileName?: string;
21
+ /** Path to browser binary (auto-detected if not provided) */
22
+ binaryPath?: string;
23
+ /** Arguments to pass to Chrome */
24
+ extraArgs?: string[];
25
+ /** Headless mode (default: true for scraping) */
26
+ headless?: boolean;
27
+ /** Launch timeout in ms */
28
+ launchTimeout?: number;
29
+ }
30
+ export interface BrowserProfile {
31
+ /** Path to the profile directory */
32
+ profilePath: string;
33
+ /** Provider name */
34
+ provider: string;
35
+ /** Whether the profile exists */
36
+ exists: boolean;
37
+ /** Last used timestamp */
38
+ lastUsed?: number;
39
+ }
40
+ /** Auto-detect Chrome user data directory based on OS */
41
+ export declare function detectChromeUserDataDir(): string | null;
42
+ /** Auto-detect Chrome binary path */
43
+ export declare function detectChromeBinary(): string | null;
44
+ /**
45
+ * Chrome Profile Manager for browser-based scraping
46
+ *
47
+ * Manages Chrome profiles for different providers to maintain
48
+ * authenticated sessions across scraping runs.
49
+ */
50
+ export declare class ChromeProfileManager {
51
+ private profilesDir;
52
+ private profiles;
53
+ constructor(profilesDir?: string);
54
+ private ensureProfilesDir;
55
+ private getProfileMetaPath;
56
+ private loadProfiles;
57
+ /**
58
+ * Get profile path for a provider
59
+ */
60
+ getProfilePath(provider: string): string;
61
+ /**
62
+ * Ensure profile directory exists
63
+ */
64
+ ensureProfile(provider: string): BrowserProfile;
65
+ private saveProfileMeta;
66
+ /**
67
+ * List all managed profiles
68
+ */
69
+ listProfiles(): BrowserProfile[];
70
+ /**
71
+ * Delete a profile
72
+ */
73
+ deleteProfile(provider: string): Promise<void>;
74
+ /**
75
+ * Get Chrome launch arguments for anti-bot evasion
76
+ * Based on google-flow-mcp approach
77
+ */
78
+ getLaunchArgs(config: ChromeProfileConfig): string[];
79
+ }
80
+ export declare function getChromeProfileManager(): ChromeProfileManager;
81
+ //# sourceMappingURL=chrome-profile-manager.d.ts.map
@@ -0,0 +1,297 @@
1
+ /**
2
+ * Chrome Profile Manager — Browser-based quota scraping via Playwright
3
+ *
4
+ * Key concepts from google-flow-mcp:
5
+ * - Uses Playwright to connect to existing Chrome profile with stored cookies
6
+ * - Maintains persistent session across runs
7
+ * - Bypasses anti-bot measures by launching Chrome directly
8
+ *
9
+ * This enables scraping JavaScript-rendered pages that require authentication:
10
+ * - chatgpt.com/codex/cloud/settings/analytics
11
+ * - z.ai/manage-apikey/coding-plan/personal/usage
12
+ * - etc.
13
+ */
14
+
15
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
16
+ import { join, dirname } from "node:path";
17
+ import { homedir } from "node:os";
18
+
19
+ export interface ChromeProfileConfig {
20
+ /** Provider name (e.g., "codex", "z-ai") */
21
+ provider: string;
22
+ /** Path to Chrome user data directory (auto-detected if not provided) */
23
+ userDataDir?: string;
24
+ /** Profile directory name within userDataDir */
25
+ profileName?: string;
26
+ /** Path to browser binary (auto-detected if not provided) */
27
+ binaryPath?: string;
28
+ /** Arguments to pass to Chrome */
29
+ extraArgs?: string[];
30
+ /** Headless mode (default: true for scraping) */
31
+ headless?: boolean;
32
+ /** Launch timeout in ms */
33
+ launchTimeout?: number;
34
+ }
35
+
36
+ export interface BrowserProfile {
37
+ /** Path to the profile directory */
38
+ profilePath: string;
39
+ /** Provider name */
40
+ provider: string;
41
+ /** Whether the profile exists */
42
+ exists: boolean;
43
+ /** Last used timestamp */
44
+ lastUsed?: number;
45
+ }
46
+
47
+ /** Auto-detect Chrome user data directory based on OS */
48
+ export function detectChromeUserDataDir(): string | null {
49
+ const home = homedir();
50
+ const os = process.platform;
51
+
52
+ if (os === "linux") {
53
+ // Common Chrome Linux locations
54
+ const candidates = [
55
+ join(home, ".config", "google-chrome"),
56
+ join(home, ".config", "chromium"),
57
+ join(home, ".config", "google-chrome", "Default"),
58
+ ];
59
+ for (const candidate of candidates) {
60
+ if (existsSync(candidate)) {
61
+ return dirname(candidate);
62
+ }
63
+ }
64
+ // Return default without checking
65
+ return join(home, ".config", "google-chrome");
66
+ }
67
+
68
+ if (os === "darwin") {
69
+ return join(home, "Library", "Application Support", "Google", "Chrome");
70
+ }
71
+
72
+ if (os === "win32") {
73
+ const localAppData = process.env.LOCALAPPDATA ?? join(home, "AppData", "Local");
74
+ return join(localAppData, "Google", "Chrome", "User Data");
75
+ }
76
+
77
+ return null;
78
+ }
79
+
80
+ /** Auto-detect Chrome binary path */
81
+ export function detectChromeBinary(): string | null {
82
+ const os = process.platform;
83
+
84
+ if (os === "linux") {
85
+ const candidates = [
86
+ "/usr/bin/google-chrome",
87
+ "/usr/bin/google-chrome-stable",
88
+ "/usr/bin/chromium",
89
+ "/usr/bin/chromium-browser",
90
+ "/snap/bin/chromium",
91
+ ];
92
+ for (const candidate of candidates) {
93
+ if (existsSync(candidate)) {
94
+ return candidate;
95
+ }
96
+ }
97
+ }
98
+
99
+ if (os === "darwin") {
100
+ const candidates = [
101
+ "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
102
+ "/Applications/Chromium.app/Contents/MacOS/Chromium",
103
+ ];
104
+ for (const candidate of candidates) {
105
+ if (existsSync(candidate)) {
106
+ return candidate;
107
+ }
108
+ }
109
+ }
110
+
111
+ if (os === "win32") {
112
+ const programFiles = process.env["ProgramFiles"] ?? "C:\\Program Files";
113
+ const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
114
+ const candidates = [
115
+ join(programFiles, "Google", "Chrome", "Application", "chrome.exe"),
116
+ join(programFilesX86, "Google", "Chrome", "Application", "chrome.exe"),
117
+ join(programFiles, "Chromium", "Application", "chrome.exe"),
118
+ ];
119
+ for (const candidate of candidates) {
120
+ if (existsSync(candidate)) {
121
+ return candidate;
122
+ }
123
+ }
124
+ }
125
+
126
+ return null;
127
+ }
128
+
129
+ /**
130
+ * Chrome Profile Manager for browser-based scraping
131
+ *
132
+ * Manages Chrome profiles for different providers to maintain
133
+ * authenticated sessions across scraping runs.
134
+ */
135
+ export class ChromeProfileManager {
136
+ private profilesDir: string;
137
+ private profiles: Map<string, BrowserProfile> = new Map();
138
+
139
+ constructor(profilesDir?: string) {
140
+ this.profilesDir =
141
+ profilesDir ?? join(homedir(), ".pi-harness-runtime", "browser-profiles");
142
+ this.ensureProfilesDir();
143
+ this.loadProfiles();
144
+ }
145
+
146
+ private ensureProfilesDir(): void {
147
+ if (!existsSync(this.profilesDir)) {
148
+ mkdirSync(this.profilesDir, { recursive: true });
149
+ }
150
+ }
151
+
152
+ private getProfileMetaPath(provider: string): string {
153
+ return join(this.profilesDir, `${provider}.meta.json`);
154
+ }
155
+
156
+ private loadProfiles(): void {
157
+ if (!existsSync(this.profilesDir)) return;
158
+
159
+ const { readdirSync } = require("node:fs");
160
+ const entries = readdirSync(this.profilesDir);
161
+ for (const entry of entries) {
162
+ if (entry.endsWith(".meta.json")) {
163
+ const provider = entry.replace(".meta.json", "");
164
+ const metaPath = this.getProfileMetaPath(provider);
165
+ try {
166
+ const meta = JSON.parse(readFileSync(metaPath, "utf-8"));
167
+ this.profiles.set(provider, meta);
168
+ } catch {
169
+ // Skip invalid meta files
170
+ }
171
+ }
172
+ }
173
+ }
174
+
175
+ /**
176
+ * Get profile path for a provider
177
+ */
178
+ getProfilePath(provider: string): string {
179
+ return join(this.profilesDir, provider);
180
+ }
181
+
182
+ /**
183
+ * Ensure profile directory exists
184
+ */
185
+ ensureProfile(provider: string): BrowserProfile {
186
+ const profilePath = this.getProfilePath(provider);
187
+
188
+ if (!existsSync(profilePath)) {
189
+ mkdirSync(profilePath, { recursive: true });
190
+ }
191
+
192
+ const profile: BrowserProfile = {
193
+ profilePath,
194
+ provider,
195
+ exists: true,
196
+ lastUsed: Date.now(),
197
+ };
198
+
199
+ this.saveProfileMeta(profile);
200
+ this.profiles.set(provider, profile);
201
+
202
+ return profile;
203
+ }
204
+
205
+ private saveProfileMeta(profile: BrowserProfile): void {
206
+ const metaPath = this.getProfileMetaPath(profile.provider);
207
+ writeFileSync(metaPath, JSON.stringify(profile, null, 2));
208
+ }
209
+
210
+ /**
211
+ * List all managed profiles
212
+ */
213
+ listProfiles(): BrowserProfile[] {
214
+ return Array.from(this.profiles.values());
215
+ }
216
+
217
+ /**
218
+ * Delete a profile
219
+ */
220
+ async deleteProfile(provider: string): Promise<void> {
221
+ const { rmSync } = await import("node:fs");
222
+ const profilePath = this.getProfilePath(provider);
223
+
224
+ if (existsSync(profilePath)) {
225
+ rmSync(profilePath, { recursive: true, force: true });
226
+ }
227
+
228
+ const metaPath = this.getProfileMetaPath(provider);
229
+ if (existsSync(metaPath)) {
230
+ rmSync(metaPath, { force: true });
231
+ }
232
+
233
+ this.profiles.delete(provider);
234
+ }
235
+
236
+ /**
237
+ * Get Chrome launch arguments for anti-bot evasion
238
+ * Based on google-flow-mcp approach
239
+ */
240
+ getLaunchArgs(config: ChromeProfileConfig): string[] {
241
+ const args = [
242
+ // Disable automation flags
243
+ "--disable-blink-features=AutomationControlled",
244
+ "--no-first-run",
245
+ "--no-default-browser-check",
246
+ // Disable extensions
247
+ "--disable-extensions",
248
+ // Disable background networking
249
+ "--disable-background-networking",
250
+ // Disable background threading
251
+ "--disable-background-timer-throttling",
252
+ // Disable background render
253
+ "--disable-renderer-backgrounding",
254
+ // Disable background occluded windows
255
+ "--disable-backgrounding-occluded-windows",
256
+ // Disable crash reporter
257
+ "--disable-crash-reporter",
258
+ // Disable logging
259
+ "--disable-logging",
260
+ // Disable devtools sharing
261
+ "--disable-dev-shm-usage",
262
+ // Disable Chrome sandbox (needed in some environments)
263
+ // "--no-sandbox", // Uncomment if running in Docker without sandbox
264
+ ];
265
+
266
+ // Add user data dir if using managed profile
267
+ if (!config.userDataDir && config.profileName) {
268
+ // Use our managed profile directory
269
+ args.push(`--user-data-dir=${this.getProfilePath(config.provider)}`);
270
+ } else if (config.userDataDir) {
271
+ // Use external Chrome user data dir
272
+ args.push(`--user-data-dir=${config.userDataDir}`);
273
+ if (config.profileName) {
274
+ args.push(`--profile-directory=${config.profileName}`);
275
+ }
276
+ }
277
+
278
+ // Add extra args
279
+ if (config.extraArgs) {
280
+ args.push(...config.extraArgs);
281
+ }
282
+
283
+ return args;
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Default Chrome profile manager instance
289
+ */
290
+ let defaultManager: ChromeProfileManager | null = null;
291
+
292
+ export function getChromeProfileManager(): ChromeProfileManager {
293
+ if (!defaultManager) {
294
+ defaultManager = new ChromeProfileManager();
295
+ }
296
+ return defaultManager;
297
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Codex Browser Scraper — Scrapes chatgpt.com/codex/cloud/settings/analytics
3
+ *
4
+ * Uses Playwright with Chrome profile to access the authenticated page
5
+ * and extract usage/quota data.
6
+ */
7
+ import { BaseBrowserScraper } from "./base-browser-scraper.js";
8
+ export interface CodexQuotaData {
9
+ provider: "openai-codex";
10
+ /** Plan type (e.g., "pro", "plus") */
11
+ planType?: string;
12
+ /** Current usage percentage (0-100) */
13
+ usagePercent: number;
14
+ /** Total quota amount */
15
+ totalQuota?: string;
16
+ /** Used quota amount */
17
+ usedQuota?: string;
18
+ /** Remaining quota */
19
+ remainingQuota?: string;
20
+ /** Reset date/time */
21
+ resetAt?: string;
22
+ /** Usage period description */
23
+ period?: string;
24
+ /** Raw data for debugging */
25
+ rawData?: Record<string, unknown>;
26
+ /** Timestamp */
27
+ scrapedAt: string;
28
+ }
29
+ interface CodexScraperConfig {
30
+ provider?: string;
31
+ url?: string;
32
+ headless?: boolean;
33
+ timeout?: number;
34
+ viewport?: {
35
+ width: number;
36
+ height: number;
37
+ };
38
+ slowMo?: number;
39
+ }
40
+ /**
41
+ * Codex Browser Scraper
42
+ *
43
+ * Scrapes usage data from chatgpt.com/codex/cloud/settings/analytics
44
+ */
45
+ export declare class CodexBrowserScraper extends BaseBrowserScraper<CodexQuotaData> {
46
+ constructor(config?: Partial<CodexScraperConfig>);
47
+ protected createBrowser(): Promise<void>;
48
+ private getProfileDir;
49
+ protected isLoginPage(): Promise<boolean>;
50
+ protected extractData(): Promise<CodexQuotaData | null>;
51
+ private extractUsageData;
52
+ private extractAdditionalData;
53
+ private extractFromHeadings;
54
+ private extractChartData;
55
+ }
56
+ /**
57
+ * Quick scrape function
58
+ */
59
+ export declare function scrapeCodexQuota(): Promise<CodexQuotaData | null>;
60
+ export {};
61
+ //# sourceMappingURL=codex-browser-scraper.d.ts.map