@phuetz/code-buddy 0.1.12 → 0.1.14

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 (321) hide show
  1. package/README.md +228 -13
  2. package/dist/agent/architect-mode.d.ts +11 -0
  3. package/dist/agent/architect-mode.js +133 -25
  4. package/dist/agent/architect-mode.js.map +1 -1
  5. package/dist/agent/codebuddy-agent.d.ts +24 -0
  6. package/dist/agent/codebuddy-agent.js +118 -16
  7. package/dist/agent/codebuddy-agent.js.map +1 -1
  8. package/dist/agent/execution/agent-executor.d.ts +9 -0
  9. package/dist/agent/execution/agent-executor.js +62 -1
  10. package/dist/agent/execution/agent-executor.js.map +1 -1
  11. package/dist/agent/message-queue.d.ts +77 -0
  12. package/dist/agent/message-queue.js +116 -0
  13. package/dist/agent/message-queue.js.map +1 -0
  14. package/dist/agent/middleware/auto-observation.d.ts +37 -0
  15. package/dist/agent/middleware/auto-observation.js +231 -0
  16. package/dist/agent/middleware/auto-observation.js.map +1 -0
  17. package/dist/agent/middleware/index.d.ts +2 -0
  18. package/dist/agent/middleware/index.js +1 -0
  19. package/dist/agent/middleware/index.js.map +1 -1
  20. package/dist/agent/tool-handler.js +3 -2
  21. package/dist/agent/tool-handler.js.map +1 -1
  22. package/dist/agent/turn-diff-tracker.js +3 -0
  23. package/dist/agent/turn-diff-tracker.js.map +1 -1
  24. package/dist/agent/types.d.ts +7 -2
  25. package/dist/analytics/budget-alerts.d.ts +81 -0
  26. package/dist/analytics/budget-alerts.js +126 -0
  27. package/dist/analytics/budget-alerts.js.map +1 -0
  28. package/dist/analytics/cost-predictor.d.ts +79 -0
  29. package/dist/analytics/cost-predictor.js +150 -0
  30. package/dist/analytics/cost-predictor.js.map +1 -0
  31. package/dist/analytics/index.d.ts +2 -0
  32. package/dist/analytics/index.js +2 -0
  33. package/dist/analytics/index.js.map +1 -1
  34. package/dist/auth/profile-manager.d.ts +205 -0
  35. package/dist/auth/profile-manager.js +484 -0
  36. package/dist/auth/profile-manager.js.map +1 -0
  37. package/dist/browser-automation/browser-manager.d.ts +79 -1
  38. package/dist/browser-automation/browser-manager.js +265 -2
  39. package/dist/browser-automation/browser-manager.js.map +1 -1
  40. package/dist/browser-automation/profile-manager.d.ts +32 -0
  41. package/dist/browser-automation/profile-manager.js +83 -0
  42. package/dist/browser-automation/profile-manager.js.map +1 -0
  43. package/dist/browser-automation/route-interceptor.d.ts +29 -0
  44. package/dist/browser-automation/route-interceptor.js +103 -0
  45. package/dist/browser-automation/route-interceptor.js.map +1 -0
  46. package/dist/browser-automation/screenshot-annotator.d.ts +23 -0
  47. package/dist/browser-automation/screenshot-annotator.js +86 -0
  48. package/dist/browser-automation/screenshot-annotator.js.map +1 -0
  49. package/dist/browser-automation/types.d.ts +47 -0
  50. package/dist/cache/llm-response-cache.js +3 -0
  51. package/dist/cache/llm-response-cache.js.map +1 -1
  52. package/dist/canvas/canvas-server.js +4 -3
  53. package/dist/canvas/canvas-server.js.map +1 -1
  54. package/dist/channels/discord/client.d.ts +2 -1
  55. package/dist/channels/discord/client.js +28 -16
  56. package/dist/channels/discord/client.js.map +1 -1
  57. package/dist/channels/dm-pairing.js +6 -3
  58. package/dist/channels/dm-pairing.js.map +1 -1
  59. package/dist/channels/google-chat/index.d.ts +210 -0
  60. package/dist/channels/google-chat/index.js +505 -0
  61. package/dist/channels/google-chat/index.js.map +1 -0
  62. package/dist/channels/group-security.d.ts +182 -0
  63. package/dist/channels/group-security.js +407 -0
  64. package/dist/channels/group-security.js.map +1 -0
  65. package/dist/channels/index.d.ts +17 -1
  66. package/dist/channels/index.js +16 -0
  67. package/dist/channels/index.js.map +1 -1
  68. package/dist/channels/matrix/index.d.ts +181 -0
  69. package/dist/channels/matrix/index.js +643 -0
  70. package/dist/channels/matrix/index.js.map +1 -0
  71. package/dist/channels/offline-queue.d.ts +92 -0
  72. package/dist/channels/offline-queue.js +112 -0
  73. package/dist/channels/offline-queue.js.map +1 -0
  74. package/dist/channels/reconnection-manager.d.ts +117 -0
  75. package/dist/channels/reconnection-manager.js +171 -0
  76. package/dist/channels/reconnection-manager.js.map +1 -0
  77. package/dist/channels/signal/index.d.ts +184 -0
  78. package/dist/channels/signal/index.js +488 -0
  79. package/dist/channels/signal/index.js.map +1 -0
  80. package/dist/channels/slack/client.d.ts +2 -1
  81. package/dist/channels/slack/client.js +30 -15
  82. package/dist/channels/slack/client.js.map +1 -1
  83. package/dist/channels/teams/index.d.ts +196 -0
  84. package/dist/channels/teams/index.js +477 -0
  85. package/dist/channels/teams/index.js.map +1 -0
  86. package/dist/channels/telegram/client.d.ts +3 -1
  87. package/dist/channels/telegram/client.js +29 -2
  88. package/dist/channels/telegram/client.js.map +1 -1
  89. package/dist/channels/webchat/index.d.ts +103 -0
  90. package/dist/channels/webchat/index.js +697 -0
  91. package/dist/channels/webchat/index.js.map +1 -0
  92. package/dist/channels/whatsapp/index.d.ts +105 -0
  93. package/dist/channels/whatsapp/index.js +533 -0
  94. package/dist/channels/whatsapp/index.js.map +1 -0
  95. package/dist/codebuddy/client.js +11 -5
  96. package/dist/codebuddy/client.js.map +1 -1
  97. package/dist/codebuddy/tool-definitions/advanced-tools.d.ts +1 -0
  98. package/dist/codebuddy/tool-definitions/advanced-tools.js +103 -3
  99. package/dist/codebuddy/tool-definitions/advanced-tools.js.map +1 -1
  100. package/dist/codebuddy/tool-definitions/index.d.ts +1 -1
  101. package/dist/codebuddy/tool-definitions/index.js +1 -1
  102. package/dist/codebuddy/tool-definitions/index.js.map +1 -1
  103. package/dist/codebuddy/tools.js +3 -1
  104. package/dist/codebuddy/tools.js.map +1 -1
  105. package/dist/commands/cli/config-command.d.ts +8 -0
  106. package/dist/commands/cli/config-command.js +90 -0
  107. package/dist/commands/cli/config-command.js.map +1 -0
  108. package/dist/commands/cli/openclaw-commands.d.ts +12 -0
  109. package/dist/commands/cli/openclaw-commands.js +446 -0
  110. package/dist/commands/cli/openclaw-commands.js.map +1 -0
  111. package/dist/commands/cli/utility-commands.js +30 -0
  112. package/dist/commands/cli/utility-commands.js.map +1 -1
  113. package/dist/commands/client-dispatcher.js +22 -2
  114. package/dist/commands/client-dispatcher.js.map +1 -1
  115. package/dist/commands/enhanced-command-handler.js +21 -2
  116. package/dist/commands/enhanced-command-handler.js.map +1 -1
  117. package/dist/commands/handlers/extra-handlers.d.ts +30 -0
  118. package/dist/commands/handlers/extra-handlers.js +547 -0
  119. package/dist/commands/handlers/extra-handlers.js.map +1 -0
  120. package/dist/commands/handlers/index.d.ts +1 -0
  121. package/dist/commands/handlers/index.js +2 -0
  122. package/dist/commands/handlers/index.js.map +1 -1
  123. package/dist/commands/slash/builtin-commands.js +41 -34
  124. package/dist/commands/slash/builtin-commands.js.map +1 -1
  125. package/dist/config/env-schema.d.ts +58 -0
  126. package/dist/config/env-schema.js +789 -0
  127. package/dist/config/env-schema.js.map +1 -0
  128. package/dist/config/feature-flags.js +2 -1
  129. package/dist/config/feature-flags.js.map +1 -1
  130. package/dist/context/bootstrap-loader.d.ts +48 -0
  131. package/dist/context/bootstrap-loader.js +123 -0
  132. package/dist/context/bootstrap-loader.js.map +1 -0
  133. package/dist/context/codebase-rag/chunker.js +2 -2
  134. package/dist/context/codebase-rag/chunker.js.map +1 -1
  135. package/dist/copilot/copilot-proxy.d.ts +15 -1
  136. package/dist/copilot/copilot-proxy.js +92 -23
  137. package/dist/copilot/copilot-proxy.js.map +1 -1
  138. package/dist/daemon/health-monitor.js +11 -7
  139. package/dist/daemon/health-monitor.js.map +1 -1
  140. package/dist/daemon/heartbeat.d.ts +112 -0
  141. package/dist/daemon/heartbeat.js +339 -0
  142. package/dist/daemon/heartbeat.js.map +1 -0
  143. package/dist/desktop-automation/smart-snapshot.d.ts +11 -0
  144. package/dist/desktop-automation/smart-snapshot.js +38 -0
  145. package/dist/desktop-automation/smart-snapshot.js.map +1 -1
  146. package/dist/extensions/extension-loader.js +4 -0
  147. package/dist/extensions/extension-loader.js.map +1 -1
  148. package/dist/identity/identity-manager.d.ts +95 -0
  149. package/dist/identity/identity-manager.js +242 -0
  150. package/dist/identity/identity-manager.js.map +1 -0
  151. package/dist/index.js +147 -17
  152. package/dist/index.js.map +1 -1
  153. package/dist/input/text-to-speech.js +4 -2
  154. package/dist/input/text-to-speech.js.map +1 -1
  155. package/dist/input/voice-control.js +5 -3
  156. package/dist/input/voice-control.js.map +1 -1
  157. package/dist/integrations/github-integration.js +1 -1
  158. package/dist/integrations/github-integration.js.map +1 -1
  159. package/dist/orchestration/orchestrator.js +3 -0
  160. package/dist/orchestration/orchestrator.js.map +1 -1
  161. package/dist/persistence/conversation-branches.js +2 -1
  162. package/dist/persistence/conversation-branches.js.map +1 -1
  163. package/dist/persistence/session-store.d.ts +1 -1
  164. package/dist/persistence/session-store.js +1 -1
  165. package/dist/persistence/session-store.js.map +1 -1
  166. package/dist/plugins/plugin-system.js +5 -2
  167. package/dist/plugins/plugin-system.js.map +1 -1
  168. package/dist/providers/gemini-provider.js +6 -4
  169. package/dist/providers/gemini-provider.js.map +1 -1
  170. package/dist/providers/local-llm-provider.js +8 -0
  171. package/dist/providers/local-llm-provider.js.map +1 -1
  172. package/dist/sandbox/auto-sandbox.d.ts +59 -0
  173. package/dist/sandbox/auto-sandbox.js +145 -0
  174. package/dist/sandbox/auto-sandbox.js.map +1 -0
  175. package/dist/scheduler/cron-scheduler.js +2 -0
  176. package/dist/scheduler/cron-scheduler.js.map +1 -1
  177. package/dist/scheduler/scheduler.js +11 -2
  178. package/dist/scheduler/scheduler.js.map +1 -1
  179. package/dist/security/audit-logger.d.ts +127 -0
  180. package/dist/security/audit-logger.js +194 -0
  181. package/dist/security/audit-logger.js.map +1 -0
  182. package/dist/security/bash-allowlist/allowlist-store.js +3 -2
  183. package/dist/security/bash-allowlist/allowlist-store.js.map +1 -1
  184. package/dist/security/bash-parser.js +0 -2
  185. package/dist/security/bash-parser.js.map +1 -1
  186. package/dist/security/code-validator.d.ts +51 -0
  187. package/dist/security/code-validator.js +185 -0
  188. package/dist/security/code-validator.js.map +1 -0
  189. package/dist/security/dangerous-patterns.d.ts +68 -0
  190. package/dist/security/dangerous-patterns.js +218 -0
  191. package/dist/security/dangerous-patterns.js.map +1 -0
  192. package/dist/security/remote-approval.d.ts +65 -0
  193. package/dist/security/remote-approval.js +138 -0
  194. package/dist/security/remote-approval.js.map +1 -0
  195. package/dist/security/security-audit.d.ts +7 -0
  196. package/dist/security/security-audit.js +23 -0
  197. package/dist/security/security-audit.js.map +1 -1
  198. package/dist/security/syntax-validator.d.ts +17 -0
  199. package/dist/security/syntax-validator.js +292 -0
  200. package/dist/security/syntax-validator.js.map +1 -0
  201. package/dist/server/index.js +277 -2
  202. package/dist/server/index.js.map +1 -1
  203. package/dist/server/middleware/logging.js +9 -1
  204. package/dist/server/middleware/logging.js.map +1 -1
  205. package/dist/server/routes/memory.js +4 -1
  206. package/dist/server/routes/memory.js.map +1 -1
  207. package/dist/server/routes/metrics.js +1 -1
  208. package/dist/server/routes/metrics.js.map +1 -1
  209. package/dist/server/routes/sessions.js +5 -4
  210. package/dist/server/routes/sessions.js.map +1 -1
  211. package/dist/server/websocket/handler.js +8 -2
  212. package/dist/server/websocket/handler.js.map +1 -1
  213. package/dist/services/prompt-builder.js +16 -0
  214. package/dist/services/prompt-builder.js.map +1 -1
  215. package/dist/skills/hub.d.ts +231 -0
  216. package/dist/skills/hub.js +694 -0
  217. package/dist/skills/hub.js.map +1 -0
  218. package/dist/skills/skill-loader.js +1 -1
  219. package/dist/skills/skill-loader.js.map +1 -1
  220. package/dist/skills/skill-manager.js +2 -1
  221. package/dist/skills/skill-manager.js.map +1 -1
  222. package/dist/skills/skill-registry.js +4 -0
  223. package/dist/skills/skill-registry.js.map +1 -1
  224. package/dist/talk-mode/providers/audioreader-tts.js +1 -0
  225. package/dist/talk-mode/providers/audioreader-tts.js.map +1 -1
  226. package/dist/tools/apply-patch.d.ts +1 -0
  227. package/dist/tools/apply-patch.js +66 -12
  228. package/dist/tools/apply-patch.js.map +1 -1
  229. package/dist/tools/bash/bash-tool.d.ts +123 -0
  230. package/dist/tools/bash/bash-tool.js +549 -0
  231. package/dist/tools/bash/bash-tool.js.map +1 -0
  232. package/dist/tools/bash/command-validator.d.ts +49 -0
  233. package/dist/tools/bash/command-validator.js +223 -0
  234. package/dist/tools/bash/command-validator.js.map +1 -0
  235. package/dist/tools/bash/index.d.ts +7 -0
  236. package/dist/tools/bash/index.js +8 -0
  237. package/dist/tools/bash/index.js.map +1 -0
  238. package/dist/tools/bash/security-patterns.d.ts +44 -0
  239. package/dist/tools/bash/security-patterns.js +234 -0
  240. package/dist/tools/bash/security-patterns.js.map +1 -0
  241. package/dist/tools/bash/streaming-executor.d.ts +23 -0
  242. package/dist/tools/bash/streaming-executor.js +134 -0
  243. package/dist/tools/bash/streaming-executor.js.map +1 -0
  244. package/dist/tools/bash.js +5 -3
  245. package/dist/tools/bash.js.map +1 -1
  246. package/dist/tools/code-formatter.js +41 -27
  247. package/dist/tools/code-formatter.js.map +1 -1
  248. package/dist/tools/code-review.js +1 -1
  249. package/dist/tools/code-review.js.map +1 -1
  250. package/dist/tools/computer-control-tool.js +21 -0
  251. package/dist/tools/computer-control-tool.js.map +1 -1
  252. package/dist/tools/document-tool.js +3 -2
  253. package/dist/tools/document-tool.js.map +1 -1
  254. package/dist/tools/git-tool.d.ts +45 -0
  255. package/dist/tools/git-tool.js +224 -2
  256. package/dist/tools/git-tool.js.map +1 -1
  257. package/dist/tools/index.d.ts +1 -1
  258. package/dist/tools/index.js +1 -1
  259. package/dist/tools/index.js.map +1 -1
  260. package/dist/tools/morph-editor.js +1 -0
  261. package/dist/tools/morph-editor.js.map +1 -1
  262. package/dist/tools/multi-edit.js +31 -3
  263. package/dist/tools/multi-edit.js.map +1 -1
  264. package/dist/tools/notebook-tool.js +8 -2
  265. package/dist/tools/notebook-tool.js.map +1 -1
  266. package/dist/tools/process-tool.d.ts +69 -0
  267. package/dist/tools/process-tool.js +222 -0
  268. package/dist/tools/process-tool.js.map +1 -0
  269. package/dist/tools/registry/git-tools.d.ts +32 -0
  270. package/dist/tools/registry/git-tools.js +211 -0
  271. package/dist/tools/registry/git-tools.js.map +1 -0
  272. package/dist/tools/registry/index.d.ts +2 -0
  273. package/dist/tools/registry/index.js +8 -0
  274. package/dist/tools/registry/index.js.map +1 -1
  275. package/dist/tools/registry/misc-tools.d.ts +32 -4
  276. package/dist/tools/registry/misc-tools.js +230 -90
  277. package/dist/tools/registry/misc-tools.js.map +1 -1
  278. package/dist/tools/registry/process-tools.d.ts +20 -0
  279. package/dist/tools/registry/process-tools.js +141 -0
  280. package/dist/tools/registry/process-tools.js.map +1 -0
  281. package/dist/tools/registry/types.d.ts +2 -0
  282. package/dist/tools/search.js +4 -2
  283. package/dist/tools/search.js.map +1 -1
  284. package/dist/tools/video-tool.js +30 -14
  285. package/dist/tools/video-tool.js.map +1 -1
  286. package/dist/tools/web-search.js +4 -1
  287. package/dist/tools/web-search.js.map +1 -1
  288. package/dist/ui/components/ChatInterface.js +9 -0
  289. package/dist/ui/components/ChatInterface.js.map +1 -1
  290. package/dist/utils/autonomy-manager.js +3 -2
  291. package/dist/utils/autonomy-manager.js.map +1 -1
  292. package/dist/utils/config-validation/schema.d.ts +15 -15
  293. package/dist/utils/confirmation-service.d.ts +16 -0
  294. package/dist/utils/confirmation-service.js +37 -3
  295. package/dist/utils/confirmation-service.js.map +1 -1
  296. package/dist/utils/custom-instructions.js +2 -1
  297. package/dist/utils/custom-instructions.js.map +1 -1
  298. package/dist/utils/diff-generator.js +3 -1
  299. package/dist/utils/diff-generator.js.map +1 -1
  300. package/dist/utils/graceful-shutdown.js +9 -9
  301. package/dist/utils/graceful-shutdown.js.map +1 -1
  302. package/dist/utils/head-tail-truncation.d.ts +18 -0
  303. package/dist/utils/head-tail-truncation.js +127 -0
  304. package/dist/utils/head-tail-truncation.js.map +1 -1
  305. package/dist/utils/history-manager.js +3 -2
  306. package/dist/utils/history-manager.js.map +1 -1
  307. package/dist/utils/logger.d.ts +2 -0
  308. package/dist/utils/logger.js +18 -3
  309. package/dist/utils/logger.js.map +1 -1
  310. package/dist/utils/performance.js +16 -15
  311. package/dist/utils/performance.js.map +1 -1
  312. package/dist/utils/stream-helpers.js +4 -2
  313. package/dist/utils/stream-helpers.js.map +1 -1
  314. package/dist/utils/update-notifier.js +2 -1
  315. package/dist/utils/update-notifier.js.map +1 -1
  316. package/dist/workflows/pipeline.d.ts +54 -1
  317. package/dist/workflows/pipeline.js +128 -7
  318. package/dist/workflows/pipeline.js.map +1 -1
  319. package/dist/workflows/step-manager.js +2 -1
  320. package/dist/workflows/step-manager.js.map +1 -1
  321. package/package.json +6 -3
@@ -0,0 +1,484 @@
1
+ /**
2
+ * Auth Profile Manager
3
+ *
4
+ * OpenClaw-inspired profile manager with round-robin rotation and
5
+ * session stickiness. Manages authentication profiles across multiple
6
+ * providers with exponential backoff cooldowns, billing-aware failure
7
+ * handling, and persistent state.
8
+ */
9
+ import { EventEmitter } from 'events';
10
+ import fs from 'fs';
11
+ import path from 'path';
12
+ import os from 'os';
13
+ import { logger } from '../utils/logger.js';
14
+ /**
15
+ * Default configuration
16
+ */
17
+ export const DEFAULT_AUTH_PROFILE_MANAGER_CONFIG = {
18
+ profiles: [],
19
+ rotationStrategy: 'round-robin',
20
+ sessionSticky: true,
21
+ cooldownMs: 60_000, // 1 minute
22
+ billingCooldownMs: 18_000_000, // 5 hours
23
+ maxCooldownMs: 86_400_000, // 24 hours
24
+ persistPath: path.join(os.homedir(), '.codebuddy', 'auth-profiles.json'),
25
+ };
26
+ // ============================================================================
27
+ // Auth Profile Manager
28
+ // ============================================================================
29
+ /**
30
+ * Auth Profile Manager
31
+ *
32
+ * Manages authentication profiles with round-robin rotation, session
33
+ * stickiness, and exponential backoff cooldowns. Supports billing-aware
34
+ * failure handling with separate escalation.
35
+ *
36
+ * Events:
37
+ * - `profile:selected` - Emitted when a profile is selected (profileId, sessionId?)
38
+ * - `profile:failed` - Emitted when a profile fails (profileId, error)
39
+ * - `profile:cooldown` - Emitted when a profile enters cooldown (profileId, cooldownMs)
40
+ * - `profile:recovered` - Emitted when a profile exits cooldown (profileId)
41
+ */
42
+ export class AuthProfileManager extends EventEmitter {
43
+ config;
44
+ profiles = new Map();
45
+ cooldownStates = new Map();
46
+ sessionBindings = new Map(); // sessionId -> profileId
47
+ roundRobinIndex = 0;
48
+ recoveryTimers = new Map();
49
+ constructor(config = {}) {
50
+ super();
51
+ this.config = { ...DEFAULT_AUTH_PROFILE_MANAGER_CONFIG, ...config };
52
+ // Register provided profiles
53
+ for (const profile of this.config.profiles) {
54
+ this.profiles.set(profile.id, profile);
55
+ this.cooldownStates.set(profile.id, {
56
+ profileId: profile.id,
57
+ inCooldown: false,
58
+ cooldownUntil: 0,
59
+ failureCount: 0,
60
+ lastFailureWasBilling: false,
61
+ });
62
+ }
63
+ // Load persisted state
64
+ this.loadState();
65
+ }
66
+ // ============================================================================
67
+ // Profile Management
68
+ // ============================================================================
69
+ /**
70
+ * Add a profile
71
+ */
72
+ addProfile(profile) {
73
+ this.profiles.set(profile.id, profile);
74
+ if (!this.cooldownStates.has(profile.id)) {
75
+ this.cooldownStates.set(profile.id, {
76
+ profileId: profile.id,
77
+ inCooldown: false,
78
+ cooldownUntil: 0,
79
+ failureCount: 0,
80
+ lastFailureWasBilling: false,
81
+ });
82
+ }
83
+ }
84
+ /**
85
+ * Remove a profile
86
+ */
87
+ removeProfile(profileId) {
88
+ const timer = this.recoveryTimers.get(profileId);
89
+ if (timer) {
90
+ clearTimeout(timer);
91
+ this.recoveryTimers.delete(profileId);
92
+ }
93
+ this.cooldownStates.delete(profileId);
94
+ // Remove session bindings pointing to this profile
95
+ for (const [sessionId, boundProfileId] of this.sessionBindings.entries()) {
96
+ if (boundProfileId === profileId) {
97
+ this.sessionBindings.delete(sessionId);
98
+ }
99
+ }
100
+ return this.profiles.delete(profileId);
101
+ }
102
+ /**
103
+ * Get a profile by ID
104
+ */
105
+ getProfile(profileId) {
106
+ return this.profiles.get(profileId);
107
+ }
108
+ /**
109
+ * Get all registered profiles
110
+ */
111
+ getAllProfiles() {
112
+ return Array.from(this.profiles.values());
113
+ }
114
+ // ============================================================================
115
+ // Profile Selection
116
+ // ============================================================================
117
+ /**
118
+ * Get the next available profile, optionally sticky to a session.
119
+ *
120
+ * If sessionSticky is enabled and a session already has a bound profile
121
+ * that is healthy, that profile is returned. Otherwise a new profile is
122
+ * selected using the configured rotation strategy.
123
+ */
124
+ getNextProfile(sessionId) {
125
+ // Session stickiness: return the bound profile if healthy
126
+ if (sessionId && this.config.sessionSticky) {
127
+ const boundProfileId = this.sessionBindings.get(sessionId);
128
+ if (boundProfileId) {
129
+ const profile = this.profiles.get(boundProfileId);
130
+ if (profile && !this.isInCooldown(boundProfileId)) {
131
+ this.emit('profile:selected', boundProfileId, sessionId);
132
+ return profile;
133
+ }
134
+ // Bound profile is unhealthy, unbind
135
+ this.sessionBindings.delete(sessionId);
136
+ }
137
+ }
138
+ const healthy = this.getHealthyProfiles();
139
+ if (healthy.length === 0) {
140
+ return null;
141
+ }
142
+ let selected;
143
+ switch (this.config.rotationStrategy) {
144
+ case 'round-robin':
145
+ selected = this.selectRoundRobin(healthy);
146
+ break;
147
+ case 'priority':
148
+ selected = this.selectByPriority(healthy);
149
+ break;
150
+ case 'random':
151
+ selected = this.selectRandom(healthy);
152
+ break;
153
+ default:
154
+ selected = this.selectRoundRobin(healthy);
155
+ }
156
+ // Bind to session if sticky
157
+ if (sessionId && this.config.sessionSticky) {
158
+ this.sessionBindings.set(sessionId, selected.id);
159
+ }
160
+ this.emit('profile:selected', selected.id, sessionId);
161
+ logger.debug(`Auth profile selected: ${selected.id} (${selected.provider})`);
162
+ return selected;
163
+ }
164
+ /**
165
+ * Get the sticky profile for a session (without selecting a new one)
166
+ */
167
+ getProfileForSession(sessionId) {
168
+ const boundProfileId = this.sessionBindings.get(sessionId);
169
+ if (!boundProfileId) {
170
+ return null;
171
+ }
172
+ return this.profiles.get(boundProfileId) ?? null;
173
+ }
174
+ /**
175
+ * Get all profiles not currently in cooldown
176
+ */
177
+ getHealthyProfiles() {
178
+ const now = Date.now();
179
+ const healthy = [];
180
+ for (const profile of this.profiles.values()) {
181
+ const state = this.cooldownStates.get(profile.id);
182
+ if (!state || !state.inCooldown || state.cooldownUntil <= now) {
183
+ // If cooldown has expired, mark as recovered
184
+ if (state && state.inCooldown && state.cooldownUntil <= now) {
185
+ this.recoverProfile(profile.id);
186
+ }
187
+ healthy.push(profile);
188
+ }
189
+ }
190
+ // OAuth profiles are prioritized over API key profiles
191
+ healthy.sort((a, b) => {
192
+ if (a.type === 'oauth' && b.type !== 'oauth')
193
+ return -1;
194
+ if (a.type !== 'oauth' && b.type === 'oauth')
195
+ return 1;
196
+ return b.priority - a.priority;
197
+ });
198
+ return healthy;
199
+ }
200
+ // ============================================================================
201
+ // Failure & Recovery
202
+ // ============================================================================
203
+ /**
204
+ * Mark a profile as failed with exponential backoff cooldown.
205
+ *
206
+ * Normal failures: 1min -> 5min -> 25min -> 1h (max)
207
+ * Billing failures: 5h -> 10h -> 20h -> 24h (max)
208
+ *
209
+ * The backoff multiplier is 5x for normal and 2x for billing.
210
+ */
211
+ markFailed(profileId, error, isBilling = false) {
212
+ const state = this.cooldownStates.get(profileId);
213
+ if (!state) {
214
+ logger.warn(`markFailed called for unknown profile: ${profileId}`);
215
+ return;
216
+ }
217
+ state.failureCount++;
218
+ state.lastError = error;
219
+ state.lastFailureAt = Date.now();
220
+ state.lastFailureWasBilling = isBilling;
221
+ // Calculate cooldown with exponential backoff
222
+ let cooldownMs;
223
+ if (isBilling) {
224
+ // Billing: 5h initial, 2x escalation, capped at 24h
225
+ cooldownMs = this.config.billingCooldownMs * Math.pow(2, state.failureCount - 1);
226
+ cooldownMs = Math.min(cooldownMs, this.config.maxCooldownMs);
227
+ }
228
+ else {
229
+ // Normal: 1min initial, 5x escalation, capped at 1h (3_600_000 ms)
230
+ cooldownMs = this.config.cooldownMs * Math.pow(5, state.failureCount - 1);
231
+ cooldownMs = Math.min(cooldownMs, 3_600_000);
232
+ }
233
+ state.inCooldown = true;
234
+ state.cooldownUntil = Date.now() + cooldownMs;
235
+ this.emit('profile:failed', profileId, error);
236
+ this.emit('profile:cooldown', profileId, cooldownMs);
237
+ logger.warn(`Auth profile ${profileId} failed (${isBilling ? 'billing' : 'error'}), ` +
238
+ `cooldown ${Math.round(cooldownMs / 1000)}s, failures: ${state.failureCount}`);
239
+ // Schedule recovery timer
240
+ this.scheduleRecovery(profileId, cooldownMs);
241
+ // Persist state
242
+ this.saveState();
243
+ }
244
+ /**
245
+ * Mark a profile as successful, resetting its failure count
246
+ */
247
+ markSuccess(profileId) {
248
+ const state = this.cooldownStates.get(profileId);
249
+ if (!state)
250
+ return;
251
+ state.failureCount = 0;
252
+ state.inCooldown = false;
253
+ state.cooldownUntil = 0;
254
+ state.lastError = undefined;
255
+ state.lastFailureWasBilling = false;
256
+ // Cancel recovery timer since we're already healthy
257
+ const timer = this.recoveryTimers.get(profileId);
258
+ if (timer) {
259
+ clearTimeout(timer);
260
+ this.recoveryTimers.delete(profileId);
261
+ }
262
+ // Persist state
263
+ this.saveState();
264
+ }
265
+ /**
266
+ * Release a session's sticky profile binding
267
+ */
268
+ releaseSession(sessionId) {
269
+ this.sessionBindings.delete(sessionId);
270
+ }
271
+ // ============================================================================
272
+ // Internal Selection Strategies
273
+ // ============================================================================
274
+ /**
275
+ * Round-robin selection across healthy profiles
276
+ */
277
+ selectRoundRobin(healthy) {
278
+ if (this.roundRobinIndex >= healthy.length) {
279
+ this.roundRobinIndex = 0;
280
+ }
281
+ const selected = healthy[this.roundRobinIndex];
282
+ this.roundRobinIndex = (this.roundRobinIndex + 1) % healthy.length;
283
+ return selected;
284
+ }
285
+ /**
286
+ * Priority-based selection (highest priority first)
287
+ */
288
+ selectByPriority(healthy) {
289
+ // Already sorted by priority in getHealthyProfiles()
290
+ return healthy[0];
291
+ }
292
+ /**
293
+ * Random selection
294
+ */
295
+ selectRandom(healthy) {
296
+ const index = Math.floor(Math.random() * healthy.length);
297
+ return healthy[index];
298
+ }
299
+ // ============================================================================
300
+ // Cooldown Management
301
+ // ============================================================================
302
+ /**
303
+ * Check if a profile is currently in cooldown
304
+ */
305
+ isInCooldown(profileId) {
306
+ const state = this.cooldownStates.get(profileId);
307
+ if (!state || !state.inCooldown)
308
+ return false;
309
+ if (state.cooldownUntil <= Date.now()) {
310
+ // Cooldown expired, recover
311
+ this.recoverProfile(profileId);
312
+ return false;
313
+ }
314
+ return true;
315
+ }
316
+ /**
317
+ * Recover a profile from cooldown
318
+ */
319
+ recoverProfile(profileId) {
320
+ const state = this.cooldownStates.get(profileId);
321
+ if (!state)
322
+ return;
323
+ state.inCooldown = false;
324
+ // Keep failureCount so next failure escalates appropriately
325
+ // Only markSuccess() fully resets
326
+ const timer = this.recoveryTimers.get(profileId);
327
+ if (timer) {
328
+ clearTimeout(timer);
329
+ this.recoveryTimers.delete(profileId);
330
+ }
331
+ this.emit('profile:recovered', profileId);
332
+ logger.info(`Auth profile ${profileId} recovered from cooldown`);
333
+ this.saveState();
334
+ }
335
+ /**
336
+ * Schedule automatic recovery after cooldown expires
337
+ */
338
+ scheduleRecovery(profileId, cooldownMs) {
339
+ // Cancel existing timer
340
+ const existing = this.recoveryTimers.get(profileId);
341
+ if (existing) {
342
+ clearTimeout(existing);
343
+ }
344
+ const timer = setTimeout(() => {
345
+ this.recoveryTimers.delete(profileId);
346
+ this.recoverProfile(profileId);
347
+ }, cooldownMs);
348
+ // Unref so it doesn't keep the process alive
349
+ if (timer.unref) {
350
+ timer.unref();
351
+ }
352
+ this.recoveryTimers.set(profileId, timer);
353
+ }
354
+ // ============================================================================
355
+ // Persistence
356
+ // ============================================================================
357
+ /**
358
+ * Save cooldown states to disk
359
+ */
360
+ saveState() {
361
+ try {
362
+ const persistDir = path.dirname(this.config.persistPath);
363
+ if (!fs.existsSync(persistDir)) {
364
+ fs.mkdirSync(persistDir, { recursive: true });
365
+ }
366
+ const state = {
367
+ cooldowns: {},
368
+ savedAt: Date.now(),
369
+ };
370
+ for (const [id, cooldownState] of this.cooldownStates.entries()) {
371
+ state.cooldowns[id] = {
372
+ cooldownUntil: cooldownState.cooldownUntil,
373
+ failureCount: cooldownState.failureCount,
374
+ lastFailureWasBilling: cooldownState.lastFailureWasBilling,
375
+ lastError: cooldownState.lastError,
376
+ lastFailureAt: cooldownState.lastFailureAt,
377
+ };
378
+ }
379
+ fs.writeFileSync(this.config.persistPath, JSON.stringify(state, null, 2), 'utf-8');
380
+ }
381
+ catch (err) {
382
+ logger.warn(`Failed to save auth profile state: ${err}`);
383
+ }
384
+ }
385
+ /**
386
+ * Load cooldown states from disk
387
+ */
388
+ loadState() {
389
+ try {
390
+ if (!fs.existsSync(this.config.persistPath)) {
391
+ return;
392
+ }
393
+ const raw = fs.readFileSync(this.config.persistPath, 'utf-8');
394
+ const state = JSON.parse(raw);
395
+ if (!state || !state.cooldowns) {
396
+ return;
397
+ }
398
+ const now = Date.now();
399
+ for (const [id, saved] of Object.entries(state.cooldowns)) {
400
+ const existing = this.cooldownStates.get(id);
401
+ if (!existing)
402
+ continue;
403
+ existing.failureCount = saved.failureCount;
404
+ existing.lastFailureWasBilling = saved.lastFailureWasBilling;
405
+ existing.lastError = saved.lastError;
406
+ existing.lastFailureAt = saved.lastFailureAt;
407
+ if (saved.cooldownUntil > now) {
408
+ existing.inCooldown = true;
409
+ existing.cooldownUntil = saved.cooldownUntil;
410
+ // Schedule recovery for remaining time
411
+ this.scheduleRecovery(id, saved.cooldownUntil - now);
412
+ }
413
+ else {
414
+ // Cooldown already expired
415
+ existing.inCooldown = false;
416
+ existing.cooldownUntil = 0;
417
+ }
418
+ }
419
+ logger.debug('Auth profile state loaded from disk');
420
+ }
421
+ catch (err) {
422
+ logger.warn(`Failed to load auth profile state: ${err}`);
423
+ }
424
+ }
425
+ // ============================================================================
426
+ // Stats & Diagnostics
427
+ // ============================================================================
428
+ /**
429
+ * Get status of all profiles
430
+ */
431
+ getStatus() {
432
+ const now = Date.now();
433
+ return this.getAllProfiles().map(profile => {
434
+ const state = this.cooldownStates.get(profile.id);
435
+ const inCooldown = state?.inCooldown && (state.cooldownUntil > now);
436
+ return {
437
+ profileId: profile.id,
438
+ provider: profile.provider,
439
+ type: profile.type,
440
+ priority: profile.priority,
441
+ healthy: !inCooldown,
442
+ failureCount: state?.failureCount ?? 0,
443
+ inCooldown: !!inCooldown,
444
+ cooldownRemainingMs: inCooldown ? state.cooldownUntil - now : 0,
445
+ lastError: state?.lastError,
446
+ };
447
+ });
448
+ }
449
+ /**
450
+ * Shutdown - clear all timers
451
+ */
452
+ shutdown() {
453
+ for (const timer of this.recoveryTimers.values()) {
454
+ clearTimeout(timer);
455
+ }
456
+ this.recoveryTimers.clear();
457
+ this.sessionBindings.clear();
458
+ this.saveState();
459
+ }
460
+ }
461
+ // ============================================================================
462
+ // Singleton
463
+ // ============================================================================
464
+ let authProfileManagerInstance = null;
465
+ /**
466
+ * Get the auth profile manager singleton
467
+ */
468
+ export function getAuthProfileManager(config) {
469
+ if (!authProfileManagerInstance) {
470
+ authProfileManagerInstance = new AuthProfileManager(config);
471
+ }
472
+ return authProfileManagerInstance;
473
+ }
474
+ /**
475
+ * Reset the auth profile manager singleton
476
+ */
477
+ export function resetAuthProfileManager() {
478
+ if (authProfileManagerInstance) {
479
+ authProfileManagerInstance.shutdown();
480
+ authProfileManagerInstance = null;
481
+ }
482
+ }
483
+ export default AuthProfileManager;
484
+ //# sourceMappingURL=profile-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile-manager.js","sourceRoot":"","sources":["../../src/auth/profile-manager.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@
10
10
  * - Device emulation
11
11
  */
12
12
  import { EventEmitter } from 'events';
13
- import { BrowserTab, WebElement, WebSnapshot, SnapshotOptions, ClickOptions, TypeOptions, FillOptions, ScrollOptions, SelectOptions, NavigateOptions, ScreenshotOptions, PDFOptions, Cookie, DeviceConfig, GeolocationConfig, EvaluateOptions, EvaluateResult, DialogAction, FileUploadOptions, BrowserConfig } from './types.js';
13
+ import { BrowserTab, WebElement, WebSnapshot, SnapshotOptions, ClickOptions, TypeOptions, FillOptions, ScrollOptions, SelectOptions, NavigateOptions, ScreenshotOptions, PDFOptions, Cookie, DeviceConfig, GeolocationConfig, EvaluateOptions, EvaluateResult, DialogAction, FileUploadOptions, BrowserConfig, ConsoleEntry, RouteRule, ExtendedDeviceConfig } from './types.js';
14
14
  export declare class BrowserManager extends EventEmitter {
15
15
  private config;
16
16
  private browser;
@@ -20,6 +20,10 @@ export declare class BrowserManager extends EventEmitter {
20
20
  private currentSnapshot;
21
21
  private nextRef;
22
22
  private playwright;
23
+ private consoleBuffer;
24
+ private static readonly MAX_CONSOLE_ENTRIES;
25
+ private _routeInterceptor;
26
+ private _profileManager;
23
27
  constructor(config?: Partial<BrowserConfig>);
24
28
  /**
25
29
  * Launch browser
@@ -53,6 +57,10 @@ export declare class BrowserManager extends EventEmitter {
53
57
  /**
54
58
  * Take snapshot of current page
55
59
  */
60
+ /**
61
+ * Get next available ref number (for shared ref space with desktop)
62
+ */
63
+ getNextRef(): number;
56
64
  takeSnapshot(options?: SnapshotOptions): Promise<WebSnapshot>;
57
65
  /**
58
66
  * Extract elements from page
@@ -177,6 +185,76 @@ export declare class BrowserManager extends EventEmitter {
177
185
  * Check if browser is launched
178
186
  */
179
187
  isLaunched(): boolean;
188
+ /**
189
+ * Get console history buffer
190
+ */
191
+ getConsoleHistory(type?: string, limit?: number): ConsoleEntry[];
192
+ /**
193
+ * Clear console history buffer
194
+ */
195
+ clearConsoleHistory(): void;
196
+ /**
197
+ * Get localStorage for the current page's origin
198
+ */
199
+ getLocalStorage(): Promise<Record<string, string>>;
200
+ /**
201
+ * Set localStorage entries for the current page
202
+ */
203
+ setLocalStorage(data: Record<string, string>): Promise<void>;
204
+ /**
205
+ * Get sessionStorage for the current page's origin
206
+ */
207
+ getSessionStorage(): Promise<Record<string, string>>;
208
+ /**
209
+ * Set sessionStorage entries for the current page
210
+ */
211
+ setSessionStorage(data: Record<string, string>): Promise<void>;
212
+ /**
213
+ * Set timezone for the browser context
214
+ */
215
+ setTimezone(timezoneId: string): Promise<void>;
216
+ /**
217
+ * Set locale for the browser context
218
+ */
219
+ setLocale(locale: string): Promise<void>;
220
+ /**
221
+ * Set color scheme preference
222
+ */
223
+ setColorScheme(colorScheme: 'light' | 'dark' | 'no-preference'): Promise<void>;
224
+ /**
225
+ * Grant permissions to the browser context
226
+ */
227
+ grantPermissions(permissions: string[]): Promise<void>;
228
+ /**
229
+ * Extended device emulation with timezone, locale, colorScheme, permissions
230
+ */
231
+ emulateDeviceExtended(device: ExtendedDeviceConfig): Promise<void>;
232
+ private getProfileManager;
233
+ /**
234
+ * Save current browser state as a named profile
235
+ */
236
+ saveProfile(name: string): Promise<void>;
237
+ /**
238
+ * Load a named profile into the browser
239
+ */
240
+ loadProfile(name: string): Promise<boolean>;
241
+ private getRouteInterceptor;
242
+ /**
243
+ * Add a route interception rule
244
+ */
245
+ addRouteRule(rule: RouteRule): Promise<void>;
246
+ /**
247
+ * Remove a route interception rule
248
+ */
249
+ removeRouteRule(ruleId: string): Promise<void>;
250
+ /**
251
+ * List active route rules
252
+ */
253
+ listRouteRules(): RouteRule[];
254
+ /**
255
+ * Clear all route rules
256
+ */
257
+ clearRouteRules(): Promise<void>;
180
258
  /**
181
259
  * Get current snapshot
182
260
  */