@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,12 @@
1
+ /**
2
+ * Detects the project ecosystem from marker files and returns
3
+ * sensible defaults for ORC.md sections (setup, verify, allowed commands).
4
+ */
5
+ export interface DetectedProject {
6
+ ecosystem: string;
7
+ setupCommands: string[];
8
+ verifyCommands: string[];
9
+ allowedCommands: string[];
10
+ }
11
+ export declare function detectProject(cwd: string): DetectedProject;
12
+ //# sourceMappingURL=project-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-detector.d.ts","sourceRoot":"","sources":["../../../src/utils/project-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CA8H1D"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Detects the project ecosystem from marker files and returns
3
+ * sensible defaults for ORC.md sections (setup, verify, allowed commands).
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as path from "node:path";
7
+ export function detectProject(cwd) {
8
+ const has = (file) => fs.existsSync(path.join(cwd, file));
9
+ // Node.js — check lock files first for specificity
10
+ if (has("package.json") && has("yarn.lock")) {
11
+ return {
12
+ ecosystem: "node (yarn)",
13
+ setupCommands: ["yarn install"],
14
+ verifyCommands: ["yarn lint", "yarn typecheck", "yarn test"],
15
+ allowedCommands: ["yarn *"],
16
+ };
17
+ }
18
+ if (has("package.json") && has("pnpm-lock.yaml")) {
19
+ return {
20
+ ecosystem: "node (pnpm)",
21
+ setupCommands: ["pnpm install"],
22
+ verifyCommands: ["pnpm lint", "pnpm typecheck", "pnpm test"],
23
+ allowedCommands: ["pnpm *"],
24
+ };
25
+ }
26
+ if (has("package.json")) {
27
+ return {
28
+ ecosystem: "node (npm)",
29
+ setupCommands: ["npm install"],
30
+ verifyCommands: ["npm run lint", "npm run typecheck", "npm test"],
31
+ allowedCommands: ["npm *", "npx *"],
32
+ };
33
+ }
34
+ // Rust
35
+ if (has("Cargo.toml")) {
36
+ return {
37
+ ecosystem: "rust",
38
+ setupCommands: ["cargo build"],
39
+ verifyCommands: ["cargo clippy -- -D warnings", "cargo test"],
40
+ allowedCommands: ["cargo *"],
41
+ };
42
+ }
43
+ // Go
44
+ if (has("go.mod")) {
45
+ return {
46
+ ecosystem: "go",
47
+ setupCommands: ["go mod download"],
48
+ verifyCommands: ["go vet ./...", "go test ./..."],
49
+ allowedCommands: ["go *"],
50
+ };
51
+ }
52
+ // Python
53
+ if (has("pyproject.toml") || has("requirements.txt")) {
54
+ return {
55
+ ecosystem: "python",
56
+ setupCommands: ["pip install -e .[dev]"],
57
+ verifyCommands: ["ruff check .", "mypy .", "pytest"],
58
+ allowedCommands: ["python *", "pip *", "ruff *", "mypy *", "pytest *"],
59
+ };
60
+ }
61
+ // Ruby
62
+ if (has("Gemfile")) {
63
+ return {
64
+ ecosystem: "ruby",
65
+ setupCommands: ["bundle install"],
66
+ verifyCommands: ["bundle exec rubocop", "bundle exec rspec"],
67
+ allowedCommands: ["bundle *", "ruby *", "rake *"],
68
+ };
69
+ }
70
+ // Elixir
71
+ if (has("mix.exs")) {
72
+ return {
73
+ ecosystem: "elixir",
74
+ setupCommands: ["mix deps.get"],
75
+ verifyCommands: ["mix compile --warnings-as-errors", "mix test"],
76
+ allowedCommands: ["mix *"],
77
+ };
78
+ }
79
+ // JVM — Gradle
80
+ if (has("build.gradle") || has("build.gradle.kts")) {
81
+ return {
82
+ ecosystem: "gradle",
83
+ setupCommands: ["./gradlew build"],
84
+ verifyCommands: ["./gradlew check", "./gradlew test"],
85
+ allowedCommands: ["./gradlew *", "gradle *"],
86
+ };
87
+ }
88
+ // JVM — Maven
89
+ if (has("pom.xml")) {
90
+ return {
91
+ ecosystem: "maven",
92
+ setupCommands: ["mvn compile"],
93
+ verifyCommands: ["mvn verify"],
94
+ allowedCommands: ["mvn *"],
95
+ };
96
+ }
97
+ // CMake
98
+ if (has("CMakeLists.txt")) {
99
+ return {
100
+ ecosystem: "cmake",
101
+ setupCommands: ["cmake -B build", "cmake --build build"],
102
+ verifyCommands: ["cmake --build build --target test"],
103
+ allowedCommands: ["cmake *", "make *"],
104
+ };
105
+ }
106
+ // Makefile (generic)
107
+ if (has("Makefile")) {
108
+ return {
109
+ ecosystem: "make",
110
+ setupCommands: ["make"],
111
+ verifyCommands: ["make test"],
112
+ allowedCommands: ["make *"],
113
+ };
114
+ }
115
+ // Unknown
116
+ return {
117
+ ecosystem: "unknown",
118
+ setupCommands: [],
119
+ verifyCommands: [],
120
+ allowedCommands: [],
121
+ };
122
+ }
123
+ //# sourceMappingURL=project-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-detector.js","sourceRoot":"","sources":["../../../src/utils/project-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared utilities for quoting comment bodies in GitHub replies.
3
+ * This ensures consistent quoting format across comment-fetcher and thread-responder.
4
+ */
5
+ /**
6
+ * Quote a comment body for inclusion in a reply.
7
+ * Converts each line to markdown quote format (prefixed with "> ").
8
+ */
9
+ export declare function quoteCommentBody(originalBody: string): string;
10
+ /**
11
+ * Check whether a reply contains an exact quote of the given original comment body.
12
+ * Uses precise matching to avoid false positives from substring matching.
13
+ */
14
+ export declare function containsQuotedComment(replyBody: string, originalBody: string): boolean;
15
+ //# sourceMappingURL=quoting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quoting.d.ts","sourceRoot":"","sources":["../../../src/utils/quoting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAK7D;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAsBtF"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Shared utilities for quoting comment bodies in GitHub replies.
3
+ * This ensures consistent quoting format across comment-fetcher and thread-responder.
4
+ */
5
+ /**
6
+ * Quote a comment body for inclusion in a reply.
7
+ * Converts each line to markdown quote format (prefixed with "> ").
8
+ */
9
+ export function quoteCommentBody(originalBody) {
10
+ return originalBody
11
+ .split("\n")
12
+ .map((line) => `> ${line}`)
13
+ .join("\n");
14
+ }
15
+ /**
16
+ * Check whether a reply contains an exact quote of the given original comment body.
17
+ * Uses precise matching to avoid false positives from substring matching.
18
+ */
19
+ export function containsQuotedComment(replyBody, originalBody) {
20
+ const quotedBody = quoteCommentBody(originalBody);
21
+ // Split reply into lines to check for exact quote block boundaries
22
+ const replyLines = replyBody.split("\n");
23
+ const quotedLines = quotedBody.split("\n");
24
+ // Look for the quoted content as a contiguous block
25
+ for (let i = 0; i <= replyLines.length - quotedLines.length; i++) {
26
+ let matches = true;
27
+ for (let j = 0; j < quotedLines.length; j++) {
28
+ if (replyLines[i + j] !== quotedLines[j]) {
29
+ matches = false;
30
+ break;
31
+ }
32
+ }
33
+ if (matches) {
34
+ return true;
35
+ }
36
+ }
37
+ return false;
38
+ }
39
+ //# sourceMappingURL=quoting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quoting.js","sourceRoot":"","sources":["../../../src/utils/quoting.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,YAAoB;IACnD,OAAO,YAAY;SAChB,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;SAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,YAAoB;IAC3E,MAAM,UAAU,GAAG,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAElD,mEAAmE;IACnE,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE3C,oDAAoD;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjE,IAAI,OAAO,GAAG,IAAI,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzC,OAAO,GAAG,KAAK,CAAC;gBAChB,MAAM;YACR,CAAC;QACH,CAAC;QACD,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Thrown when a GitHub API call fails due to rate limiting.
3
+ * Retrying immediately would waste quota, so callers should back off.
4
+ */
5
+ export declare class RateLimitError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ /**
9
+ * Retry an async operation with exponential backoff.
10
+ * Rate-limit errors are thrown immediately without retrying.
11
+ */
12
+ export declare function withRetry<T>(fn: () => Promise<T>, label: string, maxRetries?: number): Promise<T>;
13
+ export declare function sleep(ms: number): Promise<void>;
14
+ //# sourceMappingURL=retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,KAAK,EAAE,MAAM,EACb,UAAU,SAA0B,GACnC,OAAO,CAAC,CAAC,CAAC,CAqBZ;AAED,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
@@ -0,0 +1,41 @@
1
+ import { RETRY_BACKOFF_MS } from "../constants.js";
2
+ import { logger } from "./logger.js";
3
+ /**
4
+ * Thrown when a GitHub API call fails due to rate limiting.
5
+ * Retrying immediately would waste quota, so callers should back off.
6
+ */
7
+ export class RateLimitError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "RateLimitError";
11
+ }
12
+ }
13
+ /**
14
+ * Retry an async operation with exponential backoff.
15
+ * Rate-limit errors are thrown immediately without retrying.
16
+ */
17
+ export async function withRetry(fn, label, maxRetries = RETRY_BACKOFF_MS.length) {
18
+ let lastError;
19
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
20
+ try {
21
+ return await fn();
22
+ }
23
+ catch (err) {
24
+ if (err instanceof RateLimitError) {
25
+ logger.warn(`${label} hit rate limit, not retrying`);
26
+ throw err;
27
+ }
28
+ lastError = err;
29
+ if (attempt < maxRetries) {
30
+ const delay = RETRY_BACKOFF_MS[attempt] ?? 16000;
31
+ logger.warn(`${label} failed (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms`);
32
+ await sleep(delay);
33
+ }
34
+ }
35
+ }
36
+ throw lastError;
37
+ }
38
+ export function sleep(ms) {
39
+ return new Promise((resolve) => setTimeout(resolve, ms));
40
+ }
41
+ //# sourceMappingURL=retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/utils/retry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;;GAGG;AACH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,KAAa,EACb,UAAU,GAAG,gBAAgB,CAAC,MAAM;IAEpC,IAAI,SAAkB,CAAC;IACvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,+BAA+B,CAAC,CAAC;gBACrD,MAAM,GAAG,CAAC;YACZ,CAAC;YACD,SAAS,GAAG,GAAG,CAAC;YAChB,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC;gBACjD,MAAM,CAAC,IAAI,CACT,GAAG,KAAK,oBAAoB,OAAO,GAAG,CAAC,IAAI,UAAU,GAAG,CAAC,kBAAkB,KAAK,IAAI,CACrF,CAAC;gBACF,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type Terminal = "ghostty" | "iterm2" | "terminal" | "kitty" | "wezterm" | "alacritty";
2
+ export interface UserSettings {
3
+ theme: "dark" | "light";
4
+ terminal?: Terminal;
5
+ autoResolveConflicts?: "always" | "ask" | "never";
6
+ pollInterval?: number;
7
+ claudeTimeout?: number;
8
+ notifications?: boolean;
9
+ maxConcurrentSessions?: number;
10
+ sessionTimeout?: number;
11
+ }
12
+ export declare function loadSettings(): UserSettings | null;
13
+ export declare function saveSettings(settings: Partial<UserSettings>): void;
14
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../src/utils/settings.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,QAAQ,GAChB,SAAS,GACT,QAAQ,GACR,UAAU,GACV,OAAO,GACP,SAAS,GACT,WAAW,CAAC;AAEhB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,oBAAoB,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAKD,wBAAgB,YAAY,IAAI,YAAY,GAAG,IAAI,CAOlD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAKlE"}
@@ -0,0 +1,21 @@
1
+ import { mkdirSync, readFileSync, writeFileSync } from "fs";
2
+ import { homedir } from "os";
3
+ import { join } from "path";
4
+ const settingsDir = join(homedir(), ".config", "orc");
5
+ const settingsPath = join(settingsDir, "settings.json");
6
+ export function loadSettings() {
7
+ try {
8
+ const raw = readFileSync(settingsPath, "utf-8");
9
+ return JSON.parse(raw);
10
+ }
11
+ catch {
12
+ return null;
13
+ }
14
+ }
15
+ export function saveSettings(settings) {
16
+ mkdirSync(settingsDir, { recursive: true });
17
+ const existing = loadSettings() ?? {};
18
+ const merged = { ...existing, ...settings };
19
+ writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + "\n");
20
+ }
21
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../src/utils/settings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAqB5B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AACtD,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;AAExD,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAA+B;IAC1D,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,YAAY,EAAE,IAAI,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC5C,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function formatTime(iso: string): string;
2
+ //# sourceMappingURL=time.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../../src/utils/time.ts"],"names":[],"mappings":"AAAA,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C"}
@@ -0,0 +1,5 @@
1
+ export function formatTime(iso) {
2
+ const d = new Date(iso);
3
+ return d.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit", hour12: false });
4
+ }
5
+ //# sourceMappingURL=time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"time.js","sourceRoot":"","sources":["../../../src/utils/time.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;AACzF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@vaporsoft/orc",
3
+ "version": "0.1.0",
4
+ "description": "Automate PR feedback loops — poll reviews & CI, fix with Claude Code, push, repeat.",
5
+ "type": "module",
6
+ "bin": "./dist/bin/orc.js",
7
+ "files": [
8
+ "dist",
9
+ "LICENSE",
10
+ "README.md"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsc --watch",
15
+ "start": "node dist/bin/orc.js",
16
+ "start:dev": "node dist/bin/orc.js --write-logs --verbose",
17
+ "lint": "eslint src/",
18
+ "lint:fix": "eslint src/ --fix",
19
+ "typecheck": "tsc --noEmit",
20
+ "test": "vitest run",
21
+ "test:watch": "vitest",
22
+ "prepublishOnly": "yarn build",
23
+ "publish:npm": "yarn lint && yarn typecheck && yarn build && npm publish"
24
+ },
25
+ "keywords": [
26
+ "github",
27
+ "pull-request",
28
+ "code-review",
29
+ "automation",
30
+ "claude",
31
+ "claude-code",
32
+ "ci",
33
+ "tui",
34
+ "terminal",
35
+ "ink"
36
+ ],
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/vaporsoft/orc.git"
40
+ },
41
+ "homepage": "https://github.com/vaporsoft/orc#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/vaporsoft/orc/issues"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "dependencies": {
49
+ "@anthropic-ai/claude-agent-sdk": "^0.1.0",
50
+ "commander": "^13.0.0",
51
+ "ink": "^5",
52
+ "node-notifier": "^10.0.1",
53
+ "react": "^18",
54
+ "zod": "^3.24.0"
55
+ },
56
+ "devDependencies": {
57
+ "@eslint/js": "^10.0.1",
58
+ "@types/node": "^22.0.0",
59
+ "@types/node-notifier": "^8.0.5",
60
+ "@types/react": "^18",
61
+ "eslint": "^10.0.1",
62
+ "globals": "^17.3.0",
63
+ "typescript": "^5.7.0",
64
+ "typescript-eslint": "^8.56.0",
65
+ "vitest": "^3.0.0"
66
+ },
67
+ "engines": {
68
+ "node": ">=22.0.0"
69
+ },
70
+ "author": "vaporsoft",
71
+ "license": "UNLICENSED",
72
+ "packageManager": "yarn@4.5.1+sha512.341db9396b6e289fecc30cd7ab3af65060e05ebff4b3b47547b278b9e67b08f485ecd8c79006b405446262142c7a38154445ef7f17c1d5d1de7d90bf9ce7054d"
73
+ }