@polpo-ai/node 0.11.1

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 (238) hide show
  1. package/LICENSE +13 -0
  2. package/dist/adapters/engine.d.ts +51 -0
  3. package/dist/adapters/engine.d.ts.map +1 -0
  4. package/dist/adapters/engine.js +316 -0
  5. package/dist/adapters/engine.js.map +1 -0
  6. package/dist/adapters/index.d.ts +2 -0
  7. package/dist/adapters/index.d.ts.map +1 -0
  8. package/dist/adapters/index.js +4 -0
  9. package/dist/adapters/index.js.map +1 -0
  10. package/dist/adapters/loop-engine.d.ts +36 -0
  11. package/dist/adapters/loop-engine.d.ts.map +1 -0
  12. package/dist/adapters/loop-engine.js +534 -0
  13. package/dist/adapters/loop-engine.js.map +1 -0
  14. package/dist/adapters/node-filesystem.d.ts +22 -0
  15. package/dist/adapters/node-filesystem.d.ts.map +1 -0
  16. package/dist/adapters/node-filesystem.js +59 -0
  17. package/dist/adapters/node-filesystem.js.map +1 -0
  18. package/dist/adapters/node-shell.d.ts +5 -0
  19. package/dist/adapters/node-shell.d.ts.map +1 -0
  20. package/dist/adapters/node-shell.js +34 -0
  21. package/dist/adapters/node-shell.js.map +1 -0
  22. package/dist/adapters/node-spawner.d.ts +14 -0
  23. package/dist/adapters/node-spawner.d.ts.map +1 -0
  24. package/dist/adapters/node-spawner.js +103 -0
  25. package/dist/adapters/node-spawner.js.map +1 -0
  26. package/dist/assessment/assessor.d.ts +6 -0
  27. package/dist/assessment/assessor.d.ts.map +1 -0
  28. package/dist/assessment/assessor.js +37 -0
  29. package/dist/assessment/assessor.js.map +1 -0
  30. package/dist/assessment/index.d.ts +6 -0
  31. package/dist/assessment/index.d.ts.map +1 -0
  32. package/dist/assessment/index.js +6 -0
  33. package/dist/assessment/index.js.map +1 -0
  34. package/dist/assessment/llm-review.d.ts +34 -0
  35. package/dist/assessment/llm-review.d.ts.map +1 -0
  36. package/dist/assessment/llm-review.js +669 -0
  37. package/dist/assessment/llm-review.js.map +1 -0
  38. package/dist/assessment/schemas.d.ts +5 -0
  39. package/dist/assessment/schemas.d.ts.map +1 -0
  40. package/dist/assessment/schemas.js +5 -0
  41. package/dist/assessment/schemas.js.map +1 -0
  42. package/dist/assessment/scoring.d.ts +5 -0
  43. package/dist/assessment/scoring.d.ts.map +1 -0
  44. package/dist/assessment/scoring.js +5 -0
  45. package/dist/assessment/scoring.js.map +1 -0
  46. package/dist/assessment/transcript-parser.d.ts +31 -0
  47. package/dist/assessment/transcript-parser.d.ts.map +1 -0
  48. package/dist/assessment/transcript-parser.js +203 -0
  49. package/dist/assessment/transcript-parser.js.map +1 -0
  50. package/dist/auth/index.d.ts +2 -0
  51. package/dist/auth/index.d.ts.map +1 -0
  52. package/dist/auth/index.js +4 -0
  53. package/dist/auth/index.js.map +1 -0
  54. package/dist/core/adapter.d.ts +62 -0
  55. package/dist/core/adapter.d.ts.map +1 -0
  56. package/dist/core/adapter.js +2 -0
  57. package/dist/core/adapter.js.map +1 -0
  58. package/dist/core/assessment-orchestrator.d.ts +18 -0
  59. package/dist/core/assessment-orchestrator.d.ts.map +1 -0
  60. package/dist/core/assessment-orchestrator.js +93 -0
  61. package/dist/core/assessment-orchestrator.js.map +1 -0
  62. package/dist/core/config.d.ts +17 -0
  63. package/dist/core/config.d.ts.map +1 -0
  64. package/dist/core/config.js +272 -0
  65. package/dist/core/config.js.map +1 -0
  66. package/dist/core/constants.d.ts +10 -0
  67. package/dist/core/constants.d.ts.map +1 -0
  68. package/dist/core/constants.js +11 -0
  69. package/dist/core/constants.js.map +1 -0
  70. package/dist/core/deadlock-resolver.d.ts +35 -0
  71. package/dist/core/deadlock-resolver.d.ts.map +1 -0
  72. package/dist/core/deadlock-resolver.js +317 -0
  73. package/dist/core/deadlock-resolver.js.map +1 -0
  74. package/dist/core/drizzle-sqlite-schema.d.ts +8 -0
  75. package/dist/core/drizzle-sqlite-schema.d.ts.map +1 -0
  76. package/dist/core/drizzle-sqlite-schema.js +250 -0
  77. package/dist/core/drizzle-sqlite-schema.js.map +1 -0
  78. package/dist/core/events.d.ts +26 -0
  79. package/dist/core/events.d.ts.map +1 -0
  80. package/dist/core/events.js +39 -0
  81. package/dist/core/events.js.map +1 -0
  82. package/dist/core/index.d.ts +37 -0
  83. package/dist/core/index.d.ts.map +1 -0
  84. package/dist/core/index.js +31 -0
  85. package/dist/core/index.js.map +1 -0
  86. package/dist/core/ink.d.ts +165 -0
  87. package/dist/core/ink.d.ts.map +1 -0
  88. package/dist/core/ink.js +445 -0
  89. package/dist/core/ink.js.map +1 -0
  90. package/dist/core/orchestrator.d.ts +387 -0
  91. package/dist/core/orchestrator.d.ts.map +1 -0
  92. package/dist/core/orchestrator.js +1015 -0
  93. package/dist/core/orchestrator.js.map +1 -0
  94. package/dist/core/question-detector.d.ts +19 -0
  95. package/dist/core/question-detector.d.ts.map +1 -0
  96. package/dist/core/question-detector.js +29 -0
  97. package/dist/core/question-detector.js.map +1 -0
  98. package/dist/core/runner.d.ts +14 -0
  99. package/dist/core/runner.d.ts.map +1 -0
  100. package/dist/core/runner.js +299 -0
  101. package/dist/core/runner.js.map +1 -0
  102. package/dist/core/session-reader.d.ts +46 -0
  103. package/dist/core/session-reader.d.ts.map +1 -0
  104. package/dist/core/session-reader.js +166 -0
  105. package/dist/core/session-reader.js.map +1 -0
  106. package/dist/index.d.ts +24 -0
  107. package/dist/index.d.ts.map +1 -0
  108. package/dist/index.js +29 -0
  109. package/dist/index.js.map +1 -0
  110. package/dist/llm/index.d.ts +8 -0
  111. package/dist/llm/index.d.ts.map +1 -0
  112. package/dist/llm/index.js +21 -0
  113. package/dist/llm/index.js.map +1 -0
  114. package/dist/llm/pi-client.d.ts +8 -0
  115. package/dist/llm/pi-client.d.ts.map +1 -0
  116. package/dist/llm/pi-client.js +8 -0
  117. package/dist/llm/pi-client.js.map +1 -0
  118. package/dist/llm/prompts.d.ts +14 -0
  119. package/dist/llm/prompts.d.ts.map +1 -0
  120. package/dist/llm/prompts.js +1618 -0
  121. package/dist/llm/prompts.js.map +1 -0
  122. package/dist/llm/retry.d.ts +5 -0
  123. package/dist/llm/retry.d.ts.map +1 -0
  124. package/dist/llm/retry.js +5 -0
  125. package/dist/llm/retry.js.map +1 -0
  126. package/dist/llm/skills.d.ts +265 -0
  127. package/dist/llm/skills.d.ts.map +1 -0
  128. package/dist/llm/skills.js +804 -0
  129. package/dist/llm/skills.js.map +1 -0
  130. package/dist/quality/index.d.ts +3 -0
  131. package/dist/quality/index.d.ts.map +1 -0
  132. package/dist/quality/index.js +3 -0
  133. package/dist/quality/index.js.map +1 -0
  134. package/dist/quality/quality-controller.d.ts +2 -0
  135. package/dist/quality/quality-controller.d.ts.map +1 -0
  136. package/dist/quality/quality-controller.js +2 -0
  137. package/dist/quality/quality-controller.js.map +1 -0
  138. package/dist/quality/sla-monitor.d.ts +2 -0
  139. package/dist/quality/sla-monitor.d.ts.map +1 -0
  140. package/dist/quality/sla-monitor.js +2 -0
  141. package/dist/quality/sla-monitor.js.map +1 -0
  142. package/dist/scheduling/cron.d.ts +2 -0
  143. package/dist/scheduling/cron.d.ts.map +1 -0
  144. package/dist/scheduling/cron.js +2 -0
  145. package/dist/scheduling/cron.js.map +1 -0
  146. package/dist/scheduling/index.d.ts +3 -0
  147. package/dist/scheduling/index.d.ts.map +1 -0
  148. package/dist/scheduling/index.js +3 -0
  149. package/dist/scheduling/index.js.map +1 -0
  150. package/dist/scheduling/scheduler.d.ts +2 -0
  151. package/dist/scheduling/scheduler.d.ts.map +1 -0
  152. package/dist/scheduling/scheduler.js +2 -0
  153. package/dist/scheduling/scheduler.js.map +1 -0
  154. package/dist/server/app.d.ts +19 -0
  155. package/dist/server/app.d.ts.map +1 -0
  156. package/dist/server/app.js +302 -0
  157. package/dist/server/app.js.map +1 -0
  158. package/dist/server/deps.d.ts +157 -0
  159. package/dist/server/deps.d.ts.map +1 -0
  160. package/dist/server/deps.js +9 -0
  161. package/dist/server/deps.js.map +1 -0
  162. package/dist/server/index.d.ts +43 -0
  163. package/dist/server/index.d.ts.map +1 -0
  164. package/dist/server/index.js +128 -0
  165. package/dist/server/index.js.map +1 -0
  166. package/dist/server/middleware/auth.d.ts +3 -0
  167. package/dist/server/middleware/auth.d.ts.map +1 -0
  168. package/dist/server/middleware/auth.js +35 -0
  169. package/dist/server/middleware/auth.js.map +1 -0
  170. package/dist/server/middleware/error.d.ts +15 -0
  171. package/dist/server/middleware/error.d.ts.map +1 -0
  172. package/dist/server/middleware/error.js +44 -0
  173. package/dist/server/middleware/error.js.map +1 -0
  174. package/dist/server/middleware/rate-limit.d.ts +16 -0
  175. package/dist/server/middleware/rate-limit.d.ts.map +1 -0
  176. package/dist/server/middleware/rate-limit.js +51 -0
  177. package/dist/server/middleware/rate-limit.js.map +1 -0
  178. package/dist/server/routes/config.d.ts +25 -0
  179. package/dist/server/routes/config.d.ts.map +1 -0
  180. package/dist/server/routes/config.js +446 -0
  181. package/dist/server/routes/config.js.map +1 -0
  182. package/dist/server/routes/files.d.ts +11 -0
  183. package/dist/server/routes/files.d.ts.map +1 -0
  184. package/dist/server/routes/files.js +514 -0
  185. package/dist/server/routes/files.js.map +1 -0
  186. package/dist/server/routes/filesystem.d.ts +3 -0
  187. package/dist/server/routes/filesystem.d.ts.map +1 -0
  188. package/dist/server/routes/filesystem.js +152 -0
  189. package/dist/server/routes/filesystem.js.map +1 -0
  190. package/dist/server/routes/providers.d.ts +7 -0
  191. package/dist/server/routes/providers.d.ts.map +1 -0
  192. package/dist/server/routes/providers.js +256 -0
  193. package/dist/server/routes/providers.js.map +1 -0
  194. package/dist/server/routes/skills.d.ts +11 -0
  195. package/dist/server/routes/skills.d.ts.map +1 -0
  196. package/dist/server/routes/skills.js +543 -0
  197. package/dist/server/routes/skills.js.map +1 -0
  198. package/dist/server/security.d.ts +34 -0
  199. package/dist/server/security.d.ts.map +1 -0
  200. package/dist/server/security.js +118 -0
  201. package/dist/server/security.js.map +1 -0
  202. package/dist/server/sse-bridge.d.ts +36 -0
  203. package/dist/server/sse-bridge.d.ts.map +1 -0
  204. package/dist/server/sse-bridge.js +110 -0
  205. package/dist/server/sse-bridge.js.map +1 -0
  206. package/dist/server/types.d.ts +69 -0
  207. package/dist/server/types.d.ts.map +1 -0
  208. package/dist/server/types.js +2 -0
  209. package/dist/server/types.js.map +1 -0
  210. package/dist/setup/env-persistence.d.ts +9 -0
  211. package/dist/setup/env-persistence.d.ts.map +1 -0
  212. package/dist/setup/env-persistence.js +42 -0
  213. package/dist/setup/env-persistence.js.map +1 -0
  214. package/dist/setup/index.d.ts +32 -0
  215. package/dist/setup/index.d.ts.map +1 -0
  216. package/dist/setup/index.js +24 -0
  217. package/dist/setup/index.js.map +1 -0
  218. package/dist/setup/models.d.ts +20 -0
  219. package/dist/setup/models.d.ts.map +1 -0
  220. package/dist/setup/models.js +33 -0
  221. package/dist/setup/models.js.map +1 -0
  222. package/dist/setup/providers.d.ts +26 -0
  223. package/dist/setup/providers.d.ts.map +1 -0
  224. package/dist/setup/providers.js +31 -0
  225. package/dist/setup/providers.js.map +1 -0
  226. package/dist/vault/encrypted-store.d.ts +45 -0
  227. package/dist/vault/encrypted-store.d.ts.map +1 -0
  228. package/dist/vault/encrypted-store.js +149 -0
  229. package/dist/vault/encrypted-store.js.map +1 -0
  230. package/dist/vault/index.d.ts +4 -0
  231. package/dist/vault/index.d.ts.map +1 -0
  232. package/dist/vault/index.js +3 -0
  233. package/dist/vault/index.js.map +1 -0
  234. package/dist/vault/resolver.d.ts +8 -0
  235. package/dist/vault/resolver.d.ts.map +1 -0
  236. package/dist/vault/resolver.js +8 -0
  237. package/dist/vault/resolver.js.map +1 -0
  238. package/package.json +76 -0
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Security redaction module — pure functions for sanitizing sensitive data
3
+ * before exposing it through API responses or persisting to transcript logs.
4
+ *
5
+ * Handles:
6
+ * - Provider API key masking
7
+ * - Transcript parameter sanitization (passwords, tokens, secrets)
8
+ *
9
+ * NOTE: Vault credentials are no longer stored on AgentConfig — they live in
10
+ * the encrypted vault store (.polpo/vault.enc). Agent/team/state redaction
11
+ * functions are kept as pass-throughs for API compatibility.
12
+ */
13
+ // ── Constants ──
14
+ /** Regex matching parameter names that likely contain secrets. */
15
+ export const SENSITIVE_PARAM_RE = /pass|secret|token|key|auth|password|credential/i;
16
+ // ── Agent Config Redaction ──
17
+ /**
18
+ * Returns the agent config as-is (vault credentials are no longer inline).
19
+ * Kept for backward compatibility with callers that expect redaction.
20
+ */
21
+ export function redactAgentConfig(agent) {
22
+ return agent;
23
+ }
24
+ // ── Team Redaction ──
25
+ /** Returns the team as-is (no inline credentials to redact). */
26
+ export function redactTeam(team) {
27
+ return team;
28
+ }
29
+ // ── State Redaction ──
30
+ /** Returns the state as-is (no inline credentials to redact). */
31
+ export function redactPolpoState(state) {
32
+ return state;
33
+ }
34
+ // ── Config Redaction ──
35
+ /** Return config as-is — providers no longer contain secrets (API keys resolved via env/OAuth only). */
36
+ export function redactPolpoConfig(config) {
37
+ return config;
38
+ }
39
+ // ── Transcript Sanitization ──
40
+ /**
41
+ * Recursively sanitize an object, redacting any string values whose keys
42
+ * match the SENSITIVE_PARAM_RE pattern. Handles nested objects and arrays.
43
+ *
44
+ * @param obj - The object to sanitize.
45
+ * @param depth - Current recursion depth (capped to prevent DoS on cyclic data).
46
+ * @returns A tuple of [sanitized copy, whether any value was redacted].
47
+ */
48
+ const MAX_SANITIZE_DEPTH = 10;
49
+ function sanitizeObject(obj, depth = 0) {
50
+ if (depth > MAX_SANITIZE_DEPTH)
51
+ return [obj, false];
52
+ const result = {};
53
+ let changed = false;
54
+ for (const [key, value] of Object.entries(obj)) {
55
+ if (SENSITIVE_PARAM_RE.test(key) && typeof value === "string") {
56
+ result[key] = "[REDACTED]";
57
+ changed = true;
58
+ }
59
+ else if (value && typeof value === "object" && !Array.isArray(value)) {
60
+ const [sanitized, childChanged] = sanitizeObject(value, depth + 1);
61
+ result[key] = childChanged ? sanitized : value;
62
+ if (childChanged)
63
+ changed = true;
64
+ }
65
+ else if (Array.isArray(value)) {
66
+ const [sanitized, childChanged] = sanitizeArray(value, depth + 1);
67
+ result[key] = childChanged ? sanitized : value;
68
+ if (childChanged)
69
+ changed = true;
70
+ }
71
+ else {
72
+ result[key] = value;
73
+ }
74
+ }
75
+ return [result, changed];
76
+ }
77
+ /**
78
+ * Recursively sanitize an array, descending into nested objects/arrays.
79
+ */
80
+ function sanitizeArray(arr, depth) {
81
+ if (depth > MAX_SANITIZE_DEPTH)
82
+ return [arr, false];
83
+ let changed = false;
84
+ const result = arr.map((item) => {
85
+ if (item && typeof item === "object" && !Array.isArray(item)) {
86
+ const [sanitized, childChanged] = sanitizeObject(item, depth + 1);
87
+ if (childChanged)
88
+ changed = true;
89
+ return childChanged ? sanitized : item;
90
+ }
91
+ if (Array.isArray(item)) {
92
+ const [sanitized, childChanged] = sanitizeArray(item, depth + 1);
93
+ if (childChanged)
94
+ changed = true;
95
+ return childChanged ? sanitized : item;
96
+ }
97
+ return item;
98
+ });
99
+ return [result, changed];
100
+ }
101
+ /**
102
+ * Sanitize a transcript entry by masking sensitive parameter values in tool_use inputs.
103
+ * Recursively descends into nested objects and arrays to catch secrets at any depth.
104
+ * Only touches entries with `type === "tool_use"` that have an `input` object.
105
+ * Returns the entry unchanged for all other types (assistant, tool_result, etc.).
106
+ */
107
+ export function sanitizeTranscriptEntry(entry) {
108
+ if (entry.type !== "tool_use")
109
+ return entry;
110
+ const input = entry.input;
111
+ if (!input || typeof input !== "object")
112
+ return entry;
113
+ const [sanitized, changed] = sanitizeObject(input);
114
+ if (!changed)
115
+ return entry;
116
+ return { ...entry, input: sanitized };
117
+ }
118
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/server/security.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { Orchestrator } from "../core/orchestrator.js";
2
+ export interface SSEClient {
3
+ id: string;
4
+ send(event: string, data: unknown, eventId: string): void;
5
+ close(): void;
6
+ }
7
+ export interface BufferedEvent {
8
+ id: string;
9
+ event: string;
10
+ data: unknown;
11
+ ts: number;
12
+ }
13
+ /**
14
+ * Bridges Orchestrator TypedEmitter events to SSE clients.
15
+ * Supports multiple concurrent clients per orchestrator.
16
+ * Maintains a circular buffer for Last-Event-ID reconnection.
17
+ */
18
+ export declare class SSEBridge {
19
+ private orchestrator;
20
+ private clients;
21
+ private eventBuffer;
22
+ private maxBufferSize;
23
+ private eventCounter;
24
+ private disposeFn;
25
+ constructor(orchestrator: Orchestrator);
26
+ /** Start listening to all orchestrator events. */
27
+ start(): void;
28
+ /** Add an SSE client. Replays events since lastEventId if provided. */
29
+ addClient(client: SSEClient, lastEventId?: string): void;
30
+ /** Remove an SSE client. */
31
+ removeClient(clientId: string): void;
32
+ get clientCount(): number;
33
+ /** Cleanup: remove all handlers and close all clients. */
34
+ dispose(): void;
35
+ }
36
+ //# sourceMappingURL=sse-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-bridge.d.ts","sourceRoot":"","sources":["../../src/server/sse-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AA6B5D,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1D,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,qBAAa,SAAS;IAOR,OAAO,CAAC,YAAY;IANhC,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,SAAS,CAA6B;gBAE1B,YAAY,EAAE,YAAY;IAE9C,kDAAkD;IAClD,KAAK,IAAI,IAAI;IAmCb,uEAAuE;IACvE,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IAoBxD,4BAA4B;IAC5B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKpC,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,0DAA0D;IAC1D,OAAO,IAAI,IAAI;CAOhB"}
@@ -0,0 +1,110 @@
1
+ /** All Polpo events to subscribe to. */
2
+ const ALL_EVENTS = [
3
+ "task:created", "task:transition", "task:updated", "task:removed",
4
+ "agent:spawned", "agent:finished", "agent:activity",
5
+ "assessment:started", "assessment:progress", "assessment:check:started", "assessment:check:complete", "assessment:complete", "assessment:corrected",
6
+ "orchestrator:started", "orchestrator:tick", "orchestrator:deadlock", "orchestrator:shutdown",
7
+ "task:retry", "task:retry:blocked", "task:fix", "task:maxRetries",
8
+ "task:question", "task:answered",
9
+ "deadlock:detected", "deadlock:resolving", "deadlock:resolved", "deadlock:unresolvable",
10
+ "task:timeout", "agent:stale",
11
+ "task:recovered",
12
+ "mission:saved", "mission:executed", "mission:completed", "mission:resumed", "mission:deleted",
13
+ "session:created", "message:added",
14
+ "approval:requested", "approval:resolved", "approval:rejected", "approval:timeout",
15
+ "escalation:triggered", "escalation:resolved", "escalation:human",
16
+ "sla:warning", "sla:violated", "sla:met",
17
+ "checkpoint:reached", "checkpoint:resumed",
18
+ "delay:started", "delay:expired",
19
+ "quality:gate:passed", "quality:gate:failed", "quality:threshold:failed",
20
+ "schedule:triggered", "schedule:created", "schedule:completed",
21
+ "watcher:created", "watcher:fired", "watcher:removed",
22
+ "action:triggered",
23
+ "file:changed",
24
+ "log",
25
+ ];
26
+ /**
27
+ * Bridges Orchestrator TypedEmitter events to SSE clients.
28
+ * Supports multiple concurrent clients per orchestrator.
29
+ * Maintains a circular buffer for Last-Event-ID reconnection.
30
+ */
31
+ export class SSEBridge {
32
+ orchestrator;
33
+ clients = new Map();
34
+ eventBuffer = [];
35
+ maxBufferSize = 1000;
36
+ eventCounter = 0;
37
+ disposeFn = null;
38
+ constructor(orchestrator) {
39
+ this.orchestrator = orchestrator;
40
+ }
41
+ /** Start listening to all orchestrator events. */
42
+ start() {
43
+ const handlers = [];
44
+ for (const event of ALL_EVENTS) {
45
+ const fn = (data) => {
46
+ const eventId = String(++this.eventCounter);
47
+ // Buffer for reconnection
48
+ this.eventBuffer.push({ id: eventId, event, data, ts: Date.now() });
49
+ if (this.eventBuffer.length > this.maxBufferSize) {
50
+ this.eventBuffer.shift();
51
+ }
52
+ // Broadcast to SSE clients
53
+ for (const client of this.clients.values()) {
54
+ try {
55
+ client.send(event, data, eventId);
56
+ }
57
+ catch { /* client disconnected */
58
+ this.removeClient(client.id);
59
+ }
60
+ }
61
+ };
62
+ this.orchestrator.on(event, fn);
63
+ handlers.push({ event, fn });
64
+ }
65
+ this.disposeFn = () => {
66
+ for (const { event, fn } of handlers) {
67
+ this.orchestrator.off(event, fn);
68
+ }
69
+ };
70
+ }
71
+ /** Add an SSE client. Replays events since lastEventId if provided. */
72
+ addClient(client, lastEventId) {
73
+ this.clients.set(client.id, client);
74
+ // Replay buffered events since lastEventId
75
+ if (lastEventId) {
76
+ const startIdx = this.eventBuffer.findIndex(e => e.id === lastEventId);
77
+ const events = startIdx >= 0
78
+ ? this.eventBuffer.slice(startIdx + 1)
79
+ : this.eventBuffer; // unknown ID: send all buffered
80
+ for (const e of events) {
81
+ try {
82
+ client.send(e.event, e.data, e.id);
83
+ }
84
+ catch { /* client disconnected */
85
+ this.removeClient(client.id);
86
+ return;
87
+ }
88
+ }
89
+ }
90
+ }
91
+ /** Remove an SSE client. */
92
+ removeClient(clientId) {
93
+ this.clients.delete(clientId);
94
+ }
95
+ get clientCount() {
96
+ return this.clients.size;
97
+ }
98
+ /** Cleanup: remove all handlers and close all clients. */
99
+ dispose() {
100
+ this.disposeFn?.();
101
+ for (const client of this.clients.values()) {
102
+ try {
103
+ client.close();
104
+ }
105
+ catch { /* already closed */ }
106
+ }
107
+ this.clients.clear();
108
+ }
109
+ }
110
+ //# sourceMappingURL=sse-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse-bridge.js","sourceRoot":"","sources":["../../src/server/sse-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ import type { TaskExpectation, ExpectedOutcome, RetryPolicy, MissionStatus } from "@polpo-ai/core/types";
2
+ import type { PolpoEvent } from "../core/events.js";
3
+ export interface ApiResponse<T> {
4
+ ok: true;
5
+ data: T;
6
+ }
7
+ export interface ApiError {
8
+ ok: false;
9
+ error: string;
10
+ code: string;
11
+ details?: unknown;
12
+ }
13
+ export type ApiResult<T> = ApiResponse<T> | ApiError;
14
+ export type ErrorCode = "NOT_FOUND" | "INVALID_STATE" | "VALIDATION_ERROR" | "AUTH_REQUIRED" | "FORBIDDEN" | "CONFLICT" | "INTERNAL_ERROR";
15
+ export interface CreateTaskRequest {
16
+ title: string;
17
+ description: string;
18
+ assignTo: string;
19
+ expectations?: TaskExpectation[];
20
+ expectedOutcomes?: ExpectedOutcome[];
21
+ dependsOn?: string[];
22
+ group?: string;
23
+ maxDuration?: number;
24
+ retryPolicy?: RetryPolicy;
25
+ }
26
+ export interface UpdateTaskRequest {
27
+ description?: string;
28
+ assignTo?: string;
29
+ expectations?: TaskExpectation[];
30
+ }
31
+ export interface CreateMissionRequest {
32
+ data: string;
33
+ prompt?: string;
34
+ name?: string;
35
+ status?: MissionStatus;
36
+ }
37
+ export interface UpdateMissionRequest {
38
+ data?: string;
39
+ status?: MissionStatus;
40
+ name?: string;
41
+ }
42
+ export interface AddAgentRequest {
43
+ name: string;
44
+ role?: string;
45
+ model?: string;
46
+ allowedTools?: string[];
47
+ systemPrompt?: string;
48
+ skills?: string[];
49
+ maxTurns?: number;
50
+ identity?: import("@polpo-ai/core/types").AgentIdentity;
51
+ reportsTo?: string;
52
+ browserProfile?: string;
53
+ }
54
+ export interface SSEEvent {
55
+ id: string;
56
+ event: PolpoEvent;
57
+ data: unknown;
58
+ timestamp: string;
59
+ }
60
+ export interface ServerConfig {
61
+ port: number;
62
+ host: string;
63
+ workDir: string;
64
+ apiKeys?: string[];
65
+ corsOrigins?: string[];
66
+ /** Start the supervisor loop on server start. Default: true. */
67
+ autoStart?: boolean;
68
+ }
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,WAAW,EACX,aAAa,EACd,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIpD,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC;AAIrD,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,eAAe,GACf,kBAAkB,GAClB,eAAe,GACf,WAAW,GACX,UAAU,GACV,gBAAgB,CAAC;AAIrB,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC;AAID,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,QAAQ,CAAC,EAAE,OAAO,sBAAsB,EAAE,aAAa,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAID,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAID,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/server/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Persist an env var to the .polpo/.env file (upsert semantics).
3
+ */
4
+ export declare function persistToEnvFile(polpoDir: string, envVar: string, value: string): void;
5
+ /**
6
+ * Remove an env var from the .polpo/.env file.
7
+ */
8
+ export declare function removeFromEnvFile(polpoDir: string, envVar: string): void;
9
+ //# sourceMappingURL=env-persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-persistence.d.ts","sourceRoot":"","sources":["../../src/setup/env-persistence.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAmBtF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMxE"}
@@ -0,0 +1,42 @@
1
+ import { join } from "node:path";
2
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from "node:fs";
3
+ /**
4
+ * Persist an env var to the .polpo/.env file (upsert semantics).
5
+ */
6
+ export function persistToEnvFile(polpoDir, envVar, value) {
7
+ const envPath = join(polpoDir, ".env");
8
+ if (!existsSync(polpoDir))
9
+ mkdirSync(polpoDir, { recursive: true });
10
+ let content = "";
11
+ if (existsSync(envPath)) {
12
+ content = readFileSync(envPath, "utf-8");
13
+ const regex = new RegExp(`^${envVar}=.*$`, "m");
14
+ if (regex.test(content)) {
15
+ content = content.replace(regex, `${envVar}=${value}`);
16
+ writeFileSync(envPath, content, "utf-8");
17
+ try {
18
+ chmodSync(envPath, 0o600);
19
+ }
20
+ catch { /* best-effort */ }
21
+ return;
22
+ }
23
+ }
24
+ const line = `${envVar}=${value}\n`;
25
+ writeFileSync(envPath, content ? `${content.trimEnd()}\n${line}` : line, "utf-8");
26
+ try {
27
+ chmodSync(envPath, 0o600);
28
+ }
29
+ catch { /* best-effort */ }
30
+ }
31
+ /**
32
+ * Remove an env var from the .polpo/.env file.
33
+ */
34
+ export function removeFromEnvFile(polpoDir, envVar) {
35
+ const envPath = join(polpoDir, ".env");
36
+ if (!existsSync(envPath))
37
+ return;
38
+ const content = readFileSync(envPath, "utf-8");
39
+ const updated = content.replace(new RegExp(`^${envVar}=.*\\n?`, "m"), "");
40
+ writeFileSync(envPath, updated, "utf-8");
41
+ }
42
+ //# sourceMappingURL=env-persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-persistence.js","sourceRoot":"","sources":["../../src/setup/env-persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAExF;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,MAAc,EAAE,KAAa;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpE,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,MAAM,MAAM,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;YACvD,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACzC,IAAI,CAAC;gBAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,GAAG,MAAM,IAAI,KAAK,IAAI,CAAC;IACpC,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAClF,IAAI,CAAC;QAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAc;IAChE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO;IACjC,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1E,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,32 @@
1
+ export { detectProviders, hasOAuthProfilesForProvider, type DetectedProvider, } from "./providers.js";
2
+ export { persistToEnvFile, removeFromEnvFile, } from "./env-persistence.js";
3
+ export { getProviderModels, formatCost, modelLabel, type ModelInfo, } from "./models.js";
4
+ export interface AuthOption {
5
+ id: string;
6
+ label: string;
7
+ description: string;
8
+ type: "oauth" | "api_key";
9
+ oauthId?: string;
10
+ free: boolean;
11
+ }
12
+ export interface LoginCallbacks {
13
+ onAuthUrl?: (url: string, instructions?: string) => void;
14
+ onPrompt?: (message: string, placeholder?: string) => Promise<string>;
15
+ onProgress?: (message: string) => void;
16
+ }
17
+ /** OAuth providers removed — returns only the manual API key option. */
18
+ export declare function getAuthOptions(): AuthOption[];
19
+ /** OAuth providers removed — empty set. */
20
+ export declare const FREE_OAUTH_PROVIDERS: Set<string>;
21
+ /** OAuth providers removed — always returns undefined. */
22
+ export declare function findOAuthProvider(_providerId: string): undefined;
23
+ /** OAuth providers removed — returns empty list. */
24
+ export declare function getOAuthProviderList(): {
25
+ id: string;
26
+ name: string;
27
+ flow: string;
28
+ free: boolean;
29
+ }[];
30
+ /** OAuth login removed — always throws. */
31
+ export declare function startOAuthLogin(_providerId: string, _callbacks: LoginCallbacks): Promise<string>;
32
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,2BAA2B,EAC3B,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACtE,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,wEAAwE;AACxE,wBAAgB,cAAc,IAAI,UAAU,EAAE,CAI7C;AAED,2CAA2C;AAC3C,eAAO,MAAM,oBAAoB,aAAoB,CAAC;AAEtD,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAEhE;AAED,oDAAoD;AACpD,wBAAgB,oBAAoB,IAAI;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EAAE,CAElG;AAED,2CAA2C;AAC3C,wBAAsB,eAAe,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,cAAc,GACzB,OAAO,CAAC,MAAM,CAAC,CAEjB"}
@@ -0,0 +1,24 @@
1
+ export { detectProviders, hasOAuthProfilesForProvider, } from "./providers.js";
2
+ export { persistToEnvFile, removeFromEnvFile, } from "./env-persistence.js";
3
+ export { getProviderModels, formatCost, modelLabel, } from "./models.js";
4
+ /** OAuth providers removed — returns only the manual API key option. */
5
+ export function getAuthOptions() {
6
+ return [
7
+ { id: "api-key", label: "Enter an API key manually", description: "For any provider (OpenAI, Anthropic, Groq, etc.)", type: "api_key", free: false },
8
+ ];
9
+ }
10
+ /** OAuth providers removed — empty set. */
11
+ export const FREE_OAUTH_PROVIDERS = new Set();
12
+ /** OAuth providers removed — always returns undefined. */
13
+ export function findOAuthProvider(_providerId) {
14
+ return undefined;
15
+ }
16
+ /** OAuth providers removed — returns empty list. */
17
+ export function getOAuthProviderList() {
18
+ return [];
19
+ }
20
+ /** OAuth login removed — always throws. */
21
+ export async function startOAuthLogin(_providerId, _callbacks) {
22
+ throw new Error("OAuth login has been removed. Use API keys instead.");
23
+ }
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/setup/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,2BAA2B,GAE5B,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,UAAU,GAEX,MAAM,aAAa,CAAC;AAmBrB,wEAAwE;AACxE,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,WAAW,EAAE,kDAAkD,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE;KACrJ,CAAC;AACJ,CAAC;AAED,2CAA2C;AAC3C,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAU,CAAC;AAEtD,0DAA0D;AAC1D,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,oDAAoD;AACpD,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,2CAA2C;AAC3C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,WAAmB,EACnB,UAA0B;IAE1B,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;AACzE,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ModelInfo } from "../llm/pi-client.js";
2
+ export type { ModelInfo };
3
+ /**
4
+ * Get models for a provider, sorted by cost (cheapest first).
5
+ */
6
+ export declare function getProviderModels(provider: string): ModelInfo[];
7
+ /**
8
+ * Format a model cost as a human-readable string.
9
+ */
10
+ export declare function formatCost(cost: number): string;
11
+ /**
12
+ * Get structured label data for a model. Pure data — no formatting.
13
+ * CLI wraps this with chalk, server returns it as JSON.
14
+ */
15
+ export declare function modelLabel(m: ModelInfo): {
16
+ name: string;
17
+ tags: string[];
18
+ costStr: string;
19
+ };
20
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/setup/models.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAErD,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,CAE/D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAQ1F"}
@@ -0,0 +1,33 @@
1
+ import { listModels as piListModels } from "../llm/pi-client.js";
2
+ /**
3
+ * Get models for a provider, sorted by cost (cheapest first).
4
+ */
5
+ export function getProviderModels(provider) {
6
+ return piListModels(provider).sort((a, b) => a.cost.input - b.cost.input);
7
+ }
8
+ /**
9
+ * Format a model cost as a human-readable string.
10
+ */
11
+ export function formatCost(cost) {
12
+ if (cost === 0)
13
+ return "free";
14
+ if (cost < 1)
15
+ return `$${cost.toFixed(2)}/M`;
16
+ return `$${cost.toFixed(0)}/M`;
17
+ }
18
+ /**
19
+ * Get structured label data for a model. Pure data — no formatting.
20
+ * CLI wraps this with chalk, server returns it as JSON.
21
+ */
22
+ export function modelLabel(m) {
23
+ const tags = [];
24
+ if (m.reasoning)
25
+ tags.push("reasoning");
26
+ if (m.cost.input === 0 && m.cost.output === 0)
27
+ tags.push("free");
28
+ const costStr = m.cost.input > 0
29
+ ? `in:${formatCost(m.cost.input)} out:${formatCost(m.cost.output)}`
30
+ : "";
31
+ return { name: m.name, tags, costStr };
32
+ }
33
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/setup/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKjE;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9B,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7C,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,CAAY;IACrC,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,CAAC,CAAC,SAAS;QAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC;QAC9B,CAAC,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QACnE,CAAC,CAAC,EAAE,CAAC;IACP,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,26 @@
1
+ export interface DetectedProvider {
2
+ /** Provider name exactly as it appears in the AI Gateway catalog (e.g. "openai", "openai-codex", "google") */
3
+ name: string;
4
+ /** Environment variable for API key (if any) */
5
+ envVar: string | undefined;
6
+ /** Whether a usable credential exists (env key) */
7
+ hasKey: boolean;
8
+ /** Source of credentials */
9
+ source: "env" | "none";
10
+ }
11
+ /**
12
+ * Detect all providers from the AI Gateway catalog with their credential status.
13
+ *
14
+ * This is a 1:1 pass-through of the catalog — every provider the gateway knows about
15
+ * is returned. No deduplication, no name mapping. The UI is a mere wrapper on this.
16
+ *
17
+ * Credential detection:
18
+ * - env: the provider has a known env var (PROVIDER_ENV_MAP) and it's set
19
+ * - none: no credentials found
20
+ */
21
+ export declare function detectProviders(): DetectedProvider[];
22
+ /**
23
+ * Check if a provider has credentials available (env key only, OAuth removed).
24
+ */
25
+ export declare function hasOAuthProfilesForProvider(_provider: string): boolean;
26
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/setup/providers.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,8GAA8G;IAC9G,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,mDAAmD;IACnD,MAAM,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,gBAAgB,EAAE,CAcpD;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAEtE"}
@@ -0,0 +1,31 @@
1
+ import { PROVIDER_ENV_MAP, listProviders } from "../llm/pi-client.js";
2
+ /**
3
+ * Detect all providers from the AI Gateway catalog with their credential status.
4
+ *
5
+ * This is a 1:1 pass-through of the catalog — every provider the gateway knows about
6
+ * is returned. No deduplication, no name mapping. The UI is a mere wrapper on this.
7
+ *
8
+ * Credential detection:
9
+ * - env: the provider has a known env var (PROVIDER_ENV_MAP) and it's set
10
+ * - none: no credentials found
11
+ */
12
+ export function detectProviders() {
13
+ const catalogProviders = listProviders();
14
+ return catalogProviders.map((name) => {
15
+ const envVar = PROVIDER_ENV_MAP[name];
16
+ const hasEnvKey = envVar ? !!process.env[envVar] : false;
17
+ return {
18
+ name,
19
+ envVar,
20
+ hasKey: hasEnvKey,
21
+ source: hasEnvKey ? "env" : "none",
22
+ };
23
+ });
24
+ }
25
+ /**
26
+ * Check if a provider has credentials available (env key only, OAuth removed).
27
+ */
28
+ export function hasOAuthProfilesForProvider(_provider) {
29
+ return false;
30
+ }
31
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/setup/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAatE;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,gBAAgB,GAAG,aAAa,EAAE,CAAC;IAEzC,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QAEzD,OAAO;YACL,IAAI;YACJ,MAAM;YACN,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,KAAc,CAAC,CAAC,CAAC,MAAe;SACrD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO,KAAK,CAAC;AACf,CAAC"}