claude-task-worker 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 +21 -0
- package/README.md +386 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +84 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/gh.d.ts +47 -0
- package/dist/gh.js +113 -0
- package/dist/gh.js.map +1 -0
- package/dist/git.d.ts +1 -0
- package/dist/git.js +14 -0
- package/dist/git.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1890 -0
- package/dist/index.js.map +1 -0
- package/dist/process-manager.d.ts +8 -0
- package/dist/process-manager.js +218 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/random-name.d.ts +1 -0
- package/dist/random-name.js +59 -0
- package/dist/random-name.js.map +1 -0
- package/dist/slack.d.ts +5 -0
- package/dist/slack.js +125 -0
- package/dist/slack.js.map +1 -0
- package/dist/usage.d.ts +2 -0
- package/dist/usage.js +52 -0
- package/dist/usage.js.map +1 -0
- package/dist/workers/create-issue.d.ts +1 -0
- package/dist/workers/create-issue.js +55 -0
- package/dist/workers/create-issue.js.map +1 -0
- package/dist/workers/exec-issue.d.ts +1 -0
- package/dist/workers/exec-issue.js +50 -0
- package/dist/workers/exec-issue.js.map +1 -0
- package/dist/workers/fix-review-point.d.ts +1 -0
- package/dist/workers/fix-review-point.js +62 -0
- package/dist/workers/fix-review-point.js.map +1 -0
- package/dist/workers/triage-issues.d.ts +3 -0
- package/dist/workers/triage-issues.js +54 -0
- package/dist/workers/triage-issues.js.map +1 -0
- package/dist/workers/triage-prs.d.ts +3 -0
- package/dist/workers/triage-prs.js +56 -0
- package/dist/workers/triage-prs.js.map +1 -0
- package/dist/workers/update-issue.d.ts +1 -0
- package/dist/workers/update-issue.js +61 -0
- package/dist/workers/update-issue.js.map +1 -0
- package/dist/worktree.d.ts +2 -0
- package/dist/worktree.js +34 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { getCurrentUser, getRepoInfo, listIssues, removeLabel, addLabel } from "../gh.js";
|
|
2
|
+
import { syncDefaultBranch } from "../git.js";
|
|
3
|
+
import { isRunning, isWorkerAtCapacity, isShuttingDown, run } from "../process-manager.js";
|
|
4
|
+
import { generateWorktreeName } from "../random-name.js";
|
|
5
|
+
import { notifyTaskCompleted, notifyTaskFailed, notifyError } from "../slack.js";
|
|
6
|
+
import { removeWorktree } from "../worktree.js";
|
|
7
|
+
const POLLING_INTERVAL_MS = 30 * 1000;
|
|
8
|
+
export async function execIssueWorker() {
|
|
9
|
+
const { owner, name, defaultBranch } = await getRepoInfo();
|
|
10
|
+
const user = await getCurrentUser();
|
|
11
|
+
console.log(`[exec-issue] Polling issues every 30 seconds for ${owner}/${name} (assignee: ${user})`);
|
|
12
|
+
const tick = async () => {
|
|
13
|
+
if (isShuttingDown())
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
const issues = await listIssues(user, "cc-exec-issue");
|
|
17
|
+
for (const issue of issues) {
|
|
18
|
+
if (issue.labels.some(l => l.name === "cc-in-progress"))
|
|
19
|
+
continue;
|
|
20
|
+
if (isRunning(issue.number))
|
|
21
|
+
continue;
|
|
22
|
+
if (isWorkerAtCapacity("exec-issue"))
|
|
23
|
+
break;
|
|
24
|
+
const issueUrl = `https://github.com/${owner}/${name}/issues/${issue.number}`;
|
|
25
|
+
const worktreeId = generateWorktreeName();
|
|
26
|
+
await addLabel("issue", issue.number, "cc-in-progress");
|
|
27
|
+
syncDefaultBranch(defaultBranch);
|
|
28
|
+
run("claude", ["--dangerously-skip-permissions", "-p", `/base-tools:exec-issue ${issue.number} --triage-scope`, "--worktree", worktreeId], issue.number, issue.title, "exec-issue", worktreeId, async (status, output) => {
|
|
29
|
+
if (status === "completed") {
|
|
30
|
+
await addLabel("issue", issue.number, "cc-pr-created");
|
|
31
|
+
await notifyTaskCompleted("exec-issue", name, issue.number, issue.title, issueUrl);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
await notifyTaskFailed("exec-issue", name, issue.number, issue.title, issueUrl, output);
|
|
35
|
+
}
|
|
36
|
+
await removeLabel("issue", issue.number, "cc-exec-issue");
|
|
37
|
+
await removeLabel("issue", issue.number, "cc-in-progress");
|
|
38
|
+
await removeWorktree(worktreeId);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(`[exec-issue] tick error: ${err}`);
|
|
44
|
+
await notifyError("exec-issue", name, err);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
await tick();
|
|
48
|
+
setInterval(tick, POLLING_INTERVAL_MS);
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=exec-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-issue.js","sourceRoot":"","sources":["../../src/workers/exec-issue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function fixReviewPointWorker(): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { getCurrentUser, getRepoInfo, listPullRequestsWithChecks, isCICompleted, addLabel, removeLabel } from "../gh.js";
|
|
2
|
+
import { syncDefaultBranch } from "../git.js";
|
|
3
|
+
import { isRunning, isWorkerAtCapacity, isWorkerRunning, isShuttingDown, run } from "../process-manager.js";
|
|
4
|
+
import { generateWorktreeName } from "../random-name.js";
|
|
5
|
+
import { notifyTaskCompleted, notifyTaskFailed, notifyError } from "../slack.js";
|
|
6
|
+
import { removeWorktree } from "../worktree.js";
|
|
7
|
+
const POLLING_INTERVAL_MS = 30 * 1000;
|
|
8
|
+
const LABEL_FIX_ONETIME = "cc-fix-onetime";
|
|
9
|
+
const LABEL_FIX_REPEAT = "cc-fix-repeat";
|
|
10
|
+
const LABEL_IN_PROGRESS = "cc-in-progress";
|
|
11
|
+
export async function fixReviewPointWorker() {
|
|
12
|
+
const { owner, name, defaultBranch } = await getRepoInfo();
|
|
13
|
+
const user = await getCurrentUser();
|
|
14
|
+
console.log(`[fix-review-point] Polling PRs every 30 seconds for ${owner}/${name} (assignee: ${user})`);
|
|
15
|
+
const tick = async () => {
|
|
16
|
+
if (isShuttingDown())
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
if (isWorkerRunning("triage-prs"))
|
|
20
|
+
return;
|
|
21
|
+
const prs = await listPullRequestsWithChecks(user);
|
|
22
|
+
const candidates = prs.filter((pr) => {
|
|
23
|
+
const labels = pr.labels.map((l) => l.name);
|
|
24
|
+
if (labels.includes(LABEL_IN_PROGRESS))
|
|
25
|
+
return false;
|
|
26
|
+
if (!isCICompleted(pr.statusCheckRollup))
|
|
27
|
+
return false;
|
|
28
|
+
return labels.includes(LABEL_FIX_ONETIME) || labels.includes(LABEL_FIX_REPEAT);
|
|
29
|
+
});
|
|
30
|
+
for (const pr of candidates) {
|
|
31
|
+
if (isRunning(pr.number))
|
|
32
|
+
continue;
|
|
33
|
+
if (isWorkerAtCapacity("fix-review-point"))
|
|
34
|
+
break;
|
|
35
|
+
const isOnetime = pr.labels.some((l) => l.name === LABEL_FIX_ONETIME);
|
|
36
|
+
const prUrl = `https://github.com/${owner}/${name}/pull/${pr.number}`;
|
|
37
|
+
const worktreeId = generateWorktreeName();
|
|
38
|
+
await addLabel("pr", pr.number, LABEL_IN_PROGRESS);
|
|
39
|
+
syncDefaultBranch(defaultBranch);
|
|
40
|
+
run("claude", ["--dangerously-skip-permissions", "-p", `/base-tools:fix-review-point ${pr.headRefName}`, "--worktree", worktreeId], pr.number, `PR #${pr.number} (${pr.headRefName})`, "fix-review-point", worktreeId, async (status, output) => {
|
|
41
|
+
await removeWorktree(worktreeId);
|
|
42
|
+
if (isOnetime)
|
|
43
|
+
await removeLabel("pr", pr.number, LABEL_FIX_ONETIME);
|
|
44
|
+
await removeLabel("pr", pr.number, LABEL_IN_PROGRESS);
|
|
45
|
+
if (status === "completed") {
|
|
46
|
+
await notifyTaskCompleted("fix-review-point", name, pr.number, pr.title, prUrl);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
await notifyTaskFailed("fix-review-point", name, pr.number, pr.title, prUrl, output);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
console.error(`[fix-review-point] tick error: ${err}`);
|
|
56
|
+
await notifyError("fix-review-point", name, err);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
await tick();
|
|
60
|
+
setInterval(tick, POLLING_INTERVAL_MS);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=fix-review-point.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-review-point.js","sourceRoot":"","sources":["../../src/workers/fix-review-point.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { getCurrentUser, getRepoInfo, listAllIssues } from "../gh.js";
|
|
2
|
+
import { syncDefaultBranch } from "../git.js";
|
|
3
|
+
import { isRunning, isShuttingDown, run } from "../process-manager.js";
|
|
4
|
+
import { notifyTaskCompleted, notifyTaskFailed, notifyError } from "../slack.js";
|
|
5
|
+
const POLLING_INTERVAL_MS = 5 * 60 * 1000;
|
|
6
|
+
const TASK_ID = -1;
|
|
7
|
+
export async function triageIssuesWorker(options) {
|
|
8
|
+
const assignee = await getCurrentUser();
|
|
9
|
+
const { owner, name, defaultBranch } = await getRepoInfo();
|
|
10
|
+
console.log(`[triage-issues] Polling issues every 5 minutes for ${name}`);
|
|
11
|
+
let firstRunResolve;
|
|
12
|
+
const firstRunPromise = options?.waitForFirstRun
|
|
13
|
+
? new Promise(resolve => { firstRunResolve = resolve; })
|
|
14
|
+
: undefined;
|
|
15
|
+
const tick = async () => {
|
|
16
|
+
if (isShuttingDown())
|
|
17
|
+
return;
|
|
18
|
+
try {
|
|
19
|
+
if (isRunning(TASK_ID))
|
|
20
|
+
return;
|
|
21
|
+
const issues = await listAllIssues(assignee);
|
|
22
|
+
const EXCLUDE_LABELS = ["cc-create-issue", "cc-update-issue", "cc-exec-issue", "cc-pr-created"];
|
|
23
|
+
const candidates = issues.filter(issue => !issue.labels.some(l => EXCLUDE_LABELS.includes(l.name)));
|
|
24
|
+
if (candidates.length === 0) {
|
|
25
|
+
firstRunResolve?.();
|
|
26
|
+
firstRunResolve = undefined;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const repoUrl = `https://github.com/${owner}/${name}`;
|
|
30
|
+
syncDefaultBranch(defaultBranch);
|
|
31
|
+
run("claude", ["--dangerously-skip-permissions", "-p", "/base-tools:triage-issues"], TASK_ID, "Triage Issues", "triage-issues", undefined, async (status, output) => {
|
|
32
|
+
if (status === "completed") {
|
|
33
|
+
await notifyTaskCompleted("triage-issues", name, TASK_ID, "Triage Issues", repoUrl);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
await notifyTaskFailed("triage-issues", name, TASK_ID, "Triage Issues", repoUrl, output);
|
|
37
|
+
}
|
|
38
|
+
firstRunResolve?.();
|
|
39
|
+
firstRunResolve = undefined;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error(`[triage-issues] tick error: ${err}`);
|
|
44
|
+
await notifyError("triage-issues", name, err);
|
|
45
|
+
firstRunResolve?.();
|
|
46
|
+
firstRunResolve = undefined;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
await tick();
|
|
50
|
+
setInterval(tick, POLLING_INTERVAL_MS);
|
|
51
|
+
if (firstRunPromise)
|
|
52
|
+
await firstRunPromise;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=triage-issues.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-issues.js","sourceRoot":"","sources":["../../src/workers/triage-issues.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getCurrentUser, getRepoInfo, listPullRequestsWithChecks, isCICompleted } from "../gh.js";
|
|
2
|
+
import { syncDefaultBranch } from "../git.js";
|
|
3
|
+
import { isRunning, isShuttingDown, run } from "../process-manager.js";
|
|
4
|
+
import { notifyTaskCompleted, notifyTaskFailed, notifyError } from "../slack.js";
|
|
5
|
+
import { removeAllAgentWorktrees } from "../worktree.js";
|
|
6
|
+
const POLLING_INTERVAL_MS = 5 * 60 * 1000;
|
|
7
|
+
const TASK_ID = -2;
|
|
8
|
+
export async function triagePrsWorker(options) {
|
|
9
|
+
const { owner, name, defaultBranch } = await getRepoInfo();
|
|
10
|
+
const user = await getCurrentUser();
|
|
11
|
+
console.log(`[triage-prs] Polling PRs every 5 minutes for ${name} (assignee: ${user})`);
|
|
12
|
+
let firstRunResolve;
|
|
13
|
+
const firstRunPromise = options?.waitForFirstRun
|
|
14
|
+
? new Promise(resolve => { firstRunResolve = resolve; })
|
|
15
|
+
: undefined;
|
|
16
|
+
const tick = async () => {
|
|
17
|
+
if (isShuttingDown())
|
|
18
|
+
return;
|
|
19
|
+
try {
|
|
20
|
+
if (isRunning(TASK_ID))
|
|
21
|
+
return;
|
|
22
|
+
const prs = await listPullRequestsWithChecks(user, { triageScope: true });
|
|
23
|
+
const candidates = prs.filter(pr => !pr.labels.some(l => l.name === "cc-fix-onetime") &&
|
|
24
|
+
isCICompleted(pr.statusCheckRollup));
|
|
25
|
+
if (candidates.length === 0) {
|
|
26
|
+
firstRunResolve?.();
|
|
27
|
+
firstRunResolve = undefined;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const repoUrl = `https://github.com/${owner}/${name}`;
|
|
31
|
+
syncDefaultBranch(defaultBranch);
|
|
32
|
+
run("claude", ["--dangerously-skip-permissions", "-p", "/base-tools:triage-prs"], TASK_ID, "Triage PRs", "triage-prs", undefined, async (status, output) => {
|
|
33
|
+
await removeAllAgentWorktrees();
|
|
34
|
+
if (status === "completed") {
|
|
35
|
+
await notifyTaskCompleted("triage-prs", name, TASK_ID, "Triage PRs", repoUrl);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
await notifyTaskFailed("triage-prs", name, TASK_ID, "Triage PRs", repoUrl, output);
|
|
39
|
+
}
|
|
40
|
+
firstRunResolve?.();
|
|
41
|
+
firstRunResolve = undefined;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
console.error(`[triage-prs] tick error: ${err}`);
|
|
46
|
+
await notifyError("triage-prs", name, err);
|
|
47
|
+
firstRunResolve?.();
|
|
48
|
+
firstRunResolve = undefined;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
await tick();
|
|
52
|
+
setInterval(tick, POLLING_INTERVAL_MS);
|
|
53
|
+
if (firstRunPromise)
|
|
54
|
+
await firstRunPromise;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=triage-prs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-prs.js","sourceRoot":"","sources":["../../src/workers/triage-prs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function updateIssueWorker(): Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { getCurrentUser, getRepoInfo, listIssues, removeLabel, addLabel, getLastIssueComment } from "../gh.js";
|
|
2
|
+
import { syncDefaultBranch } from "../git.js";
|
|
3
|
+
import { isRunning, isWorkerAtCapacity, isShuttingDown, run } from "../process-manager.js";
|
|
4
|
+
import { generateWorktreeName } from "../random-name.js";
|
|
5
|
+
import { notifyTaskCompleted, notifyTaskFailed, notifyError } from "../slack.js";
|
|
6
|
+
import { removeWorktree } from "../worktree.js";
|
|
7
|
+
const POLLING_INTERVAL_MS = 30 * 1000;
|
|
8
|
+
export async function updateIssueWorker() {
|
|
9
|
+
const { owner, name, defaultBranch } = await getRepoInfo();
|
|
10
|
+
const user = await getCurrentUser();
|
|
11
|
+
console.log(`[update-issue] Polling issues every 30 seconds for ${owner}/${name} (assignee: ${user})`);
|
|
12
|
+
const tick = async () => {
|
|
13
|
+
if (isShuttingDown())
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
const issues = await listIssues(user, "cc-update-issue");
|
|
17
|
+
for (const issue of issues) {
|
|
18
|
+
if (issue.labels.some(l => l.name === "cc-in-progress"))
|
|
19
|
+
continue;
|
|
20
|
+
if (isRunning(issue.number))
|
|
21
|
+
continue;
|
|
22
|
+
if (isWorkerAtCapacity("update-issue"))
|
|
23
|
+
break;
|
|
24
|
+
await addLabel("issue", issue.number, "cc-in-progress");
|
|
25
|
+
const lastComment = await getLastIssueComment(issue.number);
|
|
26
|
+
if (!lastComment) {
|
|
27
|
+
await removeLabel("issue", issue.number, "cc-update-issue");
|
|
28
|
+
await removeLabel("issue", issue.number, "cc-in-progress");
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const prompt = `/base-tools:update-issue\nIssue番号: ${issue.number}\n依頼内容: \n${lastComment.body}`;
|
|
32
|
+
const issueUrl = `https://github.com/${owner}/${name}/issues/${issue.number}`;
|
|
33
|
+
const worktreeId = generateWorktreeName();
|
|
34
|
+
syncDefaultBranch(defaultBranch);
|
|
35
|
+
run("claude", ["--dangerously-skip-permissions", "-p", prompt, "--worktree", worktreeId], issue.number, issue.title, "update-issue", worktreeId, async (status, output) => {
|
|
36
|
+
await removeWorktree(worktreeId);
|
|
37
|
+
try {
|
|
38
|
+
await removeLabel("issue", issue.number, "cc-update-issue");
|
|
39
|
+
await removeLabel("issue", issue.number, "cc-in-progress");
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
console.error(`[update-issue] Failed to finalize issue #${issue.number}: ${err}`);
|
|
43
|
+
}
|
|
44
|
+
if (status === "completed") {
|
|
45
|
+
await notifyTaskCompleted("update-issue", name, issue.number, issue.title, issueUrl);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
await notifyTaskFailed("update-issue", name, issue.number, issue.title, issueUrl, output);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
console.error(`[update-issue] tick error: ${err}`);
|
|
55
|
+
await notifyError("update-issue", name, err);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
await tick();
|
|
59
|
+
setInterval(tick, POLLING_INTERVAL_MS);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=update-issue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-issue.js","sourceRoot":"","sources":["../../src/workers/update-issue.ts"],"names":[],"mappings":"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"}
|
package/dist/worktree.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
import { readdir } from "node:fs/promises";
|
|
4
|
+
const execFileAsync = promisify(execFile);
|
|
5
|
+
export async function removeWorktree(worktreeId) {
|
|
6
|
+
const worktreePath = `.claude/worktrees/${worktreeId}`;
|
|
7
|
+
try {
|
|
8
|
+
await execFileAsync("git", ["worktree", "remove", "--force", worktreePath]);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
console.error(`[worktree] Failed to remove worktree ${worktreeId}:`, error);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function removeAllAgentWorktrees() {
|
|
15
|
+
const worktreesDir = ".claude/worktrees";
|
|
16
|
+
let entries;
|
|
17
|
+
try {
|
|
18
|
+
entries = await readdir(worktreesDir);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const agentDirs = entries.filter(e => e.startsWith("agent-"));
|
|
24
|
+
for (const dir of agentDirs) {
|
|
25
|
+
try {
|
|
26
|
+
await execFileAsync("git", ["worktree", "remove", "--force", `${worktreesDir}/${dir}`]);
|
|
27
|
+
console.log(`[worktree] Removed agent worktree: ${dir}`);
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
console.error(`[worktree] Failed to remove agent worktree ${dir}:`, error);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=worktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../src/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAAkB;IACrD,MAAM,YAAY,GAAG,qBAAqB,UAAU,EAAE,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC,CAAC;IAC9E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,wCAAwC,UAAU,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,YAAY,GAAG,mBAAmB,CAAC;IACzC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,YAAY,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;YACxF,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,8CAA8C,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;QAC7E,CAAC;IACH,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "claude-task-worker",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI tool that polls GitHub Issues/PRs and delegates work to Claude CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"claude-task-worker": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc --noEmit && esbuild src/index.ts --bundle --platform=node --format=esm --outfile=dist/index.js",
|
|
12
|
+
"dev": "tsc --noEmit --watch",
|
|
13
|
+
"lint": "eslint .",
|
|
14
|
+
"lint:fix": "eslint . --fix",
|
|
15
|
+
"format": "prettier --write .",
|
|
16
|
+
"format:check": "prettier --check .",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/getty104/claude-task-worker.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/getty104/claude-task-worker#readme",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/getty104/claude-task-worker/issues"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"claude",
|
|
32
|
+
"claude-code",
|
|
33
|
+
"github",
|
|
34
|
+
"cli",
|
|
35
|
+
"automation",
|
|
36
|
+
"issues",
|
|
37
|
+
"pull-requests"
|
|
38
|
+
],
|
|
39
|
+
"author": "getty104",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@eslint/js": "^10.0.1",
|
|
46
|
+
"@types/node": "^22.0.0",
|
|
47
|
+
"esbuild": "^0.27.4",
|
|
48
|
+
"eslint": "^10.3.0",
|
|
49
|
+
"eslint-config-prettier": "^10.1.8",
|
|
50
|
+
"prettier": "^3.8.3",
|
|
51
|
+
"typescript": "^5.7.0",
|
|
52
|
+
"typescript-eslint": "^8.59.1"
|
|
53
|
+
}
|
|
54
|
+
}
|