@joynt/foundry 0.0.0-stage → 0.1.51

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,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getStateDir = getStateDir;
4
+ exports.getLogDir = getLogDir;
5
+ exports.getTaskStateDir = getTaskStateDir;
6
+ exports.getRunnerId = getRunnerId;
7
+ exports.loadRunnerState = loadRunnerState;
8
+ exports.saveRunnerState = saveRunnerState;
9
+ exports.upsertTask = upsertTask;
10
+ exports.updateTaskStatus = updateTaskStatus;
11
+ exports.removeTask = removeTask;
12
+ exports.getActiveTaskCount = getActiveTaskCount;
13
+ exports.getAllTasks = getAllTasks;
14
+ exports.listTaskIssueNumbers = listTaskIssueNumbers;
15
+ exports.getTask = getTask;
16
+ const file_store_js_1 = require("./stores/file-store.js");
17
+ const store = new file_store_js_1.FileStateStore();
18
+ function getStateDir() {
19
+ return store.getStateDir();
20
+ }
21
+ function getLogDir(repo, issue) {
22
+ return store.getLogDir(repo, issue);
23
+ }
24
+ function getTaskStateDir(repo, issue) {
25
+ return store.getTaskStateDir(repo, issue);
26
+ }
27
+ function getRunnerId() {
28
+ return store.getRunnerId();
29
+ }
30
+ function loadRunnerState(repo) {
31
+ return store.loadState(repo);
32
+ }
33
+ function saveRunnerState(state) {
34
+ store.saveState(state);
35
+ }
36
+ function upsertTask(repo, task) {
37
+ store.upsertTask(repo, task);
38
+ }
39
+ function updateTaskStatus(repo, issue, status, extra) {
40
+ store.updateTaskStatus(repo, issue, status, extra);
41
+ }
42
+ function removeTask(repo, issue) {
43
+ store.removeTask(repo, issue);
44
+ }
45
+ function getActiveTaskCount(repo) {
46
+ return store.getActiveTaskCount(repo);
47
+ }
48
+ function getAllTasks(repo) {
49
+ return store.getAllTasks(repo);
50
+ }
51
+ function listTaskIssueNumbers(repo) {
52
+ return store.listTaskIssueNumbers(repo);
53
+ }
54
+ function getTask(repo, issue) {
55
+ return store.getTask(repo, issue);
56
+ }
57
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/lib/state.ts"],"names":[],"mappings":";;AAaA,kCAEC;AAED,8BAEC;AAED,0CAEC;AAED,kCAEC;AAED,0CAEC;AAED,0CAEC;AAED,gCAEC;AAED,4CAEC;AAED,gCAEC;AAED,gDAEC;AAED,kCAEC;AAED,oDAEC;AAED,0BAEC;AAtDD,0DAAwD;AAExD,MAAM,KAAK,GAAG,IAAI,8BAAc,EAAE,CAAC;AAEnC,SAAgB,WAAW;IACzB,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACtC,CAAC;AAED,SAAgB,eAAe,CAAC,IAAY,EAAE,KAAa;IACzD,OAAO,KAAK,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;AAC7B,CAAC;AAED,SAAgB,eAAe,CAAC,IAAY;IAC1C,OAAO,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,SAAgB,eAAe,CAAC,KAAkB;IAChD,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,SAAgB,UAAU,CAAC,IAAY,EAAE,IAAe;IACtD,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAY,EAAE,KAAa,EAAE,MAA2B,EAAE,KAA0B;IACnH,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AACrD,CAAC;AAED,SAAgB,UAAU,CAAC,IAAY,EAAE,KAAa;IACpD,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAChC,CAAC;AAED,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,OAAO,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,OAAO,KAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED,SAAgB,OAAO,CAAC,IAAY,EAAE,KAAa;IACjD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { TaskState } from '../types.js';
2
+ export interface StatusCommentOpts {
3
+ task: TaskState;
4
+ message?: string;
5
+ prUrl?: string;
6
+ previewUrl?: string;
7
+ historyEntry?: string;
8
+ }
9
+ export declare function buildStatusComment(opts: StatusCommentOpts): string;
10
+ /**
11
+ * Post or update the consolidated status comment on an issue.
12
+ */
13
+ export declare function updateStatusComment(repo: string, issueNumber: number, opts: StatusCommentOpts): Promise<void>;
14
+ //# sourceMappingURL=status-comment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-comment.d.ts","sourceRoot":"","sources":["../../src/lib/status-comment.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,aAAa,CAAC;AAoCzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAkDlE;AA4CD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,iBAAiB,GACtB,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -0,0 +1,195 @@
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.buildStatusComment = buildStatusComment;
37
+ exports.updateStatusComment = updateStatusComment;
38
+ /**
39
+ * Consolidated status comment — maintains a single "Foundry Status" comment
40
+ * per issue that updates in place as the task progresses.
41
+ *
42
+ * Uses the <!-- foundry-status --> marker for upsert (same pattern as preview.ts).
43
+ * The claim comment (<!-- foundry-claim-block -->) remains separate.
44
+ */
45
+ const github = __importStar(require("./github.js"));
46
+ const log = __importStar(require("./log.js"));
47
+ const COMMENT_MARKER = '<!-- foundry-status -->';
48
+ const STATUS_MAP = {
49
+ 'claimed': { emoji: '📋', label: 'Claimed' },
50
+ 'agent-running': { emoji: '🤖', label: 'Agent Running' },
51
+ 'verifying': { emoji: '🔍', label: 'Verifying' },
52
+ 'pr-open': { emoji: '🔀', label: 'PR Open' },
53
+ 'reviewing': { emoji: '👀', label: 'Reviewing' },
54
+ 'waiting-for-input': { emoji: '💬', label: 'Waiting for Input' },
55
+ 'resuming': { emoji: '▶️', label: 'Resuming' },
56
+ 'pr-changes-requested': { emoji: '🔄', label: 'Addressing Feedback' },
57
+ 'plan-review': { emoji: '📝', label: 'Plan Review' },
58
+ 'done': { emoji: '✅', label: 'Done' },
59
+ 'failed': { emoji: '❌', label: 'Failed' },
60
+ 'stopped': { emoji: '⏹️', label: 'Stopped' },
61
+ };
62
+ // ── Comment building ─────────────────────────────────────────────────────
63
+ function formatDuration(ms) {
64
+ const s = Math.round(ms / 1000);
65
+ if (s < 60)
66
+ return `${s}s`;
67
+ const m = Math.floor(s / 60);
68
+ const r = s % 60;
69
+ return r === 0 ? `${m}m` : `${m}m${String(r).padStart(2, '0')}s`;
70
+ }
71
+ function buildStatusComment(opts) {
72
+ const { task, message, prUrl, previewUrl, historyEntry } = opts;
73
+ const display = STATUS_MAP[task.status] ?? { emoji: '❓', label: task.status };
74
+ const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
75
+ const lines = [
76
+ COMMENT_MARKER,
77
+ `### ${display.emoji} Foundry Status: ${display.label}`,
78
+ '',
79
+ '| Field | Value |',
80
+ '|-------|-------|',
81
+ `| Agent | \`${task.agent_backend}\` |`,
82
+ `| Branch | \`${task.branch}\` |`,
83
+ ];
84
+ if (prUrl || task.pr_url) {
85
+ lines.push(`| PR | ${prUrl ?? task.pr_url} |`);
86
+ }
87
+ if (previewUrl || task.preview_url) {
88
+ lines.push(`| Preview | ${previewUrl ?? task.preview_url} |`);
89
+ }
90
+ const run = task.last_run;
91
+ if (run && (run.cost_usd !== undefined || run.turns !== undefined || run.duration_ms !== undefined)) {
92
+ const parts = [];
93
+ if (run.cost_usd !== undefined)
94
+ parts.push(`$${run.cost_usd.toFixed(2)}`);
95
+ if (run.turns !== undefined)
96
+ parts.push(`${run.turns} turn${run.turns === 1 ? '' : 's'}`);
97
+ if (run.duration_ms !== undefined)
98
+ parts.push(formatDuration(run.duration_ms));
99
+ lines.push(`| Last run | ${parts.join(' · ')} |`);
100
+ }
101
+ lines.push(`| Updated | ${timestamp} |`);
102
+ if (message) {
103
+ lines.push('');
104
+ lines.push('---');
105
+ lines.push('');
106
+ lines.push(message);
107
+ }
108
+ // Append history entry as a compact timeline addition
109
+ if (historyEntry) {
110
+ lines.push('');
111
+ lines.push(`_${timestamp} — ${historyEntry}_`);
112
+ }
113
+ lines.push('');
114
+ lines.push(`<!-- /foundry-status -->`);
115
+ return lines.join('\n');
116
+ }
117
+ // ── Upsert logic (find existing or create new) ──────────────────────────
118
+ /**
119
+ * Find the existing status comment for an issue, or return null.
120
+ */
121
+ async function findStatusComment(repo, issueOrPr) {
122
+ try {
123
+ const comments = await github.getComments(repo, issueOrPr);
124
+ const existing = comments.find(c => c.body.includes(COMMENT_MARKER));
125
+ if (existing) {
126
+ return { id: existing.id, body: existing.body };
127
+ }
128
+ }
129
+ catch (err) {
130
+ log.warn(`Failed to fetch comments for status upsert on #${issueOrPr}: ${err.message}`);
131
+ }
132
+ return null;
133
+ }
134
+ /**
135
+ * Preserve the history timeline from an existing status comment body.
136
+ * History entries are lines matching `_YYYY-... — ..._` at the end.
137
+ */
138
+ function extractHistory(existingBody) {
139
+ const lines = existingBody.split('\n');
140
+ const historyLines = [];
141
+ // Walk backwards from the end, collecting timeline entries
142
+ for (let i = lines.length - 1; i >= 0; i--) {
143
+ const line = lines[i].trim();
144
+ if (line === '<!-- /foundry-status -->')
145
+ continue;
146
+ if (line === '')
147
+ continue;
148
+ if (line.startsWith('_') && line.endsWith('_') && line.includes(' — ')) {
149
+ historyLines.unshift(line);
150
+ }
151
+ else {
152
+ break;
153
+ }
154
+ }
155
+ return historyLines;
156
+ }
157
+ /**
158
+ * Post or update the consolidated status comment on an issue.
159
+ */
160
+ async function updateStatusComment(repo, issueNumber, opts) {
161
+ const existing = await findStatusComment(repo, issueNumber);
162
+ // Build the new comment, preserving history from the existing one
163
+ let historyBlock = '';
164
+ if (existing) {
165
+ const previousHistory = extractHistory(existing.body);
166
+ if (opts.historyEntry) {
167
+ const timestamp = new Date().toISOString().replace('T', ' ').slice(0, 19) + ' UTC';
168
+ previousHistory.push(`_${timestamp} — ${opts.historyEntry}_`);
169
+ }
170
+ // Keep last 10 history entries to avoid bloat
171
+ const trimmedHistory = previousHistory.slice(-10);
172
+ if (trimmedHistory.length > 0) {
173
+ historyBlock = '\n' + trimmedHistory.join('\n');
174
+ }
175
+ // Build without historyEntry since we already appended it
176
+ opts = { ...opts, historyEntry: undefined };
177
+ }
178
+ let body = buildStatusComment(opts);
179
+ // Insert accumulated history before the closing marker
180
+ if (historyBlock) {
181
+ body = body.replace('\n<!-- /foundry-status -->', historyBlock + '\n\n<!-- /foundry-status -->');
182
+ }
183
+ try {
184
+ if (existing) {
185
+ await github.updateComment(repo, existing.id, body);
186
+ }
187
+ else {
188
+ await github.addComment(repo, issueNumber, body);
189
+ }
190
+ }
191
+ catch (err) {
192
+ log.warn(`Failed to upsert status comment on #${issueNumber}: ${err.message}`);
193
+ }
194
+ }
195
+ //# sourceMappingURL=status-comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status-comment.js","sourceRoot":"","sources":["../../src/lib/status-comment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { RunnerState, TaskState, TaskStatus } from '../../types.js';
2
+ import type { StateStore } from '../state-store.js';
3
+ export declare class FileStateStore implements StateStore {
4
+ private readonly stateDir;
5
+ constructor(stateDir?: string);
6
+ private stateFile;
7
+ private runnerIdFile;
8
+ getRunnerId(): string;
9
+ getStateDir(): string;
10
+ loadState(repo: string): RunnerState;
11
+ saveState(state: RunnerState): void;
12
+ upsertTask(repo: string, task: TaskState): void;
13
+ updateTaskStatus(repo: string, issue: number, status: TaskStatus, extra?: Partial<TaskState>): void;
14
+ removeTask(repo: string, issue: number): void;
15
+ getActiveTaskCount(repo: string): number;
16
+ getAllTasks(repo: string): TaskState[];
17
+ getTask(repo: string, issue: number): TaskState | undefined;
18
+ listTaskIssueNumbers(repo: string): number[];
19
+ getLogDir(repo: string, issue: number): string;
20
+ getTaskStateDir(repo: string, issue: number): string;
21
+ }
22
+ //# sourceMappingURL=file-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-store.d.ts","sourceRoot":"","sources":["../../../src/lib/stores/file-store.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAcpD,qBAAa,cAAe,YAAW,UAAU;IAC/C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,CAAC,EAAE,MAAM;IAI7B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,YAAY;IAIpB,WAAW,IAAI,MAAM;IAWrB,WAAW,IAAI,MAAM;IAKrB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IAYpC,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAKnC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAO/C,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI;IAUnG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM7C,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAOxC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE;IAKtC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAK3D,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IA6B5C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAM9C,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;CAKrD"}
@@ -0,0 +1,172 @@
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.FileStateStore = void 0;
37
+ /**
38
+ * FileStateStore — file-based state persistence under ~/.joynt-foundry/.
39
+ *
40
+ * This is a direct lift of the original lib/state.ts logic into a class
41
+ * that implements the StateStore interface. All paths and atomic-write
42
+ * semantics are preserved exactly.
43
+ */
44
+ const fs = __importStar(require("node:fs"));
45
+ const path = __importStar(require("node:path"));
46
+ const os = __importStar(require("node:os"));
47
+ const crypto = __importStar(require("node:crypto"));
48
+ const DEFAULT_STATE_DIR = path.join(os.homedir(), '.joynt-foundry');
49
+ function ensureDir(dir) {
50
+ fs.mkdirSync(dir, { recursive: true });
51
+ }
52
+ function atomicWrite(filePath, data) {
53
+ const tmp = filePath + '.tmp.' + process.pid;
54
+ fs.writeFileSync(tmp, data, 'utf-8');
55
+ fs.renameSync(tmp, filePath);
56
+ }
57
+ class FileStateStore {
58
+ stateDir;
59
+ constructor(stateDir) {
60
+ this.stateDir = stateDir ?? DEFAULT_STATE_DIR;
61
+ }
62
+ stateFile(repo) {
63
+ const safe = repo.replace(/\//g, '__');
64
+ return path.join(this.stateDir, `state-${safe}.json`);
65
+ }
66
+ runnerIdFile() {
67
+ return path.join(this.stateDir, 'runner-id');
68
+ }
69
+ getRunnerId() {
70
+ ensureDir(this.stateDir);
71
+ const file = this.runnerIdFile();
72
+ if (fs.existsSync(file)) {
73
+ return fs.readFileSync(file, 'utf-8').trim();
74
+ }
75
+ const id = `${os.hostname()}-${crypto.randomBytes(4).toString('hex')}`;
76
+ atomicWrite(file, id);
77
+ return id;
78
+ }
79
+ getStateDir() {
80
+ ensureDir(this.stateDir);
81
+ return this.stateDir;
82
+ }
83
+ loadState(repo) {
84
+ const file = this.stateFile(repo);
85
+ if (fs.existsSync(file)) {
86
+ try {
87
+ return JSON.parse(fs.readFileSync(file, 'utf-8'));
88
+ }
89
+ catch {
90
+ // corrupted — start fresh
91
+ }
92
+ }
93
+ return { runner_id: this.getRunnerId(), repo, tasks: {} };
94
+ }
95
+ saveState(state) {
96
+ ensureDir(this.stateDir);
97
+ atomicWrite(this.stateFile(state.repo), JSON.stringify(state, null, 2));
98
+ }
99
+ upsertTask(repo, task) {
100
+ const state = this.loadState(repo);
101
+ state.tasks[task.issue] = task;
102
+ state.runner_id = this.getRunnerId();
103
+ this.saveState(state);
104
+ }
105
+ updateTaskStatus(repo, issue, status, extra) {
106
+ const state = this.loadState(repo);
107
+ const t = state.tasks[issue];
108
+ if (!t)
109
+ return;
110
+ t.status = status;
111
+ t.updated_at = new Date().toISOString();
112
+ if (extra)
113
+ Object.assign(t, extra);
114
+ this.saveState(state);
115
+ }
116
+ removeTask(repo, issue) {
117
+ const state = this.loadState(repo);
118
+ delete state.tasks[issue];
119
+ this.saveState(state);
120
+ }
121
+ getActiveTaskCount(repo) {
122
+ const state = this.loadState(repo);
123
+ return Object.values(state.tasks).filter(t => !['done', 'failed', 'stopped'].includes(t.status)).length;
124
+ }
125
+ getAllTasks(repo) {
126
+ const state = this.loadState(repo);
127
+ return Object.values(state.tasks);
128
+ }
129
+ getTask(repo, issue) {
130
+ const state = this.loadState(repo);
131
+ return state.tasks[issue];
132
+ }
133
+ listTaskIssueNumbers(repo) {
134
+ const safe = repo.replace(/\//g, '__');
135
+ const tasksDir = path.join(this.stateDir, 'tasks', safe);
136
+ const issueSet = new Set();
137
+ // Scan task subdirectories (each named by issue number)
138
+ if (fs.existsSync(tasksDir)) {
139
+ try {
140
+ const entries = fs.readdirSync(tasksDir, { withFileTypes: true });
141
+ for (const entry of entries) {
142
+ if (entry.isDirectory()) {
143
+ const num = parseInt(entry.name, 10);
144
+ if (!isNaN(num))
145
+ issueSet.add(num);
146
+ }
147
+ }
148
+ }
149
+ catch { }
150
+ }
151
+ // Also include issues from state JSON
152
+ const st = this.loadState(repo);
153
+ for (const key of Object.keys(st.tasks)) {
154
+ const num = parseInt(key, 10);
155
+ if (!isNaN(num))
156
+ issueSet.add(num);
157
+ }
158
+ return Array.from(issueSet).sort((a, b) => a - b);
159
+ }
160
+ getLogDir(repo, issue) {
161
+ const dir = path.join(this.stateDir, 'logs', repo.replace(/\//g, '__'), String(issue));
162
+ ensureDir(dir);
163
+ return dir;
164
+ }
165
+ getTaskStateDir(repo, issue) {
166
+ const dir = path.join(this.stateDir, 'tasks', repo.replace(/\//g, '__'), String(issue));
167
+ ensureDir(dir);
168
+ return dir;
169
+ }
170
+ }
171
+ exports.FileStateStore = FileStateStore;
172
+ //# sourceMappingURL=file-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-store.js","sourceRoot":"","sources":["../../../src/lib/stores/file-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Store resolver — returns a StateStore based on config.
3
+ *
4
+ * Currently only 'file' is supported. Extend the switch when adding
5
+ * database-backed stores (sqlite, postgres, etc.).
6
+ */
7
+ import type { StateStore } from '../state-store.js';
8
+ export type StateStoreConfig = {
9
+ type: 'file';
10
+ };
11
+ export declare function resolveStateStore(config?: StateStoreConfig): StateStore;
12
+ export { FileStateStore } from './file-store.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/stores/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAIF,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAUvE;AAED,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileStateStore = void 0;
4
+ exports.resolveStateStore = resolveStateStore;
5
+ const file_store_js_1 = require("./file-store.js");
6
+ let _default;
7
+ function resolveStateStore(config) {
8
+ const storeType = config?.type ?? 'file';
9
+ switch (storeType) {
10
+ case 'file':
11
+ if (!_default)
12
+ _default = new file_store_js_1.FileStateStore();
13
+ return _default;
14
+ default:
15
+ throw new Error(`Unknown state_store type: ${storeType}`);
16
+ }
17
+ }
18
+ var file_store_js_2 = require("./file-store.js");
19
+ Object.defineProperty(exports, "FileStateStore", { enumerable: true, get: function () { return file_store_js_2.FileStateStore; } });
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/stores/index.ts"],"names":[],"mappings":";;;AAeA,8CAUC;AAlBD,mDAAiD;AAMjD,IAAI,QAAgC,CAAC;AAErC,SAAgB,iBAAiB,CAAC,MAAyB;IACzD,MAAM,SAAS,GAAG,MAAM,EAAE,IAAI,IAAI,MAAM,CAAC;IAEzC,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,MAAM;YACT,IAAI,CAAC,QAAQ;gBAAE,QAAQ,GAAG,IAAI,8BAAc,EAAE,CAAC;YAC/C,OAAO,QAAQ,CAAC;QAClB;YACE,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC;AAED,iDAAiD;AAAxC,+GAAA,cAAc,OAAA"}
@@ -0,0 +1,22 @@
1
+ import type { FoundryConfig, TaskState, TaskStatus, GitHubIssue } from '../types.js';
2
+ /**
3
+ * Turn a branch template like `feature/{issue}-{slug}` into a matcher that
4
+ * pulls the issue number back out of a branch name.
5
+ */
6
+ export declare function issueNumberFromBranch(template: string, branch: string): number | null;
7
+ /**
8
+ * Find the issue a webhook payload is about. Issues and comments carry it
9
+ * directly; pull requests carry it via the head branch name, with the PR
10
+ * body's `Closes #N` as a fallback.
11
+ */
12
+ export declare function issueNumberFromPayload(payload: Record<string, any>, config: FoundryConfig): number | null;
13
+ /** Map the issue's current state label to a TaskStatus. Null if untracked. */
14
+ export declare function statusFromLabels(config: FoundryConfig, labels: string[]): TaskStatus | null;
15
+ /**
16
+ * Rebuild the TaskState for an issue from GitHub. Returns null when the issue
17
+ * has never been claimed by Foundry (no claim comment). A claim with no state
18
+ * label (after `foundry reset`) comes back as `claimed`, which `@foundry go`
19
+ * treats as a fresh start.
20
+ */
21
+ export declare function recoverTask(config: FoundryConfig, repoDir: string, issueNumber: number, issue?: GitHubIssue): Promise<TaskState | null>;
22
+ //# sourceMappingURL=task-recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-recovery.d.ts","sourceRoot":"","sources":["../../src/lib/task-recovery.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAIrF;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOrF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,aAAa,GAAG,MAAM,GAAG,IAAI,CAezG;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,IAAI,CAU3F;AAUD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAqD3B"}