exempclaw 0.4.0

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 (201) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +306 -0
  3. package/dist/agent/agent.d.ts +91 -0
  4. package/dist/agent/agent.js +258 -0
  5. package/dist/agent/agent.js.map +1 -0
  6. package/dist/agent/config.d.ts +49 -0
  7. package/dist/agent/config.js +58 -0
  8. package/dist/agent/config.js.map +1 -0
  9. package/dist/agent/persona.d.ts +39 -0
  10. package/dist/agent/persona.js +81 -0
  11. package/dist/agent/persona.js.map +1 -0
  12. package/dist/agents/registry.d.ts +21 -0
  13. package/dist/agents/registry.js +51 -0
  14. package/dist/agents/registry.js.map +1 -0
  15. package/dist/cli/approve.d.ts +17 -0
  16. package/dist/cli/approve.js +50 -0
  17. package/dist/cli/approve.js.map +1 -0
  18. package/dist/cli/chat.d.ts +16 -0
  19. package/dist/cli/chat.js +148 -0
  20. package/dist/cli/chat.js.map +1 -0
  21. package/dist/cli/demo.d.ts +7 -0
  22. package/dist/cli/demo.js +82 -0
  23. package/dist/cli/demo.js.map +1 -0
  24. package/dist/cli/init.d.ts +17 -0
  25. package/dist/cli/init.js +89 -0
  26. package/dist/cli/init.js.map +1 -0
  27. package/dist/cli/live.d.ts +10 -0
  28. package/dist/cli/live.js +109 -0
  29. package/dist/cli/live.js.map +1 -0
  30. package/dist/cli/offline.d.ts +23 -0
  31. package/dist/cli/offline.js +236 -0
  32. package/dist/cli/offline.js.map +1 -0
  33. package/dist/cli/probe.d.ts +23 -0
  34. package/dist/cli/probe.js +140 -0
  35. package/dist/cli/probe.js.map +1 -0
  36. package/dist/cli/render.d.ts +15 -0
  37. package/dist/cli/render.js +50 -0
  38. package/dist/cli/render.js.map +1 -0
  39. package/dist/cli/tui.d.ts +101 -0
  40. package/dist/cli/tui.js +334 -0
  41. package/dist/cli/tui.js.map +1 -0
  42. package/dist/config/index.d.ts +33 -0
  43. package/dist/config/index.js +48 -0
  44. package/dist/config/index.js.map +1 -0
  45. package/dist/connectors/connector.d.ts +58 -0
  46. package/dist/connectors/connector.js +30 -0
  47. package/dist/connectors/connector.js.map +1 -0
  48. package/dist/connectors/email/email-connector.d.ts +43 -0
  49. package/dist/connectors/email/email-connector.js +364 -0
  50. package/dist/connectors/email/email-connector.js.map +1 -0
  51. package/dist/connectors/github/github-connector.d.ts +52 -0
  52. package/dist/connectors/github/github-connector.js +271 -0
  53. package/dist/connectors/github/github-connector.js.map +1 -0
  54. package/dist/connectors/http.d.ts +34 -0
  55. package/dist/connectors/http.js +78 -0
  56. package/dist/connectors/http.js.map +1 -0
  57. package/dist/connectors/index.d.ts +34 -0
  58. package/dist/connectors/index.js +86 -0
  59. package/dist/connectors/index.js.map +1 -0
  60. package/dist/connectors/notion/notion-connector.d.ts +45 -0
  61. package/dist/connectors/notion/notion-connector.js +222 -0
  62. package/dist/connectors/notion/notion-connector.js.map +1 -0
  63. package/dist/connectors/slack/slack-connector.d.ts +43 -0
  64. package/dist/connectors/slack/slack-connector.js +291 -0
  65. package/dist/connectors/slack/slack-connector.js.map +1 -0
  66. package/dist/core/errors.d.ts +36 -0
  67. package/dist/core/errors.js +40 -0
  68. package/dist/core/errors.js.map +1 -0
  69. package/dist/core/logger.d.ts +14 -0
  70. package/dist/core/logger.js +44 -0
  71. package/dist/core/logger.js.map +1 -0
  72. package/dist/core/run-log.d.ts +37 -0
  73. package/dist/core/run-log.js +37 -0
  74. package/dist/core/run-log.js.map +1 -0
  75. package/dist/core/usage.d.ts +22 -0
  76. package/dist/core/usage.js +58 -0
  77. package/dist/core/usage.js.map +1 -0
  78. package/dist/dashboard/data.d.ts +62 -0
  79. package/dist/dashboard/data.js +84 -0
  80. package/dist/dashboard/data.js.map +1 -0
  81. package/dist/dashboard/page.d.ts +9 -0
  82. package/dist/dashboard/page.js +421 -0
  83. package/dist/dashboard/page.js.map +1 -0
  84. package/dist/dashboard/server.d.ts +19 -0
  85. package/dist/dashboard/server.js +44 -0
  86. package/dist/dashboard/server.js.map +1 -0
  87. package/dist/demo/bootstrap.d.ts +25 -0
  88. package/dist/demo/bootstrap.js +60 -0
  89. package/dist/demo/bootstrap.js.map +1 -0
  90. package/dist/demo/claude.d.ts +31 -0
  91. package/dist/demo/claude.js +230 -0
  92. package/dist/demo/claude.js.map +1 -0
  93. package/dist/demo/demo-connector.d.ts +19 -0
  94. package/dist/demo/demo-connector.js +168 -0
  95. package/dist/demo/demo-connector.js.map +1 -0
  96. package/dist/demo/world.d.ts +60 -0
  97. package/dist/demo/world.js +117 -0
  98. package/dist/demo/world.js.map +1 -0
  99. package/dist/index.d.ts +2 -0
  100. package/dist/index.js +396 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/ingest/ingest.d.ts +63 -0
  103. package/dist/ingest/ingest.js +258 -0
  104. package/dist/ingest/ingest.js.map +1 -0
  105. package/dist/llm/claude.d.ts +97 -0
  106. package/dist/llm/claude.js +163 -0
  107. package/dist/llm/claude.js.map +1 -0
  108. package/dist/memory/compaction.d.ts +22 -0
  109. package/dist/memory/compaction.js +79 -0
  110. package/dist/memory/compaction.js.map +1 -0
  111. package/dist/memory/file-store.d.ts +28 -0
  112. package/dist/memory/file-store.js +110 -0
  113. package/dist/memory/file-store.js.map +1 -0
  114. package/dist/memory/store.d.ts +32 -0
  115. package/dist/memory/store.js +2 -0
  116. package/dist/memory/store.js.map +1 -0
  117. package/dist/orchestrator/orchestrator.d.ts +63 -0
  118. package/dist/orchestrator/orchestrator.js +181 -0
  119. package/dist/orchestrator/orchestrator.js.map +1 -0
  120. package/dist/orchestrator/scheduler.d.ts +33 -0
  121. package/dist/orchestrator/scheduler.js +67 -0
  122. package/dist/orchestrator/scheduler.js.map +1 -0
  123. package/dist/orchestrator/seen-events.d.ts +21 -0
  124. package/dist/orchestrator/seen-events.js +71 -0
  125. package/dist/orchestrator/seen-events.js.map +1 -0
  126. package/dist/plugins/apply.d.ts +9 -0
  127. package/dist/plugins/apply.js +17 -0
  128. package/dist/plugins/apply.js.map +1 -0
  129. package/dist/plugins/define.d.ts +29 -0
  130. package/dist/plugins/define.js +30 -0
  131. package/dist/plugins/define.js.map +1 -0
  132. package/dist/plugins/loader.d.ts +31 -0
  133. package/dist/plugins/loader.js +61 -0
  134. package/dist/plugins/loader.js.map +1 -0
  135. package/dist/plugins/scaffold.d.ts +5 -0
  136. package/dist/plugins/scaffold.js +72 -0
  137. package/dist/plugins/scaffold.js.map +1 -0
  138. package/dist/tools/builtin.d.ts +8 -0
  139. package/dist/tools/builtin.js +63 -0
  140. package/dist/tools/builtin.js.map +1 -0
  141. package/dist/tools/tool.d.ts +84 -0
  142. package/dist/tools/tool.js +70 -0
  143. package/dist/tools/tool.js.map +1 -0
  144. package/dist/ui/agent-view.test.d.ts +1 -0
  145. package/dist/ui/agent-view.test.js +54 -0
  146. package/dist/ui/agent-view.test.js.map +1 -0
  147. package/dist/ui/agents-data.d.ts +7 -0
  148. package/dist/ui/agents-data.js +25 -0
  149. package/dist/ui/agents-data.js.map +1 -0
  150. package/dist/ui/app.d.ts +24 -0
  151. package/dist/ui/app.js +59 -0
  152. package/dist/ui/app.js.map +1 -0
  153. package/dist/ui/app.test.d.ts +1 -0
  154. package/dist/ui/app.test.js +47 -0
  155. package/dist/ui/app.test.js.map +1 -0
  156. package/dist/ui/components/key-hints.d.ts +4 -0
  157. package/dist/ui/components/key-hints.js +6 -0
  158. package/dist/ui/components/key-hints.js.map +1 -0
  159. package/dist/ui/components/menu.d.ts +11 -0
  160. package/dist/ui/components/menu.js +20 -0
  161. package/dist/ui/components/menu.js.map +1 -0
  162. package/dist/ui/create-wizard.test.d.ts +1 -0
  163. package/dist/ui/create-wizard.test.js +58 -0
  164. package/dist/ui/create-wizard.test.js.map +1 -0
  165. package/dist/ui/doctor-data.d.ts +6 -0
  166. package/dist/ui/doctor-data.js +29 -0
  167. package/dist/ui/doctor-data.js.map +1 -0
  168. package/dist/ui/history-data.d.ts +2 -0
  169. package/dist/ui/history-data.js +18 -0
  170. package/dist/ui/history-data.js.map +1 -0
  171. package/dist/ui/screens/agent.d.ts +8 -0
  172. package/dist/ui/screens/agent.js +95 -0
  173. package/dist/ui/screens/agent.js.map +1 -0
  174. package/dist/ui/screens/agents.d.ts +7 -0
  175. package/dist/ui/screens/agents.js +47 -0
  176. package/dist/ui/screens/agents.js.map +1 -0
  177. package/dist/ui/screens/create.d.ts +7 -0
  178. package/dist/ui/screens/create.js +141 -0
  179. package/dist/ui/screens/create.js.map +1 -0
  180. package/dist/ui/screens/doctor.d.ts +5 -0
  181. package/dist/ui/screens/doctor.js +13 -0
  182. package/dist/ui/screens/doctor.js.map +1 -0
  183. package/dist/ui/screens/history.d.ts +7 -0
  184. package/dist/ui/screens/history.js +50 -0
  185. package/dist/ui/screens/history.js.map +1 -0
  186. package/dist/ui/screens/home.d.ts +8 -0
  187. package/dist/ui/screens/home.js +35 -0
  188. package/dist/ui/screens/home.js.map +1 -0
  189. package/dist/ui/screens/plugins.d.ts +7 -0
  190. package/dist/ui/screens/plugins.js +40 -0
  191. package/dist/ui/screens/plugins.js.map +1 -0
  192. package/dist/ui/services.d.ts +33 -0
  193. package/dist/ui/services.js +67 -0
  194. package/dist/ui/services.js.map +1 -0
  195. package/dist/ui/start.d.ts +1 -0
  196. package/dist/ui/start.js +16 -0
  197. package/dist/ui/start.js.map +1 -0
  198. package/dist/ui/theme.d.ts +6 -0
  199. package/dist/ui/theme.js +26 -0
  200. package/dist/ui/theme.js.map +1 -0
  201. package/package.json +69 -0
@@ -0,0 +1,52 @@
1
+ import { type Connector, type ConnectorContext, type InboundEvent } from "../connector.js";
2
+ import { type FetchLike } from "../http.js";
3
+ import { type Tool } from "../../tools/tool.js";
4
+ /**
5
+ * GitHub connector over the REST API. Tools cover issue/PR triage and
6
+ * commenting; inbound events come from polling the configured repos
7
+ * (GITHUB_REPOS) for recently-updated issues — webhooks need a public
8
+ * endpoint, polling doesn't.
9
+ *
10
+ * Works with a fine-grained PAT that has Issues read/write on the target
11
+ * repos (plus "Read access to metadata").
12
+ */
13
+ interface GitHubIssue {
14
+ number: number;
15
+ title: string;
16
+ state: string;
17
+ body?: string | null;
18
+ user?: {
19
+ login: string;
20
+ } | null;
21
+ labels?: Array<{
22
+ name?: string;
23
+ } | string>;
24
+ comments?: number;
25
+ created_at: string;
26
+ updated_at: string;
27
+ html_url: string;
28
+ pull_request?: unknown;
29
+ }
30
+ export declare class GitHubConnector implements Connector {
31
+ private readonly fetchImpl?;
32
+ readonly id = "github";
33
+ private log;
34
+ private api;
35
+ private selfLogin;
36
+ private repos;
37
+ private pollMs;
38
+ /** repo#number → epoch ms of the agent's own last write, for loop suppression. */
39
+ private readonly selfActions;
40
+ constructor(fetchImpl?: FetchLike | undefined);
41
+ init(ctx: ConnectorContext): Promise<void>;
42
+ private resolveRepo;
43
+ tools(): Tool[];
44
+ /** Polls configured repos for updated issues and surfaces them as events. */
45
+ listen(onEvent: (event: InboundEvent) => void, signal: AbortSignal): Promise<void>;
46
+ /** Maps an updated issue to an InboundEvent, suppressing our own echoes. */
47
+ issueToInbound(repo: string, issue: GitHubIssue, since: string): InboundEvent | null;
48
+ private recordSelfAction;
49
+ /** True if the agent itself just wrote to this issue (poll echo window). */
50
+ isRecentSelfAction(repo: string, number: number, now?: number): boolean;
51
+ }
52
+ export {};
@@ -0,0 +1,271 @@
1
+ import { z } from "zod";
2
+ import { sleep } from "../connector.js";
3
+ import { HttpJson } from "../http.js";
4
+ import { ConnectorError } from "../../core/errors.js";
5
+ import { defineTool } from "../../tools/tool.js";
6
+ const REPO_RE = /^[\w.-]+\/[\w.-]+$/;
7
+ export class GitHubConnector {
8
+ fetchImpl;
9
+ id = "github";
10
+ log;
11
+ api;
12
+ selfLogin = "";
13
+ repos = [];
14
+ pollMs = 60_000;
15
+ /** repo#number → epoch ms of the agent's own last write, for loop suppression. */
16
+ selfActions = new Map();
17
+ constructor(fetchImpl) {
18
+ this.fetchImpl = fetchImpl;
19
+ }
20
+ async init(ctx) {
21
+ this.log = ctx.log.child({ scope: "connector", connector: this.id });
22
+ const token = ctx.config.token;
23
+ if (!token) {
24
+ throw new ConnectorError(this.id, "missing GITHUB_TOKEN (fine-grained PAT with Issues read/write)");
25
+ }
26
+ this.repos = (ctx.config.repos ?? "")
27
+ .split(",")
28
+ .map((r) => r.trim())
29
+ .filter(Boolean);
30
+ for (const repo of this.repos) {
31
+ if (!REPO_RE.test(repo))
32
+ throw new ConnectorError(this.id, `invalid repo in GITHUB_REPOS: "${repo}" (use owner/name)`);
33
+ }
34
+ const pollSeconds = Number(ctx.config.pollSeconds ?? 60);
35
+ this.pollMs = Math.max(15, pollSeconds) * 1000;
36
+ this.api = new HttpJson({
37
+ connector: this.id,
38
+ baseUrl: "https://api.github.com",
39
+ headers: {
40
+ authorization: `Bearer ${token}`,
41
+ accept: "application/vnd.github+json",
42
+ "x-github-api-version": "2022-11-28",
43
+ "user-agent": "exempclaw",
44
+ },
45
+ fetchImpl: this.fetchImpl,
46
+ });
47
+ const me = await this.api.get("/user");
48
+ this.selfLogin = me.login;
49
+ this.log.info("github connected", { as: me.login, repos: this.repos.join(",") || "none" });
50
+ }
51
+ resolveRepo(repo) {
52
+ const resolved = repo ?? this.repos[0];
53
+ if (!resolved) {
54
+ throw new ConnectorError(this.id, "no repo given and GITHUB_REPOS is not configured");
55
+ }
56
+ if (!REPO_RE.test(resolved))
57
+ throw new ConnectorError(this.id, `invalid repo "${resolved}" (use owner/name)`);
58
+ return resolved;
59
+ }
60
+ tools() {
61
+ const listIssues = defineTool({
62
+ name: "github_list_issues",
63
+ description: "List recent issues in a repository, most recently updated first.",
64
+ schema: z.object({
65
+ repo: z.string().optional().describe("owner/name; defaults to the first configured repo."),
66
+ state: z.enum(["open", "closed", "all"]).default("open"),
67
+ limit: z.number().int().min(1).max(50).default(20),
68
+ includePullRequests: z.boolean().default(false),
69
+ }),
70
+ execute: async (input, ctx) => {
71
+ const repo = this.resolveRepo(input.repo);
72
+ const issues = await this.api.get(`/repos/${repo}/issues`, {
73
+ query: { state: input.state, sort: "updated", direction: "desc", per_page: input.limit },
74
+ signal: ctx.signal,
75
+ });
76
+ const filtered = issues.filter((i) => input.includePullRequests || !i.pull_request);
77
+ if (filtered.length === 0)
78
+ return { content: `No ${input.state} issues in ${repo}.` };
79
+ return {
80
+ content: filtered
81
+ .map((i) => `#${i.number} [${i.state}]${i.pull_request ? " [PR]" : ""} ${i.title} (by ${i.user?.login ?? "?"}, updated ${i.updated_at})${renderLabels(i)}`)
82
+ .join("\n"),
83
+ };
84
+ },
85
+ });
86
+ const readIssue = defineTool({
87
+ name: "github_read_issue",
88
+ description: "Read one issue or pull request, including its recent comments.",
89
+ schema: z.object({
90
+ repo: z.string().optional(),
91
+ number: z.number().int().min(1),
92
+ }),
93
+ execute: async (input, ctx) => {
94
+ const repo = this.resolveRepo(input.repo);
95
+ const issue = await this.api.get(`/repos/${repo}/issues/${input.number}`, {
96
+ signal: ctx.signal,
97
+ });
98
+ const comments = await this.api.get(`/repos/${repo}/issues/${input.number}/comments`, {
99
+ query: { per_page: 30 },
100
+ signal: ctx.signal,
101
+ });
102
+ const lines = [
103
+ `#${issue.number} [${issue.state}] ${issue.title}`,
104
+ `by ${issue.user?.login ?? "?"} · created ${issue.created_at} · updated ${issue.updated_at}${renderLabels(issue)}`,
105
+ issue.html_url,
106
+ "",
107
+ truncate(issue.body ?? "(no description)", 4000),
108
+ ];
109
+ if (comments.length > 0) {
110
+ lines.push("", `--- comments (${comments.length}) ---`);
111
+ for (const c of comments) {
112
+ lines.push(`[${c.created_at}] ${c.user?.login ?? "?"}: ${truncate(c.body ?? "", 1500)}`);
113
+ }
114
+ }
115
+ return { content: lines.join("\n") };
116
+ },
117
+ });
118
+ const comment = defineTool({
119
+ name: "github_comment",
120
+ description: "Comment on an issue or pull request. Acts outward; requires approval.",
121
+ outward: true,
122
+ schema: z.object({
123
+ repo: z.string().optional(),
124
+ number: z.number().int().min(1),
125
+ body: z.string().min(1),
126
+ }),
127
+ execute: async (input, ctx) => {
128
+ const repo = this.resolveRepo(input.repo);
129
+ const res = await this.api.post(`/repos/${repo}/issues/${input.number}/comments`, {
130
+ body: { body: input.body },
131
+ signal: ctx.signal,
132
+ });
133
+ this.recordSelfAction(repo, input.number);
134
+ return { content: `Commented on ${repo}#${input.number}: ${res.html_url}` };
135
+ },
136
+ });
137
+ const updateIssue = defineTool({
138
+ name: "github_update_issue",
139
+ description: "Close or reopen an issue, and/or add labels to it. Acts outward; requires approval.",
140
+ outward: true,
141
+ schema: z
142
+ .object({
143
+ repo: z.string().optional(),
144
+ number: z.number().int().min(1),
145
+ state: z.enum(["open", "closed"]).optional(),
146
+ addLabels: z.array(z.string()).default([]),
147
+ })
148
+ .refine((v) => v.state !== undefined || v.addLabels.length > 0, {
149
+ message: "give a state and/or labels to add",
150
+ }),
151
+ execute: async (input, ctx) => {
152
+ const repo = this.resolveRepo(input.repo);
153
+ const did = [];
154
+ if (input.state) {
155
+ await this.api.patch(`/repos/${repo}/issues/${input.number}`, {
156
+ body: { state: input.state },
157
+ signal: ctx.signal,
158
+ });
159
+ did.push(input.state === "closed" ? "closed" : "reopened");
160
+ }
161
+ if (input.addLabels.length > 0) {
162
+ await this.api.post(`/repos/${repo}/issues/${input.number}/labels`, {
163
+ body: { labels: input.addLabels },
164
+ signal: ctx.signal,
165
+ });
166
+ did.push(`labeled [${input.addLabels.join(", ")}]`);
167
+ }
168
+ this.recordSelfAction(repo, input.number);
169
+ return { content: `${repo}#${input.number}: ${did.join(", ")}.` };
170
+ },
171
+ });
172
+ const createIssue = defineTool({
173
+ name: "github_create_issue",
174
+ description: "Open a new issue. Acts outward; requires approval.",
175
+ outward: true,
176
+ schema: z.object({
177
+ repo: z.string().optional(),
178
+ title: z.string().min(1),
179
+ body: z.string().default(""),
180
+ labels: z.array(z.string()).default([]),
181
+ }),
182
+ execute: async (input, ctx) => {
183
+ const repo = this.resolveRepo(input.repo);
184
+ const res = await this.api.post(`/repos/${repo}/issues`, {
185
+ body: { title: input.title, body: input.body, ...(input.labels.length ? { labels: input.labels } : {}) },
186
+ signal: ctx.signal,
187
+ });
188
+ this.recordSelfAction(repo, res.number);
189
+ return { content: `Created ${repo}#${res.number}: ${res.html_url}` };
190
+ },
191
+ });
192
+ return [listIssues, readIssue, comment, updateIssue, createIssue];
193
+ }
194
+ /** Polls configured repos for updated issues and surfaces them as events. */
195
+ async listen(onEvent, signal) {
196
+ if (this.repos.length === 0) {
197
+ this.log.warn("GITHUB_REPOS not set — github inbound events disabled (tools still work)");
198
+ return;
199
+ }
200
+ // Start from "now": don't replay the backlog on every restart.
201
+ let since = new Date().toISOString();
202
+ this.log.info("github polling started", { repos: this.repos.join(","), everyMs: this.pollMs });
203
+ while (!signal.aborted) {
204
+ await sleep(this.pollMs, signal);
205
+ if (signal.aborted)
206
+ break;
207
+ const cycleStart = new Date().toISOString();
208
+ for (const repo of this.repos) {
209
+ try {
210
+ const issues = await this.api.get(`/repos/${repo}/issues`, {
211
+ query: { state: "all", sort: "updated", direction: "desc", per_page: 20, since },
212
+ signal,
213
+ });
214
+ for (const issue of issues) {
215
+ const event = this.issueToInbound(repo, issue, since);
216
+ if (event)
217
+ onEvent(event);
218
+ }
219
+ }
220
+ catch (err) {
221
+ if (signal.aborted)
222
+ break;
223
+ this.log.warn("github poll failed", { repo, error: err.message });
224
+ }
225
+ }
226
+ since = cycleStart;
227
+ }
228
+ }
229
+ /** Maps an updated issue to an InboundEvent, suppressing our own echoes. */
230
+ issueToInbound(repo, issue, since) {
231
+ if (this.isRecentSelfAction(repo, issue.number))
232
+ return null;
233
+ const isNew = issue.created_at >= since;
234
+ if (isNew && issue.user?.login === this.selfLogin)
235
+ return null;
236
+ return {
237
+ connector: this.id,
238
+ type: isNew ? "github.issue_opened" : "github.issue_updated",
239
+ eventId: `${repo}#${issue.number}@${issue.updated_at}`,
240
+ threadId: `${repo}#${issue.number}`,
241
+ summary: [
242
+ `${isNew ? "New" : "Updated"} ${issue.pull_request ? "pull request" : "issue"} ${repo}#${issue.number}: ${issue.title}`,
243
+ `state=${issue.state} author=${issue.user?.login ?? "?"} updated=${issue.updated_at}`,
244
+ `Read it with github_read_issue (repo="${repo}", number=${issue.number}) before deciding whether to act.`,
245
+ isNew && issue.body ? `\n${truncate(issue.body, 1500)}` : "",
246
+ ]
247
+ .filter(Boolean)
248
+ .join("\n"),
249
+ payload: issue,
250
+ receivedAt: new Date().toISOString(),
251
+ };
252
+ }
253
+ recordSelfAction(repo, number) {
254
+ this.selfActions.set(`${repo}#${number}`, Date.now());
255
+ }
256
+ /** True if the agent itself just wrote to this issue (poll echo window). */
257
+ isRecentSelfAction(repo, number, now = Date.now()) {
258
+ const at = this.selfActions.get(`${repo}#${number}`);
259
+ return at !== undefined && now - at < 2 * this.pollMs;
260
+ }
261
+ }
262
+ function renderLabels(issue) {
263
+ const names = (issue.labels ?? [])
264
+ .map((l) => (typeof l === "string" ? l : (l.name ?? "")))
265
+ .filter(Boolean);
266
+ return names.length ? ` [${names.join(", ")}]` : "";
267
+ }
268
+ function truncate(text, max) {
269
+ return text.length > max ? `${text.slice(0, max)}…` : text;
270
+ }
271
+ //# sourceMappingURL=github-connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-connector.js","sourceRoot":"","sources":["../../../src/connectors/github/github-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAA4D,MAAM,iBAAiB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAkB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAa,MAAM,qBAAqB,CAAC;AAiC5D,MAAM,OAAO,GAAG,oBAAoB,CAAC;AAErC,MAAM,OAAO,eAAe;IAUG;IATpB,EAAE,GAAG,QAAQ,CAAC;IACf,GAAG,CAAU;IACb,GAAG,CAAY;IACf,SAAS,GAAG,EAAE,CAAC;IACf,KAAK,GAAa,EAAE,CAAC;IACrB,MAAM,GAAG,MAAM,CAAC;IACxB,kFAAkF;IACjE,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEzD,YAA6B,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI,CAAC,GAAqB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,gEAAgE,CAAC,CAAC;QACtG,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;aAClC,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;QACnB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,kCAAkC,IAAI,oBAAoB,CAAC,CAAC;QACzH,CAAC;QACD,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC;QAE/C,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC;YACtB,SAAS,EAAE,IAAI,CAAC,EAAE;YAClB,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,MAAM,EAAE,6BAA6B;gBACrC,sBAAsB,EAAE,YAAY;gBACpC,YAAY,EAAE,WAAW;aAC1B;YACD,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAoB,OAAO,CAAC,CAAC;QAC1D,IAAI,CAAC,SAAS,GAAG,EAAE,CAAC,KAAK,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,MAAM,EAAE,CAAC,CAAC;IAC7F,CAAC;IAEO,WAAW,CAAC,IAAa;QAC/B,MAAM,QAAQ,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,kDAAkD,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,QAAQ,oBAAoB,CAAC,CAAC;QAC9G,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,KAAK;QACH,MAAM,UAAU,GAAG,UAAU,CAAC;YAC5B,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,kEAAkE;YAC/E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,oDAAoD,CAAC;gBAC1F,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBACxD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClD,mBAAmB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;aAChD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAgB,UAAU,IAAI,SAAS,EAAE;oBACxE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,KAAK,EAAE;oBACxF,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,mBAAmB,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBACpF,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,KAAK,cAAc,IAAI,GAAG,EAAE,CAAC;gBACtF,OAAO;oBACL,OAAO,EAAE,QAAQ;yBACd,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,aAAa,CAAC,CAAC,UAAU,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CACjJ;yBACA,IAAI,CAAC,IAAI,CAAC;iBACd,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,UAAU,CAAC;YAC3B,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,gEAAgE;YAC7E,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;aAChC,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAc,UAAU,IAAI,WAAW,KAAK,CAAC,MAAM,EAAE,EAAE;oBACrF,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAkB,UAAU,IAAI,WAAW,KAAK,CAAC,MAAM,WAAW,EAAE;oBACrG,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;oBACvB,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;gBACH,MAAM,KAAK,GAAG;oBACZ,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,KAAK,EAAE;oBAClD,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,cAAc,KAAK,CAAC,UAAU,cAAc,KAAK,CAAC,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,EAAE;oBAClH,KAAK,CAAC,QAAQ;oBACd,EAAE;oBACF,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,kBAAkB,EAAE,IAAI,CAAC;iBACjD,CAAC;gBACF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,iBAAiB,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;oBACxD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;wBACzB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;oBAC3F,CAAC;gBACH,CAAC;gBACD,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACvC,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,UAAU,CAAC;YACzB,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,uEAAuE;YACpF,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC/B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;aACxB,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAuB,UAAU,IAAI,WAAW,KAAK,CAAC,MAAM,WAAW,EAAE;oBACtG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE;oBAC1B,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;gBACH,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC1C,OAAO,EAAE,OAAO,EAAE,gBAAgB,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;YAC9E,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,UAAU,CAAC;YAC7B,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EAAE,qFAAqF;YAClG,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,CAAC;iBACN,MAAM,CAAC;gBACN,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBAC/B,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;gBAC5C,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;aAC3C,CAAC;iBACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC9D,OAAO,EAAE,mCAAmC;aAC7C,CAAC;YACJ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,GAAG,GAAa,EAAE,CAAC;gBACzB,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;oBAChB,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,WAAW,KAAK,CAAC,MAAM,EAAE,EAAE;wBAC5D,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;wBAC5B,MAAM,EAAE,GAAG,CAAC,MAAM;qBACnB,CAAC,CAAC;oBACH,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBAC7D,CAAC;gBACD,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC/B,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,KAAK,CAAC,MAAM,SAAS,EAAE;wBAClE,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,EAAE;wBACjC,MAAM,EAAE,GAAG,CAAC,MAAM;qBACnB,CAAC,CAAC;oBACH,GAAG,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtD,CAAC;gBACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC1C,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACpE,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,UAAU,CAAC;YAC7B,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EAAE,oDAAoD;YACjE,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACxB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;aACxC,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC1C,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAuC,UAAU,IAAI,SAAS,EAAE;oBAC7F,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;oBACxG,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB,CAAC,CAAC;gBACH,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACxC,OAAO,EAAE,OAAO,EAAE,WAAW,IAAI,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC;YACvE,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;IACpE,CAAC;IAED,6EAA6E;IAC7E,KAAK,CAAC,MAAM,CAAC,OAAsC,EAAE,MAAmB;QACtE,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;YAC1F,OAAO;QACT,CAAC;QACD,+DAA+D;QAC/D,IAAI,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAE/F,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACjC,IAAI,MAAM,CAAC,OAAO;gBAAE,MAAM;YAC1B,MAAM,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YAC5C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAgB,UAAU,IAAI,SAAS,EAAE;wBACxE,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE;wBAChF,MAAM;qBACP,CAAC,CAAC;oBACH,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;wBAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;wBACtD,IAAI,KAAK;4BAAE,OAAO,CAAC,KAAK,CAAC,CAAC;oBAC5B,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,MAAM,CAAC,OAAO;wBAAE,MAAM;oBAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,IAAI,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/E,CAAC;YACH,CAAC;YACD,KAAK,GAAG,UAAU,CAAC;QACrB,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,cAAc,CAAC,IAAY,EAAE,KAAkB,EAAE,KAAa;QAC5D,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC;QACxC,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC,SAAS;YAAE,OAAO,IAAI,CAAC;QAC/D,OAAO;YACL,SAAS,EAAE,IAAI,CAAC,EAAE;YAClB,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,sBAAsB;YAC5D,OAAO,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,UAAU,EAAE;YACtD,QAAQ,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,MAAM,EAAE;YACnC,OAAO,EAAE;gBACP,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,KAAK,EAAE;gBACvH,SAAS,KAAK,CAAC,KAAK,WAAW,KAAK,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,YAAY,KAAK,CAAC,UAAU,EAAE;gBACrF,yCAAyC,IAAI,aAAa,KAAK,CAAC,MAAM,mCAAmC;gBACzG,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE;aAC7D;iBACE,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,KAAK;YACd,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACrC,CAAC;IACJ,CAAC;IAEO,gBAAgB,CAAC,IAAY,EAAE,MAAc;QACnD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,MAAM,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACxD,CAAC;IAED,4EAA4E;IAC5E,kBAAkB,CAAC,IAAY,EAAE,MAAc,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;QAC/D,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,MAAM,EAAE,CAAC,CAAC;QACrD,OAAO,EAAE,KAAK,SAAS,IAAI,GAAG,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;IACxD,CAAC;CACF;AAED,SAAS,YAAY,CAAC,KAAkB;IACtC,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;SACxD,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AACtD,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,GAAW;IACzC,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Minimal JSON-over-HTTPS client shared by the fetch-based connectors
3
+ * (Slack, GitHub, Notion). Handles timeouts, 429/5xx retries with
4
+ * Retry-After, and maps failures to ConnectorError. The fetch implementation
5
+ * is injectable so connector logic is unit-testable without a network.
6
+ */
7
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
8
+ export interface HttpJsonOptions {
9
+ connector: string;
10
+ baseUrl: string;
11
+ headers?: Record<string, string>;
12
+ fetchImpl?: FetchLike;
13
+ timeoutMs?: number;
14
+ /** Max retries on 429/5xx. Default 2. */
15
+ maxRetries?: number;
16
+ }
17
+ export interface RequestOptions {
18
+ query?: Record<string, string | number | boolean | undefined>;
19
+ body?: unknown;
20
+ headers?: Record<string, string>;
21
+ signal?: AbortSignal;
22
+ }
23
+ export declare class HttpJson {
24
+ private readonly opts;
25
+ private readonly fetchImpl;
26
+ private readonly timeoutMs;
27
+ private readonly maxRetries;
28
+ constructor(opts: HttpJsonOptions);
29
+ get<T>(path: string, options?: RequestOptions): Promise<T>;
30
+ post<T>(path: string, options?: RequestOptions): Promise<T>;
31
+ patch<T>(path: string, options?: RequestOptions): Promise<T>;
32
+ request<T>(method: string, path: string, options?: RequestOptions): Promise<T>;
33
+ private buildUrl;
34
+ }
@@ -0,0 +1,78 @@
1
+ import { ConnectorError } from "../core/errors.js";
2
+ import { sleep } from "./connector.js";
3
+ export class HttpJson {
4
+ opts;
5
+ fetchImpl;
6
+ timeoutMs;
7
+ maxRetries;
8
+ constructor(opts) {
9
+ this.opts = opts;
10
+ this.fetchImpl = opts.fetchImpl ?? ((input, init) => fetch(input, init));
11
+ this.timeoutMs = opts.timeoutMs ?? 30_000;
12
+ this.maxRetries = opts.maxRetries ?? 2;
13
+ }
14
+ get(path, options = {}) {
15
+ return this.request("GET", path, options);
16
+ }
17
+ post(path, options = {}) {
18
+ return this.request("POST", path, options);
19
+ }
20
+ patch(path, options = {}) {
21
+ return this.request("PATCH", path, options);
22
+ }
23
+ async request(method, path, options = {}) {
24
+ const url = this.buildUrl(path, options.query);
25
+ for (let attempt = 0;; attempt++) {
26
+ const signal = options.signal
27
+ ? AbortSignal.any([options.signal, AbortSignal.timeout(this.timeoutMs)])
28
+ : AbortSignal.timeout(this.timeoutMs);
29
+ let response;
30
+ try {
31
+ response = await this.fetchImpl(url, {
32
+ method,
33
+ headers: {
34
+ accept: "application/json",
35
+ ...(options.body !== undefined ? { "content-type": "application/json" } : {}),
36
+ ...this.opts.headers,
37
+ ...options.headers,
38
+ },
39
+ ...(options.body !== undefined ? { body: JSON.stringify(options.body) } : {}),
40
+ signal,
41
+ });
42
+ }
43
+ catch (err) {
44
+ if (options.signal?.aborted)
45
+ throw err;
46
+ throw new ConnectorError(this.opts.connector, `request to ${path} failed: ${err.message}`, {
47
+ retryable: true,
48
+ cause: err,
49
+ });
50
+ }
51
+ if (response.ok) {
52
+ const text = await response.text();
53
+ return (text ? JSON.parse(text) : undefined);
54
+ }
55
+ const retryable = response.status === 429 || response.status >= 500;
56
+ if (retryable && attempt < this.maxRetries) {
57
+ const retryAfter = Number(response.headers.get("retry-after"));
58
+ const delayMs = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1000 : 500 * 2 ** attempt;
59
+ await sleep(delayMs, options.signal);
60
+ if (options.signal?.aborted) {
61
+ throw new ConnectorError(this.opts.connector, `request to ${path} aborted`, { retryable: false });
62
+ }
63
+ continue;
64
+ }
65
+ const detail = (await response.text().catch(() => "")).slice(0, 300);
66
+ throw new ConnectorError(this.opts.connector, `${method} ${path} → HTTP ${response.status}${detail ? `: ${detail}` : ""}`, { retryable });
67
+ }
68
+ }
69
+ buildUrl(path, query) {
70
+ const url = new URL(path.startsWith("http") ? path : `${this.opts.baseUrl}${path}`);
71
+ for (const [key, value] of Object.entries(query ?? {})) {
72
+ if (value !== undefined)
73
+ url.searchParams.set(key, String(value));
74
+ }
75
+ return url.toString();
76
+ }
77
+ }
78
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/connectors/http.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Connector } from "./connector.js";
2
+ export type { Connector, ConnectorContext, InboundEvent } from "./connector.js";
3
+ export { renderEventInput } from "./connector.js";
4
+ export interface ConnectorEnvKey {
5
+ /** Config field name handed to the connector. */
6
+ field: string;
7
+ /** Environment variable it is read from. */
8
+ env: string;
9
+ required: boolean;
10
+ note?: string;
11
+ }
12
+ export declare function availableConnectorIds(): string[];
13
+ /** Registers a plugin-provided connector. Throws on id collision. */
14
+ export declare function registerConnector(entry: {
15
+ id: string;
16
+ description: string;
17
+ envKeys: ConnectorEnvKey[];
18
+ make: () => Connector;
19
+ }): void;
20
+ export interface ConnectorStatus {
21
+ id: string;
22
+ description: string;
23
+ envKeys: Array<ConnectorEnvKey & {
24
+ set: boolean;
25
+ }>;
26
+ configured: boolean;
27
+ }
28
+ /** Reports each connector's env-var status for `exempclaw connectors`/`doctor`. */
29
+ export declare function connectorStatuses(env?: NodeJS.ProcessEnv): ConnectorStatus[];
30
+ /** Instantiates a connector by id and resolves its config from the environment. */
31
+ export declare function createConnector(id: string, env?: NodeJS.ProcessEnv): {
32
+ connector: Connector;
33
+ config: Record<string, string>;
34
+ };
@@ -0,0 +1,86 @@
1
+ import { EmailConnector } from "./email/email-connector.js";
2
+ import { SlackConnector } from "./slack/slack-connector.js";
3
+ import { NotionConnector } from "./notion/notion-connector.js";
4
+ import { GitHubConnector } from "./github/github-connector.js";
5
+ import { DemoConnector } from "../demo/demo-connector.js";
6
+ export { renderEventInput } from "./connector.js";
7
+ /** Maps a connector id to its constructor and the env vars it consumes. */
8
+ const REGISTRY = {
9
+ email: {
10
+ make: () => new EmailConnector(),
11
+ description: "IMAP inbox (read + live events) and SMTP send.",
12
+ envKeys: [
13
+ { field: "user", env: "EMAIL_USER", required: true },
14
+ { field: "password", env: "EMAIL_PASSWORD", required: true, note: "app password for Gmail/Workspace" },
15
+ { field: "imapHost", env: "EMAIL_IMAP_HOST", required: false, note: "needed for reading + events" },
16
+ { field: "imapPort", env: "EMAIL_IMAP_PORT", required: false },
17
+ { field: "smtpHost", env: "EMAIL_SMTP_HOST", required: false, note: "needed for sending" },
18
+ { field: "smtpPort", env: "EMAIL_SMTP_PORT", required: false },
19
+ { field: "from", env: "EMAIL_FROM", required: false, note: "defaults to EMAIL_USER" },
20
+ ],
21
+ },
22
+ slack: {
23
+ make: () => new SlackConnector(),
24
+ description: "Slack Web API tools + Socket Mode mentions/DMs.",
25
+ envKeys: [
26
+ { field: "botToken", env: "SLACK_BOT_TOKEN", required: true, note: "xoxb-… bot token" },
27
+ { field: "appToken", env: "SLACK_APP_TOKEN", required: false, note: "xapp-… enables inbound events" },
28
+ ],
29
+ },
30
+ notion: {
31
+ make: () => new NotionConnector(),
32
+ description: "Notion search/read/write (share pages with the integration).",
33
+ envKeys: [{ field: "token", env: "NOTION_TOKEN", required: true, note: "internal integration secret" }],
34
+ },
35
+ github: {
36
+ make: () => new GitHubConnector(),
37
+ description: "GitHub issues/PRs; polls GITHUB_REPOS for inbound events.",
38
+ envKeys: [
39
+ { field: "token", env: "GITHUB_TOKEN", required: true, note: "fine-grained PAT, Issues read/write" },
40
+ { field: "repos", env: "GITHUB_REPOS", required: false, note: "comma-separated owner/name list" },
41
+ { field: "pollSeconds", env: "GITHUB_POLL_SECONDS", required: false, note: "default 60" },
42
+ ],
43
+ },
44
+ demo: {
45
+ make: () => new DemoConnector(),
46
+ description: "Fictional email+Slack workspace for demo mode and sandboxing. No credentials.",
47
+ envKeys: [],
48
+ },
49
+ };
50
+ export function availableConnectorIds() {
51
+ return Object.keys(REGISTRY);
52
+ }
53
+ /** Registers a plugin-provided connector. Throws on id collision. */
54
+ export function registerConnector(entry) {
55
+ if (REGISTRY[entry.id]) {
56
+ throw new Error(`connector "${entry.id}" already registered`);
57
+ }
58
+ REGISTRY[entry.id] = { make: entry.make, envKeys: entry.envKeys, description: entry.description };
59
+ }
60
+ /** Reports each connector's env-var status for `exempclaw connectors`/`doctor`. */
61
+ export function connectorStatuses(env = process.env) {
62
+ return Object.entries(REGISTRY).map(([id, entry]) => {
63
+ const envKeys = entry.envKeys.map((key) => ({ ...key, set: Boolean(env[key.env]) }));
64
+ return {
65
+ id,
66
+ description: entry.description,
67
+ envKeys,
68
+ configured: envKeys.filter((k) => k.required).every((k) => k.set),
69
+ };
70
+ });
71
+ }
72
+ /** Instantiates a connector by id and resolves its config from the environment. */
73
+ export function createConnector(id, env = process.env) {
74
+ const entry = REGISTRY[id];
75
+ if (!entry) {
76
+ throw new Error(`unknown connector "${id}". Available: ${availableConnectorIds().join(", ")}`);
77
+ }
78
+ const config = {};
79
+ for (const key of entry.envKeys) {
80
+ const value = env[key.env];
81
+ if (value)
82
+ config[key.field] = value;
83
+ }
84
+ return { connector: entry.make(), config };
85
+ }
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/connectors/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { Connector, ConnectorContext } from "../connector.js";
2
+ import { type FetchLike } from "../http.js";
3
+ import { type Tool } from "../../tools/tool.js";
4
+ interface RichText {
5
+ plain_text?: string;
6
+ }
7
+ interface NotionBlock {
8
+ id: string;
9
+ type: string;
10
+ has_children?: boolean;
11
+ [key: string]: unknown;
12
+ }
13
+ interface SearchResult {
14
+ id: string;
15
+ object: "page" | "database";
16
+ last_edited_time?: string;
17
+ url?: string;
18
+ properties?: Record<string, {
19
+ type?: string;
20
+ title?: RichText[];
21
+ }>;
22
+ title?: RichText[];
23
+ }
24
+ export declare class NotionConnector implements Connector {
25
+ private readonly fetchImpl?;
26
+ readonly id = "notion";
27
+ private log;
28
+ private api;
29
+ constructor(fetchImpl?: FetchLike | undefined);
30
+ init(ctx: ConnectorContext): Promise<void>;
31
+ tools(): Tool[];
32
+ }
33
+ /** Accepts dashed/undashed UUIDs or a Notion URL; returns a dashed UUID. */
34
+ export declare function normalizePageId(input: string): string | null;
35
+ export declare function resultTitle(result: SearchResult): string;
36
+ /** Renders one block to a plain-text line. Unknown types become markers. */
37
+ export declare function renderBlock(block: NotionBlock): string;
38
+ interface ParagraphBlock {
39
+ object: "block";
40
+ type: string;
41
+ [key: string]: unknown;
42
+ }
43
+ /** Converts simple markdown into Notion block objects. */
44
+ export declare function markdownToBlocks(markdown: string): ParagraphBlock[];
45
+ export {};