@joynt/foundry 0.0.0-stage → 0.1.50

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 (216) hide show
  1. package/dist/backends/command.d.ts +37 -0
  2. package/dist/backends/command.d.ts.map +1 -0
  3. package/dist/backends/command.js +79 -0
  4. package/dist/backends/command.js.map +1 -0
  5. package/dist/backends/index.d.ts +9 -0
  6. package/dist/backends/index.d.ts.map +1 -0
  7. package/dist/backends/index.js +37 -0
  8. package/dist/backends/index.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +191 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/commands/action.d.ts +6 -0
  14. package/dist/commands/action.d.ts.map +1 -0
  15. package/dist/commands/action.js +171 -0
  16. package/dist/commands/action.js.map +1 -0
  17. package/dist/commands/cancelled.d.ts +5 -0
  18. package/dist/commands/cancelled.d.ts.map +1 -0
  19. package/dist/commands/cancelled.js +107 -0
  20. package/dist/commands/cancelled.js.map +1 -0
  21. package/dist/commands/init.d.ts +5 -0
  22. package/dist/commands/init.d.ts.map +1 -0
  23. package/dist/commands/init.js +323 -0
  24. package/dist/commands/init.js.map +1 -0
  25. package/dist/commands/preview.d.ts +4 -0
  26. package/dist/commands/preview.d.ts.map +1 -0
  27. package/dist/commands/preview.js +108 -0
  28. package/dist/commands/preview.js.map +1 -0
  29. package/dist/commands/release.d.ts +2 -0
  30. package/dist/commands/release.d.ts.map +1 -0
  31. package/dist/commands/release.js +89 -0
  32. package/dist/commands/release.js.map +1 -0
  33. package/dist/commands/report.d.ts +14 -0
  34. package/dist/commands/report.d.ts.map +1 -0
  35. package/dist/commands/report.js +91 -0
  36. package/dist/commands/report.js.map +1 -0
  37. package/dist/commands/reset.d.ts +4 -0
  38. package/dist/commands/reset.d.ts.map +1 -0
  39. package/dist/commands/reset.js +155 -0
  40. package/dist/commands/reset.js.map +1 -0
  41. package/dist/commands/review.d.ts +2 -0
  42. package/dist/commands/review.d.ts.map +1 -0
  43. package/dist/commands/review.js +73 -0
  44. package/dist/commands/review.js.map +1 -0
  45. package/dist/commands/setup-bot.d.ts +31 -0
  46. package/dist/commands/setup-bot.d.ts.map +1 -0
  47. package/dist/commands/setup-bot.js +429 -0
  48. package/dist/commands/setup-bot.js.map +1 -0
  49. package/dist/commands/sync.d.ts +2 -0
  50. package/dist/commands/sync.d.ts.map +1 -0
  51. package/dist/commands/sync.js +77 -0
  52. package/dist/commands/sync.js.map +1 -0
  53. package/dist/config.d.ts +9 -0
  54. package/dist/config.d.ts.map +1 -0
  55. package/dist/config.js +147 -0
  56. package/dist/config.js.map +1 -0
  57. package/dist/index.d.ts +15 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +29 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/lib/agent-output.d.ts +49 -0
  62. package/dist/lib/agent-output.d.ts.map +1 -0
  63. package/dist/lib/agent-output.js +256 -0
  64. package/dist/lib/agent-output.js.map +1 -0
  65. package/dist/lib/agent-report.d.ts +107 -0
  66. package/dist/lib/agent-report.d.ts.map +1 -0
  67. package/dist/lib/agent-report.js +233 -0
  68. package/dist/lib/agent-report.js.map +1 -0
  69. package/dist/lib/authorize.d.ts +3 -0
  70. package/dist/lib/authorize.d.ts.map +1 -0
  71. package/dist/lib/authorize.js +67 -0
  72. package/dist/lib/authorize.js.map +1 -0
  73. package/dist/lib/branches.d.ts +22 -0
  74. package/dist/lib/branches.d.ts.map +1 -0
  75. package/dist/lib/branches.js +82 -0
  76. package/dist/lib/branches.js.map +1 -0
  77. package/dist/lib/claim.d.ts +22 -0
  78. package/dist/lib/claim.d.ts.map +1 -0
  79. package/dist/lib/claim.js +129 -0
  80. package/dist/lib/claim.js.map +1 -0
  81. package/dist/lib/completion.d.ts +5 -0
  82. package/dist/lib/completion.d.ts.map +1 -0
  83. package/dist/lib/completion.js +63 -0
  84. package/dist/lib/completion.js.map +1 -0
  85. package/dist/lib/deployments.d.ts +21 -0
  86. package/dist/lib/deployments.d.ts.map +1 -0
  87. package/dist/lib/deployments.js +104 -0
  88. package/dist/lib/deployments.js.map +1 -0
  89. package/dist/lib/event-handler.d.ts +74 -0
  90. package/dist/lib/event-handler.d.ts.map +1 -0
  91. package/dist/lib/event-handler.js +1002 -0
  92. package/dist/lib/event-handler.js.map +1 -0
  93. package/dist/lib/events.d.ts +72 -0
  94. package/dist/lib/events.d.ts.map +1 -0
  95. package/dist/lib/events.js +3 -0
  96. package/dist/lib/events.js.map +1 -0
  97. package/dist/lib/gh-cli-client.d.ts +46 -0
  98. package/dist/lib/gh-cli-client.d.ts.map +1 -0
  99. package/dist/lib/gh-cli-client.js +260 -0
  100. package/dist/lib/gh-cli-client.js.map +1 -0
  101. package/dist/lib/git.d.ts +42 -0
  102. package/dist/lib/git.d.ts.map +1 -0
  103. package/dist/lib/git.js +247 -0
  104. package/dist/lib/git.js.map +1 -0
  105. package/dist/lib/github-client.d.ts +98 -0
  106. package/dist/lib/github-client.d.ts.map +1 -0
  107. package/dist/lib/github-client.js +3 -0
  108. package/dist/lib/github-client.js.map +1 -0
  109. package/dist/lib/github.d.ts +82 -0
  110. package/dist/lib/github.d.ts.map +1 -0
  111. package/dist/lib/github.js +202 -0
  112. package/dist/lib/github.js.map +1 -0
  113. package/dist/lib/issue-file.d.ts +15 -0
  114. package/dist/lib/issue-file.d.ts.map +1 -0
  115. package/dist/lib/issue-file.js +84 -0
  116. package/dist/lib/issue-file.js.map +1 -0
  117. package/dist/lib/labels.d.ts +14 -0
  118. package/dist/lib/labels.d.ts.map +1 -0
  119. package/dist/lib/labels.js +70 -0
  120. package/dist/lib/labels.js.map +1 -0
  121. package/dist/lib/log.d.ts +11 -0
  122. package/dist/lib/log.d.ts.map +1 -0
  123. package/dist/lib/log.js +53 -0
  124. package/dist/lib/log.js.map +1 -0
  125. package/dist/lib/octokit-client.d.ts +112 -0
  126. package/dist/lib/octokit-client.d.ts.map +1 -0
  127. package/dist/lib/octokit-client.js +507 -0
  128. package/dist/lib/octokit-client.js.map +1 -0
  129. package/dist/lib/preview-verify.d.ts +48 -0
  130. package/dist/lib/preview-verify.d.ts.map +1 -0
  131. package/dist/lib/preview-verify.js +148 -0
  132. package/dist/lib/preview-verify.js.map +1 -0
  133. package/dist/lib/preview.d.ts +33 -0
  134. package/dist/lib/preview.d.ts.map +1 -0
  135. package/dist/lib/preview.js +308 -0
  136. package/dist/lib/preview.js.map +1 -0
  137. package/dist/lib/reconcile.d.ts +14 -0
  138. package/dist/lib/reconcile.d.ts.map +1 -0
  139. package/dist/lib/reconcile.js +114 -0
  140. package/dist/lib/reconcile.js.map +1 -0
  141. package/dist/lib/review.d.ts +38 -0
  142. package/dist/lib/review.d.ts.map +1 -0
  143. package/dist/lib/review.js +284 -0
  144. package/dist/lib/review.js.map +1 -0
  145. package/dist/lib/stale-prs.d.ts +31 -0
  146. package/dist/lib/stale-prs.d.ts.map +1 -0
  147. package/dist/lib/stale-prs.js +161 -0
  148. package/dist/lib/stale-prs.js.map +1 -0
  149. package/dist/lib/state-store.d.ts +23 -0
  150. package/dist/lib/state-store.d.ts.map +1 -0
  151. package/dist/lib/state-store.js +3 -0
  152. package/dist/lib/state-store.js.map +1 -0
  153. package/dist/lib/state.d.ts +23 -0
  154. package/dist/lib/state.d.ts.map +1 -0
  155. package/dist/lib/state.js +57 -0
  156. package/dist/lib/state.js.map +1 -0
  157. package/dist/lib/status-comment.d.ts +14 -0
  158. package/dist/lib/status-comment.d.ts.map +1 -0
  159. package/dist/lib/status-comment.js +195 -0
  160. package/dist/lib/status-comment.js.map +1 -0
  161. package/dist/lib/stores/file-store.d.ts +22 -0
  162. package/dist/lib/stores/file-store.d.ts.map +1 -0
  163. package/dist/lib/stores/file-store.js +172 -0
  164. package/dist/lib/stores/file-store.js.map +1 -0
  165. package/dist/lib/stores/index.d.ts +13 -0
  166. package/dist/lib/stores/index.d.ts.map +1 -0
  167. package/dist/lib/stores/index.js +20 -0
  168. package/dist/lib/stores/index.js.map +1 -0
  169. package/dist/lib/task-recovery.d.ts +22 -0
  170. package/dist/lib/task-recovery.d.ts.map +1 -0
  171. package/dist/lib/task-recovery.js +172 -0
  172. package/dist/lib/task-recovery.js.map +1 -0
  173. package/dist/lib/templates.d.ts +8 -0
  174. package/dist/lib/templates.d.ts.map +1 -0
  175. package/dist/lib/templates.js +58 -0
  176. package/dist/lib/templates.js.map +1 -0
  177. package/dist/lib/thread.d.ts +13 -0
  178. package/dist/lib/thread.d.ts.map +1 -0
  179. package/dist/lib/thread.js +75 -0
  180. package/dist/lib/thread.js.map +1 -0
  181. package/dist/lib/verify.d.ts +31 -0
  182. package/dist/lib/verify.d.ts.map +1 -0
  183. package/dist/lib/verify.js +90 -0
  184. package/dist/lib/verify.js.map +1 -0
  185. package/dist/lib/version.d.ts +9 -0
  186. package/dist/lib/version.d.ts.map +1 -0
  187. package/dist/lib/version.js +134 -0
  188. package/dist/lib/version.js.map +1 -0
  189. package/dist/lib/webhook.d.ts +39 -0
  190. package/dist/lib/webhook.d.ts.map +1 -0
  191. package/dist/lib/webhook.js +248 -0
  192. package/dist/lib/webhook.js.map +1 -0
  193. package/dist/lib/worker.d.ts +42 -0
  194. package/dist/lib/worker.d.ts.map +1 -0
  195. package/dist/lib/worker.js +9 -0
  196. package/dist/lib/worker.js.map +1 -0
  197. package/dist/lib/workers/index.d.ts +11 -0
  198. package/dist/lib/workers/index.d.ts.map +1 -0
  199. package/dist/lib/workers/index.js +18 -0
  200. package/dist/lib/workers/index.js.map +1 -0
  201. package/dist/lib/workers/subprocess.d.ts +8 -0
  202. package/dist/lib/workers/subprocess.d.ts.map +1 -0
  203. package/dist/lib/workers/subprocess.js +105 -0
  204. package/dist/lib/workers/subprocess.js.map +1 -0
  205. package/dist/lib/worktree.d.ts +21 -0
  206. package/dist/lib/worktree.d.ts.map +1 -0
  207. package/dist/lib/worktree.js +113 -0
  208. package/dist/lib/worktree.js.map +1 -0
  209. package/dist/types.d.ts +201 -0
  210. package/dist/types.d.ts.map +1 -0
  211. package/dist/types.js +6 -0
  212. package/dist/types.js.map +1 -0
  213. package/package.json +44 -4
  214. package/templates/foundry.yml +121 -0
  215. package/templates/vercel-preview-url.sh +61 -0
  216. package/README.md +0 -3
@@ -0,0 +1,429 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.buildManifest = buildManifest;
37
+ exports.repoSlugFromRemote = repoSlugFromRemote;
38
+ exports.runSetupBot = runSetupBot;
39
+ /**
40
+ * foundry setup-bot — create a GitHub App via manifest flow and install it.
41
+ *
42
+ * UX: two browser clicks, zero manual config.
43
+ * 1. Opens browser to GitHub App manifest creation page
44
+ * 2. Receives callback with code, exchanges for credentials
45
+ * 3. Opens browser to install the App on repos
46
+ * 4. Polls for installation, saves credentials
47
+ * 5. Verifies API access
48
+ */
49
+ const fs = __importStar(require("node:fs"));
50
+ const path = __importStar(require("node:path"));
51
+ const os = __importStar(require("node:os"));
52
+ const http = __importStar(require("node:http"));
53
+ const node_child_process_1 = require("node:child_process");
54
+ const log = __importStar(require("../lib/log.js"));
55
+ const config_js_1 = require("../config.js");
56
+ const STATE_DIR = path.join(os.homedir(), '.joynt-foundry');
57
+ /**
58
+ * Build the GitHub App manifest JSON.
59
+ */
60
+ function buildManifest(name, redirectUrl, serverUrl) {
61
+ return {
62
+ name,
63
+ url: 'https://github.com/joyntshops/foundry',
64
+ hook_attributes: {
65
+ url: serverUrl ?? 'https://example.com/unused',
66
+ active: false,
67
+ },
68
+ redirect_url: redirectUrl,
69
+ public: false,
70
+ default_permissions: {
71
+ issues: 'write',
72
+ pull_requests: 'write',
73
+ contents: 'write',
74
+ metadata: 'read',
75
+ checks: 'write',
76
+ },
77
+ default_events: ['issues', 'pull_request', 'pull_request_review', 'issue_comment'],
78
+ };
79
+ }
80
+ /**
81
+ * Open a URL in the user's browser.
82
+ */
83
+ function openBrowser(url) {
84
+ try {
85
+ if (process.platform === 'darwin') {
86
+ (0, node_child_process_1.execFileSync)('open', [url]);
87
+ }
88
+ else if (process.platform === 'win32') {
89
+ (0, node_child_process_1.execFileSync)('cmd', ['/c', 'start', url]);
90
+ }
91
+ else {
92
+ (0, node_child_process_1.execFileSync)('xdg-open', [url]);
93
+ }
94
+ }
95
+ catch {
96
+ log.warn(`Could not open browser automatically. Open this URL manually:\n ${url}`);
97
+ }
98
+ }
99
+ /**
100
+ * Start a temporary HTTP server and wait for a callback with a `code` query param.
101
+ * Returns the code from the GitHub redirect.
102
+ */
103
+ function waitForCallback(port) {
104
+ return new Promise((resolve, reject) => {
105
+ const server = http.createServer((req, res) => {
106
+ const url = new URL(req.url ?? '/', `http://localhost:${port}`);
107
+ if (url.pathname === '/callback') {
108
+ const code = url.searchParams.get('code');
109
+ if (code) {
110
+ res.writeHead(200, { 'Content-Type': 'text/html' });
111
+ res.end('<html><body><h2>Success! You can close this tab and return to the terminal.</h2></body></html>');
112
+ server.close();
113
+ resolve(code);
114
+ }
115
+ else {
116
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
117
+ res.end('Missing code parameter');
118
+ }
119
+ }
120
+ else {
121
+ res.writeHead(404);
122
+ res.end();
123
+ }
124
+ });
125
+ server.listen(port, '127.0.0.1');
126
+ server.on('error', reject);
127
+ // Timeout after 5 minutes
128
+ const timeout = setTimeout(() => {
129
+ server.close();
130
+ reject(new Error('Timed out waiting for GitHub callback (5 minutes).'));
131
+ }, 5 * 60 * 1000);
132
+ server.on('close', () => clearTimeout(timeout));
133
+ });
134
+ }
135
+ /**
136
+ * Find a free port for the callback server.
137
+ */
138
+ function findFreePort() {
139
+ return new Promise((resolve, reject) => {
140
+ const srv = http.createServer();
141
+ srv.listen(0, '127.0.0.1', () => {
142
+ const addr = srv.address();
143
+ if (addr && typeof addr === 'object') {
144
+ const port = addr.port;
145
+ srv.close(() => resolve(port));
146
+ }
147
+ else {
148
+ srv.close(() => reject(new Error('Could not determine port')));
149
+ }
150
+ });
151
+ srv.on('error', reject);
152
+ });
153
+ }
154
+ /**
155
+ * Exchange the manifest code for App credentials.
156
+ */
157
+ async function exchangeCode(code) {
158
+ const res = await fetch(`https://api.github.com/app-manifests/${code}/conversions`, {
159
+ method: 'POST',
160
+ headers: {
161
+ Accept: 'application/vnd.github+json',
162
+ 'User-Agent': 'joynt-foundry',
163
+ },
164
+ });
165
+ if (!res.ok) {
166
+ const body = await res.text();
167
+ throw new Error(`GitHub App manifest exchange failed (${res.status}): ${body}`);
168
+ }
169
+ return res.json();
170
+ }
171
+ /**
172
+ * Check if the App already has an installation (e.g., user installed it manually).
173
+ * Returns the installation ID, or null if none found.
174
+ */
175
+ async function findExistingInstallation(appId, privateKey) {
176
+ const { createAppAuth } = await import('@octokit/auth-app');
177
+ const { Octokit } = await import('@octokit/rest');
178
+ const octokit = new Octokit({
179
+ authStrategy: createAppAuth,
180
+ auth: { appId: String(appId), privateKey },
181
+ });
182
+ try {
183
+ const { data: installations } = await octokit.rest.apps.listInstallations({ per_page: 1 });
184
+ if (installations.length > 0) {
185
+ return installations[0].id;
186
+ }
187
+ }
188
+ catch {
189
+ // Auth may not be working
190
+ }
191
+ return null;
192
+ }
193
+ /**
194
+ * Poll for an installation of the App.
195
+ * Returns the installation ID, or null if timed out.
196
+ */
197
+ async function pollForInstallation(appId, privateKey, maxWaitMs = 5 * 60 * 1000) {
198
+ const start = Date.now();
199
+ const pollInterval = 3000;
200
+ while (Date.now() - start < maxWaitMs) {
201
+ const id = await findExistingInstallation(appId, privateKey);
202
+ if (id !== null)
203
+ return id;
204
+ await new Promise(r => setTimeout(r, pollInterval));
205
+ }
206
+ return null;
207
+ }
208
+ /**
209
+ * Verify the App can make API calls by listing repos for the installation.
210
+ */
211
+ async function verifyAppAuth(appId, privateKey, installationId) {
212
+ const { createAppAuth } = await import('@octokit/auth-app');
213
+ const { Octokit } = await import('@octokit/rest');
214
+ const octokit = new Octokit({
215
+ authStrategy: createAppAuth,
216
+ auth: { appId, privateKey, installationId },
217
+ });
218
+ try {
219
+ await octokit.rest.apps.listReposAccessibleToInstallation({ per_page: 1 });
220
+ return true;
221
+ }
222
+ catch {
223
+ return false;
224
+ }
225
+ }
226
+ /**
227
+ * Detect repo slug (owner/repo) from git remote origin URL.
228
+ * Works without any GitHub auth — just reads the local git config.
229
+ * Supports SSH (git@github.com:owner/repo.git) and HTTPS (https://github.com/owner/repo.git).
230
+ */
231
+ function repoSlugFromRemote() {
232
+ try {
233
+ const url = (0, node_child_process_1.execFileSync)('git', ['remote', 'get-url', 'origin'], {
234
+ encoding: 'utf-8',
235
+ timeout: 5_000,
236
+ }).trim();
237
+ // SSH: git@github.com:owner/repo.git
238
+ const sshMatch = url.match(/github\.com[:/](.+?\/.+?)(?:\.git)?$/);
239
+ if (sshMatch)
240
+ return sshMatch[1];
241
+ // HTTPS: https://github.com/owner/repo.git
242
+ const httpsMatch = url.match(/github\.com\/(.+?\/.+?)(?:\.git)?$/);
243
+ if (httpsMatch)
244
+ return httpsMatch[1];
245
+ return null;
246
+ }
247
+ catch {
248
+ return null;
249
+ }
250
+ }
251
+ /**
252
+ * Main setup-bot flow.
253
+ */
254
+ async function runSetupBot(opts = {}) {
255
+ const config = (0, config_js_1.loadConfigSafe)();
256
+ const repo = config?.repo || repoSlugFromRemote();
257
+ if (!repo) {
258
+ log.error('Could not determine repo. Run from a git repo with a GitHub remote, or run `foundry init` first.');
259
+ process.exitCode = 1;
260
+ return;
261
+ }
262
+ const org = repo.split('/')[0];
263
+ const jsonPath = path.join(STATE_DIR, `github-app-${org}.json`);
264
+ const pemPath = path.join(STATE_DIR, `github-app-${org}.pem`);
265
+ // ── Resume logic: detect partial state and pick up where we left off ──
266
+ let appId;
267
+ let slug;
268
+ let privateKey;
269
+ let installationId;
270
+ let webhookSecret;
271
+ if (fs.existsSync(jsonPath) && fs.existsSync(pemPath)) {
272
+ const meta = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
273
+ appId = meta.appId;
274
+ slug = meta.slug;
275
+ webhookSecret = meta.webhookSecret;
276
+ privateKey = fs.readFileSync(pemPath, 'utf-8');
277
+ if (meta.installationId) {
278
+ // Fully configured — verify and exit
279
+ log.info(`GitHub App already configured for ${org} (${slug}, ID: ${appId}).`);
280
+ const ok = await verifyAppAuth(String(appId), privateKey, String(meta.installationId));
281
+ if (ok) {
282
+ log.success('Verified — API access is working.');
283
+ }
284
+ else {
285
+ log.warn('App credentials exist but API verification failed. Check the App installation on GitHub.');
286
+ }
287
+ return;
288
+ }
289
+ // App created but installationId missing — check if installed out-of-band
290
+ log.info(`App "${slug}" (ID: ${appId}) exists but installation is not recorded. Checking...`);
291
+ const existingId = await findExistingInstallation(appId, privateKey);
292
+ if (existingId !== null) {
293
+ installationId = existingId;
294
+ log.success(`Found existing installation (ID: ${installationId})`);
295
+ }
296
+ else {
297
+ log.info('No installation found. Continuing with installation step...');
298
+ }
299
+ }
300
+ // ── Step 1: Create the App (skip if already created) ──
301
+ if (!appId || !privateKey) {
302
+ log.info(`Setting up Foundry Bot for ${org}...`);
303
+ log.info('');
304
+ // Determine if the owner is a GitHub org or a personal account
305
+ let isOrg = false;
306
+ try {
307
+ const ghType = (0, node_child_process_1.execFileSync)('gh', ['api', `/users/${org}`, '--jq', '.type'], {
308
+ encoding: 'utf-8',
309
+ timeout: 10_000,
310
+ }).trim();
311
+ isOrg = ghType === 'Organization';
312
+ }
313
+ catch {
314
+ try {
315
+ const resp = await fetch(`https://api.github.com/users/${org}`, {
316
+ headers: { 'User-Agent': 'joynt-foundry' },
317
+ });
318
+ if (resp.ok) {
319
+ const data = await resp.json();
320
+ isOrg = data.type === 'Organization';
321
+ }
322
+ }
323
+ catch {
324
+ isOrg = true;
325
+ }
326
+ }
327
+ // Find a free port and start the callback server
328
+ const port = await findFreePort();
329
+ const redirectUrl = `http://localhost:${port}/callback`;
330
+ // Build manifest
331
+ const appName = `Foundry Bot ${org}`;
332
+ const manifest = buildManifest(appName, redirectUrl, opts.serverUrl);
333
+ // Serve the form page
334
+ const manifestJsonForJs = JSON.stringify(JSON.stringify(manifest));
335
+ const settingsBase = isOrg
336
+ ? `https://github.com/organizations/${org}/settings/apps/new`
337
+ : 'https://github.com/settings/apps/new';
338
+ const formServer = http.createServer((_req, res) => {
339
+ res.writeHead(200, { 'Content-Type': 'text/html' });
340
+ res.end(`<!DOCTYPE html>
341
+ <html>
342
+ <head><title>Foundry Bot Setup</title></head>
343
+ <body style="font-family: system-ui, sans-serif; max-width: 500px; margin: 80px auto; text-align: center;">
344
+ <h2>Create Foundry Bot</h2>
345
+ <p>Click below to create a GitHub App for <strong>${org}</strong>.</p>
346
+ <form id="f" method="post" action="${settingsBase}">
347
+ <input type="hidden" id="manifest" name="manifest">
348
+ <button type="submit" style="font-size: 16px; padding: 12px 24px; cursor: pointer; background: #2ea44f; color: white; border: none; border-radius: 6px;">
349
+ Create GitHub App
350
+ </button>
351
+ </form>
352
+ <script>
353
+ document.getElementById('manifest').value = ${manifestJsonForJs};
354
+ </script>
355
+ </body>
356
+ </html>`);
357
+ });
358
+ const formPort = await findFreePort();
359
+ await new Promise((resolve) => {
360
+ formServer.listen(formPort, '127.0.0.1', resolve);
361
+ });
362
+ const codePromise = waitForCallback(port);
363
+ const formUrl = `http://localhost:${formPort}`;
364
+ log.info('Opening browser — click "Create GitHub App" to continue...');
365
+ log.info(` ${formUrl}`);
366
+ openBrowser(formUrl);
367
+ log.info('');
368
+ log.info('Waiting for GitHub redirect... (press Ctrl+C to cancel)');
369
+ let code;
370
+ try {
371
+ code = await codePromise;
372
+ }
373
+ finally {
374
+ formServer.close();
375
+ }
376
+ log.info('');
377
+ const appData = await exchangeCode(code);
378
+ // Save credentials (without installationId for now)
379
+ fs.mkdirSync(STATE_DIR, { recursive: true });
380
+ fs.writeFileSync(pemPath, appData.pem, { mode: 0o600 });
381
+ log.success(`Private key saved to ${pemPath}`);
382
+ appId = appData.id;
383
+ slug = appData.slug;
384
+ privateKey = appData.pem;
385
+ webhookSecret = appData.webhook_secret;
386
+ const metaJson = { appId, slug, webhookSecret };
387
+ fs.writeFileSync(jsonPath, JSON.stringify(metaJson, null, 2) + '\n');
388
+ log.success(`App created: ${slug} (ID: ${appId})`);
389
+ }
390
+ // ── Step 2: Install the App (skip if already installed) ──
391
+ if (!installationId) {
392
+ const installUrl = `https://github.com/apps/${slug}/installations/new`;
393
+ log.info('');
394
+ log.info('Now install the app on your repos:');
395
+ log.info(` ${installUrl}`);
396
+ openBrowser(installUrl);
397
+ log.info('');
398
+ log.info('Waiting for installation... (press Ctrl+C to cancel)');
399
+ installationId = await pollForInstallation(appId, privateKey, 5 * 60 * 1000) ?? undefined;
400
+ if (!installationId) {
401
+ log.warn('Timed out waiting for installation.');
402
+ log.info('If you already installed the app, re-run `foundry setup-bot` to detect it.');
403
+ log.info(`Or install it now at: ${installUrl}`);
404
+ process.exitCode = 1;
405
+ return;
406
+ }
407
+ log.success(`Installation confirmed (ID: ${installationId})`);
408
+ }
409
+ // ── Step 3: Save final state and verify ──
410
+ const fullMeta = { appId, slug, installationId, webhookSecret };
411
+ fs.writeFileSync(jsonPath, JSON.stringify(fullMeta, null, 2) + '\n');
412
+ const ok = await verifyAppAuth(String(appId), privateKey, String(installationId));
413
+ if (ok) {
414
+ log.success('Test API call successful — actions will appear as "Foundry Bot[bot]"');
415
+ }
416
+ else {
417
+ log.warn('Test API call failed — the App may need additional permissions.');
418
+ }
419
+ log.info('');
420
+ log.success(`Setup complete. CLI commands on this machine use the saved credentials for ${org} repos automatically.`);
421
+ log.info('');
422
+ log.info('For the GitHub Action, add two repository secrets (the workflow template reads these names):');
423
+ log.info(` gh secret set FOUNDRY_APP_ID --repo ${org}/<repo> --body ${appId}`);
424
+ log.info(` gh secret set FOUNDRY_APP_PRIVATE_KEY --repo ${org}/<repo> < ${pemPath}`);
425
+ log.info('');
426
+ log.info('Then, in the App\'s settings, add Actions and Deployments (write) and accept the');
427
+ log.info('permission update on the installation; the manifest cannot request them.');
428
+ }
429
+ //# sourceMappingURL=setup-bot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-bot.js","sourceRoot":"","sources":["../../src/commands/setup-bot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runSyncIntegration(): Promise<void>;
2
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAWA,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiCxD"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runSyncIntegration = runSyncIntegration;
37
+ /**
38
+ * foundry sync-integration — merge the production branch into the integration branch.
39
+ *
40
+ * Used after hotfix releases to keep integration current with production.
41
+ * Branch names come from `branches:` in .joynt-foundry.yml.
42
+ */
43
+ const config_js_1 = require("../config.js");
44
+ const git = __importStar(require("../lib/git.js"));
45
+ const log = __importStar(require("../lib/log.js"));
46
+ const branches_js_1 = require("../lib/branches.js");
47
+ async function runSyncIntegration() {
48
+ const config = (0, config_js_1.loadConfig)();
49
+ const repoDir = (0, config_js_1.getConfigDir)();
50
+ const integration = (0, branches_js_1.integrationBranch)(config);
51
+ const production = (0, branches_js_1.productionBranch)(config);
52
+ log.info(`Syncing ${integration} with ${production}...`);
53
+ // Fetch latest
54
+ git.fetchAll(repoDir);
55
+ // Ensure we're on the integration branch
56
+ const branch = git.currentBranch(repoDir);
57
+ if (branch !== integration) {
58
+ log.error(`Must be on the integration branch (${integration}). Currently on: ${branch}`);
59
+ log.info(`Run: git checkout ${integration}`);
60
+ return;
61
+ }
62
+ // Merge production into integration
63
+ try {
64
+ git.merge(`origin/${production}`, repoDir);
65
+ log.success(`Merged ${production} into ${integration}.`);
66
+ }
67
+ catch (err) {
68
+ log.error(`Merge failed: ${err.message}`);
69
+ log.info('Resolve conflicts manually, then commit and push.');
70
+ return;
71
+ }
72
+ // Push
73
+ git.push(integration, repoDir);
74
+ log.success(`Pushed ${integration}.`);
75
+ log.info(`${integration} is now current with ${production}.`);
76
+ }
77
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,gDAiCC;AA5CD;;;;;GAKG;AACH,4CAAwD;AACxD,mDAAqC;AACrC,mDAAqC;AACrC,oDAAyE;AAElE,KAAK,UAAU,kBAAkB;IACtC,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;IAC5B,MAAM,OAAO,GAAG,IAAA,wBAAY,GAAE,CAAC;IAC/B,MAAM,WAAW,GAAG,IAAA,+BAAiB,EAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,UAAU,GAAG,IAAA,8BAAgB,EAAC,MAAM,CAAC,CAAC;IAE5C,GAAG,CAAC,IAAI,CAAC,WAAW,WAAW,SAAS,UAAU,KAAK,CAAC,CAAC;IAEzD,eAAe;IACf,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAEtB,yCAAyC;IACzC,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,GAAG,CAAC,KAAK,CAAC,sCAAsC,WAAW,oBAAoB,MAAM,EAAE,CAAC,CAAC;QACzF,GAAG,CAAC,IAAI,CAAC,qBAAqB,WAAW,EAAE,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,oCAAoC;IACpC,IAAI,CAAC;QACH,GAAG,CAAC,KAAK,CAAC,UAAU,UAAU,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3C,GAAG,CAAC,OAAO,CAAC,UAAU,UAAU,SAAS,WAAW,GAAG,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,GAAG,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1C,GAAG,CAAC,IAAI,CAAC,mDAAmD,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,OAAO;IACP,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/B,GAAG,CAAC,OAAO,CAAC,UAAU,WAAW,GAAG,CAAC,CAAC;IACtC,GAAG,CAAC,IAAI,CAAC,GAAG,WAAW,wBAAwB,UAAU,GAAG,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { FoundryConfig } from './types.js';
2
+ declare const CONFIG_FILENAME = ".joynt-foundry.yml";
3
+ declare const DEFAULTS: FoundryConfig;
4
+ export declare function findConfigPath(startDir?: string): string | null;
5
+ export declare function loadConfig(startDir?: string): FoundryConfig;
6
+ export declare function loadConfigSafe(startDir?: string): FoundryConfig | null;
7
+ export declare function getConfigDir(startDir?: string): string;
8
+ export { CONFIG_FILENAME, DEFAULTS };
9
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,QAAA,MAAM,eAAe,uBAAuB,CAAC;AAE7C,QAAA,MAAM,QAAQ,EAAE,aA0Cf,CAAC;AAuBF,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAS/D;AAED,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,CAU3D;AAED,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAMtE;AAED,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,CAAC"}