patchrelay 0.26.0 → 0.29.1

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 (57) hide show
  1. package/README.md +83 -31
  2. package/dist/agent-session-plan.js +0 -7
  3. package/dist/build-info.json +3 -3
  4. package/dist/cli/args.js +22 -18
  5. package/dist/cli/commands/feed.js +1 -1
  6. package/dist/cli/commands/issues.js +44 -4
  7. package/dist/cli/commands/linear.js +67 -0
  8. package/dist/cli/commands/repo.js +213 -0
  9. package/dist/cli/commands/setup.js +140 -21
  10. package/dist/cli/connect-flow.js +5 -3
  11. package/dist/cli/formatters/text.js +1 -1
  12. package/dist/cli/help.js +134 -63
  13. package/dist/cli/index.js +166 -188
  14. package/dist/cli/interactive.js +25 -0
  15. package/dist/cli/operator-client.js +11 -0
  16. package/dist/cli/service-commands.js +11 -4
  17. package/dist/cli/watch/App.js +1 -1
  18. package/dist/cli/watch/FactoryStateGraph.js +31 -0
  19. package/dist/cli/watch/FeedView.js +3 -2
  20. package/dist/cli/watch/FreshnessBadge.js +13 -0
  21. package/dist/cli/watch/IssueDetailView.js +9 -2
  22. package/dist/cli/watch/IssueListView.js +2 -2
  23. package/dist/cli/watch/IssueRow.js +9 -11
  24. package/dist/cli/watch/QueueObservationView.js +15 -0
  25. package/dist/cli/watch/StateHistoryView.js +0 -1
  26. package/dist/cli/watch/StatusBar.js +5 -2
  27. package/dist/cli/watch/format-utils.js +7 -0
  28. package/dist/cli/watch/freshness.js +30 -0
  29. package/dist/cli/watch/state-visualization.js +147 -0
  30. package/dist/cli/watch/theme.js +6 -7
  31. package/dist/cli/watch/use-watch-stream.js +5 -2
  32. package/dist/cli/watch/watch-state.js +9 -5
  33. package/dist/config.js +129 -36
  34. package/dist/db/linear-installation-store.js +23 -0
  35. package/dist/db/migrations.js +42 -0
  36. package/dist/db/repository-link-store.js +103 -0
  37. package/dist/db.js +61 -11
  38. package/dist/factory-state.js +1 -5
  39. package/dist/github-webhook-handler.js +115 -46
  40. package/dist/github-webhooks.js +4 -0
  41. package/dist/http.js +162 -0
  42. package/dist/install.js +93 -13
  43. package/dist/issue-query-service.js +34 -1
  44. package/dist/linear-client.js +80 -25
  45. package/dist/merge-queue-incident.js +104 -0
  46. package/dist/merge-queue-protocol.js +54 -0
  47. package/dist/preflight.js +28 -1
  48. package/dist/repository-linking.js +42 -0
  49. package/dist/run-orchestrator.js +197 -21
  50. package/dist/runtime-paths.js +0 -8
  51. package/dist/service.js +94 -49
  52. package/package.json +8 -7
  53. package/dist/cli/commands/connect.js +0 -54
  54. package/dist/cli/commands/project.js +0 -146
  55. package/dist/merge-queue.js +0 -200
  56. package/infra/patchrelay-reload.service +0 -6
  57. package/infra/patchrelay.path +0 -13
package/dist/cli/help.js CHANGED
@@ -2,57 +2,48 @@ export function rootHelpText() {
2
2
  return [
3
3
  "PatchRelay",
4
4
  "",
5
- "patchrelay is a local service and CLI that connects Linear issue delegation to Codex worktrees on your machine.",
5
+ "Mental model:",
6
+ " PatchRelay is a local service that owns repos, runs issues inside those repos,",
7
+ " and exposes service/auth/operator controls around that loop.",
6
8
  "",
7
9
  "Usage:",
8
10
  " patchrelay <command> [args] [flags]",
9
- " patchrelay <issueKey> # shorthand for `patchrelay inspect <issueKey>`",
10
11
  "",
11
- "First-time setup:",
12
+ "Happy path:",
12
13
  " 1. patchrelay init <public-https-url>",
13
14
  " 2. Fill in ~/.config/patchrelay/service.env",
14
- " 3. patchrelay project apply <id> <repo-path>",
15
- " 4. Add IMPLEMENTATION_WORKFLOW.md and REVIEW_WORKFLOW.md to the repo",
16
- " 5. patchrelay doctor",
15
+ " 3. patchrelay linear connect",
16
+ " 4. patchrelay linear sync",
17
+ " 5. patchrelay repo link krasnoperov/usertold --workspace usertold --team USE",
18
+ " 6. patchrelay doctor",
19
+ " 7. patchrelay service status",
17
20
  "",
18
- "Why init needs the public URL:",
19
- " Linear must reach PatchRelay at a public HTTPS origin for both the webhook endpoint",
20
- " and the OAuth callback. `patchrelay init` writes that origin to `server.public_base_url`.",
21
- "",
22
- "Default behavior:",
23
- " PatchRelay already defaults the local bind address, database path, log path, worktree",
24
- " root, and Codex runner settings. In the normal",
25
- " case you only need the public URL, the required secrets, and at least one project.",
26
- " `patchrelay init` installs the system service and config watcher, and `project apply`",
27
- " upserts the repo config and reuses or starts the Linear connection flow.",
28
- "",
29
- "Commands:",
30
- " version [--json] Show the installed PatchRelay build version",
21
+ "Core commands:",
31
22
  " init <public-base-url> [--force] [--json] Bootstrap the machine-level PatchRelay home",
32
- " project apply <id> <repo-path> [--issue-prefix <prefixes>] [--team-id <ids>] [--no-connect] [--no-open] [--timeout <seconds>] [--json]",
33
- " Upsert one local repository and connect it to Linear when ready",
34
- " doctor [--json] Check secrets, paths, git, and codex",
35
- " install-service [--force] [--write-only] [--json] Reinstall the systemd system service and watcher",
36
- " restart-service [--json] Reload-or-restart the systemd system service",
37
- " connect [--project <projectId>] [--no-open] [--timeout <seconds>] [--json]",
38
- " Advanced: start or reuse a Linear installation directly",
39
- " installations [--json] Show connected Linear installations",
40
- " feed [--follow] [--limit <count>] [--issue <issueKey>] [--project <projectId>] [--kind <kind>] [--stage <stage>] [--status <status>] [--workflow <id>] [--json]",
41
- " Show a live operator feed from the daemon",
42
- " watch [--issue <issueKey>] Live TUI dashboard of issues and runs",
43
- " serve Run the local PatchRelay service",
44
- " inspect <issueKey> Show the latest known issue state",
45
- " live <issueKey> [--watch] [--json] Show the active run status",
46
- " report <issueKey> [--run-type <type>] [--run <id>] [--json]",
47
- " Show finished run reports",
48
- " events <issueKey> [--run <id>] [--method <name>] [--follow] [--json]",
49
- " Show raw thread events",
50
- " worktree <issueKey> [--cd] [--json] Print the issue worktree path",
51
- " open <issueKey> [--print] [--json] Open Codex in the issue worktree",
52
- " retry <issueKey> [--run-type <type>] [--reason <text>] [--json]",
53
- " Requeue a run",
54
- " list [--active] [--failed] [--project <projectId>] [--json]",
23
+ " doctor [--json] Check secrets, paths, git, codex, and service reachability",
24
+ " linear connect [--no-open] [--timeout <seconds>] [--json] Connect PatchRelay to one Linear workspace",
25
+ " linear list [--json] List connected Linear workspaces",
26
+ " linear sync [workspace] [--json] Refresh teams and projects from Linear",
27
+ " linear disconnect <workspace> [--json] Remove one connected Linear workspace",
28
+ " repo link <github-repo> --workspace <workspace> --team <team>[,...] [--project <project>[,...]] [--prefix <prefix>[,...]] [--path <path>] [--json]",
29
+ " Link one GitHub repo to a Linear workspace/team and clone or reuse it locally",
30
+ " repo list [--json] List linked repositories",
31
+ " repo show <github-repo> [--json] Show one linked repository",
32
+ " repo unlink <github-repo> [--json] Remove one linked repository",
33
+ " repo sync [github-repo] [--json] Clone missing repositories or fetch origin",
34
+ " issue list [--active] [--failed] [--repo <id>] [--json]",
55
35
  " List tracked issues",
36
+ " issue show <issueKey> [--json] Show the latest known issue state",
37
+ " issue watch <issueKey> [--json] Follow the active run until it settles",
38
+ " issue open <issueKey> [--print] [--json] Open Codex in the issue worktree",
39
+ " service status [--json] Show systemd state and local health",
40
+ " service logs [--lines <count>] [--json] Show recent service logs",
41
+ "",
42
+ "Operator commands:",
43
+ " feed [--follow] [--limit <count>] [--issue <issueKey>] [--repo <id>] [--kind <kind>] [--stage <stage>] [--status <status>] [--workflow <id>] [--json]",
44
+ " Show operator activity from the daemon",
45
+ " dashboard [--issue <issueKey>] Open the TUI dashboard of issues and runs",
46
+ " serve Run the local PatchRelay service",
56
47
  "",
57
48
  "Environment options:",
58
49
  " --help, -h Show help for the root command or current command group",
@@ -65,45 +56,125 @@ export function rootHelpText() {
65
56
  "",
66
57
  "Examples:",
67
58
  " patchrelay init https://patchrelay.example.com",
68
- " patchrelay project apply app /absolute/path/to/repo",
69
- " patchrelay doctor",
70
- " patchrelay USE-54",
59
+ " patchrelay linear connect",
60
+ " patchrelay linear sync",
61
+ " patchrelay repo link krasnoperov/usertold --workspace usertold --team USE",
62
+ " patchrelay repo list",
63
+ " patchrelay issue list --active",
64
+ " patchrelay issue watch USE-54",
65
+ " patchrelay dashboard",
66
+ " patchrelay service status",
71
67
  " patchrelay version --json",
72
68
  "",
73
69
  "Command help:",
74
70
  " patchrelay help",
75
- " patchrelay help project",
76
- " patchrelay project --help",
71
+ " patchrelay help linear",
72
+ " patchrelay help repo",
73
+ " patchrelay help issue",
74
+ " patchrelay help service",
77
75
  ].join("\n");
78
76
  }
79
- export function projectHelpText() {
77
+ export function linearHelpText() {
80
78
  return [
81
79
  "Usage:",
82
- " patchrelay project apply <id> <repo-path> [options]",
80
+ " patchrelay linear connect [options]",
81
+ " patchrelay linear list [--json]",
82
+ " patchrelay linear sync [workspace] [--json]",
83
+ " patchrelay linear disconnect <workspace> [--json]",
83
84
  "",
84
- "Commands:",
85
- " apply <id> <repo-path> Create or update a repository entry in the local PatchRelay config",
86
- "",
87
- "Options:",
88
- " --issue-prefix <prefixes> Comma-separated issue key prefixes for routing",
89
- " --team-id <ids> Comma-separated Linear team ids for routing",
90
- " --no-connect Save the project without starting or reusing Linear OAuth",
85
+ "Options for `linear connect`:",
91
86
  " --no-open Do not open the browser during connect",
92
87
  " --timeout <seconds> Override the connect wait timeout",
93
88
  " --json Emit structured JSON output",
94
89
  " --help, -h Show this help",
95
90
  "",
96
91
  "Behavior:",
97
- " `patchrelay project apply` is the idempotent happy-path command. It updates",
98
- " the local config, reruns readiness checks, reloads the service when ready,",
99
- " and reuses or starts the Linear connect flow unless `--no-connect` is set.",
92
+ " `patchrelay linear connect` authorizes one Linear workspace for PatchRelay.",
93
+ " `patchrelay linear sync` refreshes that workspace's teams and projects.",
94
+ "",
95
+ "Examples:",
96
+ " patchrelay linear connect",
97
+ " patchrelay linear list",
98
+ " patchrelay linear sync usertold",
99
+ ].join("\n");
100
+ }
101
+ export function repoHelpText() {
102
+ return [
103
+ "Usage:",
104
+ " patchrelay repo link <github-repo> --workspace <workspace> --team <team>[,...] [options]",
105
+ " patchrelay repo list [--json]",
106
+ " patchrelay repo show <github-repo> [--json]",
107
+ " patchrelay repo unlink <github-repo> [--json]",
108
+ " patchrelay repo sync [github-repo] [--json]",
109
+ "",
110
+ "Options for `repo link`:",
111
+ " --workspace <workspace> Connected Linear workspace key/name/id",
112
+ " --team <team>[,...] Linear team key, name, or id",
113
+ " --project <project>[,...] Optional Linear project name or id",
114
+ " --prefix <prefix>[,...] Optional issue key prefixes (defaults from team keys when available)",
115
+ " --path <path> Override the managed local clone path",
116
+ " --json Emit structured JSON output",
117
+ " --help, -h Show this help",
118
+ "",
119
+ "Behavior:",
120
+ " `patchrelay repo link` uses the GitHub repo as the source of truth. It reuses",
121
+ " an existing local clone when origin matches, or clones into the managed repo root.",
122
+ "",
123
+ "Examples:",
124
+ " patchrelay repo link krasnoperov/usertold --workspace usertold --team USE",
125
+ " patchrelay repo show krasnoperov/usertold",
126
+ " patchrelay repo sync",
127
+ ].join("\n");
128
+ }
129
+ export function issueHelpText() {
130
+ return [
131
+ "Usage:",
132
+ " patchrelay issue <command> [args] [options]",
133
+ "",
134
+ "Commands:",
135
+ " show <issueKey> Show the latest known issue state",
136
+ " list List tracked issues",
137
+ " watch <issueKey> Follow the active run until it settles",
138
+ " report <issueKey> Show finished run reports",
139
+ " events <issueKey> Show raw thread events",
140
+ " path <issueKey> Print the issue worktree path",
141
+ " open <issueKey> Open Codex in the issue worktree",
142
+ " retry <issueKey> Requeue a run",
143
+ "",
144
+ "Examples:",
145
+ " patchrelay issue list --active",
146
+ " patchrelay issue show USE-54",
147
+ " patchrelay issue watch USE-54",
148
+ ].join("\n");
149
+ }
150
+ export function serviceHelpText() {
151
+ return [
152
+ "Usage:",
153
+ " patchrelay service <command> [options]",
154
+ "",
155
+ "Commands:",
156
+ " install [--force] [--write-only] [--json] Reinstall the systemd service unit",
157
+ " restart [--json] Reload-or-restart the service",
158
+ " status [--json] Show systemd state and service health",
159
+ " logs [--lines <count>] [--json] Show recent journal logs",
100
160
  "",
101
161
  "Examples:",
102
- " patchrelay project apply app /absolute/path/to/repo",
103
- " patchrelay project apply app /absolute/path/to/repo --issue-prefix APP",
104
- " patchrelay project apply app /absolute/path/to/repo --team-id team-123 --no-connect",
162
+ " patchrelay service install",
163
+ " patchrelay service status",
164
+ " patchrelay service logs --lines 100",
105
165
  ].join("\n");
106
166
  }
107
167
  export function helpTextFor(topic) {
108
- return topic === "project" ? projectHelpText() : rootHelpText();
168
+ switch (topic) {
169
+ case "linear":
170
+ return linearHelpText();
171
+ case "repo":
172
+ return repoHelpText();
173
+ case "issue":
174
+ return issueHelpText();
175
+ case "service":
176
+ return serviceHelpText();
177
+ default:
178
+ return rootHelpText();
179
+ }
109
180
  }