@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.
- package/LICENSE +6 -0
- package/README.md +178 -0
- package/dist/bin/orc.d.ts +3 -0
- package/dist/bin/orc.d.ts.map +1 -0
- package/dist/bin/orc.js +4 -0
- package/dist/bin/orc.js.map +1 -0
- package/dist/src/cli.d.ts +6 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +28 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/init.d.ts +6 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +58 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/start.d.ts +17 -0
- package/dist/src/commands/start.d.ts.map +1 -0
- package/dist/src/commands/start.js +146 -0
- package/dist/src/commands/start.js.map +1 -0
- package/dist/src/constants.d.ts +18 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +42 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/core/comment-categorizer.d.ts +20 -0
- package/dist/src/core/comment-categorizer.d.ts.map +1 -0
- package/dist/src/core/comment-categorizer.js +208 -0
- package/dist/src/core/comment-categorizer.js.map +1 -0
- package/dist/src/core/comment-fetcher.d.ts +37 -0
- package/dist/src/core/comment-fetcher.d.ts.map +1 -0
- package/dist/src/core/comment-fetcher.js +138 -0
- package/dist/src/core/comment-fetcher.js.map +1 -0
- package/dist/src/core/daemon.d.ts +92 -0
- package/dist/src/core/daemon.d.ts.map +1 -0
- package/dist/src/core/daemon.js +896 -0
- package/dist/src/core/daemon.js.map +1 -0
- package/dist/src/core/fix-executor.d.ts +50 -0
- package/dist/src/core/fix-executor.d.ts.map +1 -0
- package/dist/src/core/fix-executor.js +374 -0
- package/dist/src/core/fix-executor.js.map +1 -0
- package/dist/src/core/git-manager.d.ts +44 -0
- package/dist/src/core/git-manager.d.ts.map +1 -0
- package/dist/src/core/git-manager.js +230 -0
- package/dist/src/core/git-manager.js.map +1 -0
- package/dist/src/core/pilot-config.d.ts +18 -0
- package/dist/src/core/pilot-config.d.ts.map +1 -0
- package/dist/src/core/pilot-config.js +76 -0
- package/dist/src/core/pilot-config.js.map +1 -0
- package/dist/src/core/progress-store.d.ts +32 -0
- package/dist/src/core/progress-store.d.ts.map +1 -0
- package/dist/src/core/progress-store.js +106 -0
- package/dist/src/core/progress-store.js.map +1 -0
- package/dist/src/core/repo-config.d.ts +11 -0
- package/dist/src/core/repo-config.d.ts.map +1 -0
- package/dist/src/core/repo-config.js +168 -0
- package/dist/src/core/repo-config.js.map +1 -0
- package/dist/src/core/session-controller.d.ts +61 -0
- package/dist/src/core/session-controller.d.ts.map +1 -0
- package/dist/src/core/session-controller.js +926 -0
- package/dist/src/core/session-controller.js.map +1 -0
- package/dist/src/core/thread-responder.d.ts +28 -0
- package/dist/src/core/thread-responder.d.ts.map +1 -0
- package/dist/src/core/thread-responder.js +193 -0
- package/dist/src/core/thread-responder.js.map +1 -0
- package/dist/src/core/worktree-manager.d.ts +26 -0
- package/dist/src/core/worktree-manager.d.ts.map +1 -0
- package/dist/src/core/worktree-manager.js +189 -0
- package/dist/src/core/worktree-manager.js.map +1 -0
- package/dist/src/github/gh-client.d.ts +57 -0
- package/dist/src/github/gh-client.d.ts.map +1 -0
- package/dist/src/github/gh-client.js +236 -0
- package/dist/src/github/gh-client.js.map +1 -0
- package/dist/src/github/queries.d.ts +9 -0
- package/dist/src/github/queries.d.ts.map +1 -0
- package/dist/src/github/queries.js +152 -0
- package/dist/src/github/queries.js.map +1 -0
- package/dist/src/github/types.d.ts +114 -0
- package/dist/src/github/types.d.ts.map +1 -0
- package/dist/src/github/types.js +3 -0
- package/dist/src/github/types.js.map +1 -0
- package/dist/src/tui/App.d.ts +8 -0
- package/dist/src/tui/App.d.ts.map +1 -0
- package/dist/src/tui/App.js +407 -0
- package/dist/src/tui/App.js.map +1 -0
- package/dist/src/tui/components/ActivityPane.d.ts +7 -0
- package/dist/src/tui/components/ActivityPane.d.ts.map +1 -0
- package/dist/src/tui/components/ActivityPane.js +10 -0
- package/dist/src/tui/components/ActivityPane.js.map +1 -0
- package/dist/src/tui/components/DetailPanel.d.ts +15 -0
- package/dist/src/tui/components/DetailPanel.d.ts.map +1 -0
- package/dist/src/tui/components/DetailPanel.js +137 -0
- package/dist/src/tui/components/DetailPanel.js.map +1 -0
- package/dist/src/tui/components/DrillInOverlay.d.ts +13 -0
- package/dist/src/tui/components/DrillInOverlay.d.ts.map +1 -0
- package/dist/src/tui/components/DrillInOverlay.js +85 -0
- package/dist/src/tui/components/DrillInOverlay.js.map +1 -0
- package/dist/src/tui/components/ExpandedContent.d.ts +10 -0
- package/dist/src/tui/components/ExpandedContent.d.ts.map +1 -0
- package/dist/src/tui/components/ExpandedContent.js +99 -0
- package/dist/src/tui/components/ExpandedContent.js.map +1 -0
- package/dist/src/tui/components/Header.d.ts +12 -0
- package/dist/src/tui/components/Header.d.ts.map +1 -0
- package/dist/src/tui/components/Header.js +35 -0
- package/dist/src/tui/components/Header.js.map +1 -0
- package/dist/src/tui/components/HelpBar.d.ts +2 -0
- package/dist/src/tui/components/HelpBar.d.ts.map +1 -0
- package/dist/src/tui/components/HelpBar.js +11 -0
- package/dist/src/tui/components/HelpBar.js.map +1 -0
- package/dist/src/tui/components/KeybindLegend.d.ts +7 -0
- package/dist/src/tui/components/KeybindLegend.d.ts.map +1 -0
- package/dist/src/tui/components/KeybindLegend.js +53 -0
- package/dist/src/tui/components/KeybindLegend.js.map +1 -0
- package/dist/src/tui/components/LogPane.d.ts +11 -0
- package/dist/src/tui/components/LogPane.d.ts.map +1 -0
- package/dist/src/tui/components/LogPane.js +31 -0
- package/dist/src/tui/components/LogPane.js.map +1 -0
- package/dist/src/tui/components/SessionList.d.ts +14 -0
- package/dist/src/tui/components/SessionList.d.ts.map +1 -0
- package/dist/src/tui/components/SessionList.js +31 -0
- package/dist/src/tui/components/SessionList.js.map +1 -0
- package/dist/src/tui/components/SessionRow.d.ts +10 -0
- package/dist/src/tui/components/SessionRow.d.ts.map +1 -0
- package/dist/src/tui/components/SessionRow.js +52 -0
- package/dist/src/tui/components/SessionRow.js.map +1 -0
- package/dist/src/tui/components/SettingsPanel.d.ts +8 -0
- package/dist/src/tui/components/SettingsPanel.d.ts.map +1 -0
- package/dist/src/tui/components/SettingsPanel.js +191 -0
- package/dist/src/tui/components/SettingsPanel.js.map +1 -0
- package/dist/src/tui/components/StatusBadge.d.ts +9 -0
- package/dist/src/tui/components/StatusBadge.d.ts.map +1 -0
- package/dist/src/tui/components/StatusBadge.js +52 -0
- package/dist/src/tui/components/StatusBadge.js.map +1 -0
- package/dist/src/tui/components/Toolbar.d.ts +5 -0
- package/dist/src/tui/components/Toolbar.d.ts.map +1 -0
- package/dist/src/tui/components/Toolbar.js +2 -0
- package/dist/src/tui/components/Toolbar.js.map +1 -0
- package/dist/src/tui/components/comment-constants.d.ts +4 -0
- package/dist/src/tui/components/comment-constants.d.ts.map +1 -0
- package/dist/src/tui/components/comment-constants.js +15 -0
- package/dist/src/tui/components/comment-constants.js.map +1 -0
- package/dist/src/tui/hooks/logFlushUtils.d.ts +15 -0
- package/dist/src/tui/hooks/logFlushUtils.d.ts.map +1 -0
- package/dist/src/tui/hooks/logFlushUtils.js +33 -0
- package/dist/src/tui/hooks/logFlushUtils.js.map +1 -0
- package/dist/src/tui/hooks/useBranchLogs.d.ts +7 -0
- package/dist/src/tui/hooks/useBranchLogs.d.ts.map +1 -0
- package/dist/src/tui/hooks/useBranchLogs.js +58 -0
- package/dist/src/tui/hooks/useBranchLogs.js.map +1 -0
- package/dist/src/tui/hooks/useDaemonState.d.ts +19 -0
- package/dist/src/tui/hooks/useDaemonState.d.ts.map +1 -0
- package/dist/src/tui/hooks/useDaemonState.js +152 -0
- package/dist/src/tui/hooks/useDaemonState.js.map +1 -0
- package/dist/src/tui/hooks/useInitialDiscovery.d.ts +8 -0
- package/dist/src/tui/hooks/useInitialDiscovery.d.ts.map +1 -0
- package/dist/src/tui/hooks/useInitialDiscovery.js +31 -0
- package/dist/src/tui/hooks/useInitialDiscovery.js.map +1 -0
- package/dist/src/tui/hooks/useLogBuffer.d.ts +7 -0
- package/dist/src/tui/hooks/useLogBuffer.d.ts.map +1 -0
- package/dist/src/tui/hooks/useLogBuffer.js +52 -0
- package/dist/src/tui/hooks/useLogBuffer.js.map +1 -0
- package/dist/src/tui/hooks/useNextCheckCountdown.d.ts +7 -0
- package/dist/src/tui/hooks/useNextCheckCountdown.d.ts.map +1 -0
- package/dist/src/tui/hooks/useNextCheckCountdown.js +42 -0
- package/dist/src/tui/hooks/useNextCheckCountdown.js.map +1 -0
- package/dist/src/tui/hooks/useTerminalFocus.d.ts +9 -0
- package/dist/src/tui/hooks/useTerminalFocus.d.ts.map +1 -0
- package/dist/src/tui/hooks/useTerminalFocus.js +43 -0
- package/dist/src/tui/hooks/useTerminalFocus.js.map +1 -0
- package/dist/src/tui/theme.d.ts +32 -0
- package/dist/src/tui/theme.d.ts.map +1 -0
- package/dist/src/tui/theme.js +61 -0
- package/dist/src/tui/theme.js.map +1 -0
- package/dist/src/types/config.d.ts +35 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +14 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/index.d.ts +107 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +3 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/utils/concurrency.d.ts +7 -0
- package/dist/src/utils/concurrency.d.ts.map +1 -0
- package/dist/src/utils/concurrency.js +26 -0
- package/dist/src/utils/concurrency.js.map +1 -0
- package/dist/src/utils/format.d.ts +2 -0
- package/dist/src/utils/format.d.ts.map +1 -0
- package/dist/src/utils/format.js +8 -0
- package/dist/src/utils/format.js.map +1 -0
- package/dist/src/utils/logger.d.ts +39 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +120 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/notify.d.ts +6 -0
- package/dist/src/utils/notify.d.ts.map +1 -0
- package/dist/src/utils/notify.js +15 -0
- package/dist/src/utils/notify.js.map +1 -0
- package/dist/src/utils/open-terminal.d.ts +12 -0
- package/dist/src/utils/open-terminal.d.ts.map +1 -0
- package/dist/src/utils/open-terminal.js +93 -0
- package/dist/src/utils/open-terminal.js.map +1 -0
- package/dist/src/utils/process.d.ts +14 -0
- package/dist/src/utils/process.d.ts.map +1 -0
- package/dist/src/utils/process.js +36 -0
- package/dist/src/utils/process.js.map +1 -0
- package/dist/src/utils/project-detector.d.ts +12 -0
- package/dist/src/utils/project-detector.d.ts.map +1 -0
- package/dist/src/utils/project-detector.js +123 -0
- package/dist/src/utils/project-detector.js.map +1 -0
- package/dist/src/utils/quoting.d.ts +15 -0
- package/dist/src/utils/quoting.d.ts.map +1 -0
- package/dist/src/utils/quoting.js +39 -0
- package/dist/src/utils/quoting.js.map +1 -0
- package/dist/src/utils/retry.d.ts +14 -0
- package/dist/src/utils/retry.d.ts.map +1 -0
- package/dist/src/utils/retry.js +41 -0
- package/dist/src/utils/retry.js.map +1 -0
- package/dist/src/utils/settings.d.ts +14 -0
- package/dist/src/utils/settings.d.ts.map +1 -0
- package/dist/src/utils/settings.js +21 -0
- package/dist/src/utils/settings.js.map +1 -0
- package/dist/src/utils/time.d.ts +2 -0
- package/dist/src/utils/time.d.ts.map +1 -0
- package/dist/src/utils/time.js +5 -0
- package/dist/src/utils/time.js.map +1 -0
- package/package.json +73 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Copyright (c) 2025 vaporsoft. All rights reserved.
|
|
2
|
+
|
|
3
|
+
This software is proprietary and confidential. No license is granted
|
|
4
|
+
to use, copy, modify, or distribute this software or its source code.
|
|
5
|
+
|
|
6
|
+
Use of the published npm package is permitted for its intended purpose only.
|
package/README.md
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# orc
|
|
2
|
+
|
|
3
|
+
Interactive terminal dashboard to automate PR feedback loops — poll reviews & CI, fix with Claude Code, push, repeat.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
orc provides an interactive terminal dashboard to monitor your open pull requests. It:
|
|
8
|
+
|
|
9
|
+
1. **Monitors** multiple PRs simultaneously with real-time status updates
|
|
10
|
+
2. **Fetches** new review comments and conversation threads
|
|
11
|
+
3. **Categorizes** feedback to classify severity (must-fix, should-fix, nice-to-have, false-positive)
|
|
12
|
+
4. **Fixes** issues using Claude Code in isolated git worktrees with repo-specific context
|
|
13
|
+
5. **Verifies** changes with configured commands, pushes, and replies to threads
|
|
14
|
+
|
|
15
|
+
You can manually start/stop monitoring per PR or let it run automatically until each PR is clean.
|
|
16
|
+
|
|
17
|
+
## How it works
|
|
18
|
+
|
|
19
|
+
orc is designed to run as a background process on your machine while you work. The intended workflow:
|
|
20
|
+
|
|
21
|
+
1. **You open PRs as usual.** Push your branch, create a PR on GitHub, request reviews.
|
|
22
|
+
2. **Start orc.** Run `orc start my-branch` (or pass multiple branches). orc opens a terminal dashboard and begins polling.
|
|
23
|
+
3. **Reviewers leave comments.** orc detects new review comments and CI failures on each poll cycle.
|
|
24
|
+
4. **orc categorizes feedback.** Each comment is classified by severity — `must-fix`, `should-fix`, `nice-to-have`, or `false-positive` — so it knows what to act on and what to skip.
|
|
25
|
+
5. **orc fixes issues autonomously.** For actionable comments, orc checks out the branch in an isolated git worktree, invokes Claude Code with the review context and any repo-specific instructions from `ORC.md`, and applies the fix.
|
|
26
|
+
6. **orc verifies and pushes.** After fixing, orc runs your configured verify commands (lint, typecheck, tests). If they pass, it pushes the fix and replies to the review thread. If they fail, it retries.
|
|
27
|
+
7. **The loop repeats.** orc continues polling until there are no more actionable comments, the max loop count is reached, or you stop it manually.
|
|
28
|
+
|
|
29
|
+
The net effect: you get a PR up, context-switch to other work, and come back to find review feedback already addressed. You stay in the loop via the dashboard and can intervene at any point.
|
|
30
|
+
|
|
31
|
+
## Tech Stack
|
|
32
|
+
|
|
33
|
+
orc is built with:
|
|
34
|
+
|
|
35
|
+
- **TypeScript + Node.js**: Core runtime for cross-platform CLI tooling and robust type safety
|
|
36
|
+
- **Ink**: React-like framework for building rich terminal user interfaces with component-based architecture
|
|
37
|
+
- **GitHub CLI (`gh`)**: Official GitHub API client for reliable repository and PR operations
|
|
38
|
+
- **Claude Code**: AI-powered code editing with repository context for intelligent automated fixes
|
|
39
|
+
- **Git Worktrees**: Isolated working directories for safe parallel PR processing without conflicts
|
|
40
|
+
|
|
41
|
+
This stack was chosen to provide a responsive terminal UI while leveraging proven tools for GitHub integration and AI-assisted code modifications.
|
|
42
|
+
|
|
43
|
+
## Prerequisites
|
|
44
|
+
|
|
45
|
+
- Node.js >= 22
|
|
46
|
+
- [GitHub CLI](https://cli.github.com/) (`gh`) — authenticated with repo access
|
|
47
|
+
- [Claude Code](https://docs.anthropic.com/en/docs/claude-code) installed and authenticated
|
|
48
|
+
|
|
49
|
+
## Install
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Install globally
|
|
53
|
+
npm install -g @vaporsoft/orc
|
|
54
|
+
|
|
55
|
+
# Or run directly with npx
|
|
56
|
+
npx @vaporsoft/orc start my-branch
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### From source
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
yarn install
|
|
63
|
+
yarn build
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Configuration
|
|
67
|
+
|
|
68
|
+
orc can be configured per-repository using an `ORC.md` file in your repo root:
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
# Orc
|
|
72
|
+
|
|
73
|
+
## Instructions
|
|
74
|
+
Custom instructions passed to Claude Code for context about your project.
|
|
75
|
+
|
|
76
|
+
## Verify
|
|
77
|
+
- `yarn lint`
|
|
78
|
+
- `yarn typecheck`
|
|
79
|
+
- `npm test`
|
|
80
|
+
|
|
81
|
+
## Auto-fix
|
|
82
|
+
- must_fix: true
|
|
83
|
+
- should_fix: true
|
|
84
|
+
- nice_to_have: false
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The configuration allows you to:
|
|
88
|
+
- **Instructions**: Provide project-specific context for Claude Code
|
|
89
|
+
- **Verify**: Define commands to run after fixes (linting, testing, etc.)
|
|
90
|
+
- **Auto-fix**: Control which comment severities to automatically fix
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Start interactive TUI dashboard for one or more branches
|
|
96
|
+
orc start my-feature-branch
|
|
97
|
+
|
|
98
|
+
# Watch multiple branches in TUI
|
|
99
|
+
orc start branch-a branch-b
|
|
100
|
+
|
|
101
|
+
# With options
|
|
102
|
+
orc start my-branch \
|
|
103
|
+
--poll-interval 60 \
|
|
104
|
+
--max-loops 5 \
|
|
105
|
+
--confidence 0.8 \
|
|
106
|
+
--dry-run
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Interactive TUI Controls
|
|
110
|
+
|
|
111
|
+
Once started, orc opens an interactive terminal dashboard with these controls:
|
|
112
|
+
|
|
113
|
+
| Key | Action |
|
|
114
|
+
|-----|--------|
|
|
115
|
+
| `q` | Quit |
|
|
116
|
+
| `r` | Refresh all PRs immediately |
|
|
117
|
+
| `Tab` | Toggle between Sessions and Logs view |
|
|
118
|
+
| `↑`/`↓` | Navigate sessions or scroll logs |
|
|
119
|
+
| `Enter` | Start/stop monitoring for selected PR |
|
|
120
|
+
| `a` | Start monitoring all PRs |
|
|
121
|
+
| `x` | Stop monitoring all PRs |
|
|
122
|
+
|
|
123
|
+
The dashboard shows:
|
|
124
|
+
- **Real-time status** of each PR being monitored with comment counts
|
|
125
|
+
- **Last check timestamp** for polling activity
|
|
126
|
+
- **Detailed information** about comments, CI status, and fixes
|
|
127
|
+
- **Scrollable logs** accessible via Tab key
|
|
128
|
+
|
|
129
|
+
### Options
|
|
130
|
+
|
|
131
|
+
| Flag | Description | Default |
|
|
132
|
+
|------|-------------|---------|
|
|
133
|
+
| `--max-loops <n>` | Max fix iterations per branch | 10 |
|
|
134
|
+
| `--poll-interval <n>` | Seconds between polls | 30 |
|
|
135
|
+
| `--confidence <n>` | Min confidence to act on a comment (0-1) | 0.75 |
|
|
136
|
+
| `--model <model>` | Claude model for fixes | — |
|
|
137
|
+
| `--max-turns <n>` | Max turns per Claude Code session | 30 |
|
|
138
|
+
| `--claude-timeout <n>` | Seconds before killing Claude Code | 900 |
|
|
139
|
+
| `--dry-run` | Show what would be done without executing | — |
|
|
140
|
+
| `--verbose` | Include detailed output | — |
|
|
141
|
+
|
|
142
|
+
## Development
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
yarn dev # Watch mode (rebuilds on change)
|
|
146
|
+
yarn typecheck # Type-check without emitting
|
|
147
|
+
yarn lint # Lint source files
|
|
148
|
+
yarn test # Run tests
|
|
149
|
+
yarn test:watch # Run tests in watch mode
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## FAQ
|
|
153
|
+
|
|
154
|
+
### Does this violate Anthropic's Terms of Service?
|
|
155
|
+
|
|
156
|
+
No. `orc` is a CI/CD automation tool that invokes Claude Code as a subprocess — it does not access the Anthropic API directly or tamper with Claude Code's authentication. Specifically:
|
|
157
|
+
|
|
158
|
+
- **No direct API calls.** `orc` never makes HTTP requests to `api.anthropic.com` or any Anthropic endpoint. All Claude interactions go through the official [Claude Code Agent SDK](https://docs.anthropic.com/en/docs/claude-code/sdk) (`@anthropic-ai/claude-code`), which spawns Claude Code as a subprocess.
|
|
159
|
+
- **No token extraction.** `orc` never reads, stores, or forwards OAuth tokens, session tokens, or any credentials from Claude Code's internal state or config files.
|
|
160
|
+
- **No header spoofing.** `orc` never sets `Authorization`, `User-Agent`, `X-Api-Key`, or any other HTTP header to impersonate Claude Code.
|
|
161
|
+
- **No credential parsing.** `orc` never accesses `~/.claude`, Claude Code's authentication files, or any credential storage. Authentication is handled entirely by Claude Code itself.
|
|
162
|
+
|
|
163
|
+
`orc` is architecturally equivalent to a shell script that runs `claude` commands in a loop — it just adds a TUI dashboard and PR-aware orchestration on top.
|
|
164
|
+
|
|
165
|
+
## Disclaimers
|
|
166
|
+
|
|
167
|
+
**This software is provided "as is", without warranty of any kind.** By using orc, you acknowledge and agree to the following:
|
|
168
|
+
|
|
169
|
+
- **Cost responsibility.** orc invokes Claude Code, which requires an active [Claude Code subscription](https://docs.anthropic.com/en/docs/claude-code). Each fix cycle consumes usage against your subscription or API quota. The authors are not responsible for any costs, charges, or overages incurred through use of this software.
|
|
170
|
+
- **Autonomous code changes.** orc is designed to automatically modify code, commit, and push to your GitHub repositories. While it operates in isolated worktrees and runs configured verification commands, the authors make no guarantees about the correctness, safety, or suitability of any changes it produces. You are solely responsible for reviewing and accepting changes pushed to your repositories.
|
|
171
|
+
- **No liability.** In no event shall the authors or copyright holders be liable for any claim, damages, or other liability arising from the use of this software, including but not limited to data loss, repository corruption, CI/CD costs, or unintended code modifications.
|
|
172
|
+
- **Third-party services.** orc depends on third-party services (GitHub, Claude Code) that have their own terms of service, pricing, and availability. The authors make no guarantees about the availability or behavior of these services and are not responsible for changes to their terms or pricing.
|
|
173
|
+
|
|
174
|
+
Use of this software constitutes acceptance of these terms. Always review changes before merging, and use the `--dry-run` flag to preview behavior before enabling autonomous fixes.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orc.d.ts","sourceRoot":"","sources":["../../bin/orc.ts"],"names":[],"mappings":""}
|
package/dist/bin/orc.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orc.js","sourceRoot":"","sources":["../../bin/orc.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAEpC,GAAG,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,GAAG,SA2BO,CAAC"}
|
package/dist/src/cli.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI setup using Commander.
|
|
3
|
+
*/
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
import { startCommand } from "./commands/start.js";
|
|
7
|
+
import { initCommand } from "./commands/init.js";
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const pkg = require("../../package.json");
|
|
10
|
+
export const cli = new Command()
|
|
11
|
+
.name("orc")
|
|
12
|
+
.description("Automate PR feedback loops — fetch review comments, fix with Claude Code, push, repeat.")
|
|
13
|
+
.version(pkg.version)
|
|
14
|
+
.option("--poll-interval <n>", "Seconds between polls", parseInt)
|
|
15
|
+
.option("--confidence <n>", "Min confidence to act on a comment (0-1)", parseFloat)
|
|
16
|
+
.option("--model <model>", "Claude model for fixes")
|
|
17
|
+
.option("--session-timeout <n>", "Hours before stopping a watch session (0 = unlimited, default: unlimited)", parseFloat)
|
|
18
|
+
.option("--claude-timeout <n>", "Seconds before killing Claude Code", parseInt)
|
|
19
|
+
.option("--dry-run", "Show what would be done without executing")
|
|
20
|
+
.option("--verbose", "Include detailed output")
|
|
21
|
+
.option("--write-logs", "Write logs to orc.log (rolling 10-minute window)")
|
|
22
|
+
.option("--theme <mode>", "Color theme (dark, light)")
|
|
23
|
+
.action(startCommand);
|
|
24
|
+
cli
|
|
25
|
+
.command("init")
|
|
26
|
+
.description("Generate an ORC.md config for this repo")
|
|
27
|
+
.action(initCommand);
|
|
28
|
+
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;AAEjE,MAAM,CAAC,MAAM,GAAG,GAAG,IAAI,OAAO,EAAE;KAC7B,IAAI,CAAC,KAAK,CAAC;KACX,WAAW,CACV,yFAAyF,CAC1F;KACA,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,qBAAqB,EAAE,uBAAuB,EAAE,QAAQ,CAAC;KAChE,MAAM,CACL,kBAAkB,EAClB,0CAA0C,EAC1C,UAAU,CACX;KACA,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,CAAC;KACnD,MAAM,CACL,uBAAuB,EACvB,2EAA2E,EAC3E,UAAU,CACX;KACA,MAAM,CACL,sBAAsB,EACtB,oCAAoC,EACpC,QAAQ,CACT;KACA,MAAM,CAAC,WAAW,EAAE,2CAA2C,CAAC;KAChE,MAAM,CAAC,WAAW,EAAE,yBAAyB,CAAC;KAC9C,MAAM,CAAC,cAAc,EAAE,kDAAkD,CAAC;KAC1E,MAAM,CAAC,gBAAgB,EAAE,2BAA2B,CAAC;KACrD,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,GAAG;KACA,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,yCAAyC,CAAC;KACtD,MAAM,CAAC,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuCH,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CA8BjD"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `orc init` — generates ORC.md + orc.config.json for the current repo
|
|
3
|
+
* by detecting the project ecosystem and writing sensible defaults.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import { detectProject } from "../utils/project-detector.js";
|
|
8
|
+
function generateMarkdown() {
|
|
9
|
+
return `# Orc
|
|
10
|
+
|
|
11
|
+
Add repo-specific instructions and context for Claude Code here.
|
|
12
|
+
`;
|
|
13
|
+
}
|
|
14
|
+
function generateConfig(cwd) {
|
|
15
|
+
const detected = detectProject(cwd);
|
|
16
|
+
const config = {
|
|
17
|
+
setup: detected.setupCommands,
|
|
18
|
+
verify: detected.verifyCommands,
|
|
19
|
+
allowedCommands: detected.allowedCommands,
|
|
20
|
+
autoFix: {
|
|
21
|
+
must_fix: true,
|
|
22
|
+
should_fix: true,
|
|
23
|
+
nice_to_have: false,
|
|
24
|
+
verify_and_fix: true,
|
|
25
|
+
needs_clarification: true,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
return { config, ecosystem: detected.ecosystem };
|
|
29
|
+
}
|
|
30
|
+
export async function initCommand() {
|
|
31
|
+
const cwd = process.cwd();
|
|
32
|
+
const mdPath = path.join(cwd, "ORC.md");
|
|
33
|
+
const jsonPath = path.join(cwd, "orc.config.json");
|
|
34
|
+
const mdExists = fs.existsSync(mdPath);
|
|
35
|
+
const jsonExists = fs.existsSync(jsonPath);
|
|
36
|
+
if (mdExists && jsonExists) {
|
|
37
|
+
console.log("ORC.md and orc.config.json already exist. Remove them first to re-initialize.");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const { config, ecosystem } = generateConfig(cwd);
|
|
41
|
+
if (!mdExists) {
|
|
42
|
+
fs.writeFileSync(mdPath, generateMarkdown(), "utf-8");
|
|
43
|
+
console.log("Created ORC.md (instructions)");
|
|
44
|
+
}
|
|
45
|
+
if (!jsonExists) {
|
|
46
|
+
fs.writeFileSync(jsonPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
47
|
+
console.log("Created orc.config.json (config)");
|
|
48
|
+
}
|
|
49
|
+
console.log(`\nDetected: ${ecosystem}`);
|
|
50
|
+
if (config.setup.length > 0)
|
|
51
|
+
console.log(` Setup: ${config.setup.join(", ")}`);
|
|
52
|
+
if (config.verify.length > 0)
|
|
53
|
+
console.log(` Verify: ${config.verify.join(", ")}`);
|
|
54
|
+
if (config.allowedCommands.length > 0)
|
|
55
|
+
console.log(` Commands: ${config.allowedCommands.join(", ")}`);
|
|
56
|
+
console.log("\nReview and customize both files for your project.");
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/commands/init.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,SAAS,gBAAgB;IACvB,OAAO;;;CAGR,CAAC;AACF,CAAC;AASD,SAAS,cAAc,CAAC,GAAW;IACjC,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;IAEpC,MAAM,MAAM,GAAc;QACxB,KAAK,EAAE,QAAQ,CAAC,aAAa;QAC7B,MAAM,EAAE,QAAQ,CAAC,cAAc;QAC/B,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,IAAI;YAChB,YAAY,EAAE,KAAK;YACnB,cAAc,EAAE,IAAI;YACpB,mBAAmB,EAAE,IAAI;SAC1B;KACF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,SAAS,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC;IAEnD,MAAM,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,+EAA+E,CAAC,CAAC;QAC7F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAElD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,EAAE,CAAC,aAAa,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnF,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACrF,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACvG,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for the daemon — discovers and watches all open PRs
|
|
3
|
+
* authored by the current user.
|
|
4
|
+
*/
|
|
5
|
+
export interface StartOptions {
|
|
6
|
+
pollInterval?: number;
|
|
7
|
+
confidence?: number;
|
|
8
|
+
model?: string;
|
|
9
|
+
sessionTimeout?: number;
|
|
10
|
+
claudeTimeout?: number;
|
|
11
|
+
dryRun?: boolean;
|
|
12
|
+
verbose?: boolean;
|
|
13
|
+
writeLogs?: boolean;
|
|
14
|
+
theme?: "dark" | "light";
|
|
15
|
+
}
|
|
16
|
+
export declare function startCommand(options: StartOptions): Promise<void>;
|
|
17
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/commands/start.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,YAAY;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AA6ED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAwFvE"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entry point for the daemon — discovers and watches all open PRs
|
|
3
|
+
* authored by the current user.
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import React, { useState } from "react";
|
|
8
|
+
import { render, Box, Text, useInput } from "ink";
|
|
9
|
+
import { Daemon } from "../core/daemon.js";
|
|
10
|
+
import { ConfigSchema } from "../types/config.js";
|
|
11
|
+
import { logger } from "../utils/logger.js";
|
|
12
|
+
import { loadSettings, saveSettings } from "../utils/settings.js";
|
|
13
|
+
import { App } from "../tui/App.js";
|
|
14
|
+
import { ThemeProvider } from "../tui/theme.js";
|
|
15
|
+
function ThemePicker({ onPick }) {
|
|
16
|
+
const [selected, setSelected] = useState(0);
|
|
17
|
+
useInput((input, key) => {
|
|
18
|
+
if (key.upArrow || input === "k")
|
|
19
|
+
setSelected(0);
|
|
20
|
+
if (key.downArrow || input === "j")
|
|
21
|
+
setSelected(1);
|
|
22
|
+
if (key.return)
|
|
23
|
+
onPick(selected === 0 ? "dark" : "light");
|
|
24
|
+
});
|
|
25
|
+
const options = [
|
|
26
|
+
{ label: "dark", index: 0 },
|
|
27
|
+
{ label: "light", index: 1 },
|
|
28
|
+
];
|
|
29
|
+
return React.createElement(Box, { flexDirection: "column", paddingX: 1, paddingY: 1 }, React.createElement(Text, { bold: true }, "Pick a theme:"), React.createElement(Box, { marginTop: 1, flexDirection: "column" }, ...options.map(({ label, index }) => React.createElement(Text, { key: label }, selected === index
|
|
30
|
+
? React.createElement(Text, { color: "green" }, "> ")
|
|
31
|
+
: " ", React.createElement(Text, { bold: selected === index }, label)))), React.createElement(Text, { dimColor: true }, "↑/↓ to move, enter to select"));
|
|
32
|
+
}
|
|
33
|
+
function ThemePickerWrapper({ onDone }) {
|
|
34
|
+
return React.createElement(ThemePicker, {
|
|
35
|
+
onPick: (theme) => {
|
|
36
|
+
onDone(theme);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
async function promptTheme() {
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
const instance = render(React.createElement(ThemePickerWrapper, {
|
|
43
|
+
onDone: (theme) => {
|
|
44
|
+
instance.unmount();
|
|
45
|
+
resolve(theme);
|
|
46
|
+
},
|
|
47
|
+
}));
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async function resolveTheme(explicitTheme) {
|
|
51
|
+
// 1. Explicit --theme flag takes priority
|
|
52
|
+
if (explicitTheme)
|
|
53
|
+
return explicitTheme;
|
|
54
|
+
// 2. Saved settings
|
|
55
|
+
const saved = loadSettings();
|
|
56
|
+
if (saved && saved.theme && (saved.theme === "dark" || saved.theme === "light")) {
|
|
57
|
+
return saved.theme;
|
|
58
|
+
}
|
|
59
|
+
// 3. First run — prompt the user
|
|
60
|
+
const isTTY = process.stdin.isTTY === true;
|
|
61
|
+
if (!isTTY)
|
|
62
|
+
return "dark";
|
|
63
|
+
const chosen = await promptTheme();
|
|
64
|
+
try {
|
|
65
|
+
saveSettings({ theme: chosen });
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
// Continue without saving if settings directory is not writable
|
|
69
|
+
logger.warn("Could not save theme preference:", error instanceof Error ? error.message : String(error));
|
|
70
|
+
}
|
|
71
|
+
return chosen;
|
|
72
|
+
}
|
|
73
|
+
export async function startCommand(options) {
|
|
74
|
+
const theme = await resolveTheme(options.theme);
|
|
75
|
+
const config = ConfigSchema.parse({
|
|
76
|
+
pollInterval: options.pollInterval,
|
|
77
|
+
confidence: options.confidence,
|
|
78
|
+
model: options.model,
|
|
79
|
+
sessionTimeout: options.sessionTimeout,
|
|
80
|
+
claudeTimeout: options.claudeTimeout,
|
|
81
|
+
dryRun: options.dryRun ?? false,
|
|
82
|
+
verbose: options.verbose ?? false,
|
|
83
|
+
writeLogs: options.writeLogs ?? false,
|
|
84
|
+
theme,
|
|
85
|
+
});
|
|
86
|
+
logger.init(config.writeLogs ? "orc.log" : undefined, config.verbose);
|
|
87
|
+
// Clean up session log files from previous runs
|
|
88
|
+
try {
|
|
89
|
+
const cwd = process.cwd();
|
|
90
|
+
for (const entry of fs.readdirSync(cwd)) {
|
|
91
|
+
if (entry.startsWith(".orc-session-") && entry.endsWith(".txt")) {
|
|
92
|
+
try {
|
|
93
|
+
fs.unlinkSync(path.join(cwd, entry));
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// Continue cleanup even if individual file deletion fails
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// Directory read failed, skip cleanup
|
|
103
|
+
}
|
|
104
|
+
const isTTY = process.stdin.isTTY === true;
|
|
105
|
+
if (isTTY) {
|
|
106
|
+
logger.setSuppressConsole(true);
|
|
107
|
+
}
|
|
108
|
+
logger.info(`Orc starting`);
|
|
109
|
+
logger.info(`Config: ${JSON.stringify(config, null, 2)}`);
|
|
110
|
+
if (config.dryRun) {
|
|
111
|
+
logger.info("[DRY RUN MODE] No changes will be made.");
|
|
112
|
+
}
|
|
113
|
+
const cwd = process.cwd();
|
|
114
|
+
const daemon = new Daemon(config, cwd);
|
|
115
|
+
if (!isTTY) {
|
|
116
|
+
const cleanup = async () => {
|
|
117
|
+
await daemon.stop();
|
|
118
|
+
logger.close();
|
|
119
|
+
process.exit(0);
|
|
120
|
+
};
|
|
121
|
+
process.on("SIGINT", cleanup);
|
|
122
|
+
process.on("SIGTERM", cleanup);
|
|
123
|
+
try {
|
|
124
|
+
await daemon.run();
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
logger.close();
|
|
128
|
+
}
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const startTime = Date.now();
|
|
132
|
+
const daemonPromise = daemon.run().catch((err) => {
|
|
133
|
+
logger.error(`Daemon error: ${err}`);
|
|
134
|
+
});
|
|
135
|
+
const instance = render(React.createElement(ThemeProvider, { initialMode: config.theme }, React.createElement(App, { daemon, startTime })), { exitOnCtrlC: true });
|
|
136
|
+
await instance.waitUntilExit();
|
|
137
|
+
const shutdown = async () => {
|
|
138
|
+
await daemon.stop();
|
|
139
|
+
await daemonPromise;
|
|
140
|
+
logger.close();
|
|
141
|
+
};
|
|
142
|
+
const timeout = new Promise((resolve) => setTimeout(resolve, 2000));
|
|
143
|
+
await Promise.race([shutdown(), timeout]);
|
|
144
|
+
process.exit(0);
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Default values and magic numbers. */
|
|
2
|
+
/** Seconds between GitHub polls. */
|
|
3
|
+
export declare const DEFAULT_POLL_INTERVAL = 60;
|
|
4
|
+
/** Default confidence threshold for comment classification. */
|
|
5
|
+
export declare const DEFAULT_CONFIDENCE = 0.75;
|
|
6
|
+
/** Default Claude Code session timeout in seconds. */
|
|
7
|
+
export declare const DEFAULT_CLAUDE_TIMEOUT = 900;
|
|
8
|
+
/** Default session timeout in hours. 0 = unlimited. */
|
|
9
|
+
export declare const DEFAULT_SESSION_TIMEOUT = 0;
|
|
10
|
+
/** Retry backoff intervals in milliseconds. */
|
|
11
|
+
export declare const RETRY_BACKOFF_MS: number[];
|
|
12
|
+
/** Worktree base directory. Supports ORC_WORKTREE_BASE env override. */
|
|
13
|
+
export declare const WORKTREE_BASE: string;
|
|
14
|
+
/** Maximum number of CI fix attempts per session cycle. */
|
|
15
|
+
export declare const MAX_CI_FIX_ATTEMPTS = 2;
|
|
16
|
+
/** Tools allowed in Claude Code sessions. */
|
|
17
|
+
export declare const ALLOWED_TOOLS: readonly ["Read", "Write", "Edit", "Glob", "Grep", "Task", "Bash(git diff *)", "Bash(git log *)", "Bash(git status *)", "Bash(git add *)", "Bash(git commit *)", "Bash(npm run lint *)", "Bash(npm run typecheck *)", "Bash(npm run test *)", "Bash(yarn lint *)", "Bash(yarn typecheck *)", "Bash(yarn test *)", "Bash(git merge-tree *)", "Bash(git rebase *)", "Bash(git show *)", "Bash(git checkout *)"];
|
|
18
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAKxC,oCAAoC;AACpC,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,uDAAuD;AACvD,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,UAA4B,CAAC;AAE1D,wEAAwE;AACxE,eAAO,MAAM,aAAa,QAAiE,CAAC;AAE5F,2DAA2D;AAC3D,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,6CAA6C;AAC7C,eAAO,MAAM,aAAa,+YAsBhB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Default values and magic numbers. */
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
/** Seconds between GitHub polls. */
|
|
5
|
+
export const DEFAULT_POLL_INTERVAL = 60;
|
|
6
|
+
/** Default confidence threshold for comment classification. */
|
|
7
|
+
export const DEFAULT_CONFIDENCE = 0.75;
|
|
8
|
+
/** Default Claude Code session timeout in seconds. */
|
|
9
|
+
export const DEFAULT_CLAUDE_TIMEOUT = 900;
|
|
10
|
+
/** Default session timeout in hours. 0 = unlimited. */
|
|
11
|
+
export const DEFAULT_SESSION_TIMEOUT = 0;
|
|
12
|
+
/** Retry backoff intervals in milliseconds. */
|
|
13
|
+
export const RETRY_BACKOFF_MS = [2000, 4000, 8000, 16000];
|
|
14
|
+
/** Worktree base directory. Supports ORC_WORKTREE_BASE env override. */
|
|
15
|
+
export const WORKTREE_BASE = process.env.ORC_WORKTREE_BASE || path.join(os.tmpdir(), "orc");
|
|
16
|
+
/** Maximum number of CI fix attempts per session cycle. */
|
|
17
|
+
export const MAX_CI_FIX_ATTEMPTS = 2;
|
|
18
|
+
/** Tools allowed in Claude Code sessions. */
|
|
19
|
+
export const ALLOWED_TOOLS = [
|
|
20
|
+
"Read",
|
|
21
|
+
"Write",
|
|
22
|
+
"Edit",
|
|
23
|
+
"Glob",
|
|
24
|
+
"Grep",
|
|
25
|
+
"Task",
|
|
26
|
+
"Bash(git diff *)",
|
|
27
|
+
"Bash(git log *)",
|
|
28
|
+
"Bash(git status *)",
|
|
29
|
+
"Bash(git add *)",
|
|
30
|
+
"Bash(git commit *)",
|
|
31
|
+
"Bash(npm run lint *)",
|
|
32
|
+
"Bash(npm run typecheck *)",
|
|
33
|
+
"Bash(npm run test *)",
|
|
34
|
+
"Bash(yarn lint *)",
|
|
35
|
+
"Bash(yarn typecheck *)",
|
|
36
|
+
"Bash(yarn test *)",
|
|
37
|
+
"Bash(git merge-tree *)",
|
|
38
|
+
"Bash(git rebase *)",
|
|
39
|
+
"Bash(git show *)",
|
|
40
|
+
"Bash(git checkout *)",
|
|
41
|
+
];
|
|
42
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,wCAAwC;AAExC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,oCAAoC;AACpC,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,uDAAuD;AACvD,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC,+CAA+C;AAC/C,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAE1D,wEAAwE;AACxE,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;AAE5F,2DAA2D;AAC3D,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,kBAAkB;IAClB,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,oBAAoB;IACpB,sBAAsB;IACtB,2BAA2B;IAC3B,sBAAsB;IACtB,mBAAmB;IACnB,wBAAwB;IACxB,mBAAmB;IACnB,wBAAwB;IACxB,oBAAoB;IACpB,kBAAkB;IAClB,sBAAsB;CACd,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Uses the Claude Code SDK to classify PR review comments by severity.
|
|
3
|
+
* Piggybacks on Claude Code's existing authentication (no separate API key needed).
|
|
4
|
+
*/
|
|
5
|
+
import type { CategorizedComment } from "../types/index.js";
|
|
6
|
+
import type { FetchedComment } from "./comment-fetcher.js";
|
|
7
|
+
export interface CategorizationResult {
|
|
8
|
+
comments: CategorizedComment[];
|
|
9
|
+
costUsd: number;
|
|
10
|
+
inputTokens: number;
|
|
11
|
+
outputTokens: number;
|
|
12
|
+
}
|
|
13
|
+
export declare class CommentCategorizer {
|
|
14
|
+
private cwd;
|
|
15
|
+
private confidenceThreshold;
|
|
16
|
+
constructor(cwd: string, confidenceThreshold?: number);
|
|
17
|
+
categorize(comments: FetchedComment[], abortSignal?: AbortSignal): Promise<CategorizationResult>;
|
|
18
|
+
private classifyComment;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=comment-categorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-categorizer.d.ts","sourceRoot":"","sources":["../../../src/core/comment-categorizer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAsC3D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,GAAG,CAAS;IACpB,OAAO,CAAC,mBAAmB,CAAS;gBAExB,GAAG,EAAE,MAAM,EAAE,mBAAmB,SAAO;IAK7C,UAAU,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,oBAAoB,CAAC;YA8FxF,eAAe;CAsF9B"}
|