@vaporsoft/orc 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (223) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +178 -0
  3. package/dist/bin/orc.d.ts +3 -0
  4. package/dist/bin/orc.d.ts.map +1 -0
  5. package/dist/bin/orc.js +4 -0
  6. package/dist/bin/orc.js.map +1 -0
  7. package/dist/src/cli.d.ts +6 -0
  8. package/dist/src/cli.d.ts.map +1 -0
  9. package/dist/src/cli.js +28 -0
  10. package/dist/src/cli.js.map +1 -0
  11. package/dist/src/commands/init.d.ts +6 -0
  12. package/dist/src/commands/init.d.ts.map +1 -0
  13. package/dist/src/commands/init.js +58 -0
  14. package/dist/src/commands/init.js.map +1 -0
  15. package/dist/src/commands/start.d.ts +17 -0
  16. package/dist/src/commands/start.d.ts.map +1 -0
  17. package/dist/src/commands/start.js +146 -0
  18. package/dist/src/commands/start.js.map +1 -0
  19. package/dist/src/constants.d.ts +18 -0
  20. package/dist/src/constants.d.ts.map +1 -0
  21. package/dist/src/constants.js +42 -0
  22. package/dist/src/constants.js.map +1 -0
  23. package/dist/src/core/comment-categorizer.d.ts +20 -0
  24. package/dist/src/core/comment-categorizer.d.ts.map +1 -0
  25. package/dist/src/core/comment-categorizer.js +208 -0
  26. package/dist/src/core/comment-categorizer.js.map +1 -0
  27. package/dist/src/core/comment-fetcher.d.ts +37 -0
  28. package/dist/src/core/comment-fetcher.d.ts.map +1 -0
  29. package/dist/src/core/comment-fetcher.js +138 -0
  30. package/dist/src/core/comment-fetcher.js.map +1 -0
  31. package/dist/src/core/daemon.d.ts +92 -0
  32. package/dist/src/core/daemon.d.ts.map +1 -0
  33. package/dist/src/core/daemon.js +896 -0
  34. package/dist/src/core/daemon.js.map +1 -0
  35. package/dist/src/core/fix-executor.d.ts +50 -0
  36. package/dist/src/core/fix-executor.d.ts.map +1 -0
  37. package/dist/src/core/fix-executor.js +374 -0
  38. package/dist/src/core/fix-executor.js.map +1 -0
  39. package/dist/src/core/git-manager.d.ts +44 -0
  40. package/dist/src/core/git-manager.d.ts.map +1 -0
  41. package/dist/src/core/git-manager.js +230 -0
  42. package/dist/src/core/git-manager.js.map +1 -0
  43. package/dist/src/core/pilot-config.d.ts +18 -0
  44. package/dist/src/core/pilot-config.d.ts.map +1 -0
  45. package/dist/src/core/pilot-config.js +76 -0
  46. package/dist/src/core/pilot-config.js.map +1 -0
  47. package/dist/src/core/progress-store.d.ts +32 -0
  48. package/dist/src/core/progress-store.d.ts.map +1 -0
  49. package/dist/src/core/progress-store.js +106 -0
  50. package/dist/src/core/progress-store.js.map +1 -0
  51. package/dist/src/core/repo-config.d.ts +11 -0
  52. package/dist/src/core/repo-config.d.ts.map +1 -0
  53. package/dist/src/core/repo-config.js +168 -0
  54. package/dist/src/core/repo-config.js.map +1 -0
  55. package/dist/src/core/session-controller.d.ts +61 -0
  56. package/dist/src/core/session-controller.d.ts.map +1 -0
  57. package/dist/src/core/session-controller.js +926 -0
  58. package/dist/src/core/session-controller.js.map +1 -0
  59. package/dist/src/core/thread-responder.d.ts +28 -0
  60. package/dist/src/core/thread-responder.d.ts.map +1 -0
  61. package/dist/src/core/thread-responder.js +193 -0
  62. package/dist/src/core/thread-responder.js.map +1 -0
  63. package/dist/src/core/worktree-manager.d.ts +26 -0
  64. package/dist/src/core/worktree-manager.d.ts.map +1 -0
  65. package/dist/src/core/worktree-manager.js +189 -0
  66. package/dist/src/core/worktree-manager.js.map +1 -0
  67. package/dist/src/github/gh-client.d.ts +57 -0
  68. package/dist/src/github/gh-client.d.ts.map +1 -0
  69. package/dist/src/github/gh-client.js +236 -0
  70. package/dist/src/github/gh-client.js.map +1 -0
  71. package/dist/src/github/queries.d.ts +9 -0
  72. package/dist/src/github/queries.d.ts.map +1 -0
  73. package/dist/src/github/queries.js +152 -0
  74. package/dist/src/github/queries.js.map +1 -0
  75. package/dist/src/github/types.d.ts +114 -0
  76. package/dist/src/github/types.d.ts.map +1 -0
  77. package/dist/src/github/types.js +3 -0
  78. package/dist/src/github/types.js.map +1 -0
  79. package/dist/src/tui/App.d.ts +8 -0
  80. package/dist/src/tui/App.d.ts.map +1 -0
  81. package/dist/src/tui/App.js +407 -0
  82. package/dist/src/tui/App.js.map +1 -0
  83. package/dist/src/tui/components/ActivityPane.d.ts +7 -0
  84. package/dist/src/tui/components/ActivityPane.d.ts.map +1 -0
  85. package/dist/src/tui/components/ActivityPane.js +10 -0
  86. package/dist/src/tui/components/ActivityPane.js.map +1 -0
  87. package/dist/src/tui/components/DetailPanel.d.ts +15 -0
  88. package/dist/src/tui/components/DetailPanel.d.ts.map +1 -0
  89. package/dist/src/tui/components/DetailPanel.js +137 -0
  90. package/dist/src/tui/components/DetailPanel.js.map +1 -0
  91. package/dist/src/tui/components/DrillInOverlay.d.ts +13 -0
  92. package/dist/src/tui/components/DrillInOverlay.d.ts.map +1 -0
  93. package/dist/src/tui/components/DrillInOverlay.js +85 -0
  94. package/dist/src/tui/components/DrillInOverlay.js.map +1 -0
  95. package/dist/src/tui/components/ExpandedContent.d.ts +10 -0
  96. package/dist/src/tui/components/ExpandedContent.d.ts.map +1 -0
  97. package/dist/src/tui/components/ExpandedContent.js +99 -0
  98. package/dist/src/tui/components/ExpandedContent.js.map +1 -0
  99. package/dist/src/tui/components/Header.d.ts +12 -0
  100. package/dist/src/tui/components/Header.d.ts.map +1 -0
  101. package/dist/src/tui/components/Header.js +35 -0
  102. package/dist/src/tui/components/Header.js.map +1 -0
  103. package/dist/src/tui/components/HelpBar.d.ts +2 -0
  104. package/dist/src/tui/components/HelpBar.d.ts.map +1 -0
  105. package/dist/src/tui/components/HelpBar.js +11 -0
  106. package/dist/src/tui/components/HelpBar.js.map +1 -0
  107. package/dist/src/tui/components/KeybindLegend.d.ts +7 -0
  108. package/dist/src/tui/components/KeybindLegend.d.ts.map +1 -0
  109. package/dist/src/tui/components/KeybindLegend.js +53 -0
  110. package/dist/src/tui/components/KeybindLegend.js.map +1 -0
  111. package/dist/src/tui/components/LogPane.d.ts +11 -0
  112. package/dist/src/tui/components/LogPane.d.ts.map +1 -0
  113. package/dist/src/tui/components/LogPane.js +31 -0
  114. package/dist/src/tui/components/LogPane.js.map +1 -0
  115. package/dist/src/tui/components/SessionList.d.ts +14 -0
  116. package/dist/src/tui/components/SessionList.d.ts.map +1 -0
  117. package/dist/src/tui/components/SessionList.js +31 -0
  118. package/dist/src/tui/components/SessionList.js.map +1 -0
  119. package/dist/src/tui/components/SessionRow.d.ts +10 -0
  120. package/dist/src/tui/components/SessionRow.d.ts.map +1 -0
  121. package/dist/src/tui/components/SessionRow.js +52 -0
  122. package/dist/src/tui/components/SessionRow.js.map +1 -0
  123. package/dist/src/tui/components/SettingsPanel.d.ts +8 -0
  124. package/dist/src/tui/components/SettingsPanel.d.ts.map +1 -0
  125. package/dist/src/tui/components/SettingsPanel.js +191 -0
  126. package/dist/src/tui/components/SettingsPanel.js.map +1 -0
  127. package/dist/src/tui/components/StatusBadge.d.ts +9 -0
  128. package/dist/src/tui/components/StatusBadge.d.ts.map +1 -0
  129. package/dist/src/tui/components/StatusBadge.js +52 -0
  130. package/dist/src/tui/components/StatusBadge.js.map +1 -0
  131. package/dist/src/tui/components/Toolbar.d.ts +5 -0
  132. package/dist/src/tui/components/Toolbar.d.ts.map +1 -0
  133. package/dist/src/tui/components/Toolbar.js +2 -0
  134. package/dist/src/tui/components/Toolbar.js.map +1 -0
  135. package/dist/src/tui/components/comment-constants.d.ts +4 -0
  136. package/dist/src/tui/components/comment-constants.d.ts.map +1 -0
  137. package/dist/src/tui/components/comment-constants.js +15 -0
  138. package/dist/src/tui/components/comment-constants.js.map +1 -0
  139. package/dist/src/tui/hooks/logFlushUtils.d.ts +15 -0
  140. package/dist/src/tui/hooks/logFlushUtils.d.ts.map +1 -0
  141. package/dist/src/tui/hooks/logFlushUtils.js +33 -0
  142. package/dist/src/tui/hooks/logFlushUtils.js.map +1 -0
  143. package/dist/src/tui/hooks/useBranchLogs.d.ts +7 -0
  144. package/dist/src/tui/hooks/useBranchLogs.d.ts.map +1 -0
  145. package/dist/src/tui/hooks/useBranchLogs.js +58 -0
  146. package/dist/src/tui/hooks/useBranchLogs.js.map +1 -0
  147. package/dist/src/tui/hooks/useDaemonState.d.ts +19 -0
  148. package/dist/src/tui/hooks/useDaemonState.d.ts.map +1 -0
  149. package/dist/src/tui/hooks/useDaemonState.js +152 -0
  150. package/dist/src/tui/hooks/useDaemonState.js.map +1 -0
  151. package/dist/src/tui/hooks/useInitialDiscovery.d.ts +8 -0
  152. package/dist/src/tui/hooks/useInitialDiscovery.d.ts.map +1 -0
  153. package/dist/src/tui/hooks/useInitialDiscovery.js +31 -0
  154. package/dist/src/tui/hooks/useInitialDiscovery.js.map +1 -0
  155. package/dist/src/tui/hooks/useLogBuffer.d.ts +7 -0
  156. package/dist/src/tui/hooks/useLogBuffer.d.ts.map +1 -0
  157. package/dist/src/tui/hooks/useLogBuffer.js +52 -0
  158. package/dist/src/tui/hooks/useLogBuffer.js.map +1 -0
  159. package/dist/src/tui/hooks/useNextCheckCountdown.d.ts +7 -0
  160. package/dist/src/tui/hooks/useNextCheckCountdown.d.ts.map +1 -0
  161. package/dist/src/tui/hooks/useNextCheckCountdown.js +42 -0
  162. package/dist/src/tui/hooks/useNextCheckCountdown.js.map +1 -0
  163. package/dist/src/tui/hooks/useTerminalFocus.d.ts +9 -0
  164. package/dist/src/tui/hooks/useTerminalFocus.d.ts.map +1 -0
  165. package/dist/src/tui/hooks/useTerminalFocus.js +43 -0
  166. package/dist/src/tui/hooks/useTerminalFocus.js.map +1 -0
  167. package/dist/src/tui/theme.d.ts +32 -0
  168. package/dist/src/tui/theme.d.ts.map +1 -0
  169. package/dist/src/tui/theme.js +61 -0
  170. package/dist/src/tui/theme.js.map +1 -0
  171. package/dist/src/types/config.d.ts +35 -0
  172. package/dist/src/types/config.d.ts.map +1 -0
  173. package/dist/src/types/config.js +14 -0
  174. package/dist/src/types/config.js.map +1 -0
  175. package/dist/src/types/index.d.ts +107 -0
  176. package/dist/src/types/index.d.ts.map +1 -0
  177. package/dist/src/types/index.js +3 -0
  178. package/dist/src/types/index.js.map +1 -0
  179. package/dist/src/utils/concurrency.d.ts +7 -0
  180. package/dist/src/utils/concurrency.d.ts.map +1 -0
  181. package/dist/src/utils/concurrency.js +26 -0
  182. package/dist/src/utils/concurrency.js.map +1 -0
  183. package/dist/src/utils/format.d.ts +2 -0
  184. package/dist/src/utils/format.d.ts.map +1 -0
  185. package/dist/src/utils/format.js +8 -0
  186. package/dist/src/utils/format.js.map +1 -0
  187. package/dist/src/utils/logger.d.ts +39 -0
  188. package/dist/src/utils/logger.d.ts.map +1 -0
  189. package/dist/src/utils/logger.js +120 -0
  190. package/dist/src/utils/logger.js.map +1 -0
  191. package/dist/src/utils/notify.d.ts +6 -0
  192. package/dist/src/utils/notify.d.ts.map +1 -0
  193. package/dist/src/utils/notify.js +15 -0
  194. package/dist/src/utils/notify.js.map +1 -0
  195. package/dist/src/utils/open-terminal.d.ts +12 -0
  196. package/dist/src/utils/open-terminal.d.ts.map +1 -0
  197. package/dist/src/utils/open-terminal.js +93 -0
  198. package/dist/src/utils/open-terminal.js.map +1 -0
  199. package/dist/src/utils/process.d.ts +14 -0
  200. package/dist/src/utils/process.d.ts.map +1 -0
  201. package/dist/src/utils/process.js +36 -0
  202. package/dist/src/utils/process.js.map +1 -0
  203. package/dist/src/utils/project-detector.d.ts +12 -0
  204. package/dist/src/utils/project-detector.d.ts.map +1 -0
  205. package/dist/src/utils/project-detector.js +123 -0
  206. package/dist/src/utils/project-detector.js.map +1 -0
  207. package/dist/src/utils/quoting.d.ts +15 -0
  208. package/dist/src/utils/quoting.d.ts.map +1 -0
  209. package/dist/src/utils/quoting.js +39 -0
  210. package/dist/src/utils/quoting.js.map +1 -0
  211. package/dist/src/utils/retry.d.ts +14 -0
  212. package/dist/src/utils/retry.d.ts.map +1 -0
  213. package/dist/src/utils/retry.js +41 -0
  214. package/dist/src/utils/retry.js.map +1 -0
  215. package/dist/src/utils/settings.d.ts +14 -0
  216. package/dist/src/utils/settings.d.ts.map +1 -0
  217. package/dist/src/utils/settings.js +21 -0
  218. package/dist/src/utils/settings.js.map +1 -0
  219. package/dist/src/utils/time.d.ts +2 -0
  220. package/dist/src/utils/time.d.ts.map +1 -0
  221. package/dist/src/utils/time.js +5 -0
  222. package/dist/src/utils/time.js.map +1 -0
  223. package/package.json +73 -0
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Handles git operations for the orchestration loop:
3
+ * - Rebase with autosquash
4
+ * - Force-push with lease
5
+ * - Discard partial changes on failure
6
+ */
7
+ import { exec } from "../utils/process.js";
8
+ import { logger } from "../utils/logger.js";
9
+ export class GitManager {
10
+ cwd;
11
+ branch;
12
+ conflictStashPending = false;
13
+ constructor(cwd, branch) {
14
+ this.cwd = cwd;
15
+ this.branch = branch;
16
+ }
17
+ /** Interactive rebase with autosquash against the base branch.
18
+ * Skips if there are no fixup/squash commits to fold. */
19
+ async rebaseAutosquash(baseBranch) {
20
+ // Check if there are any fixup!/squash! commits to autosquash
21
+ try {
22
+ const result = await this.git([
23
+ "log",
24
+ "--oneline",
25
+ `${baseBranch}..HEAD`,
26
+ "--grep=^fixup!",
27
+ "--grep=^squash!",
28
+ "--format=%s",
29
+ ]);
30
+ if (result.stdout.trim().length === 0) {
31
+ logger.info("No fixup commits found, skipping autosquash rebase", this.branch);
32
+ return true;
33
+ }
34
+ }
35
+ catch {
36
+ // If the log fails (e.g. baseBranch doesn't exist locally), skip rebase
37
+ logger.info("Could not check for fixup commits, skipping autosquash rebase", this.branch);
38
+ return true;
39
+ }
40
+ logger.info(`Rebasing ${this.branch} onto ${baseBranch} with autosquash`);
41
+ try {
42
+ await this.git([
43
+ "-c",
44
+ "sequence.editor=:",
45
+ "rebase",
46
+ "-i",
47
+ "--autosquash",
48
+ baseBranch,
49
+ ]);
50
+ return true;
51
+ }
52
+ catch (_err) {
53
+ logger.error(`Rebase failed, aborting`, this.branch);
54
+ await this.git(["rebase", "--abort"]).catch(() => { });
55
+ return false;
56
+ }
57
+ }
58
+ /** Force-push with lease to protect against external changes. */
59
+ async forcePushWithLease() {
60
+ logger.info(`Force-pushing ${this.branch} with lease`);
61
+ try {
62
+ await this.git([
63
+ "push",
64
+ "--force-with-lease",
65
+ "origin",
66
+ `HEAD:${this.branch}`,
67
+ ]);
68
+ return true;
69
+ }
70
+ catch {
71
+ // Do NOT fetch and retry here. The lease rejection means someone else
72
+ // pushed to the branch, and retrying after fetch would update the
73
+ // tracking ref, causing the second push to succeed and overwrite their
74
+ // commits. Let the push fail so the next cycle can handle the divergence.
75
+ logger.error(`Push rejected by --force-with-lease`, this.branch);
76
+ return false;
77
+ }
78
+ }
79
+ /** Discard all uncommitted changes (used after a failed fix). */
80
+ async discardChanges() {
81
+ logger.info("Discarding uncommitted changes", this.branch);
82
+ await this.git(["checkout", "."]);
83
+ await this.git(["clean", "-fd"]);
84
+ }
85
+ /** Check if there are uncommitted changes. */
86
+ async hasUncommittedChanges() {
87
+ const result = await this.git(["status", "--porcelain"]);
88
+ return result.stdout.trim().length > 0;
89
+ }
90
+ /** Get the current HEAD sha. */
91
+ async getHeadSha() {
92
+ const result = await this.git(["rev-parse", "HEAD"]);
93
+ return result.stdout.trim();
94
+ }
95
+ /** Get list of files changed since a given sha. */
96
+ async getChangedFilesSince(sha) {
97
+ const result = await this.git([
98
+ "diff",
99
+ "--name-only",
100
+ sha,
101
+ "HEAD",
102
+ ]);
103
+ return result.stdout.trim().split("\n").filter(Boolean);
104
+ }
105
+ /** Stash any uncommitted changes. Returns true if something was stashed. */
106
+ async stash() {
107
+ const dirty = await this.hasUncommittedChanges();
108
+ if (!dirty)
109
+ return false;
110
+ await this.git(["stash", "--include-untracked"]);
111
+ logger.info("Stashed uncommitted changes before rebase", this.branch);
112
+ return true;
113
+ }
114
+ /** Pop the stash, ignoring errors if the stash is empty or conflicts. */
115
+ async stashPop() {
116
+ try {
117
+ await this.git(["stash", "pop"]);
118
+ }
119
+ catch {
120
+ // Stash pop can fail if changes conflict with rebased result — drop it
121
+ logger.warn("Stash pop failed, dropping stash", this.branch);
122
+ await this.git(["stash", "drop"]).catch(() => { });
123
+ }
124
+ }
125
+ /** Fetch and rebase onto remote branch (works with detached HEAD). */
126
+ async pullRebase(targetBranch) {
127
+ const branch = targetBranch || this.branch;
128
+ const stashed = await this.stash();
129
+ try {
130
+ await this.git(["fetch", "origin", branch]);
131
+ await this.git(["rebase", `origin/${branch}`]);
132
+ return true;
133
+ }
134
+ catch {
135
+ logger.error(`Rebase onto origin/${branch} failed`, this.branch);
136
+ await this.git(["rebase", "--abort"]).catch(() => { });
137
+ return false;
138
+ }
139
+ finally {
140
+ if (stashed)
141
+ await this.stashPop();
142
+ }
143
+ }
144
+ /**
145
+ * Start a rebase that will conflict, leaving the worktree in conflict state.
146
+ * Returns the list of conflicting files, or null if the rebase succeeded (no conflicts).
147
+ */
148
+ async startConflictingRebase(targetBranch) {
149
+ const stashed = await this.stash();
150
+ this.conflictStashPending = stashed;
151
+ try {
152
+ await this.git(["fetch", "origin", targetBranch]);
153
+ try {
154
+ await this.git(["rebase", `origin/${targetBranch}`]);
155
+ // Rebase succeeded without conflicts
156
+ if (stashed)
157
+ await this.stashPop();
158
+ this.conflictStashPending = false;
159
+ return null;
160
+ }
161
+ catch {
162
+ // Rebase stopped at a conflict — get the conflicting files
163
+ const result = await this.git(["diff", "--name-only", "--diff-filter=U"]);
164
+ const files = result.stdout.trim().split("\n").filter(Boolean);
165
+ if (files.length === 0) {
166
+ // Rebase failed for a non-conflict reason
167
+ await this.git(["rebase", "--abort"]).catch(() => { });
168
+ if (stashed)
169
+ await this.stashPop();
170
+ this.conflictStashPending = false;
171
+ return [];
172
+ }
173
+ // Keep conflictStashPending = true, will be handled after rebase completes
174
+ return files;
175
+ }
176
+ }
177
+ catch (error) {
178
+ // Error from fetch or inner catch - abort any in-progress rebase and clean up stash
179
+ await this.git(["rebase", "--abort"]).catch(() => { });
180
+ if (stashed)
181
+ await this.stashPop();
182
+ this.conflictStashPending = false;
183
+ throw error;
184
+ }
185
+ }
186
+ /** Stage all files and continue a paused rebase. Returns false if more conflicts arise. */
187
+ async continueRebase() {
188
+ try {
189
+ await this.git(["add", "."]);
190
+ await this.git(["-c", "core.editor=true", "rebase", "--continue"]);
191
+ // Rebase completed successfully - pop any pending stash
192
+ if (this.conflictStashPending) {
193
+ await this.stashPop();
194
+ this.conflictStashPending = false;
195
+ }
196
+ return true;
197
+ }
198
+ catch {
199
+ // More conflicts in subsequent commits — check if still rebasing
200
+ const status = await this.git(["diff", "--name-only", "--diff-filter=U"]);
201
+ if (status.stdout.trim().length > 0) {
202
+ return false; // Still have conflicts
203
+ }
204
+ // Rebase failed completely - abort and clean up stash
205
+ await this.git(["rebase", "--abort"]).catch(() => { });
206
+ if (this.conflictStashPending) {
207
+ await this.stashPop();
208
+ this.conflictStashPending = false;
209
+ }
210
+ return false;
211
+ }
212
+ }
213
+ /** Abort a rebase in progress. */
214
+ async abortRebase() {
215
+ await this.git(["rebase", "--abort"]).catch(() => { });
216
+ // Clean up any pending stash when aborting
217
+ if (this.conflictStashPending) {
218
+ await this.stashPop();
219
+ this.conflictStashPending = false;
220
+ }
221
+ }
222
+ /** Checkout the branch (ensuring we're on it). */
223
+ async checkout() {
224
+ await this.git(["checkout", this.branch]);
225
+ }
226
+ async git(args) {
227
+ return exec("git", args, { cwd: this.cwd });
228
+ }
229
+ }
230
+ //# sourceMappingURL=git-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-manager.js","sourceRoot":"","sources":["../../../src/core/git-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Parses an ORC.md config file from the repo root.
3
+ *
4
+ * Format:
5
+ * # Orc
6
+ * ## Instructions
7
+ * Free-form text passed to Claude Code as context.
8
+ * ## Verify
9
+ * - `yarn lint`
10
+ * - `yarn typecheck`
11
+ * ## Auto-fix
12
+ * - must_fix: true
13
+ * - should_fix: true
14
+ * - nice_to_have: false
15
+ */
16
+ import type { RepoPilotConfig } from "../types/index.js";
17
+ export declare function loadPilotConfig(cwd: string): Promise<RepoPilotConfig>;
18
+ //# sourceMappingURL=pilot-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pilot-config.d.ts","sourceRoot":"","sources":["../../../src/core/pilot-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAczD,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAoD3E"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Parses an ORC.md config file from the repo root.
3
+ *
4
+ * Format:
5
+ * # Orc
6
+ * ## Instructions
7
+ * Free-form text passed to Claude Code as context.
8
+ * ## Verify
9
+ * - `yarn lint`
10
+ * - `yarn typecheck`
11
+ * ## Auto-fix
12
+ * - must_fix: true
13
+ * - should_fix: true
14
+ * - nice_to_have: false
15
+ */
16
+ import { readFile } from "node:fs/promises";
17
+ import { join } from "node:path";
18
+ import { logger } from "../utils/logger.js";
19
+ const DEFAULT_CONFIG = {
20
+ instructions: "",
21
+ verifyCommands: [],
22
+ autoFix: {
23
+ must_fix: true,
24
+ should_fix: true,
25
+ nice_to_have: false,
26
+ verify_and_fix: true,
27
+ },
28
+ };
29
+ export async function loadPilotConfig(cwd) {
30
+ const filePath = join(cwd, "ORC.md");
31
+ let content;
32
+ try {
33
+ content = await readFile(filePath, "utf-8");
34
+ }
35
+ catch {
36
+ logger.debug("No ORC.md found, using defaults");
37
+ return { ...DEFAULT_CONFIG, autoFix: { ...DEFAULT_CONFIG.autoFix } };
38
+ }
39
+ logger.info("Loaded ORC.md config");
40
+ const sections = new Map();
41
+ let currentHeading = "";
42
+ const lines = content.split("\n");
43
+ for (const line of lines) {
44
+ const h2Match = line.match(/^## (.+)/);
45
+ if (h2Match) {
46
+ currentHeading = h2Match[1].trim().toLowerCase();
47
+ continue;
48
+ }
49
+ // Skip H1
50
+ if (line.match(/^# /))
51
+ continue;
52
+ if (currentHeading) {
53
+ const existing = sections.get(currentHeading) ?? "";
54
+ sections.set(currentHeading, existing + line + "\n");
55
+ }
56
+ }
57
+ const instructions = (sections.get("instructions") ?? "").trim();
58
+ const verifyCommands = [];
59
+ const verifySection = sections.get("verify") ?? "";
60
+ for (const line of verifySection.split("\n")) {
61
+ const match = line.match(/^-\s*`(.+)`/);
62
+ if (match) {
63
+ verifyCommands.push(match[1]);
64
+ }
65
+ }
66
+ const autoFix = { ...DEFAULT_CONFIG.autoFix };
67
+ const autoFixSection = sections.get("auto-fix") ?? "";
68
+ for (const line of autoFixSection.split("\n")) {
69
+ const match = line.match(/^-\s*(must_fix|should_fix|nice_to_have|verify_and_fix)\s*:\s*(true|false)/);
70
+ if (match) {
71
+ autoFix[match[1]] = match[2] === "true";
72
+ }
73
+ }
74
+ return { instructions, verifyCommands, autoFix };
75
+ }
76
+ //# sourceMappingURL=pilot-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pilot-config.js","sourceRoot":"","sources":["../../../src/core/pilot-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Persists review progress to disk so lifetime comment counts
3
+ * survive across sessions and daemon restarts.
4
+ *
5
+ * Stores `orc-progress.json` in the repo working directory
6
+ * (same location pattern as `orc.log`).
7
+ */
8
+ import type { CycleRecord } from "../types/index.js";
9
+ export declare class ProgressStore {
10
+ private filePath;
11
+ private data;
12
+ constructor(cwd: string);
13
+ load(): Promise<void>;
14
+ private save;
15
+ getLifetimeStats(branch: string): {
16
+ lifetimeSeen: number;
17
+ lifetimeAddressed: number;
18
+ cycleCount: number;
19
+ cycleHistory: CycleRecord[];
20
+ };
21
+ /**
22
+ * Called at the start of each fix cycle.
23
+ * Registers newly-seen thread IDs and opens a new cycle record.
24
+ */
25
+ recordCycleStart(branch: string, prNumber: number, threadIds: string[]): Promise<void>;
26
+ /**
27
+ * Called at the end of each fix cycle.
28
+ * Completes the latest cycle record with results.
29
+ */
30
+ recordCycleEnd(branch: string, commentsFixed: number, costUsd: number, inputTokens: number, outputTokens: number): Promise<void>;
31
+ }
32
+ //# sourceMappingURL=progress-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-store.d.ts","sourceRoot":"","sources":["../../../src/core/progress-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAqBrD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAyC;gBAEzC,GAAG,EAAE,MAAM;IAKjB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUb,IAAI;IASlB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG;QAChC,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,WAAW,EAAE,CAAC;KAC7B;IAiBD;;;OAGG;IACG,gBAAgB,CACpB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC;IAiChB;;;OAGG;IACG,cAAc,CAClB,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC;CAajB"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Persists review progress to disk so lifetime comment counts
3
+ * survive across sessions and daemon restarts.
4
+ *
5
+ * Stores `orc-progress.json` in the repo working directory
6
+ * (same location pattern as `orc.log`).
7
+ */
8
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
9
+ import { join } from "node:path";
10
+ import { homedir } from "node:os";
11
+ import { logger } from "../utils/logger.js";
12
+ /** Derive a stable directory name from the repo path. */
13
+ function repoSlug(cwd) {
14
+ return cwd.replace(/[^a-zA-Z0-9]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
15
+ }
16
+ export class ProgressStore {
17
+ filePath;
18
+ data = { version: 1, prs: {} };
19
+ constructor(cwd) {
20
+ const dir = join(homedir(), ".config", "orc", "progress");
21
+ this.filePath = join(dir, `${repoSlug(cwd)}.json`);
22
+ }
23
+ async load() {
24
+ try {
25
+ const raw = await readFile(this.filePath, "utf-8");
26
+ this.data = JSON.parse(raw);
27
+ }
28
+ catch {
29
+ // File doesn't exist yet or is corrupt — start fresh
30
+ this.data = { version: 1, prs: {} };
31
+ }
32
+ }
33
+ async save() {
34
+ try {
35
+ await mkdir(join(this.filePath, ".."), { recursive: true });
36
+ await writeFile(this.filePath, JSON.stringify(this.data, null, 2) + "\n");
37
+ }
38
+ catch (err) {
39
+ logger.warn(`Failed to save progress: ${err}`);
40
+ }
41
+ }
42
+ getLifetimeStats(branch) {
43
+ const pr = this.data.prs[branch];
44
+ if (!pr) {
45
+ return { lifetimeSeen: 0, lifetimeAddressed: 0, cycleCount: 0, cycleHistory: [] };
46
+ }
47
+ // Calculate lifetimeAddressed from cycle history to ensure it can never exceed lifetimeSeen
48
+ const lifetimeAddressed = pr.cycles.reduce((sum, cycle) => sum + (cycle.commentsFixed || 0), 0);
49
+ return {
50
+ lifetimeSeen: pr.seenThreadIds.length,
51
+ lifetimeAddressed,
52
+ cycleCount: pr.cycles.length,
53
+ cycleHistory: pr.cycles,
54
+ };
55
+ }
56
+ /**
57
+ * Called at the start of each fix cycle.
58
+ * Registers newly-seen thread IDs and opens a new cycle record.
59
+ */
60
+ async recordCycleStart(branch, prNumber, threadIds) {
61
+ let pr = this.data.prs[branch];
62
+ if (!pr) {
63
+ pr = {
64
+ prNumber,
65
+ branch,
66
+ seenThreadIds: [],
67
+ cycles: [],
68
+ };
69
+ this.data.prs[branch] = pr;
70
+ }
71
+ // Merge new thread IDs (dedup)
72
+ const existing = new Set(pr.seenThreadIds);
73
+ for (const id of threadIds) {
74
+ if (!existing.has(id)) {
75
+ pr.seenThreadIds.push(id);
76
+ }
77
+ }
78
+ pr.cycles.push({
79
+ startedAt: new Date().toISOString(),
80
+ completedAt: null,
81
+ commentsSeen: threadIds.length,
82
+ commentsFixed: 0,
83
+ costUsd: 0,
84
+ inputTokens: 0,
85
+ outputTokens: 0,
86
+ });
87
+ await this.save();
88
+ }
89
+ /**
90
+ * Called at the end of each fix cycle.
91
+ * Completes the latest cycle record with results.
92
+ */
93
+ async recordCycleEnd(branch, commentsFixed, costUsd, inputTokens, outputTokens) {
94
+ const pr = this.data.prs[branch];
95
+ if (!pr || pr.cycles.length === 0)
96
+ return;
97
+ const cycle = pr.cycles[pr.cycles.length - 1];
98
+ cycle.completedAt = new Date().toISOString();
99
+ cycle.commentsFixed = commentsFixed;
100
+ cycle.costUsd = costUsd;
101
+ cycle.inputTokens = inputTokens;
102
+ cycle.outputTokens = outputTokens;
103
+ await this.save();
104
+ }
105
+ }
106
+ //# sourceMappingURL=progress-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"progress-store.js","sourceRoot":"","sources":["../../../src/core/progress-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Loads per-repo configuration from two sources:
3
+ *
4
+ * - `ORC.md` — freeform instructions/context passed to Claude Code
5
+ * - `orc.config.json` — structured config (setup, verify, permissions, auto-fix)
6
+ *
7
+ * This mirrors the Claude Code pattern: markdown for context, JSON for config.
8
+ */
9
+ import type { RepoConfig } from "../types/index.js";
10
+ export declare function loadRepoConfig(cwd: string): Promise<RepoConfig>;
11
+ //# sourceMappingURL=repo-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-config.d.ts","sourceRoot":"","sources":["../../../src/core/repo-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAgCpD,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BrE"}