@a5c-ai/tasks-adapter 5.1.1-staging.0ad6ac75ae4a

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 (202) hide show
  1. package/README.md +125 -0
  2. package/dist/auth/forge-interface.d.ts +67 -0
  3. package/dist/auth/forge-interface.d.ts.map +1 -0
  4. package/dist/auth/forge-interface.js +69 -0
  5. package/dist/auth/github-app.d.ts +64 -0
  6. package/dist/auth/github-app.d.ts.map +1 -0
  7. package/dist/auth/github-app.js +141 -0
  8. package/dist/auth/github-oauth.d.ts +27 -0
  9. package/dist/auth/github-oauth.d.ts.map +1 -0
  10. package/dist/auth/github-oauth.js +89 -0
  11. package/dist/auth/index.d.ts +8 -0
  12. package/dist/auth/index.d.ts.map +1 -0
  13. package/dist/auth/index.js +14 -0
  14. package/dist/auth/jwt.d.ts +24 -0
  15. package/dist/auth/jwt.d.ts.map +1 -0
  16. package/dist/auth/jwt.js +43 -0
  17. package/dist/auth/middleware.d.ts +22 -0
  18. package/dist/auth/middleware.d.ts.map +1 -0
  19. package/dist/auth/middleware.js +36 -0
  20. package/dist/auth/ssh-keys.d.ts +21 -0
  21. package/dist/auth/ssh-keys.d.ts.map +1 -0
  22. package/dist/auth/ssh-keys.js +59 -0
  23. package/dist/auth/types.d.ts +165 -0
  24. package/dist/auth/types.d.ts.map +1 -0
  25. package/dist/auth/types.js +53 -0
  26. package/dist/backend.d.ts +248 -0
  27. package/dist/backend.d.ts.map +1 -0
  28. package/dist/backend.js +40 -0
  29. package/dist/backends/adapters.d.ts +99 -0
  30. package/dist/backends/adapters.d.ts.map +1 -0
  31. package/dist/backends/adapters.js +308 -0
  32. package/dist/backends/external-tracker.d.ts +133 -0
  33. package/dist/backends/external-tracker.d.ts.map +1 -0
  34. package/dist/backends/external-tracker.js +731 -0
  35. package/dist/backends/git-native.d.ts +69 -0
  36. package/dist/backends/git-native.d.ts.map +1 -0
  37. package/dist/backends/git-native.js +797 -0
  38. package/dist/backends/github-issues.d.ts +78 -0
  39. package/dist/backends/github-issues.d.ts.map +1 -0
  40. package/dist/backends/github-issues.js +806 -0
  41. package/dist/backends/index.d.ts +52 -0
  42. package/dist/backends/index.d.ts.map +1 -0
  43. package/dist/backends/index.js +151 -0
  44. package/dist/backends/server.d.ts +42 -0
  45. package/dist/backends/server.d.ts.map +1 -0
  46. package/dist/backends/server.js +305 -0
  47. package/dist/cli/auth-store.d.ts +49 -0
  48. package/dist/cli/auth-store.d.ts.map +1 -0
  49. package/dist/cli/auth-store.js +150 -0
  50. package/dist/cli/client-config.d.ts +10 -0
  51. package/dist/cli/client-config.d.ts.map +1 -0
  52. package/dist/cli/client-config.js +87 -0
  53. package/dist/cli/commands/ask.d.ts +3 -0
  54. package/dist/cli/commands/ask.d.ts.map +1 -0
  55. package/dist/cli/commands/ask.js +171 -0
  56. package/dist/cli/commands/auth.d.ts +3 -0
  57. package/dist/cli/commands/auth.d.ts.map +1 -0
  58. package/dist/cli/commands/auth.js +510 -0
  59. package/dist/cli/commands/breakpoints.d.ts +3 -0
  60. package/dist/cli/commands/breakpoints.d.ts.map +1 -0
  61. package/dist/cli/commands/breakpoints.js +311 -0
  62. package/dist/cli/commands/responder-loop.d.ts +3 -0
  63. package/dist/cli/commands/responder-loop.d.ts.map +1 -0
  64. package/dist/cli/commands/responder-loop.js +78 -0
  65. package/dist/cli/commands/responders.d.ts +3 -0
  66. package/dist/cli/commands/responders.d.ts.map +1 -0
  67. package/dist/cli/commands/responders.js +157 -0
  68. package/dist/cli/commands/rules.d.ts +3 -0
  69. package/dist/cli/commands/rules.d.ts.map +1 -0
  70. package/dist/cli/commands/rules.js +105 -0
  71. package/dist/cli/commands/server.d.ts +3 -0
  72. package/dist/cli/commands/server.d.ts.map +1 -0
  73. package/dist/cli/commands/server.js +34 -0
  74. package/dist/cli/commands/tasks.d.ts +3 -0
  75. package/dist/cli/commands/tasks.d.ts.map +1 -0
  76. package/dist/cli/commands/tasks.js +281 -0
  77. package/dist/cli/commands/templates.d.ts +3 -0
  78. package/dist/cli/commands/templates.d.ts.map +1 -0
  79. package/dist/cli/commands/templates.js +100 -0
  80. package/dist/cli/index.d.ts +4 -0
  81. package/dist/cli/index.d.ts.map +1 -0
  82. package/dist/cli/index.js +9 -0
  83. package/dist/cli/output.d.ts +26 -0
  84. package/dist/cli/output.d.ts.map +1 -0
  85. package/dist/cli/output.js +143 -0
  86. package/dist/cli/program.d.ts +6 -0
  87. package/dist/cli/program.d.ts.map +1 -0
  88. package/dist/cli/program.js +38 -0
  89. package/dist/cli/tasks-adapter.d.ts +3 -0
  90. package/dist/cli/tasks-adapter.d.ts.map +1 -0
  91. package/dist/cli/tasks-adapter.js +4 -0
  92. package/dist/client/answer-poller.d.ts +52 -0
  93. package/dist/client/answer-poller.d.ts.map +1 -0
  94. package/dist/client/answer-poller.js +200 -0
  95. package/dist/client/auth-client.d.ts +200 -0
  96. package/dist/client/auth-client.d.ts.map +1 -0
  97. package/dist/client/auth-client.js +309 -0
  98. package/dist/client/breakpoint-router.d.ts +45 -0
  99. package/dist/client/breakpoint-router.d.ts.map +1 -0
  100. package/dist/client/breakpoint-router.js +45 -0
  101. package/dist/client/index.d.ts +17 -0
  102. package/dist/client/index.d.ts.map +1 -0
  103. package/dist/client/index.js +16 -0
  104. package/dist/client/profile-validator.d.ts +34 -0
  105. package/dist/client/profile-validator.d.ts.map +1 -0
  106. package/dist/client/profile-validator.js +89 -0
  107. package/dist/client/responder-client.d.ts +39 -0
  108. package/dist/client/responder-client.d.ts.map +1 -0
  109. package/dist/client/responder-client.js +72 -0
  110. package/dist/client/responder-matcher.d.ts +49 -0
  111. package/dist/client/responder-matcher.d.ts.map +1 -0
  112. package/dist/client/responder-matcher.js +226 -0
  113. package/dist/client/server-client.d.ts +124 -0
  114. package/dist/client/server-client.d.ts.map +1 -0
  115. package/dist/client/server-client.js +266 -0
  116. package/dist/client/timeout-manager.d.ts +47 -0
  117. package/dist/client/timeout-manager.d.ts.map +1 -0
  118. package/dist/client/timeout-manager.js +77 -0
  119. package/dist/config.d.ts +20 -0
  120. package/dist/config.d.ts.map +1 -0
  121. package/dist/config.js +93 -0
  122. package/dist/harness/index.d.ts +4 -0
  123. package/dist/harness/index.d.ts.map +1 -0
  124. package/dist/harness/index.js +2 -0
  125. package/dist/harness/interaction-provider.d.ts +71 -0
  126. package/dist/harness/interaction-provider.d.ts.map +1 -0
  127. package/dist/harness/interaction-provider.js +124 -0
  128. package/dist/harness/routing-rules.d.ts +7 -0
  129. package/dist/harness/routing-rules.d.ts.map +1 -0
  130. package/dist/harness/routing-rules.js +37 -0
  131. package/dist/index.d.ts +29 -0
  132. package/dist/index.d.ts.map +1 -0
  133. package/dist/index.js +33 -0
  134. package/dist/mcp/backend-resolver.d.ts +43 -0
  135. package/dist/mcp/backend-resolver.d.ts.map +1 -0
  136. package/dist/mcp/backend-resolver.js +111 -0
  137. package/dist/mcp/http-transport.d.ts +37 -0
  138. package/dist/mcp/http-transport.d.ts.map +1 -0
  139. package/dist/mcp/http-transport.js +103 -0
  140. package/dist/mcp/index.d.ts +16 -0
  141. package/dist/mcp/index.d.ts.map +1 -0
  142. package/dist/mcp/index.js +12 -0
  143. package/dist/mcp/server.d.ts +20 -0
  144. package/dist/mcp/server.d.ts.map +1 -0
  145. package/dist/mcp/server.js +259 -0
  146. package/dist/mcp/tools/answer-breakpoint.d.ts +32 -0
  147. package/dist/mcp/tools/answer-breakpoint.d.ts.map +1 -0
  148. package/dist/mcp/tools/answer-breakpoint.js +45 -0
  149. package/dist/mcp/tools/ask-breakpoint.d.ts +58 -0
  150. package/dist/mcp/tools/ask-breakpoint.d.ts.map +1 -0
  151. package/dist/mcp/tools/ask-breakpoint.js +78 -0
  152. package/dist/mcp/tools/check-status.d.ts +16 -0
  153. package/dist/mcp/tools/check-status.d.ts.map +1 -0
  154. package/dist/mcp/tools/check-status.js +18 -0
  155. package/dist/mcp/tools/claim-breakpoint.d.ts +18 -0
  156. package/dist/mcp/tools/claim-breakpoint.d.ts.map +1 -0
  157. package/dist/mcp/tools/claim-breakpoint.js +28 -0
  158. package/dist/mcp/tools/list-breakpoints.d.ts +16 -0
  159. package/dist/mcp/tools/list-breakpoints.d.ts.map +1 -0
  160. package/dist/mcp/tools/list-breakpoints.js +14 -0
  161. package/dist/mcp/tools/list-responders.d.ts +18 -0
  162. package/dist/mcp/tools/list-responders.d.ts.map +1 -0
  163. package/dist/mcp/tools/list-responders.js +37 -0
  164. package/dist/mcp/tools/native-tasks.d.ts +270 -0
  165. package/dist/mcp/tools/native-tasks.d.ts.map +1 -0
  166. package/dist/mcp/tools/native-tasks.js +481 -0
  167. package/dist/mcp/tools/poll-breakpoints.d.ts +18 -0
  168. package/dist/mcp/tools/poll-breakpoints.d.ts.map +1 -0
  169. package/dist/mcp/tools/poll-breakpoints.js +36 -0
  170. package/dist/mcp/tools/verify-answer.d.ts +16 -0
  171. package/dist/mcp/tools/verify-answer.d.ts.map +1 -0
  172. package/dist/mcp/tools/verify-answer.js +38 -0
  173. package/dist/proven/index.d.ts +5 -0
  174. package/dist/proven/index.d.ts.map +1 -0
  175. package/dist/proven/index.js +3 -0
  176. package/dist/proven/keys.d.ts +33 -0
  177. package/dist/proven/keys.d.ts.map +1 -0
  178. package/dist/proven/keys.js +117 -0
  179. package/dist/proven/sign.d.ts +16 -0
  180. package/dist/proven/sign.d.ts.map +1 -0
  181. package/dist/proven/sign.js +60 -0
  182. package/dist/proven/types.d.ts +26 -0
  183. package/dist/proven/types.d.ts.map +1 -0
  184. package/dist/proven/types.js +5 -0
  185. package/dist/proven/verify.d.ts +6 -0
  186. package/dist/proven/verify.d.ts.map +1 -0
  187. package/dist/proven/verify.js +58 -0
  188. package/dist/responders/types.d.ts +38 -0
  189. package/dist/responders/types.d.ts.map +1 -0
  190. package/dist/responders/types.js +1 -0
  191. package/dist/router.d.ts +51 -0
  192. package/dist/router.d.ts.map +1 -0
  193. package/dist/router.js +200 -0
  194. package/dist/types.d.ts +7711 -0
  195. package/dist/types.d.ts.map +1 -0
  196. package/dist/types.js +479 -0
  197. package/package.json +96 -0
  198. package/responder/README.md +42 -0
  199. package/responder/backend-responder.json +9 -0
  200. package/responder/devops-responder.json +9 -0
  201. package/responder/frontend-responder.json +9 -0
  202. package/responder/schema.json +89 -0
@@ -0,0 +1,266 @@
1
+ /**
2
+ * Error thrown when the server returns a non-OK response.
3
+ */
4
+ export class ServerError extends Error {
5
+ status;
6
+ statusText;
7
+ body;
8
+ constructor(status, statusText, body) {
9
+ super(`Server responded with ${status} ${statusText}`);
10
+ this.status = status;
11
+ this.statusText = statusText;
12
+ this.body = body;
13
+ this.name = "ServerError";
14
+ }
15
+ }
16
+ export const DEFAULT_BMUX_SERVER_URL = "https://tasks-adapter.a5c.ai/api/v1";
17
+ /**
18
+ * API path helpers for the tasks-adapter server.
19
+ */
20
+ const API_PATHS = {
21
+ BREAKPOINTS: "/breakpoints",
22
+ BREAKPOINT_BY_ID: (id) => `/breakpoints/${id}`,
23
+ BREAKPOINT_EVENTS: (id) => `/breakpoints/${id}/events`,
24
+ BREAKPOINT_ANSWERS: (id) => `/breakpoints/${id}/answers`,
25
+ BREAKPOINT_BROWSER_SESSION: (id) => `/breakpoints/${id}/browser-session`,
26
+ BREAKPOINT_SESSION: (authToken) => `/breakpoints/session/${authToken}`,
27
+ BREAKPOINT_SESSION_ANSWER: (authToken) => `/breakpoints/session/${authToken}/answer`,
28
+ RESPONDERS: "/responders",
29
+ RESPONDER_BY_ID: (id) => `/responders/${id}`,
30
+ HEALTH: "/health",
31
+ };
32
+ /**
33
+ * HTTP client for communicating with the Breakpoints Adapter server.
34
+ */
35
+ export class ServerClient {
36
+ baseUrl;
37
+ defaultHeaders;
38
+ constructor(options = DEFAULT_BMUX_SERVER_URL) {
39
+ const baseUrl = typeof options === "string"
40
+ ? options
41
+ : options.baseUrl ?? DEFAULT_BMUX_SERVER_URL;
42
+ // Strip trailing slash
43
+ this.baseUrl = baseUrl.replace(/\/+$/, "");
44
+ this.defaultHeaders = typeof options === "string" ? {} : { ...(options.defaultHeaders ?? {}) };
45
+ }
46
+ // -- Breakpoints ------------------------------------------------------------
47
+ /**
48
+ * Submit a new breakpoint to the server.
49
+ */
50
+ async submitBreakpoint(breakpoint) {
51
+ return this.post(API_PATHS.BREAKPOINTS, breakpoint);
52
+ }
53
+ /**
54
+ * Retrieve a breakpoint by its ID.
55
+ */
56
+ async getBreakpoint(breakpointId) {
57
+ return this.get(API_PATHS.BREAKPOINT_BY_ID(breakpointId));
58
+ }
59
+ async createBrowserSession(breakpointId, options) {
60
+ return this.post(API_PATHS.BREAKPOINT_BROWSER_SESSION(breakpointId), {
61
+ mode: options?.mode ?? "same-user",
62
+ responderId: options?.responderId,
63
+ responderName: options?.responderName,
64
+ });
65
+ }
66
+ async getBreakpointSession(authToken) {
67
+ return this.get(API_PATHS.BREAKPOINT_SESSION(authToken));
68
+ }
69
+ async submitSessionAnswer(authToken, answer) {
70
+ return this.post(API_PATHS.BREAKPOINT_SESSION_ANSWER(authToken), answer);
71
+ }
72
+ /**
73
+ * Open an SSE stream for real-time updates on a breakpoint.
74
+ */
75
+ getBreakpointStream(breakpointId, signal) {
76
+ const url = this.resolveUrl(API_PATHS.BREAKPOINT_EVENTS(breakpointId));
77
+ const handlers = new Map();
78
+ let errorHandler;
79
+ let aborted = false;
80
+ const controller = new AbortController();
81
+ // If a parent signal is provided, forward its abort.
82
+ if (signal) {
83
+ signal.addEventListener("abort", () => controller.abort(), { once: true });
84
+ }
85
+ // Start reading in background
86
+ void (async () => {
87
+ try {
88
+ const response = await fetch(url, {
89
+ headers: { ...this.defaultHeaders, Accept: "text/event-stream" },
90
+ signal: controller.signal,
91
+ });
92
+ if (!response.ok || !response.body) {
93
+ throw new ServerError(response.status, response.statusText);
94
+ }
95
+ const reader = response.body.getReader();
96
+ const decoder = new TextDecoder();
97
+ let buffer = "";
98
+ let currentEvent = "message";
99
+ let currentData = "";
100
+ while (!aborted) {
101
+ const { done, value } = await reader.read();
102
+ if (done)
103
+ break;
104
+ buffer += decoder.decode(value, { stream: true });
105
+ const lines = buffer.split("\n");
106
+ buffer = lines.pop() ?? "";
107
+ for (const line of lines) {
108
+ if (line.startsWith("event:")) {
109
+ currentEvent = line.slice(6).trim();
110
+ }
111
+ else if (line.startsWith("data:")) {
112
+ currentData += (currentData ? "\n" : "") + line.slice(5).trim();
113
+ }
114
+ else if (line === "") {
115
+ // Empty line = dispatch event
116
+ if (currentData) {
117
+ const eventHandlers = handlers.get(currentEvent);
118
+ if (eventHandlers) {
119
+ for (const h of eventHandlers) {
120
+ h(currentData);
121
+ }
122
+ }
123
+ }
124
+ currentEvent = "message";
125
+ currentData = "";
126
+ }
127
+ }
128
+ }
129
+ }
130
+ catch (err) {
131
+ if (aborted)
132
+ return;
133
+ if (err instanceof Error && err.name === "AbortError")
134
+ return;
135
+ if (errorHandler && err instanceof Error) {
136
+ errorHandler(err);
137
+ }
138
+ }
139
+ })();
140
+ return {
141
+ on(event, handler) {
142
+ const list = handlers.get(event) ?? [];
143
+ list.push(handler);
144
+ handlers.set(event, list);
145
+ },
146
+ onError(handler) {
147
+ errorHandler = handler;
148
+ },
149
+ close() {
150
+ aborted = true;
151
+ controller.abort();
152
+ },
153
+ };
154
+ }
155
+ // -- Responders -------------------------------------------------------------
156
+ /**
157
+ * List responder profiles, optionally scoped to a project or repo.
158
+ */
159
+ async listResponders(filters) {
160
+ const params = new URLSearchParams();
161
+ if (filters?.projectId)
162
+ params.set("projectId", filters.projectId);
163
+ if (filters?.repoId)
164
+ params.set("repoId", filters.repoId);
165
+ const qs = params.toString();
166
+ return this.get(`${API_PATHS.RESPONDERS}${qs ? `?${qs}` : ""}`);
167
+ }
168
+ /**
169
+ * List pending breakpoints for a specific responder.
170
+ */
171
+ async listPendingBreakpoints(responderId, filters) {
172
+ const params = new URLSearchParams();
173
+ if (filters?.projectId)
174
+ params.set("projectId", filters.projectId);
175
+ if (filters?.repoId)
176
+ params.set("repoId", filters.repoId);
177
+ if (filters?.status)
178
+ params.set("status", filters.status);
179
+ const qs = params.toString();
180
+ const path = `${API_PATHS.RESPONDER_BY_ID(responderId)}/breakpoints${qs ? `?${qs}` : ""}`;
181
+ return this.get(path);
182
+ }
183
+ /**
184
+ * Claim a breakpoint as a responder.
185
+ */
186
+ async claimBreakpoint(breakpointId, responderId) {
187
+ const path = `${API_PATHS.BREAKPOINT_BY_ID(breakpointId)}/claim`;
188
+ return this.post(path, { responderId });
189
+ }
190
+ /**
191
+ * Submit an answer for a breakpoint.
192
+ */
193
+ async submitAnswer(breakpointId, answer) {
194
+ return this.post(API_PATHS.BREAKPOINT_ANSWERS(breakpointId), answer);
195
+ }
196
+ /**
197
+ * Cancel (delete) a breakpoint.
198
+ */
199
+ async cancelBreakpoint(breakpointId) {
200
+ const path = API_PATHS.BREAKPOINT_BY_ID(breakpointId);
201
+ await this.delete(path);
202
+ }
203
+ // -- Health -----------------------------------------------------------------
204
+ /**
205
+ * Check server health.
206
+ */
207
+ async healthCheck() {
208
+ return this.get(API_PATHS.HEALTH);
209
+ }
210
+ // -- HTTP helpers -----------------------------------------------------------
211
+ /** @internal Exposed for composition by AuthClient. */
212
+ async get(path, extraHeaders) {
213
+ return this.request(path, { method: "GET" }, extraHeaders);
214
+ }
215
+ /** @internal Exposed for composition by AuthClient. */
216
+ async post(path, body, extraHeaders) {
217
+ return this.request(path, {
218
+ method: "POST",
219
+ headers: { "Content-Type": "application/json" },
220
+ body: JSON.stringify(body),
221
+ }, extraHeaders);
222
+ }
223
+ /** @internal Exposed for composition by AuthClient. */
224
+ async put(path, body, extraHeaders) {
225
+ return this.request(path, {
226
+ method: "PUT",
227
+ headers: { "Content-Type": "application/json" },
228
+ body: JSON.stringify(body),
229
+ }, extraHeaders);
230
+ }
231
+ /** @internal Exposed for composition by AuthClient. */
232
+ async delete(path, extraHeaders) {
233
+ return this.request(path, { method: "DELETE" }, extraHeaders);
234
+ }
235
+ async request(path, init, extraHeaders) {
236
+ const url = this.resolveUrl(path);
237
+ const mergedHeaders = {
238
+ ...this.defaultHeaders,
239
+ ...init.headers,
240
+ ...extraHeaders,
241
+ };
242
+ const response = await fetch(url, {
243
+ ...init,
244
+ headers: mergedHeaders,
245
+ });
246
+ if (!response.ok) {
247
+ const body = await response.text().catch(() => undefined);
248
+ throw new ServerError(response.status, response.statusText, body);
249
+ }
250
+ // 204 No Content
251
+ if (response.status === 204) {
252
+ return undefined;
253
+ }
254
+ return (await response.json());
255
+ }
256
+ resolveUrl(path) {
257
+ // path already includes /api/v1 prefix from API_PATHS,
258
+ // and baseUrl already includes /api/v1. Strip the prefix from path
259
+ // to avoid duplication.
260
+ const apiPrefix = "/api/v1";
261
+ const relativePath = path.startsWith(apiPrefix)
262
+ ? path.slice(apiPrefix.length)
263
+ : path;
264
+ return `${this.baseUrl}${relativePath}`;
265
+ }
266
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Status of a tracked breakpoint timeout.
3
+ */
4
+ export interface TimeoutStatus {
5
+ breakpointId: string;
6
+ timedOut: boolean;
7
+ remainingMs: number;
8
+ }
9
+ /**
10
+ * Callback invoked when a breakpoint's timeout fires.
11
+ */
12
+ export type TimeoutCallback = (breakpointId: string) => void;
13
+ /**
14
+ * Manages timeout tracking for in-flight breakpoints.
15
+ * Fires a callback when a breakpoint's deadline is reached.
16
+ */
17
+ export declare class TimeoutManager {
18
+ private readonly tracked;
19
+ /**
20
+ * Register a timeout for a breakpoint.
21
+ * If the breakpoint is already tracked, the existing timeout is replaced.
22
+ */
23
+ trackBreakpoint(breakpointId: string, timeoutMs: number, onTimeout: TimeoutCallback): void;
24
+ /**
25
+ * Cancel timeout tracking for a breakpoint.
26
+ * Returns true if the breakpoint was being tracked.
27
+ */
28
+ cancelTracking(breakpointId: string): boolean;
29
+ /**
30
+ * Get the timeout status for a breakpoint.
31
+ * Returns undefined if the breakpoint is not being tracked.
32
+ */
33
+ getStatus(breakpointId: string): TimeoutStatus | undefined;
34
+ /**
35
+ * Check if a specific breakpoint has timed out.
36
+ */
37
+ isTimedOut(breakpointId: string): boolean;
38
+ /**
39
+ * Get all currently tracked breakpoint IDs.
40
+ */
41
+ getTrackedIds(): string[];
42
+ /**
43
+ * Clear all timeouts and release resources.
44
+ */
45
+ dispose(): void;
46
+ }
47
+ //# sourceMappingURL=timeout-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeout-manager.d.ts","sourceRoot":"","sources":["../../src/client/timeout-manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;AAS7D;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAE7D;;;OAGG;IACH,eAAe,CACb,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,eAAe,GACzB,IAAI;IAsBP;;;OAGG;IACH,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAS7C;;;OAGG;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAY1D;;OAEG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO;IAIzC;;OAEG;IACH,aAAa,IAAI,MAAM,EAAE;IAIzB;;OAEG;IACH,OAAO,IAAI,IAAI;CAMhB"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Manages timeout tracking for in-flight breakpoints.
3
+ * Fires a callback when a breakpoint's deadline is reached.
4
+ */
5
+ export class TimeoutManager {
6
+ tracked = new Map();
7
+ /**
8
+ * Register a timeout for a breakpoint.
9
+ * If the breakpoint is already tracked, the existing timeout is replaced.
10
+ */
11
+ trackBreakpoint(breakpointId, timeoutMs, onTimeout) {
12
+ // Cancel any existing tracking
13
+ this.cancelTracking(breakpointId);
14
+ const expiresAt = Date.now() + timeoutMs;
15
+ const timer = setTimeout(() => {
16
+ const entry = this.tracked.get(breakpointId);
17
+ if (entry) {
18
+ entry.timedOut = true;
19
+ entry.callback(breakpointId);
20
+ }
21
+ }, timeoutMs);
22
+ this.tracked.set(breakpointId, {
23
+ timer,
24
+ expiresAt,
25
+ timedOut: false,
26
+ callback: onTimeout,
27
+ });
28
+ }
29
+ /**
30
+ * Cancel timeout tracking for a breakpoint.
31
+ * Returns true if the breakpoint was being tracked.
32
+ */
33
+ cancelTracking(breakpointId) {
34
+ const entry = this.tracked.get(breakpointId);
35
+ if (!entry)
36
+ return false;
37
+ clearTimeout(entry.timer);
38
+ this.tracked.delete(breakpointId);
39
+ return true;
40
+ }
41
+ /**
42
+ * Get the timeout status for a breakpoint.
43
+ * Returns undefined if the breakpoint is not being tracked.
44
+ */
45
+ getStatus(breakpointId) {
46
+ const entry = this.tracked.get(breakpointId);
47
+ if (!entry)
48
+ return undefined;
49
+ const remainingMs = Math.max(0, entry.expiresAt - Date.now());
50
+ return {
51
+ breakpointId,
52
+ timedOut: entry.timedOut,
53
+ remainingMs,
54
+ };
55
+ }
56
+ /**
57
+ * Check if a specific breakpoint has timed out.
58
+ */
59
+ isTimedOut(breakpointId) {
60
+ return this.tracked.get(breakpointId)?.timedOut ?? false;
61
+ }
62
+ /**
63
+ * Get all currently tracked breakpoint IDs.
64
+ */
65
+ getTrackedIds() {
66
+ return [...this.tracked.keys()];
67
+ }
68
+ /**
69
+ * Clear all timeouts and release resources.
70
+ */
71
+ dispose() {
72
+ for (const entry of this.tracked.values()) {
73
+ clearTimeout(entry.timer);
74
+ }
75
+ this.tracked.clear();
76
+ }
77
+ }
@@ -0,0 +1,20 @@
1
+ import type { RoutingConfig } from "./types.js";
2
+ export interface RepoConfigResolutionOptions {
3
+ repoRoot?: string;
4
+ configRoot?: string;
5
+ responderDir?: string;
6
+ startDir?: string;
7
+ }
8
+ export declare function resolveRepositoryRoot(startDir?: string): string | undefined;
9
+ export declare function resolveConfigRoot(options?: RepoConfigResolutionOptions): string;
10
+ export declare function resolveResponderDirectory(options?: RepoConfigResolutionOptions): string;
11
+ /**
12
+ * Returns the path to the routing.json config file.
13
+ */
14
+ export declare function resolveRoutingConfigPath(configRoot?: string): string;
15
+ /**
16
+ * Loads and validates routing configuration from `.a5c/routing.json`.
17
+ * Returns `undefined` when the file does not exist or fails validation.
18
+ */
19
+ export declare function loadRoutingConfigSync(configRoot?: string): RoutingConfig | undefined;
20
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,SAAgB,GAAG,MAAM,GAAG,SAAS,CAelF;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,2BAAgC,GAAG,MAAM,CAgBnF;AAED,wBAAgB,yBAAyB,CAAC,OAAO,GAAE,2BAAgC,GAAG,MAAM,CAuB3F;AAwBD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAiBpF"}
package/dist/config.js ADDED
@@ -0,0 +1,93 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { isAbsolute, join, resolve, dirname } from "node:path";
3
+ import { RoutingConfigSchema } from "./types.js";
4
+ export function resolveRepositoryRoot(startDir = process.cwd()) {
5
+ let current = resolve(startDir);
6
+ while (true) {
7
+ if (existsSync(join(current, ".git"))) {
8
+ return current;
9
+ }
10
+ const parent = dirname(current);
11
+ if (parent === current) {
12
+ return undefined;
13
+ }
14
+ current = parent;
15
+ }
16
+ }
17
+ export function resolveConfigRoot(options = {}) {
18
+ const startDir = resolve(options.startDir ?? process.cwd());
19
+ if (options.configRoot) {
20
+ return resolveAgainstKnownRoots(options.configRoot, options.repoRoot, startDir);
21
+ }
22
+ const repoRoot = options.repoRoot
23
+ ? resolveAgainstKnownRoots(options.repoRoot, undefined, startDir)
24
+ : resolveRepositoryRoot(startDir);
25
+ if (repoRoot) {
26
+ return join(repoRoot, ".a5c");
27
+ }
28
+ return join(startDir, ".a5c");
29
+ }
30
+ export function resolveResponderDirectory(options = {}) {
31
+ const startDir = resolve(options.startDir ?? process.cwd());
32
+ if (options.responderDir) {
33
+ if (isAbsolute(options.responderDir)) {
34
+ return options.responderDir;
35
+ }
36
+ const configRoot = options.configRoot
37
+ ? resolveAgainstKnownRoots(options.configRoot, options.repoRoot, startDir)
38
+ : undefined;
39
+ const repoRoot = options.repoRoot
40
+ ? resolveAgainstKnownRoots(options.repoRoot, undefined, startDir)
41
+ : (configRoot ? dirname(configRoot) : undefined);
42
+ if (configRoot && !looksLikeRepoRelativeA5cPath(options.responderDir)) {
43
+ return resolve(configRoot, options.responderDir);
44
+ }
45
+ return resolveAgainstKnownRoots(options.responderDir, repoRoot, startDir);
46
+ }
47
+ return join(resolveConfigRoot(options), "responder");
48
+ }
49
+ function resolveAgainstKnownRoots(pathValue, repoRoot, startDir) {
50
+ if (isAbsolute(pathValue)) {
51
+ return pathValue;
52
+ }
53
+ if (repoRoot) {
54
+ const normalizedRepoRoot = isAbsolute(repoRoot) ? repoRoot : resolve(startDir, repoRoot);
55
+ return resolve(normalizedRepoRoot, pathValue);
56
+ }
57
+ const discoveredRepoRoot = resolveRepositoryRoot(startDir);
58
+ if (discoveredRepoRoot) {
59
+ return resolve(discoveredRepoRoot, pathValue);
60
+ }
61
+ return resolve(startDir, pathValue);
62
+ }
63
+ function looksLikeRepoRelativeA5cPath(pathValue) {
64
+ return pathValue === ".a5c" || pathValue.startsWith(`.a5c/`) || pathValue.startsWith(`.a5c\\`);
65
+ }
66
+ /**
67
+ * Returns the path to the routing.json config file.
68
+ */
69
+ export function resolveRoutingConfigPath(configRoot) {
70
+ const root = configRoot ?? resolveConfigRoot();
71
+ return join(root, "routing.json");
72
+ }
73
+ /**
74
+ * Loads and validates routing configuration from `.a5c/routing.json`.
75
+ * Returns `undefined` when the file does not exist or fails validation.
76
+ */
77
+ export function loadRoutingConfigSync(configRoot) {
78
+ const configPath = resolveRoutingConfigPath(configRoot);
79
+ if (!existsSync(configPath)) {
80
+ return undefined;
81
+ }
82
+ try {
83
+ const raw = JSON.parse(readFileSync(configPath, "utf-8"));
84
+ const result = RoutingConfigSchema.safeParse(raw);
85
+ if (result.success) {
86
+ return result.data;
87
+ }
88
+ return undefined;
89
+ }
90
+ catch {
91
+ return undefined;
92
+ }
93
+ }
@@ -0,0 +1,4 @@
1
+ export { BreakpointMuxInteractionProvider, } from "./interaction-provider.js";
2
+ export type { BreakpointMuxProviderOptions } from "./interaction-provider.js";
3
+ export { loadRoutingConfig } from "./routing-rules.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gCAAgC,GACjC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAE9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { BreakpointMuxInteractionProvider, } from "./interaction-provider.js";
2
+ export { loadRoutingConfig } from "./routing-rules.js";
@@ -0,0 +1,71 @@
1
+ import type { BreakpointBackend } from "../backend.js";
2
+ import type { InteractionKind } from "../types.js";
3
+ import type { RoutingConfig } from "../types.js";
4
+ /**
5
+ * Options for configuring the interaction provider.
6
+ */
7
+ export interface BreakpointMuxProviderOptions {
8
+ /** The default backend to use when no routing rule matches. */
9
+ defaultBackend: BreakpointBackend;
10
+ /** Additional backends available for routing. Keyed by backend name. */
11
+ backends?: Record<string, BreakpointBackend>;
12
+ /** Routing configuration for domain/tag-based backend selection. */
13
+ routingConfig?: RoutingConfig;
14
+ /** Default timeout in ms. */
15
+ defaultTimeoutMs?: number;
16
+ }
17
+ /**
18
+ * Maps a babysitter ProcessContext.breakpoint() call to a tasks-adapter
19
+ * backend call, handling routing, context assembly, and result mapping.
20
+ */
21
+ export declare class BreakpointMuxInteractionProvider {
22
+ private defaultBackend;
23
+ private backends;
24
+ private routingConfig?;
25
+ private defaultTimeoutMs;
26
+ constructor(options: BreakpointMuxProviderOptions);
27
+ /**
28
+ * Route a breakpoint through the appropriate backend.
29
+ *
30
+ * This method is called from the babysitter harness when a process
31
+ * invokes `ctx.breakpoint(payload, options)`.
32
+ *
33
+ * @param payload - The breakpoint payload from the process context.
34
+ * @param options - Breakpoint routing options from the process context.
35
+ * @returns A BreakpointResult compatible with babysitter's ProcessContext.
36
+ */
37
+ handleBreakpoint(payload: unknown, options: {
38
+ label?: string;
39
+ expert?: string | string[];
40
+ tags?: string[];
41
+ strategy?: string;
42
+ breakpointId?: string;
43
+ autoApproveAfterN?: number;
44
+ presentAlwaysApprove?: boolean;
45
+ interactionKind?: InteractionKind;
46
+ domain?: string;
47
+ timeoutMs?: number;
48
+ }): Promise<{
49
+ approved: boolean;
50
+ response?: string;
51
+ feedback?: string;
52
+ respondedBy?: string;
53
+ }>;
54
+ /**
55
+ * Resolve the backend using routing configuration.
56
+ */
57
+ private resolveBackend;
58
+ /**
59
+ * Check if a routing rule matches the given domain and tags.
60
+ */
61
+ private matchesRule;
62
+ /**
63
+ * Build a BreakpointContext from the process payload and options.
64
+ */
65
+ private buildContext;
66
+ /**
67
+ * Extract a text summary from an arbitrary payload.
68
+ */
69
+ private extractTextFromPayload;
70
+ }
71
+ //# sourceMappingURL=interaction-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interaction-provider.d.ts","sourceRoot":"","sources":["../../src/harness/interaction-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,aAAa,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+DAA+D;IAC/D,cAAc,EAAE,iBAAiB,CAAC;IAClC,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,oEAAoE;IACpE,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,6BAA6B;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,gCAAgC;IAC3C,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,QAAQ,CAAoC;IACpD,OAAO,CAAC,aAAa,CAAC,CAAgB;IACtC,OAAO,CAAC,gBAAgB,CAAS;gBAErB,OAAO,EAAE,4BAA4B;IAUjD;;;;;;;;;OASG;IACG,gBAAgB,CACpB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;QAC/B,eAAe,CAAC,EAAE,eAAe,CAAC;QAClC,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GACA,OAAO,CAAC;QACT,QAAQ,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IA2CF;;OAEG;IACH,OAAO,CAAC,cAAc;IAatB;;OAEG;IACH,OAAO,CAAC,WAAW;IAcnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAkBpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;CAU/B"}