@open-agent-toolkit/cli 0.1.12 → 0.1.14
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/assets/agents/oat-reviewer.md +54 -10
- package/assets/docs/workflows/projects/reviews.md +21 -2
- package/assets/docs/workflows/skills/index.md +2 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +354 -0
- package/assets/skills/oat-project-review-receive/SKILL.md +7 -10
- package/assets/skills/oat-project-review-receive-remote/SKILL.md +4 -4
- package/assets/skills/oat-review-provide-remote/SKILL.md +273 -0
- package/assets/skills/oat-review-receive/SKILL.md +6 -6
- package/assets/skills/oat-review-receive-remote/SKILL.md +5 -5
- package/dist/commands/init/tools/shared/skill-manifest.d.ts +2 -2
- package/dist/commands/init/tools/shared/skill-manifest.d.ts.map +1 -1
- package/dist/commands/init/tools/shared/skill-manifest.js +2 -0
- package/dist/config/json.d.ts +2 -0
- package/dist/config/json.d.ts.map +1 -0
- package/dist/config/json.js +29 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +4 -3
- package/dist/config/sync-config.d.ts.map +1 -1
- package/dist/config/sync-config.js +2 -1
- package/dist/review-remote/body-builder.d.ts +79 -0
- package/dist/review-remote/body-builder.d.ts.map +1 -0
- package/dist/review-remote/body-builder.js +103 -0
- package/dist/review-remote/capability-probe.d.ts +61 -0
- package/dist/review-remote/capability-probe.d.ts.map +1 -0
- package/dist/review-remote/capability-probe.js +87 -0
- package/dist/review-remote/line-mapper.d.ts +81 -0
- package/dist/review-remote/line-mapper.d.ts.map +1 -0
- package/dist/review-remote/line-mapper.js +165 -0
- package/dist/review-remote/marker-parser.d.ts +44 -0
- package/dist/review-remote/marker-parser.d.ts.map +1 -0
- package/dist/review-remote/marker-parser.js +97 -0
- package/dist/review-remote/narrowing.d.ts +81 -0
- package/dist/review-remote/narrowing.d.ts.map +1 -0
- package/dist/review-remote/narrowing.js +90 -0
- package/dist/review-remote/project-resolver.d.ts +46 -0
- package/dist/review-remote/project-resolver.d.ts.map +1 -0
- package/dist/review-remote/project-resolver.js +60 -0
- package/dist/review-remote/reviewer-dispatch.d.ts +108 -0
- package/dist/review-remote/reviewer-dispatch.d.ts.map +1 -0
- package/dist/review-remote/reviewer-dispatch.js +153 -0
- package/dist/review-remote/worktree.d.ts +62 -0
- package/dist/review-remote/worktree.d.ts.map +1 -0
- package/dist/review-remote/worktree.js +117 -0
- package/package.json +3 -2
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ephemeral worktree lifecycle helper (see design.md → Data Flow step 2).
|
|
3
|
+
*
|
|
4
|
+
* The provide-remote skills review a PR without mutating the caller's working
|
|
5
|
+
* tree. They acquire an ephemeral, repo-scoped worktree, run `gh pr checkout`
|
|
6
|
+
* INSIDE it (that step lives in the skill, not here), review, then tear the
|
|
7
|
+
* worktree down. This helper owns only the create/run/release lifecycle:
|
|
8
|
+
*
|
|
9
|
+
* - `acquireWorktree({ repoRoot })` — `mktemp -d` an ephemeral path OUTSIDE
|
|
10
|
+
* `repoRoot`, then `git -C "$repoRoot" worktree add --detach <path> HEAD`.
|
|
11
|
+
* The `-C "$repoRoot"` flag is load-bearing: it lets the command run even
|
|
12
|
+
* when the caller's CWD is not inside the repository (a thin remote-review
|
|
13
|
+
* machine invoking the skill from a home directory). `HEAD` is a
|
|
14
|
+
* placeholder ref the skill overwrites with `gh pr checkout <N>`.
|
|
15
|
+
* - `runInWorktree(handle, cb)` — invoke `cb(worktreePath)`. The helper does
|
|
16
|
+
* NOT chdir the host process; it passes the path so callers run repo-scoped
|
|
17
|
+
* git / `cd "$path" && gh pr checkout` in a subshell. This keeps the
|
|
18
|
+
* caller's CWD unchanged (verified by tests).
|
|
19
|
+
* - `releaseWorktree(handle)` — `git -C "$repoRoot" worktree remove --force`
|
|
20
|
+
* then remove the temp directory. Idempotent and safe even if the worktree
|
|
21
|
+
* never populated, so callers run it in a `finally`.
|
|
22
|
+
*
|
|
23
|
+
* Design Open Question resolution: `oat-worktree-bootstrap-auto` reuse was
|
|
24
|
+
* considered but the helper is hand-rolled per the design fallback. The plan's
|
|
25
|
+
* mechanics (repo-scoped git invocation, ephemeral path outside repo root,
|
|
26
|
+
* force-removal teardown) are implemented directly here; the helper stays
|
|
27
|
+
* agnostic to PR checkout so it has no dependency on the bootstrap contract.
|
|
28
|
+
*/
|
|
29
|
+
import { execFile as execFileCallback } from 'node:child_process';
|
|
30
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
31
|
+
import { tmpdir } from 'node:os';
|
|
32
|
+
import { join } from 'node:path';
|
|
33
|
+
import { promisify } from 'node:util';
|
|
34
|
+
const execFile = promisify(execFileCallback);
|
|
35
|
+
/**
|
|
36
|
+
* Create an ephemeral, detached worktree outside the repo root and register it
|
|
37
|
+
* with git. The path is created via `mktemp`-style `mkdtempSync` under the
|
|
38
|
+
* system temp dir, so it is guaranteed to be outside `repoRoot`.
|
|
39
|
+
*/
|
|
40
|
+
export async function acquireWorktree(options) {
|
|
41
|
+
const { repoRoot } = options;
|
|
42
|
+
// Ephemeral path under the OS temp dir — outside repoRoot by construction.
|
|
43
|
+
const worktreePath = mkdtempSync(join(tmpdir(), 'oat-review-wt-'));
|
|
44
|
+
// `git worktree add` requires the target path to NOT already exist, so remove
|
|
45
|
+
// the placeholder mkdtemp directory and let git create it fresh.
|
|
46
|
+
rmSync(worktreePath, { recursive: true, force: true });
|
|
47
|
+
try {
|
|
48
|
+
await execFile('git', [
|
|
49
|
+
'-C',
|
|
50
|
+
repoRoot,
|
|
51
|
+
'worktree',
|
|
52
|
+
'add',
|
|
53
|
+
'--detach',
|
|
54
|
+
worktreePath,
|
|
55
|
+
'HEAD',
|
|
56
|
+
]);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
// `git worktree add` can fail after partially creating the target dir
|
|
60
|
+
// and/or registering `.git/worktrees/<name>` metadata. Because we throw
|
|
61
|
+
// without returning a handle, the caller's `finally { releaseWorktree }`
|
|
62
|
+
// never runs — so clean up the partial worktree here before rethrowing.
|
|
63
|
+
// Best-effort: prune dangling worktree metadata, then remove the temp dir.
|
|
64
|
+
try {
|
|
65
|
+
await execFile('git', ['-C', repoRoot, 'worktree', 'prune']);
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Best-effort; ignore (e.g. repoRoot is not a git repo).
|
|
69
|
+
}
|
|
70
|
+
rmSync(worktreePath, { recursive: true, force: true });
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
return { repoRoot, worktreePath, released: false };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Run a callback "inside" the worktree. The callback receives the worktree
|
|
77
|
+
* path; the helper does not change the host process's working directory, so
|
|
78
|
+
* callers must scope filesystem / git operations to that path themselves
|
|
79
|
+
* (e.g., `git -C <path> …` or `cd <path> && gh pr checkout` in a subshell).
|
|
80
|
+
*/
|
|
81
|
+
export async function runInWorktree(handle, callback) {
|
|
82
|
+
return callback(handle.worktreePath);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Remove the git worktree (force) and clean up the temp directory. Idempotent:
|
|
86
|
+
* a second call is a no-op, and a failed `git worktree remove` (e.g., the
|
|
87
|
+
* worktree never populated, or was already pruned) does not prevent the temp
|
|
88
|
+
* directory cleanup. Safe to call in a `finally`.
|
|
89
|
+
*/
|
|
90
|
+
export async function releaseWorktree(handle) {
|
|
91
|
+
if (handle.released) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
handle.released = true;
|
|
95
|
+
try {
|
|
96
|
+
await execFile('git', [
|
|
97
|
+
'-C',
|
|
98
|
+
handle.repoRoot,
|
|
99
|
+
'worktree',
|
|
100
|
+
'remove',
|
|
101
|
+
'--force',
|
|
102
|
+
handle.worktreePath,
|
|
103
|
+
]);
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// `worktree remove` can fail if the worktree was never populated or was
|
|
107
|
+
// already removed. That is non-fatal — proceed to temp cleanup so we never
|
|
108
|
+
// leak the directory, then prune stale worktree metadata best-effort.
|
|
109
|
+
try {
|
|
110
|
+
await execFile('git', ['-C', handle.repoRoot, 'worktree', 'prune']);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Best-effort; ignore.
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
rmSync(handle.worktreePath, { recursive: true, force: true });
|
|
117
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -30,10 +30,11 @@
|
|
|
30
30
|
"@inquirer/prompts": "^8.2.0",
|
|
31
31
|
"chalk": "^5.6.2",
|
|
32
32
|
"commander": "^12.1.0",
|
|
33
|
+
"jsonc-parser": "3.2.1",
|
|
33
34
|
"ora": "^9.0.0",
|
|
34
35
|
"yaml": "2.8.2",
|
|
35
36
|
"zod": "^3.25.76",
|
|
36
|
-
"@open-agent-toolkit/control-plane": "0.1.
|
|
37
|
+
"@open-agent-toolkit/control-plane": "0.1.14"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/node": "^22.10.0",
|