@a5c-ai/tasks-mux 5.0.1-staging.078c111a306a

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 (175) hide show
  1. package/README.md +103 -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 +117 -0
  27. package/dist/backend.d.ts.map +1 -0
  28. package/dist/backend.js +15 -0
  29. package/dist/backends/git-native.d.ts +51 -0
  30. package/dist/backends/git-native.d.ts.map +1 -0
  31. package/dist/backends/git-native.js +324 -0
  32. package/dist/backends/github-issues.d.ts +77 -0
  33. package/dist/backends/github-issues.d.ts.map +1 -0
  34. package/dist/backends/github-issues.js +796 -0
  35. package/dist/backends/index.d.ts +48 -0
  36. package/dist/backends/index.d.ts.map +1 -0
  37. package/dist/backends/index.js +139 -0
  38. package/dist/backends/server.d.ts +41 -0
  39. package/dist/backends/server.d.ts.map +1 -0
  40. package/dist/backends/server.js +298 -0
  41. package/dist/cli/auth-store.d.ts +49 -0
  42. package/dist/cli/auth-store.d.ts.map +1 -0
  43. package/dist/cli/auth-store.js +150 -0
  44. package/dist/cli/client-config.d.ts +10 -0
  45. package/dist/cli/client-config.d.ts.map +1 -0
  46. package/dist/cli/client-config.js +87 -0
  47. package/dist/cli/commands/ask.d.ts +3 -0
  48. package/dist/cli/commands/ask.d.ts.map +1 -0
  49. package/dist/cli/commands/ask.js +171 -0
  50. package/dist/cli/commands/auth.d.ts +3 -0
  51. package/dist/cli/commands/auth.d.ts.map +1 -0
  52. package/dist/cli/commands/auth.js +510 -0
  53. package/dist/cli/commands/breakpoints.d.ts +3 -0
  54. package/dist/cli/commands/breakpoints.d.ts.map +1 -0
  55. package/dist/cli/commands/breakpoints.js +152 -0
  56. package/dist/cli/commands/responder-loop.d.ts +3 -0
  57. package/dist/cli/commands/responder-loop.d.ts.map +1 -0
  58. package/dist/cli/commands/responder-loop.js +78 -0
  59. package/dist/cli/commands/responders.d.ts +3 -0
  60. package/dist/cli/commands/responders.d.ts.map +1 -0
  61. package/dist/cli/commands/responders.js +74 -0
  62. package/dist/cli/commands/server.d.ts +3 -0
  63. package/dist/cli/commands/server.d.ts.map +1 -0
  64. package/dist/cli/commands/server.js +34 -0
  65. package/dist/cli/index.d.ts +4 -0
  66. package/dist/cli/index.d.ts.map +1 -0
  67. package/dist/cli/index.js +9 -0
  68. package/dist/cli/output.d.ts +26 -0
  69. package/dist/cli/output.d.ts.map +1 -0
  70. package/dist/cli/output.js +143 -0
  71. package/dist/cli/program.d.ts +6 -0
  72. package/dist/cli/program.d.ts.map +1 -0
  73. package/dist/cli/program.js +32 -0
  74. package/dist/client/answer-poller.d.ts +52 -0
  75. package/dist/client/answer-poller.d.ts.map +1 -0
  76. package/dist/client/answer-poller.js +199 -0
  77. package/dist/client/auth-client.d.ts +200 -0
  78. package/dist/client/auth-client.d.ts.map +1 -0
  79. package/dist/client/auth-client.js +309 -0
  80. package/dist/client/breakpoint-router.d.ts +45 -0
  81. package/dist/client/breakpoint-router.d.ts.map +1 -0
  82. package/dist/client/breakpoint-router.js +45 -0
  83. package/dist/client/index.d.ts +17 -0
  84. package/dist/client/index.d.ts.map +1 -0
  85. package/dist/client/index.js +16 -0
  86. package/dist/client/profile-validator.d.ts +34 -0
  87. package/dist/client/profile-validator.d.ts.map +1 -0
  88. package/dist/client/profile-validator.js +89 -0
  89. package/dist/client/responder-client.d.ts +39 -0
  90. package/dist/client/responder-client.d.ts.map +1 -0
  91. package/dist/client/responder-client.js +72 -0
  92. package/dist/client/responder-matcher.d.ts +49 -0
  93. package/dist/client/responder-matcher.d.ts.map +1 -0
  94. package/dist/client/responder-matcher.js +226 -0
  95. package/dist/client/server-client.d.ts +124 -0
  96. package/dist/client/server-client.d.ts.map +1 -0
  97. package/dist/client/server-client.js +266 -0
  98. package/dist/client/timeout-manager.d.ts +47 -0
  99. package/dist/client/timeout-manager.d.ts.map +1 -0
  100. package/dist/client/timeout-manager.js +77 -0
  101. package/dist/config.d.ts +20 -0
  102. package/dist/config.d.ts.map +1 -0
  103. package/dist/config.js +93 -0
  104. package/dist/harness/index.d.ts +4 -0
  105. package/dist/harness/index.d.ts.map +1 -0
  106. package/dist/harness/index.js +2 -0
  107. package/dist/harness/interaction-provider.d.ts +71 -0
  108. package/dist/harness/interaction-provider.d.ts.map +1 -0
  109. package/dist/harness/interaction-provider.js +124 -0
  110. package/dist/harness/routing-rules.d.ts +7 -0
  111. package/dist/harness/routing-rules.d.ts.map +1 -0
  112. package/dist/harness/routing-rules.js +37 -0
  113. package/dist/index.d.ts +19 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +26 -0
  116. package/dist/mcp/backend-resolver.d.ts +43 -0
  117. package/dist/mcp/backend-resolver.d.ts.map +1 -0
  118. package/dist/mcp/backend-resolver.js +111 -0
  119. package/dist/mcp/http-transport.d.ts +37 -0
  120. package/dist/mcp/http-transport.d.ts.map +1 -0
  121. package/dist/mcp/http-transport.js +103 -0
  122. package/dist/mcp/index.d.ts +14 -0
  123. package/dist/mcp/index.d.ts.map +1 -0
  124. package/dist/mcp/index.js +11 -0
  125. package/dist/mcp/server.d.ts +20 -0
  126. package/dist/mcp/server.d.ts.map +1 -0
  127. package/dist/mcp/server.js +121 -0
  128. package/dist/mcp/tools/answer-breakpoint.d.ts +32 -0
  129. package/dist/mcp/tools/answer-breakpoint.d.ts.map +1 -0
  130. package/dist/mcp/tools/answer-breakpoint.js +45 -0
  131. package/dist/mcp/tools/ask-breakpoint.d.ts +58 -0
  132. package/dist/mcp/tools/ask-breakpoint.d.ts.map +1 -0
  133. package/dist/mcp/tools/ask-breakpoint.js +78 -0
  134. package/dist/mcp/tools/check-status.d.ts +16 -0
  135. package/dist/mcp/tools/check-status.d.ts.map +1 -0
  136. package/dist/mcp/tools/check-status.js +18 -0
  137. package/dist/mcp/tools/claim-breakpoint.d.ts +18 -0
  138. package/dist/mcp/tools/claim-breakpoint.d.ts.map +1 -0
  139. package/dist/mcp/tools/claim-breakpoint.js +28 -0
  140. package/dist/mcp/tools/list-breakpoints.d.ts +16 -0
  141. package/dist/mcp/tools/list-breakpoints.d.ts.map +1 -0
  142. package/dist/mcp/tools/list-breakpoints.js +14 -0
  143. package/dist/mcp/tools/list-responders.d.ts +18 -0
  144. package/dist/mcp/tools/list-responders.d.ts.map +1 -0
  145. package/dist/mcp/tools/list-responders.js +37 -0
  146. package/dist/mcp/tools/poll-breakpoints.d.ts +18 -0
  147. package/dist/mcp/tools/poll-breakpoints.d.ts.map +1 -0
  148. package/dist/mcp/tools/poll-breakpoints.js +36 -0
  149. package/dist/mcp/tools/verify-answer.d.ts +16 -0
  150. package/dist/mcp/tools/verify-answer.d.ts.map +1 -0
  151. package/dist/mcp/tools/verify-answer.js +38 -0
  152. package/dist/proven/index.d.ts +5 -0
  153. package/dist/proven/index.d.ts.map +1 -0
  154. package/dist/proven/index.js +3 -0
  155. package/dist/proven/keys.d.ts +33 -0
  156. package/dist/proven/keys.d.ts.map +1 -0
  157. package/dist/proven/keys.js +117 -0
  158. package/dist/proven/sign.d.ts +16 -0
  159. package/dist/proven/sign.d.ts.map +1 -0
  160. package/dist/proven/sign.js +60 -0
  161. package/dist/proven/types.d.ts +26 -0
  162. package/dist/proven/types.d.ts.map +1 -0
  163. package/dist/proven/types.js +5 -0
  164. package/dist/proven/verify.d.ts +6 -0
  165. package/dist/proven/verify.d.ts.map +1 -0
  166. package/dist/proven/verify.js +58 -0
  167. package/dist/types.d.ts +4034 -0
  168. package/dist/types.d.ts.map +1 -0
  169. package/dist/types.js +244 -0
  170. package/package.json +86 -0
  171. package/responder/README.md +42 -0
  172. package/responder/backend-responder.json +9 -0
  173. package/responder/devops-responder.json +9 -0
  174. package/responder/frontend-responder.json +9 -0
  175. package/responder/schema.json +52 -0
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # @a5c-ai/tasks-mux
2
+
3
+ Breakpoint routing library, MCP server, and CLI for responder-driven review flows.
4
+
5
+ ## Install
6
+
7
+ Use the published npm package in consumers. Install it locally in a project or run it directly with `npx`.
8
+
9
+ ```bash
10
+ npm install --save-dev @a5c-ai/tasks-mux
11
+ npx --yes @a5c-ai/tasks-mux --help
12
+ ```
13
+
14
+ ## CLI
15
+
16
+ The published executable is `tasks-mux`. The supported consumer workflow is either:
17
+
18
+ - run the published package with `npx --yes @a5c-ai/tasks-mux ...`
19
+ - install `@a5c-ai/tasks-mux` and invoke `tasks-mux ...`
20
+
21
+ ```bash
22
+ npx --yes @a5c-ai/tasks-mux --help
23
+ npx --yes @a5c-ai/tasks-mux responders list
24
+ npx --yes @a5c-ai/tasks-mux auth login
25
+ npx --yes @a5c-ai/tasks-mux server start
26
+ ```
27
+
28
+ If the published package is already installed locally or globally, use the bin directly:
29
+
30
+ ```bash
31
+ tasks-mux --help
32
+ tasks-mux auth server set https://tasks-mux.a5c.ai
33
+ tasks-mux auth login
34
+ ```
35
+
36
+ Current CLI commands:
37
+
38
+ - `tasks-mux ask`
39
+ - `tasks-mux responders list`
40
+ - `tasks-mux responders show <responderId>`
41
+ - `tasks-mux breakpoints pending --responder <responderId>`
42
+ - `tasks-mux breakpoints answer <breakpointId> --answer <text> --responder <responderId> [--confidence <0-100>]`
43
+ - `tasks-mux breakpoints status <breakpointId>`
44
+ - `tasks-mux breakpoints poll <breakpointId> [--timeout <seconds>] [--interval <seconds>]`
45
+ - `tasks-mux responder-loop --responder <responderId> [--interval <seconds>] [--once]`
46
+ - `tasks-mux server start`
47
+ - `tasks-mux auth login|logout|status|server set|server clear|token set|token clear|keygen|key-push|keys`
48
+
49
+ ## MCP Tools
50
+
51
+ The MCP server currently registers these tools:
52
+
53
+ - `ask_breakpoint`
54
+ - `check_breakpoint_status`
55
+ - `list_breakpoints`
56
+ - `answer_breakpoint`
57
+ - `verify_breakpoint_answer`
58
+ - `list_responders`
59
+ - `claim_breakpoint`
60
+ - `poll_breakpoints`
61
+
62
+ ## Package Exports
63
+
64
+ Published subpath exports:
65
+
66
+ - `.`
67
+ - `./backends`
68
+ - `./proven`
69
+ - `./mcp`
70
+ - `./harness`
71
+ - `./auth`
72
+ - `./config`
73
+
74
+ Example:
75
+
76
+ ```ts
77
+ import {
78
+ createBackend,
79
+ createBreakpointMcpServer,
80
+ BreakpointMuxInteractionProvider,
81
+ } from "@a5c-ai/tasks-mux";
82
+ ```
83
+
84
+ ## Published Package Contents
85
+
86
+ The npm tarball is intentionally limited to:
87
+
88
+ - `dist/`
89
+ - `responder/`
90
+ - `README.md`
91
+
92
+ `docs/`, `skills/`, and `specs/` are repository source docs and are not published files.
93
+
94
+ ## Validation
95
+
96
+ ```bash
97
+ npm run build --workspace=@a5c-ai/tasks-mux
98
+ npm run typecheck --workspace=@a5c-ai/tasks-mux
99
+ npm run test:packaged-surface-parity --workspace=@a5c-ai/tasks-mux
100
+ npm pack --json --dry-run --workspace=@a5c-ai/tasks-mux
101
+ ```
102
+
103
+ Keep this README aligned with the exported CLI, MCP, and package topology surfaced by `packages/tasks-mux/`.
@@ -0,0 +1,67 @@
1
+ import type { GitForgeConfig } from "./types.js";
2
+ import { GitHubAppClient } from "./github-app.js";
3
+ export interface PullRequestOpts {
4
+ owner: string;
5
+ repo: string;
6
+ title: string;
7
+ head: string;
8
+ base: string;
9
+ body?: string;
10
+ }
11
+ export interface PullRequestResult {
12
+ prUrl: string;
13
+ prNumber: number;
14
+ }
15
+ export interface PushFileOpts {
16
+ owner: string;
17
+ repo: string;
18
+ path: string;
19
+ content: string;
20
+ message: string;
21
+ branch?: string;
22
+ }
23
+ export interface RepoInfo {
24
+ owner: string;
25
+ name: string;
26
+ fullName: string;
27
+ defaultBranch: string;
28
+ private: boolean;
29
+ }
30
+ /**
31
+ * Pluggable interface for interacting with Git forges (GitHub, GitLab, etc.).
32
+ */
33
+ export interface GitForge {
34
+ createPR(opts: PullRequestOpts): Promise<PullRequestResult>;
35
+ readFile(opts: {
36
+ owner: string;
37
+ repo: string;
38
+ path: string;
39
+ ref?: string;
40
+ }): Promise<string>;
41
+ pushFile(opts: PushFileOpts): Promise<void>;
42
+ listRepos(owner: string): Promise<RepoInfo[]>;
43
+ }
44
+ /**
45
+ * GitHub implementation of the GitForge interface.
46
+ * Wraps GitHubAppClient for repository operations.
47
+ */
48
+ export declare class GitHubForge implements GitForge {
49
+ private readonly client;
50
+ private readonly installationId;
51
+ constructor(client: GitHubAppClient, installationId: number);
52
+ createPR(opts: PullRequestOpts): Promise<PullRequestResult>;
53
+ readFile(opts: {
54
+ owner: string;
55
+ repo: string;
56
+ path: string;
57
+ ref?: string;
58
+ }): Promise<string>;
59
+ pushFile(opts: PushFileOpts): Promise<void>;
60
+ listRepos(owner: string): Promise<RepoInfo[]>;
61
+ }
62
+ /**
63
+ * Create a GitForge instance from a configuration object.
64
+ * Currently only supports GitHub.
65
+ */
66
+ export declare function createForge(config: GitForgeConfig): GitForge;
67
+ //# sourceMappingURL=forge-interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forge-interface.d.ts","sourceRoot":"","sources":["../../src/auth/forge-interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAmB,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIlD,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB;AAID;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7F,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;CAC/C;AAID;;;GAGG;AACH,qBAAa,WAAY,YAAW,QAAQ;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;gBAE5B,MAAM,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM;IAKrD,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAgB3D,QAAQ,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAOlG,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAK9C;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAmB5D"}
@@ -0,0 +1,69 @@
1
+ import { GitHubAppClient } from "./github-app.js";
2
+ // ── GitHubForge ───────────────────────────────────────────────────────────
3
+ /**
4
+ * GitHub implementation of the GitForge interface.
5
+ * Wraps GitHubAppClient for repository operations.
6
+ */
7
+ export class GitHubForge {
8
+ client;
9
+ installationId;
10
+ constructor(client, installationId) {
11
+ this.client = client;
12
+ this.installationId = installationId;
13
+ }
14
+ async createPR(opts) {
15
+ const result = await this.client.createKeyPR({
16
+ owner: opts.owner,
17
+ repo: opts.repo,
18
+ installationId: this.installationId,
19
+ userId: "forge",
20
+ publicKey: opts.body ?? "",
21
+ keyPath: opts.head,
22
+ });
23
+ return {
24
+ prUrl: result.prUrl,
25
+ prNumber: result.prNumber,
26
+ };
27
+ }
28
+ async readFile(opts) {
29
+ return this.client.readFile({
30
+ ...opts,
31
+ installationId: this.installationId,
32
+ });
33
+ }
34
+ pushFile(opts) {
35
+ void opts;
36
+ // Delegated to Octokit createOrUpdateFileContents via the client
37
+ return Promise.reject(new Error("pushFile not yet implemented for GitHubForge"));
38
+ }
39
+ listRepos(owner) {
40
+ void owner;
41
+ // Delegated to Octokit list repos endpoint
42
+ return Promise.reject(new Error("listRepos not yet implemented for GitHubForge"));
43
+ }
44
+ }
45
+ // ── Factory ───────────────────────────────────────────────────────────────
46
+ /**
47
+ * Create a GitForge instance from a configuration object.
48
+ * Currently only supports GitHub.
49
+ */
50
+ export function createForge(config) {
51
+ switch (config.type) {
52
+ case "github": {
53
+ const appConfig = {
54
+ appId: config.credentials.appId ?? "",
55
+ privateKey: config.credentials.privateKey ?? "",
56
+ webhookSecret: config.credentials.webhookSecret,
57
+ };
58
+ const installationId = parseInt(config.credentials.installationId ?? "0", 10);
59
+ const client = new GitHubAppClient(appConfig);
60
+ return new GitHubForge(client, installationId);
61
+ }
62
+ case "gitlab":
63
+ throw new Error("GitLab forge not yet implemented");
64
+ case "bitbucket":
65
+ throw new Error("Bitbucket forge not yet implemented");
66
+ default:
67
+ throw new Error(`Unknown forge type: ${config.type}`);
68
+ }
69
+ }
@@ -0,0 +1,64 @@
1
+ import type { GitHubAppConfig } from "./types.js";
2
+ export interface Installation {
3
+ id: number;
4
+ account: {
5
+ login: string;
6
+ type: string;
7
+ };
8
+ repositorySelection: string;
9
+ }
10
+ export interface CreateKeyPROpts {
11
+ owner: string;
12
+ repo: string;
13
+ installationId: number;
14
+ userId: string;
15
+ publicKey: string;
16
+ keyPath: string;
17
+ }
18
+ export interface CreateKeyPRResult {
19
+ prUrl: string;
20
+ prNumber: number;
21
+ branch: string;
22
+ }
23
+ /**
24
+ * Client for interacting with GitHub as a GitHub App.
25
+ * Uses @octokit/rest and @octokit/auth-app for authentication.
26
+ */
27
+ export declare class GitHubAppClient {
28
+ private readonly config;
29
+ constructor(config: GitHubAppConfig);
30
+ /**
31
+ * Get an installation access token for a specific installation.
32
+ */
33
+ getInstallationToken(installationId: number): Promise<string>;
34
+ /**
35
+ * Create a pull request to add an SSH public key to a repository.
36
+ */
37
+ createKeyPR(opts: CreateKeyPROpts): Promise<CreateKeyPRResult>;
38
+ /**
39
+ * Read a file from a repository.
40
+ */
41
+ readFile(opts: {
42
+ owner: string;
43
+ repo: string;
44
+ installationId: number;
45
+ path: string;
46
+ ref?: string;
47
+ }): Promise<string>;
48
+ /**
49
+ * List all installations for this GitHub App.
50
+ */
51
+ listInstallations(): Promise<Installation[]>;
52
+ /**
53
+ * Extract the key type prefix from an SSH public key string.
54
+ */
55
+ private extractKeyType;
56
+ /**
57
+ * Extract a short fingerprint-like identifier from an SSH public key.
58
+ * Returns the first 16 chars of the base64 key data for identification.
59
+ */
60
+ private extractKeyFingerprint;
61
+ private createAppOctokit;
62
+ private createInstallationOctokit;
63
+ }
64
+ //# sourceMappingURL=github-app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-app.d.ts","sourceRoot":"","sources":["../../src/auth/github-app.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAIlD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;GAGG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;gBAE7B,MAAM,EAAE,eAAe;IAInC;;OAEG;IACG,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAUnE;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6DpE;;OAEG;IACG,QAAQ,CAAC,IAAI,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,cAAc,EAAE,MAAM,CAAC;QACvB,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,MAAM,CAAC;IAiBnB;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAiBlD;;OAEG;IACH,OAAO,CAAC,cAAc;IAKtB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAM7B,OAAO,CAAC,gBAAgB;YAUV,yBAAyB;CAIxC"}
@@ -0,0 +1,141 @@
1
+ import { Octokit } from "@octokit/rest";
2
+ import { createAppAuth } from "@octokit/auth-app";
3
+ // ── GitHubAppClient ───────────────────────────────────────────────────────
4
+ /**
5
+ * Client for interacting with GitHub as a GitHub App.
6
+ * Uses @octokit/rest and @octokit/auth-app for authentication.
7
+ */
8
+ export class GitHubAppClient {
9
+ config;
10
+ constructor(config) {
11
+ this.config = config;
12
+ }
13
+ /**
14
+ * Get an installation access token for a specific installation.
15
+ */
16
+ async getInstallationToken(installationId) {
17
+ const octokit = this.createAppOctokit();
18
+ const { data } = await octokit.apps.createInstallationAccessToken({
19
+ installation_id: installationId,
20
+ });
21
+ return data.token;
22
+ }
23
+ /**
24
+ * Create a pull request to add an SSH public key to a repository.
25
+ */
26
+ async createKeyPR(opts) {
27
+ const octokit = await this.createInstallationOctokit(opts.installationId);
28
+ const branch = `tasks-mux/add-key-${opts.userId}-${Date.now()}`;
29
+ // Get the default branch ref
30
+ const { data: repo } = await octokit.repos.get({
31
+ owner: opts.owner,
32
+ repo: opts.repo,
33
+ });
34
+ const defaultBranch = repo.default_branch;
35
+ // Get the HEAD SHA of the default branch
36
+ const { data: ref } = await octokit.git.getRef({
37
+ owner: opts.owner,
38
+ repo: opts.repo,
39
+ ref: `heads/${defaultBranch}`,
40
+ });
41
+ const baseSha = ref.object.sha;
42
+ // Create a new branch
43
+ await octokit.git.createRef({
44
+ owner: opts.owner,
45
+ repo: opts.repo,
46
+ ref: `refs/heads/${branch}`,
47
+ sha: baseSha,
48
+ });
49
+ // Create or update the key file at {keyPath}/{userId}.pub
50
+ const filePath = `${opts.keyPath}/${opts.userId}.pub`;
51
+ await octokit.repos.createOrUpdateFileContents({
52
+ owner: opts.owner,
53
+ repo: opts.repo,
54
+ path: filePath,
55
+ message: `Add SSH public key for user ${opts.userId}`,
56
+ content: Buffer.from(opts.publicKey).toString("base64"),
57
+ branch,
58
+ });
59
+ // Create a pull request
60
+ const { data: pr } = await octokit.pulls.create({
61
+ owner: opts.owner,
62
+ repo: opts.repo,
63
+ title: `Add SSH key for user ${opts.userId}`,
64
+ head: branch,
65
+ base: defaultBranch,
66
+ body: [
67
+ `This PR adds an SSH public key for user \`${opts.userId}\`.`,
68
+ "",
69
+ `**Key path:** \`${filePath}\``,
70
+ `**Key fingerprint:** \`${this.extractKeyFingerprint(opts.publicKey)}\``,
71
+ `**Key type:** \`${this.extractKeyType(opts.publicKey)}\``,
72
+ ].join("\n"),
73
+ });
74
+ return {
75
+ prUrl: pr.html_url,
76
+ prNumber: pr.number,
77
+ branch,
78
+ };
79
+ }
80
+ /**
81
+ * Read a file from a repository.
82
+ */
83
+ async readFile(opts) {
84
+ const octokit = await this.createInstallationOctokit(opts.installationId);
85
+ const { data } = await octokit.repos.getContent({
86
+ owner: opts.owner,
87
+ repo: opts.repo,
88
+ path: opts.path,
89
+ ref: opts.ref,
90
+ });
91
+ if (Array.isArray(data) || data.type !== "file") {
92
+ throw new Error(`Path "${opts.path}" is not a file`);
93
+ }
94
+ return Buffer.from(data.content, "base64").toString("utf-8");
95
+ }
96
+ /**
97
+ * List all installations for this GitHub App.
98
+ */
99
+ async listInstallations() {
100
+ const octokit = this.createAppOctokit();
101
+ const { data } = await octokit.apps.listInstallations();
102
+ return data.map((inst) => ({
103
+ id: inst.id,
104
+ account: {
105
+ login: inst.account?.login ?? "unknown",
106
+ type: inst.account?.type ?? "unknown",
107
+ },
108
+ repositorySelection: inst.repository_selection,
109
+ }));
110
+ }
111
+ // ── Internal helpers ──────────────────────────────────────────────────
112
+ /**
113
+ * Extract the key type prefix from an SSH public key string.
114
+ */
115
+ extractKeyType(publicKey) {
116
+ const parts = publicKey.trim().split(/\s+/);
117
+ return parts[0] ?? "unknown";
118
+ }
119
+ /**
120
+ * Extract a short fingerprint-like identifier from an SSH public key.
121
+ * Returns the first 16 chars of the base64 key data for identification.
122
+ */
123
+ extractKeyFingerprint(publicKey) {
124
+ const parts = publicKey.trim().split(/\s+/);
125
+ const keyData = parts[1] ?? "";
126
+ return keyData.length > 16 ? `SHA256:${keyData.substring(0, 16)}...` : `SHA256:${keyData}`;
127
+ }
128
+ createAppOctokit() {
129
+ return new Octokit({
130
+ authStrategy: createAppAuth,
131
+ auth: {
132
+ appId: this.config.appId,
133
+ privateKey: this.config.privateKey,
134
+ },
135
+ });
136
+ }
137
+ async createInstallationOctokit(installationId) {
138
+ const token = await this.getInstallationToken(installationId);
139
+ return new Octokit({ auth: token });
140
+ }
141
+ }
@@ -0,0 +1,27 @@
1
+ import type { GitHubOAuthConfig, User } from "./types.js";
2
+ /**
3
+ * OAuth 2.0 client for GitHub authentication.
4
+ * Uses native fetch() for HTTP calls with no external dependencies.
5
+ */
6
+ export declare class GitHubOAuthClient {
7
+ private readonly config;
8
+ constructor(config: GitHubOAuthConfig);
9
+ /**
10
+ * Build the GitHub OAuth authorization URL.
11
+ * Optionally supports PKCE via codeVerifier (S256 challenge).
12
+ */
13
+ getAuthorizationUrl(state: string, codeVerifier?: string): string;
14
+ /**
15
+ * Exchange an authorization code for an access token.
16
+ */
17
+ exchangeCode(code: string, codeVerifier?: string): Promise<{
18
+ accessToken: string;
19
+ tokenType: string;
20
+ scope: string;
21
+ }>;
22
+ /**
23
+ * Fetch the authenticated user's profile from GitHub.
24
+ */
25
+ getUserProfile(accessToken: string): Promise<User>;
26
+ }
27
+ //# sourceMappingURL=github-oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-oauth.d.ts","sourceRoot":"","sources":["../../src/auth/github-oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAU1D;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;gBAE/B,MAAM,EAAE,iBAAiB;IAIrC;;;OAGG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM;IAgBjE;;OAEG;IACG,YAAY,CAChB,IAAI,EAAE,MAAM,EACZ,YAAY,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA4CrE;;OAEG;IACG,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA6BzD"}
@@ -0,0 +1,89 @@
1
+ // ── Constants ─────────────────────────────────────────────────────────────
2
+ const GITHUB_AUTHORIZE_URL = "https://github.com/login/oauth/authorize";
3
+ const GITHUB_TOKEN_URL = "https://github.com/login/oauth/access_token";
4
+ const GITHUB_API_URL = "https://api.github.com";
5
+ // ── GitHubOAuthClient ─────────────────────────────────────────────────────
6
+ /**
7
+ * OAuth 2.0 client for GitHub authentication.
8
+ * Uses native fetch() for HTTP calls with no external dependencies.
9
+ */
10
+ export class GitHubOAuthClient {
11
+ config;
12
+ constructor(config) {
13
+ this.config = config;
14
+ }
15
+ /**
16
+ * Build the GitHub OAuth authorization URL.
17
+ * Optionally supports PKCE via codeVerifier (S256 challenge).
18
+ */
19
+ getAuthorizationUrl(state, codeVerifier) {
20
+ const params = new URLSearchParams({
21
+ client_id: this.config.clientId,
22
+ redirect_uri: this.config.callbackUrl,
23
+ scope: this.config.scopes.join(" "),
24
+ state,
25
+ });
26
+ if (codeVerifier) {
27
+ params.set("code_challenge", codeVerifier);
28
+ params.set("code_challenge_method", "S256");
29
+ }
30
+ return `${GITHUB_AUTHORIZE_URL}?${params.toString()}`;
31
+ }
32
+ /**
33
+ * Exchange an authorization code for an access token.
34
+ */
35
+ async exchangeCode(code, codeVerifier) {
36
+ const body = {
37
+ client_id: this.config.clientId,
38
+ client_secret: this.config.clientSecret,
39
+ code,
40
+ redirect_uri: this.config.callbackUrl,
41
+ };
42
+ if (codeVerifier) {
43
+ body.code_verifier = codeVerifier;
44
+ }
45
+ const response = await fetch(GITHUB_TOKEN_URL, {
46
+ method: "POST",
47
+ headers: {
48
+ "Content-Type": "application/json",
49
+ Accept: "application/json",
50
+ },
51
+ body: JSON.stringify(body),
52
+ });
53
+ if (!response.ok) {
54
+ throw new Error(`GitHub OAuth token exchange failed: ${response.status} ${response.statusText}`);
55
+ }
56
+ const data = (await response.json());
57
+ if (data.error) {
58
+ throw new Error(`GitHub OAuth error: ${data.error} - ${data.error_description ?? "unknown"}`);
59
+ }
60
+ return {
61
+ accessToken: data.access_token,
62
+ tokenType: data.token_type,
63
+ scope: data.scope,
64
+ };
65
+ }
66
+ /**
67
+ * Fetch the authenticated user's profile from GitHub.
68
+ */
69
+ async getUserProfile(accessToken) {
70
+ const response = await fetch(`${GITHUB_API_URL}/user`, {
71
+ headers: {
72
+ Authorization: `Bearer ${accessToken}`,
73
+ Accept: "application/json",
74
+ },
75
+ });
76
+ if (!response.ok) {
77
+ throw new Error(`GitHub API user fetch failed: ${response.status} ${response.statusText}`);
78
+ }
79
+ const data = (await response.json());
80
+ return {
81
+ id: String(data.id),
82
+ login: data.login,
83
+ name: data.name ?? data.login,
84
+ email: data.email ?? `${data.login}@users.noreply.github.com`,
85
+ avatarUrl: data.avatar_url,
86
+ provider: "github",
87
+ };
88
+ }
89
+ }
@@ -0,0 +1,8 @@
1
+ export { UserSchema, type User, AuthTokenSchema, type AuthToken, JWTPayloadSchema, type JWTPayload, SSHKeyPairSchema, type SSHKeyPair, GitForgeConfigSchema, type GitForgeConfig, GitHubOAuthConfigSchema, type GitHubOAuthConfig, GitHubAppConfigSchema, type GitHubAppConfig, } from "./types.js";
2
+ export { signAccessToken, signRefreshToken, verifyToken, refreshAccessToken, } from "./jwt.js";
3
+ export { generateSSHKeyPair, parsePublicKey, calculateFingerprint, formatAuthorizedKey, } from "./ssh-keys.js";
4
+ export { GitHubOAuthClient } from "./github-oauth.js";
5
+ export { GitHubAppClient, type Installation, type CreateKeyPROpts, type CreateKeyPRResult, } from "./github-app.js";
6
+ export { type GitForge, type PullRequestOpts, type PullRequestResult, type PushFileOpts, type RepoInfo, GitHubForge, createForge, } from "./forge-interface.js";
7
+ export { createAuthMiddleware, type AuthMiddlewareOpts, } from "./middleware.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,UAAU,EACV,KAAK,IAAI,EACT,eAAe,EACf,KAAK,SAAS,EACd,gBAAgB,EAChB,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,UAAU,EACf,oBAAoB,EACpB,KAAK,cAAc,EACnB,uBAAuB,EACvB,KAAK,iBAAiB,EACtB,qBAAqB,EACrB,KAAK,eAAe,GACrB,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAGlB,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD,OAAO,EACL,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,QAAQ,EACb,WAAW,EACX,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,oBAAoB,EACpB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,14 @@
1
+ // Types and Zod schemas
2
+ export { UserSchema, AuthTokenSchema, JWTPayloadSchema, SSHKeyPairSchema, GitForgeConfigSchema, GitHubOAuthConfigSchema, GitHubAppConfigSchema, } from "./types.js";
3
+ // JWT utilities
4
+ export { signAccessToken, signRefreshToken, verifyToken, refreshAccessToken, } from "./jwt.js";
5
+ // SSH key management
6
+ export { generateSSHKeyPair, parsePublicKey, calculateFingerprint, formatAuthorizedKey, } from "./ssh-keys.js";
7
+ // GitHub OAuth client
8
+ export { GitHubOAuthClient } from "./github-oauth.js";
9
+ // GitHub App client
10
+ export { GitHubAppClient, } from "./github-app.js";
11
+ // Forge interface
12
+ export { GitHubForge, createForge, } from "./forge-interface.js";
13
+ // Auth middleware
14
+ export { createAuthMiddleware, } from "./middleware.js";
@@ -0,0 +1,24 @@
1
+ import type { StringValue } from "ms";
2
+ import type { JWTPayload } from "./types.js";
3
+ /**
4
+ * Sign a JWT access token with the given payload and secret.
5
+ */
6
+ export declare function signAccessToken(payload: Pick<JWTPayload, "sub" | "login" | "name">, secret: string, expiresIn?: StringValue | number): string;
7
+ /**
8
+ * Sign a JWT refresh token with the given payload and secret.
9
+ */
10
+ export declare function signRefreshToken(payload: Pick<JWTPayload, "sub" | "login" | "name">, secret: string, expiresIn?: StringValue | number): string;
11
+ /**
12
+ * Verify a JWT token and return its decoded payload.
13
+ * Throws if the token is invalid or expired.
14
+ */
15
+ export declare function verifyToken(token: string, secret: string): JWTPayload;
16
+ /**
17
+ * Refresh an access token using a valid refresh token.
18
+ * Returns a new access token and a new refresh token.
19
+ */
20
+ export declare function refreshAccessToken(refreshToken: string, secret: string): {
21
+ accessToken: string;
22
+ refreshToken: string;
23
+ };
24
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AAEtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAW7C;;GAEG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,EACnD,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,WAAW,GAAG,MAAoC,GAC5D,MAAM,CAMR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC,EACnD,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,WAAW,GAAG,MAAqC,GAC7D,MAAM,CAMR;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAIrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAa/C"}