agentic-pi 0.1.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 (53) hide show
  1. package/README.md +418 -0
  2. package/dist/args.d.ts +31 -0
  3. package/dist/args.js +109 -0
  4. package/dist/args.js.map +1 -0
  5. package/dist/cli.d.ts +9 -0
  6. package/dist/cli.js +47 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/emitter.d.ts +49 -0
  9. package/dist/emitter.js +67 -0
  10. package/dist/emitter.js.map +1 -0
  11. package/dist/extensions/github/auth.d.ts +54 -0
  12. package/dist/extensions/github/auth.js +116 -0
  13. package/dist/extensions/github/auth.js.map +1 -0
  14. package/dist/extensions/github/client.d.ts +6387 -0
  15. package/dist/extensions/github/client.js +358 -0
  16. package/dist/extensions/github/client.js.map +1 -0
  17. package/dist/extensions/github/credentials.d.ts +24 -0
  18. package/dist/extensions/github/credentials.js +44 -0
  19. package/dist/extensions/github/credentials.js.map +1 -0
  20. package/dist/extensions/github/index.d.ts +46 -0
  21. package/dist/extensions/github/index.js +67 -0
  22. package/dist/extensions/github/index.js.map +1 -0
  23. package/dist/extensions/github/profiles.d.ts +17 -0
  24. package/dist/extensions/github/profiles.js +71 -0
  25. package/dist/extensions/github/profiles.js.map +1 -0
  26. package/dist/extensions/github/tools.d.ts +18 -0
  27. package/dist/extensions/github/tools.js +289 -0
  28. package/dist/extensions/github/tools.js.map +1 -0
  29. package/dist/index.d.ts +38 -0
  30. package/dist/index.js +34 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/models.d.ts +13 -0
  33. package/dist/models.js +31 -0
  34. package/dist/models.js.map +1 -0
  35. package/dist/run.d.ts +139 -0
  36. package/dist/run.js +131 -0
  37. package/dist/run.js.map +1 -0
  38. package/dist/runner.d.ts +22 -0
  39. package/dist/runner.js +143 -0
  40. package/dist/runner.js.map +1 -0
  41. package/dist/sandbox/gondolin.d.ts +39 -0
  42. package/dist/sandbox/gondolin.js +210 -0
  43. package/dist/sandbox/gondolin.js.map +1 -0
  44. package/dist/sandbox/index.d.ts +37 -0
  45. package/dist/sandbox/index.js +55 -0
  46. package/dist/sandbox/index.js.map +1 -0
  47. package/dist/sandbox/preflight.d.ts +24 -0
  48. package/dist/sandbox/preflight.js +93 -0
  49. package/dist/sandbox/preflight.js.map +1 -0
  50. package/dist/stdin.d.ts +1 -0
  51. package/dist/stdin.js +11 -0
  52. package/dist/stdin.js.map +1 -0
  53. package/package.json +44 -0
@@ -0,0 +1,358 @@
1
+ /**
2
+ * Thin wrapper around Octokit that refreshes the token automatically.
3
+ *
4
+ * Ported 1:1 from mcp-github-app/src/github.js with TypeScript types.
5
+ * All method names, parameters, and behaviour match the original — the goal
6
+ * is bit-compatible JSON responses so the dashboard shim keeps working.
7
+ */
8
+ import { Octokit } from "@octokit/rest";
9
+ const MAX_RETRIES = 3;
10
+ const BASE_DELAY_MS = 1000;
11
+ const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
12
+ /**
13
+ * LLMs that see optional fields in a tool's JSON Schema sometimes emit
14
+ * zero / empty-string values for ones they didn't actually want to set.
15
+ * Strip those before spreading into an Octokit call so the API only sees
16
+ * fields the agent meant to pass.
17
+ */
18
+ function omitFalsy(opts) {
19
+ const out = {};
20
+ for (const [k, v] of Object.entries(opts ?? {})) {
21
+ if (v === undefined || v === null || v === "" || v === 0)
22
+ continue;
23
+ if (Array.isArray(v) && v.length === 0)
24
+ continue;
25
+ out[k] = v;
26
+ }
27
+ return out;
28
+ }
29
+ export class GitHubClient {
30
+ auth;
31
+ _octokit = null;
32
+ _tokenUsed = null;
33
+ constructor(auth) {
34
+ this.auth = auth;
35
+ }
36
+ async octokit() {
37
+ const token = await this.auth.getToken();
38
+ if (token !== this._tokenUsed) {
39
+ this._octokit = new Octokit({ auth: token });
40
+ this._tokenUsed = token;
41
+ }
42
+ return this._octokit;
43
+ }
44
+ async withRetry(fn) {
45
+ let lastError;
46
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
47
+ try {
48
+ return await fn();
49
+ }
50
+ catch (err) {
51
+ lastError = err;
52
+ const e = err;
53
+ const status = e.status || e.response?.status;
54
+ if (status && status >= 400 && status < 500 && !RETRYABLE_STATUSES.has(status)) {
55
+ throw err;
56
+ }
57
+ if (attempt === MAX_RETRIES)
58
+ break;
59
+ let delayMs;
60
+ if (status === 429) {
61
+ const retryAfter = e.response?.headers?.["retry-after"];
62
+ delayMs = retryAfter ? parseInt(retryAfter, 10) * 1000 : BASE_DELAY_MS * Math.pow(2, attempt);
63
+ }
64
+ else {
65
+ delayMs = BASE_DELAY_MS * Math.pow(2, attempt);
66
+ }
67
+ if (status === 401) {
68
+ this._tokenUsed = null;
69
+ }
70
+ await new Promise((r) => setTimeout(r, delayMs));
71
+ }
72
+ }
73
+ throw lastError;
74
+ }
75
+ // ── Repositories ──────────────────────────────────────────────────
76
+ async getRepository(owner, repo) {
77
+ return this.withRetry(async () => {
78
+ const ok = await this.octokit();
79
+ const { data } = await ok.repos.get({ owner, repo });
80
+ return data;
81
+ });
82
+ }
83
+ async getFileContents(owner, repo, path, branch) {
84
+ return this.withRetry(async () => {
85
+ const ok = await this.octokit();
86
+ const params = { owner, repo, path };
87
+ if (branch)
88
+ params.ref = branch;
89
+ const { data } = await ok.repos.getContent(params);
90
+ if (typeof data === "object" && data !== null && "content" in data && typeof data.content === "string") {
91
+ data.decoded_content = Buffer.from(data.content, "base64").toString("utf8");
92
+ }
93
+ return data;
94
+ });
95
+ }
96
+ async createOrUpdateFile(owner, repo, path, content, message, branch, sha) {
97
+ return this.withRetry(async () => {
98
+ const ok = await this.octokit();
99
+ const params = {
100
+ owner, repo, path, message,
101
+ content: Buffer.from(content).toString("base64"),
102
+ };
103
+ if (branch)
104
+ params.branch = branch;
105
+ if (sha)
106
+ params.sha = sha;
107
+ const { data } = await ok.repos.createOrUpdateFileContents(params);
108
+ return data;
109
+ });
110
+ }
111
+ async pushFiles(owner, repo, branch, files, message) {
112
+ return this.withRetry(async () => {
113
+ const ok = await this.octokit();
114
+ let ref;
115
+ try {
116
+ const { data } = await ok.git.getRef({ owner, repo, ref: `heads/${branch}` });
117
+ ref = data;
118
+ }
119
+ catch {
120
+ const { data: repoData } = await ok.repos.get({ owner, repo });
121
+ const { data: defaultRef } = await ok.git.getRef({
122
+ owner, repo, ref: `heads/${repoData.default_branch}`,
123
+ });
124
+ const { data: newRef } = await ok.git.createRef({
125
+ owner, repo,
126
+ ref: `refs/heads/${branch}`,
127
+ sha: defaultRef.object.sha,
128
+ });
129
+ ref = newRef;
130
+ }
131
+ const blobs = await Promise.all(files.map(async (f) => {
132
+ const { data } = await ok.git.createBlob({
133
+ owner, repo, content: f.content, encoding: "utf-8",
134
+ });
135
+ return { path: f.path, sha: data.sha, mode: "100644", type: "blob" };
136
+ }));
137
+ const { data: tree } = await ok.git.createTree({
138
+ owner, repo, base_tree: ref.object.sha, tree: blobs,
139
+ });
140
+ const { data: commit } = await ok.git.createCommit({
141
+ owner, repo, message, tree: tree.sha, parents: [ref.object.sha],
142
+ });
143
+ const { data: updated } = await ok.git.updateRef({
144
+ owner, repo, ref: `heads/${branch}`, sha: commit.sha,
145
+ });
146
+ return { commit: commit.sha, branch, ref: updated };
147
+ });
148
+ }
149
+ async listBranches(owner, repo, page = 1, perPage = 30) {
150
+ return this.withRetry(async () => {
151
+ const ok = await this.octokit();
152
+ const { data } = await ok.repos.listBranches({ owner, repo, page, per_page: perPage });
153
+ return data;
154
+ });
155
+ }
156
+ async createBranch(owner, repo, branch, fromBranch) {
157
+ return this.withRetry(async () => {
158
+ const ok = await this.octokit();
159
+ const { data: ref } = await ok.git.getRef({ owner, repo, ref: `heads/${fromBranch}` });
160
+ const { data } = await ok.git.createRef({
161
+ owner, repo, ref: `refs/heads/${branch}`, sha: ref.object.sha,
162
+ });
163
+ return data;
164
+ });
165
+ }
166
+ // ── Issues ────────────────────────────────────────────────────────
167
+ async listIssues(owner, repo, opts = {}) {
168
+ return this.withRetry(async () => {
169
+ const ok = await this.octokit();
170
+ const { data } = await ok.issues.listForRepo({
171
+ owner, repo, state: "open", per_page: 30, ...omitFalsy(opts),
172
+ });
173
+ return data;
174
+ });
175
+ }
176
+ async getIssue(owner, repo, issue_number) {
177
+ return this.withRetry(async () => {
178
+ const ok = await this.octokit();
179
+ const { data } = await ok.issues.get({ owner, repo, issue_number });
180
+ return data;
181
+ });
182
+ }
183
+ async createIssue(owner, repo, title, body, opts = {}) {
184
+ return this.withRetry(async () => {
185
+ const ok = await this.octokit();
186
+ const { data } = await ok.issues.create({
187
+ owner, repo, title, body, ...omitFalsy(opts),
188
+ });
189
+ return data;
190
+ });
191
+ }
192
+ async updateIssue(owner, repo, issue_number, updates) {
193
+ return this.withRetry(async () => {
194
+ const ok = await this.octokit();
195
+ const { data } = await ok.issues.update({
196
+ owner, repo, issue_number, ...omitFalsy(updates),
197
+ });
198
+ return data;
199
+ });
200
+ }
201
+ async addIssueComment(owner, repo, issue_number, body) {
202
+ return this.withRetry(async () => {
203
+ const ok = await this.octokit();
204
+ const { data } = await ok.issues.createComment({ owner, repo, issue_number, body });
205
+ return data;
206
+ });
207
+ }
208
+ async listIssueComments(owner, repo, issue_number, opts = {}) {
209
+ return this.withRetry(async () => {
210
+ const ok = await this.octokit();
211
+ const { data } = await ok.issues.listComments({
212
+ owner, repo, issue_number, per_page: 30, ...omitFalsy(opts),
213
+ });
214
+ return data;
215
+ });
216
+ }
217
+ async addLabels(owner, repo, issue_number, labels) {
218
+ return this.withRetry(async () => {
219
+ const ok = await this.octokit();
220
+ const { data } = await ok.issues.addLabels({ owner, repo, issue_number, labels });
221
+ return data;
222
+ });
223
+ }
224
+ async removeLabel(owner, repo, issue_number, name) {
225
+ return this.withRetry(async () => {
226
+ const ok = await this.octokit();
227
+ const { data } = await ok.issues.removeLabel({ owner, repo, issue_number, name });
228
+ return data;
229
+ });
230
+ }
231
+ async listLabels(owner, repo) {
232
+ return this.withRetry(async () => {
233
+ const ok = await this.octokit();
234
+ const { data } = await ok.issues.listLabelsForRepo({ owner, repo, per_page: 100 });
235
+ return data;
236
+ });
237
+ }
238
+ async createLabel(owner, repo, name, color, description) {
239
+ return this.withRetry(async () => {
240
+ const ok = await this.octokit();
241
+ const { data } = await ok.issues.createLabel({ owner, repo, name, color, description });
242
+ return data;
243
+ });
244
+ }
245
+ // ── Pull Requests ─────────────────────────────────────────────────
246
+ async listPullRequests(owner, repo, opts = {}) {
247
+ return this.withRetry(async () => {
248
+ const ok = await this.octokit();
249
+ const cleaned = {};
250
+ for (const [k, v] of Object.entries(opts)) {
251
+ if (v === "" || v === undefined || v === null)
252
+ continue;
253
+ cleaned[k] = v;
254
+ }
255
+ const { data } = await ok.pulls.list({
256
+ owner, repo, state: "open", per_page: 30, ...cleaned,
257
+ });
258
+ return data;
259
+ });
260
+ }
261
+ async getPullRequest(owner, repo, pull_number) {
262
+ return this.withRetry(async () => {
263
+ const ok = await this.octokit();
264
+ const { data } = await ok.pulls.get({ owner, repo, pull_number });
265
+ return data;
266
+ });
267
+ }
268
+ async createPullRequest(owner, repo, title, body, head, base) {
269
+ return this.withRetry(async () => {
270
+ const ok = await this.octokit();
271
+ const { data } = await ok.pulls.create({ owner, repo, title, body, head, base });
272
+ return data;
273
+ });
274
+ }
275
+ async listPullRequestFiles(owner, repo, pull_number) {
276
+ return this.withRetry(async () => {
277
+ const ok = await this.octokit();
278
+ const { data } = await ok.pulls.listFiles({ owner, repo, pull_number, per_page: 100 });
279
+ return data;
280
+ });
281
+ }
282
+ async listPullRequestReviews(owner, repo, pull_number) {
283
+ return this.withRetry(async () => {
284
+ const ok = await this.octokit();
285
+ const { data } = await ok.pulls.listReviews({ owner, repo, pull_number, per_page: 100 });
286
+ return data;
287
+ });
288
+ }
289
+ async listPullRequestReviewComments(owner, repo, pull_number) {
290
+ return this.withRetry(async () => {
291
+ const ok = await this.octokit();
292
+ const { data } = await ok.pulls.listReviewComments({ owner, repo, pull_number, per_page: 100 });
293
+ return data;
294
+ });
295
+ }
296
+ async getPullRequestDiff(owner, repo, pull_number) {
297
+ return this.withRetry(async () => {
298
+ const ok = await this.octokit();
299
+ const { data } = await ok.pulls.get({
300
+ owner, repo, pull_number,
301
+ mediaType: { format: "diff" },
302
+ });
303
+ return data;
304
+ });
305
+ }
306
+ async createPullRequestReview(owner, repo, pull_number, body, event, comments = []) {
307
+ return this.withRetry(async () => {
308
+ const ok = await this.octokit();
309
+ const params = { owner, repo, pull_number, body, event: event };
310
+ if (comments.length)
311
+ params.comments = comments;
312
+ const { data } = await ok.pulls.createReview(params);
313
+ return data;
314
+ });
315
+ }
316
+ async mergePullRequest(owner, repo, pull_number, opts = {}) {
317
+ return this.withRetry(async () => {
318
+ const ok = await this.octokit();
319
+ const { data } = await ok.pulls.merge({
320
+ owner, repo, pull_number, ...opts,
321
+ });
322
+ return data;
323
+ });
324
+ }
325
+ // ── Commits ───────────────────────────────────────────────────────
326
+ async listCommits(owner, repo, opts = {}) {
327
+ return this.withRetry(async () => {
328
+ const ok = await this.octokit();
329
+ const { data } = await ok.repos.listCommits({
330
+ owner, repo, per_page: 30, ...opts,
331
+ });
332
+ return data;
333
+ });
334
+ }
335
+ // ── Search ────────────────────────────────────────────────────────
336
+ async searchRepositories(query, page = 1, perPage = 30) {
337
+ return this.withRetry(async () => {
338
+ const ok = await this.octokit();
339
+ const { data } = await ok.search.repos({ q: query, page, per_page: perPage });
340
+ return data;
341
+ });
342
+ }
343
+ async searchIssues(query, page = 1, perPage = 30) {
344
+ return this.withRetry(async () => {
345
+ const ok = await this.octokit();
346
+ const { data } = await ok.search.issuesAndPullRequests({ q: query, page, per_page: perPage });
347
+ return data;
348
+ });
349
+ }
350
+ async searchCode(query, page = 1, perPage = 30) {
351
+ return this.withRetry(async () => {
352
+ const ok = await this.octokit();
353
+ const { data } = await ok.search.code({ q: query, page, per_page: perPage });
354
+ return data;
355
+ });
356
+ }
357
+ }
358
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/extensions/github/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * git credential-store credentials file management.
3
+ *
4
+ * Ported from mcp-github-app/src/index.js. Same shape, same guards.
5
+ * The credentials file is shared with the sandbox entrypoint and any agent
6
+ * git clone — we just rewrite the file with a fresh token when called.
7
+ */
8
+ /**
9
+ * Conservative shape check on a GitHub installation token. The credentials
10
+ * file contains `https://x-access-token:${token}@github.com`, so any `@`,
11
+ * `:`, `/`, or newline in the token would break URL parsing or inject extra
12
+ * entries. Real tokens are alphanumeric (plus `_-`); this catches any future
13
+ * format change before we write a malformed file.
14
+ */
15
+ export declare function assertSafeToken(token: unknown): asserts token is string;
16
+ /**
17
+ * Resolve the credentials-file path. Mirrors lastlight's LASTLIGHT_GIT_CREDENTIALS
18
+ * convention but accepts an explicit override too.
19
+ */
20
+ export declare function credentialsFilePath(envVar?: string): string;
21
+ /**
22
+ * Write the credentials file. Mode 600, single line, no shell anywhere.
23
+ */
24
+ export declare function writeCredentialsFile(token: string): string;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * git credential-store credentials file management.
3
+ *
4
+ * Ported from mcp-github-app/src/index.js. Same shape, same guards.
5
+ * The credentials file is shared with the sandbox entrypoint and any agent
6
+ * git clone — we just rewrite the file with a fresh token when called.
7
+ */
8
+ import { mkdirSync, writeFileSync } from "node:fs";
9
+ import { dirname, join } from "node:path";
10
+ /**
11
+ * Conservative shape check on a GitHub installation token. The credentials
12
+ * file contains `https://x-access-token:${token}@github.com`, so any `@`,
13
+ * `:`, `/`, or newline in the token would break URL parsing or inject extra
14
+ * entries. Real tokens are alphanumeric (plus `_-`); this catches any future
15
+ * format change before we write a malformed file.
16
+ */
17
+ export function assertSafeToken(token) {
18
+ if (typeof token !== "string" || !/^[A-Za-z0-9_-]+$/.test(token)) {
19
+ throw new Error("Refusing to embed a token containing characters outside [A-Za-z0-9_-] into git credentials file");
20
+ }
21
+ }
22
+ /**
23
+ * Resolve the credentials-file path. Mirrors lastlight's LASTLIGHT_GIT_CREDENTIALS
24
+ * convention but accepts an explicit override too.
25
+ */
26
+ export function credentialsFilePath(envVar = "LASTLIGHT_GIT_CREDENTIALS") {
27
+ const raw = (process.env[envVar] || "").trim() ||
28
+ join(process.env.HOME || "/tmp", ".lastlight-git-credentials");
29
+ if (/\s/.test(raw)) {
30
+ throw new Error(`${envVar} contains whitespace; git's helper-arg parsing would break: ${raw}`);
31
+ }
32
+ return raw;
33
+ }
34
+ /**
35
+ * Write the credentials file. Mode 600, single line, no shell anywhere.
36
+ */
37
+ export function writeCredentialsFile(token) {
38
+ assertSafeToken(token);
39
+ const credPath = credentialsFilePath();
40
+ mkdirSync(dirname(credPath), { recursive: true, mode: 0o700 });
41
+ writeFileSync(credPath, `https://x-access-token:${token}@github.com\n`, { mode: 0o600 });
42
+ return credPath;
43
+ }
44
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../../src/extensions/github/credentials.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CACb,iGAAiG,CAClG,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAM,GAAG,2BAA2B;IACtE,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QAC5C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,EAAE,4BAA4B,CAAC,CAAC;IACjE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,+DAA+D,GAAG,EAAE,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,eAAe,CAAC,KAAK,CAAC,CAAC;IACvB,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,aAAa,CAAC,QAAQ,EAAE,0BAA0B,KAAK,eAAe,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzF,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * GitHub extension entry point.
3
+ *
4
+ * Composes auth + tools + profile gating into something the runner can hand
5
+ * to `createAgentSession({ customTools, tools })`.
6
+ *
7
+ * Safe by default: if `--profile` is not set OR the necessary GITHUB_ env
8
+ * vars are missing, this returns an empty tool set and the runner continues
9
+ * without GitHub support. The caller can inspect `status` / `reason` to
10
+ * decide whether to surface a warning.
11
+ */
12
+ import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
13
+ import { type AuthFailureReason } from "./auth.js";
14
+ import { type GitAccessProfile } from "./profiles.js";
15
+ export { isGitAccessProfile, type GitAccessProfile } from "./profiles.js";
16
+ /** Why the extension didn't load tools. */
17
+ export type GitHubExtensionSkipReason = "no-profile" | AuthFailureReason;
18
+ export interface GitHubExtensionResult {
19
+ /** Tools to pass into `createAgentSession({ customTools })`. */
20
+ customTools: ToolDefinition<any>[];
21
+ /** Tool names registered (subset of the profile's allowlist). */
22
+ toolNames: string[];
23
+ /** Whether the extension is active. */
24
+ status: "configured" | "skipped";
25
+ /** Set when `status === "skipped"`. */
26
+ reason?: GitHubExtensionSkipReason;
27
+ /** Human-readable extra detail for warnings / logs. */
28
+ message?: string;
29
+ /** Always echoed back so the consumer knows what they asked for. */
30
+ profile?: GitAccessProfile;
31
+ }
32
+ /**
33
+ * Build the GitHub extension for a given profile.
34
+ *
35
+ * - No profile → status:"skipped", reason:"no-profile" (silent, expected).
36
+ * - Profile set but no GITHUB_* env vars → status:"skipped", reason:"no-credentials".
37
+ * - PEM file missing or partial creds → status:"skipped" with a specific reason
38
+ * and a message the caller should surface (these are misconfigurations,
39
+ * not opt-outs).
40
+ */
41
+ export declare function loadGitHubExtension(profileName?: string): GitHubExtensionResult;
42
+ /**
43
+ * True if the skip is a misconfiguration the user almost certainly wants to
44
+ * know about (vs. a benign "didn't pass --profile" case).
45
+ */
46
+ export declare function isMisconfigurationSkip(result: GitHubExtensionResult): boolean;
@@ -0,0 +1,67 @@
1
+ /**
2
+ * GitHub extension entry point.
3
+ *
4
+ * Composes auth + tools + profile gating into something the runner can hand
5
+ * to `createAgentSession({ customTools, tools })`.
6
+ *
7
+ * Safe by default: if `--profile` is not set OR the necessary GITHUB_ env
8
+ * vars are missing, this returns an empty tool set and the runner continues
9
+ * without GitHub support. The caller can inspect `status` / `reason` to
10
+ * decide whether to surface a warning.
11
+ */
12
+ import { buildAuthFromEnv } from "./auth.js";
13
+ import { buildGitHubTools } from "./tools.js";
14
+ import { PROFILE_TOOLS, isGitAccessProfile, } from "./profiles.js";
15
+ export { isGitAccessProfile } from "./profiles.js";
16
+ /**
17
+ * Build the GitHub extension for a given profile.
18
+ *
19
+ * - No profile → status:"skipped", reason:"no-profile" (silent, expected).
20
+ * - Profile set but no GITHUB_* env vars → status:"skipped", reason:"no-credentials".
21
+ * - PEM file missing or partial creds → status:"skipped" with a specific reason
22
+ * and a message the caller should surface (these are misconfigurations,
23
+ * not opt-outs).
24
+ */
25
+ export function loadGitHubExtension(profileName) {
26
+ if (!profileName) {
27
+ return {
28
+ customTools: [],
29
+ toolNames: [],
30
+ status: "skipped",
31
+ reason: "no-profile",
32
+ };
33
+ }
34
+ if (!isGitAccessProfile(profileName)) {
35
+ throw new Error(`Unknown GitHub profile '${profileName}'. Expected one of: ${Object.keys(PROFILE_TOOLS).join(", ")}`);
36
+ }
37
+ const { auth, reason, message } = buildAuthFromEnv();
38
+ if (!auth) {
39
+ return {
40
+ customTools: [],
41
+ toolNames: [],
42
+ status: "skipped",
43
+ reason,
44
+ message,
45
+ profile: profileName,
46
+ };
47
+ }
48
+ const allowed = new Set(PROFILE_TOOLS[profileName]);
49
+ const allTools = buildGitHubTools(auth);
50
+ const profileTools = allTools.filter((t) => allowed.has(t.name));
51
+ return {
52
+ customTools: profileTools,
53
+ toolNames: profileTools.map((t) => t.name),
54
+ status: "configured",
55
+ profile: profileName,
56
+ };
57
+ }
58
+ /**
59
+ * True if the skip is a misconfiguration the user almost certainly wants to
60
+ * know about (vs. a benign "didn't pass --profile" case).
61
+ */
62
+ export function isMisconfigurationSkip(result) {
63
+ if (result.status !== "skipped")
64
+ return false;
65
+ return result.reason === "pem-unreadable" || result.reason === "invalid-config";
66
+ }
67
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/github/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,kBAAkB,GAEnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,kBAAkB,EAAyB,MAAM,eAAe,CAAC;AAuB1E;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAoB;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,YAAY;SACrB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,2BAA2B,WAAW,uBAAuB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM;YACN,OAAO;YACP,OAAO,EAAE,WAAW;SACrB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,WAAW;KACrB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA6B;IAClE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,MAAM,CAAC,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,CAAC;AAClF,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * GitHub tool profiles — registration-time gate.
3
+ *
4
+ * Maps the 4 lastlight profile names to the set of Pi tool names allowed
5
+ * in that profile. Tools NOT in the active profile are never registered, so
6
+ * the LLM cannot call them. Combined with the token-scope downscoping
7
+ * lastlight does on the host side, this gives defense-in-depth.
8
+ *
9
+ * Mirrors lastlight's `GITHUB_PERMISSION_PROFILES` token scopes:
10
+ * read → contents:r, issues:r, pull_requests:r, metadata:r
11
+ * issues-write → ditto + issues:w
12
+ * review-write → ditto + pull_requests:w
13
+ * repo-write → ditto + contents:w
14
+ */
15
+ export type GitAccessProfile = "read" | "issues-write" | "review-write" | "repo-write";
16
+ export declare const PROFILE_TOOLS: Record<GitAccessProfile, readonly string[]>;
17
+ export declare function isGitAccessProfile(s: string): s is GitAccessProfile;