dispatch-ai 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 +229 -0
- package/README.md +177 -0
- package/dist/bin/dispatch.d.ts +3 -0
- package/dist/bin/dispatch.d.ts.map +1 -0
- package/dist/bin/dispatch.js +42 -0
- package/dist/bin/dispatch.js.map +1 -0
- package/dist/src/commands/create.d.ts +3 -0
- package/dist/src/commands/create.d.ts.map +1 -0
- package/dist/src/commands/create.js +154 -0
- package/dist/src/commands/create.js.map +1 -0
- package/dist/src/commands/init.d.ts +3 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +100 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/run.d.ts +3 -0
- package/dist/src/commands/run.d.ts.map +1 -0
- package/dist/src/commands/run.js +72 -0
- package/dist/src/commands/run.js.map +1 -0
- package/dist/src/commands/status.d.ts +3 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +34 -0
- package/dist/src/commands/status.js.map +1 -0
- package/dist/src/engine/base.d.ts +12 -0
- package/dist/src/engine/base.d.ts.map +1 -0
- package/dist/src/engine/base.js +161 -0
- package/dist/src/engine/base.js.map +1 -0
- package/dist/src/engine/claude.d.ts +25 -0
- package/dist/src/engine/claude.d.ts.map +1 -0
- package/dist/src/engine/claude.js +215 -0
- package/dist/src/engine/claude.js.map +1 -0
- package/dist/src/engine/types.d.ts +88 -0
- package/dist/src/engine/types.d.ts.map +1 -0
- package/dist/src/engine/types.js +2 -0
- package/dist/src/engine/types.js.map +1 -0
- package/dist/src/github/client.d.ts +58 -0
- package/dist/src/github/client.d.ts.map +1 -0
- package/dist/src/github/client.js +189 -0
- package/dist/src/github/client.js.map +1 -0
- package/dist/src/github/issues.d.ts +13 -0
- package/dist/src/github/issues.d.ts.map +1 -0
- package/dist/src/github/issues.js +67 -0
- package/dist/src/github/issues.js.map +1 -0
- package/dist/src/github/pulls.d.ts +15 -0
- package/dist/src/github/pulls.d.ts.map +1 -0
- package/dist/src/github/pulls.js +65 -0
- package/dist/src/github/pulls.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/orchestrator/classifier.d.ts +4 -0
- package/dist/src/orchestrator/classifier.d.ts.map +1 -0
- package/dist/src/orchestrator/classifier.js +45 -0
- package/dist/src/orchestrator/classifier.js.map +1 -0
- package/dist/src/orchestrator/pipeline.d.ts +13 -0
- package/dist/src/orchestrator/pipeline.d.ts.map +1 -0
- package/dist/src/orchestrator/pipeline.js +246 -0
- package/dist/src/orchestrator/pipeline.js.map +1 -0
- package/dist/src/orchestrator/planner.d.ts +13 -0
- package/dist/src/orchestrator/planner.d.ts.map +1 -0
- package/dist/src/orchestrator/planner.js +95 -0
- package/dist/src/orchestrator/planner.js.map +1 -0
- package/dist/src/orchestrator/scorer.d.ts +8 -0
- package/dist/src/orchestrator/scorer.d.ts.map +1 -0
- package/dist/src/orchestrator/scorer.js +41 -0
- package/dist/src/orchestrator/scorer.js.map +1 -0
- package/dist/src/reporter/summary.d.ts +29 -0
- package/dist/src/reporter/summary.d.ts.map +1 -0
- package/dist/src/reporter/summary.js +77 -0
- package/dist/src/reporter/summary.js.map +1 -0
- package/dist/src/utils/config.d.ts +37 -0
- package/dist/src/utils/config.d.ts.map +1 -0
- package/dist/src/utils/config.js +60 -0
- package/dist/src/utils/config.js.map +1 -0
- package/dist/src/utils/git.d.ts +30 -0
- package/dist/src/utils/git.d.ts.map +1 -0
- package/dist/src/utils/git.js +95 -0
- package/dist/src/utils/git.js.map +1 -0
- package/dist/src/utils/logger.d.ts +22 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +109 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/semaphore.d.ts +19 -0
- package/dist/src/utils/semaphore.d.ts.map +1 -0
- package/dist/src/utils/semaphore.js +41 -0
- package/dist/src/utils/semaphore.js.map +1 -0
- package/dist/src/utils/worktree.d.ts +20 -0
- package/dist/src/utils/worktree.d.ts.map +1 -0
- package/dist/src/utils/worktree.js +92 -0
- package/dist/src/utils/worktree.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { appendFile, mkdir } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
export var LogLevel;
|
|
5
|
+
(function (LogLevel) {
|
|
6
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
7
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
8
|
+
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
9
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
10
|
+
LogLevel[LogLevel["SILENT"] = 4] = "SILENT";
|
|
11
|
+
})(LogLevel || (LogLevel = {}));
|
|
12
|
+
let currentLevel = LogLevel.INFO;
|
|
13
|
+
export function setLogLevel(level) {
|
|
14
|
+
currentLevel = level;
|
|
15
|
+
}
|
|
16
|
+
function timestamp() {
|
|
17
|
+
return new Date().toLocaleTimeString("en-US", { hour12: false });
|
|
18
|
+
}
|
|
19
|
+
function isoTimestamp() {
|
|
20
|
+
return new Date().toISOString();
|
|
21
|
+
}
|
|
22
|
+
/** Strip ANSI escape codes for plain-text log files */
|
|
23
|
+
function stripAnsi(text) {
|
|
24
|
+
// eslint-disable-next-line no-control-regex
|
|
25
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
26
|
+
}
|
|
27
|
+
// --- File logging state ---
|
|
28
|
+
let logDir = null;
|
|
29
|
+
let accessLogPath = null;
|
|
30
|
+
let errorLogPath = null;
|
|
31
|
+
/** Initialize file-based logging. Creates .dispatch/logs/ directory. */
|
|
32
|
+
export async function initFileLogging(stateDir, cwd) {
|
|
33
|
+
logDir = join(cwd, stateDir, "logs");
|
|
34
|
+
await mkdir(logDir, { recursive: true });
|
|
35
|
+
accessLogPath = join(logDir, "access.log");
|
|
36
|
+
errorLogPath = join(logDir, "error.log");
|
|
37
|
+
}
|
|
38
|
+
/** Get the log directory path (for computing per-issue log paths). */
|
|
39
|
+
export function getLogDir() {
|
|
40
|
+
return logDir;
|
|
41
|
+
}
|
|
42
|
+
/** Fire-and-forget write to log files. */
|
|
43
|
+
function writeToLogFiles(level, msg) {
|
|
44
|
+
if (!accessLogPath || !errorLogPath)
|
|
45
|
+
return;
|
|
46
|
+
const plain = stripAnsi(msg);
|
|
47
|
+
const line = `[${isoTimestamp()}] ${plain}\n`;
|
|
48
|
+
// access.log gets INFO+ messages
|
|
49
|
+
if (level >= LogLevel.INFO) {
|
|
50
|
+
appendFile(accessLogPath, line).catch(() => { });
|
|
51
|
+
}
|
|
52
|
+
// error.log gets WARN+ messages
|
|
53
|
+
if (level >= LogLevel.WARN) {
|
|
54
|
+
appendFile(errorLogPath, line).catch(() => { });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export const log = {
|
|
58
|
+
debug(msg, ...args) {
|
|
59
|
+
if (currentLevel <= LogLevel.DEBUG) {
|
|
60
|
+
console.log(chalk.gray(`[${timestamp()}] ${msg}`), ...args);
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
info(msg, ...args) {
|
|
64
|
+
if (currentLevel <= LogLevel.INFO) {
|
|
65
|
+
console.log(chalk.blue(`[${timestamp()}]`) + ` ${msg}`, ...args);
|
|
66
|
+
}
|
|
67
|
+
writeToLogFiles(LogLevel.INFO, msg);
|
|
68
|
+
},
|
|
69
|
+
success(msg, ...args) {
|
|
70
|
+
if (currentLevel <= LogLevel.INFO) {
|
|
71
|
+
console.log(chalk.green(`✓ ${msg}`), ...args);
|
|
72
|
+
}
|
|
73
|
+
writeToLogFiles(LogLevel.INFO, `SUCCESS: ${msg}`);
|
|
74
|
+
},
|
|
75
|
+
warn(msg, ...args) {
|
|
76
|
+
if (currentLevel <= LogLevel.WARN) {
|
|
77
|
+
console.log(chalk.yellow(`⚠ ${msg}`), ...args);
|
|
78
|
+
}
|
|
79
|
+
writeToLogFiles(LogLevel.WARN, `WARN: ${msg}`);
|
|
80
|
+
},
|
|
81
|
+
error(msg, ...args) {
|
|
82
|
+
if (currentLevel <= LogLevel.ERROR) {
|
|
83
|
+
console.error(chalk.red(`✗ ${msg}`), ...args);
|
|
84
|
+
}
|
|
85
|
+
writeToLogFiles(LogLevel.ERROR, `ERROR: ${msg}`);
|
|
86
|
+
},
|
|
87
|
+
header(msg) {
|
|
88
|
+
if (currentLevel <= LogLevel.INFO) {
|
|
89
|
+
console.log();
|
|
90
|
+
console.log(chalk.bold.cyan(`━━━ ${msg} ━━━`));
|
|
91
|
+
console.log();
|
|
92
|
+
}
|
|
93
|
+
writeToLogFiles(LogLevel.INFO, `--- ${msg} ---`);
|
|
94
|
+
},
|
|
95
|
+
issue(number, title, status) {
|
|
96
|
+
if (currentLevel <= LogLevel.INFO) {
|
|
97
|
+
const badge = status === "solving"
|
|
98
|
+
? chalk.yellow("⏳")
|
|
99
|
+
: status === "solved"
|
|
100
|
+
? chalk.green("✓")
|
|
101
|
+
: status === "failed"
|
|
102
|
+
? chalk.red("✗")
|
|
103
|
+
: chalk.gray("○");
|
|
104
|
+
console.log(` ${badge} #${number} ${chalk.white(title)}`);
|
|
105
|
+
}
|
|
106
|
+
writeToLogFiles(LogLevel.INFO, `#${number} ${title} [${status}]`);
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promise-based semaphore for limiting concurrency.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const sem = new Semaphore(3);
|
|
6
|
+
* await sem.acquire();
|
|
7
|
+
* try { ... } finally { sem.release(); }
|
|
8
|
+
*/
|
|
9
|
+
export declare class Semaphore {
|
|
10
|
+
private readonly limit;
|
|
11
|
+
private queue;
|
|
12
|
+
private active;
|
|
13
|
+
constructor(limit: number);
|
|
14
|
+
acquire(): Promise<void>;
|
|
15
|
+
release(): void;
|
|
16
|
+
get activeCount(): number;
|
|
17
|
+
get waitingCount(): number;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=semaphore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semaphore.d.ts","sourceRoot":"","sources":["../../../src/utils/semaphore.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,SAAS;IAIR,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,KAAK,CAAyB;IACtC,OAAO,CAAC,MAAM,CAAK;gBAEU,KAAK,EAAE,MAAM;IAEpC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAa9B,OAAO,IAAI,IAAI;IAMf,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promise-based semaphore for limiting concurrency.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const sem = new Semaphore(3);
|
|
6
|
+
* await sem.acquire();
|
|
7
|
+
* try { ... } finally { sem.release(); }
|
|
8
|
+
*/
|
|
9
|
+
export class Semaphore {
|
|
10
|
+
limit;
|
|
11
|
+
queue = [];
|
|
12
|
+
active = 0;
|
|
13
|
+
constructor(limit) {
|
|
14
|
+
this.limit = limit;
|
|
15
|
+
}
|
|
16
|
+
async acquire() {
|
|
17
|
+
if (this.active < this.limit) {
|
|
18
|
+
this.active++;
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
this.queue.push(() => {
|
|
23
|
+
this.active++;
|
|
24
|
+
resolve();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
release() {
|
|
29
|
+
this.active--;
|
|
30
|
+
const next = this.queue.shift();
|
|
31
|
+
if (next)
|
|
32
|
+
next();
|
|
33
|
+
}
|
|
34
|
+
get activeCount() {
|
|
35
|
+
return this.active;
|
|
36
|
+
}
|
|
37
|
+
get waitingCount() {
|
|
38
|
+
return this.queue.length;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=semaphore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semaphore.js","sourceRoot":"","sources":["../../../src/utils/semaphore.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,OAAO,SAAS;IAIS;IAHrB,KAAK,GAAsB,EAAE,CAAC;IAC9B,MAAM,GAAG,CAAC,CAAC;IAEnB,YAA6B,KAAa;QAAb,UAAK,GAAL,KAAK,CAAQ;IAAG,CAAC;IAE9C,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,OAAO;QACT,CAAC;QACD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;gBACnB,IAAI,CAAC,MAAM,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,IAAI,CAAC,MAAM,EAAE,CAAC;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,IAAI;YAAE,IAAI,EAAE,CAAC;IACnB,CAAC;IAED,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a git worktree with a new branch based on a remote base branch.
|
|
3
|
+
*/
|
|
4
|
+
export declare function createWorktree(worktreePath: string, branchName: string, baseBranch: string, cwd: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Remove a git worktree and optionally delete the associated branch.
|
|
7
|
+
*/
|
|
8
|
+
export declare function removeWorktree(worktreePath: string, cwd: string, options?: {
|
|
9
|
+
deleteBranch?: string;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Build the worktree path for an issue.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getWorktreePath(cwd: string, stateDir: string, issueNumber: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Clean up all worktrees in the dispatch state directory.
|
|
17
|
+
* Useful for crash recovery at pipeline start.
|
|
18
|
+
*/
|
|
19
|
+
export declare function cleanupAllWorktrees(cwd: string, stateDir: string): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=worktree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../../src/utils/worktree.ts"],"names":[],"mappings":"AAiBA;;GAEG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,MAAM,CAAA;CAAO,GACtC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1F;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMtF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { rm, access } from "node:fs/promises";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { promisify } from "node:util";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
const exec = promisify(execFile);
|
|
7
|
+
async function git(args, cwd) {
|
|
8
|
+
log.debug(`git ${args.join(" ")}`);
|
|
9
|
+
const { stdout } = await exec("git", args, {
|
|
10
|
+
cwd: cwd || process.cwd(),
|
|
11
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
12
|
+
});
|
|
13
|
+
return stdout.trim();
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Create a git worktree with a new branch based on a remote base branch.
|
|
17
|
+
*/
|
|
18
|
+
export async function createWorktree(worktreePath, branchName, baseBranch, cwd) {
|
|
19
|
+
// Clean up if path already exists (e.g. from a previous crashed run)
|
|
20
|
+
try {
|
|
21
|
+
await access(worktreePath);
|
|
22
|
+
log.warn(`Worktree path already exists: ${worktreePath}, removing...`);
|
|
23
|
+
await removeWorktree(worktreePath, cwd);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Path doesn't exist, good
|
|
27
|
+
}
|
|
28
|
+
// Prune stale worktree references first — this is critical because
|
|
29
|
+
// `git branch -D` refuses to delete a branch that git thinks is still
|
|
30
|
+
// checked out in a worktree (even if the worktree directory is gone).
|
|
31
|
+
try {
|
|
32
|
+
await git(["worktree", "prune"], cwd);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// ignore prune errors
|
|
36
|
+
}
|
|
37
|
+
await git(["fetch", "origin", baseBranch], cwd);
|
|
38
|
+
// Delete stale branch from a previous crashed run (if it exists)
|
|
39
|
+
try {
|
|
40
|
+
await git(["branch", "-D", branchName], cwd);
|
|
41
|
+
log.warn(`Deleted stale branch: ${branchName}`);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Branch doesn't exist, good
|
|
45
|
+
}
|
|
46
|
+
await git(["worktree", "add", worktreePath, "-b", branchName, `origin/${baseBranch}`], cwd);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Remove a git worktree and optionally delete the associated branch.
|
|
50
|
+
*/
|
|
51
|
+
export async function removeWorktree(worktreePath, cwd, options = {}) {
|
|
52
|
+
try {
|
|
53
|
+
await git(["worktree", "remove", worktreePath, "--force"], cwd);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
log.debug(`worktree remove failed (may already be gone): ${err}`);
|
|
57
|
+
try {
|
|
58
|
+
await git(["worktree", "prune"], cwd);
|
|
59
|
+
}
|
|
60
|
+
catch { /* ignore prune errors */ }
|
|
61
|
+
}
|
|
62
|
+
// Clean up directory if it still exists
|
|
63
|
+
try {
|
|
64
|
+
await rm(worktreePath, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
catch { /* ignore */ }
|
|
67
|
+
if (options.deleteBranch) {
|
|
68
|
+
try {
|
|
69
|
+
await git(["branch", "-D", options.deleteBranch], cwd);
|
|
70
|
+
}
|
|
71
|
+
catch { /* branch may not exist */ }
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Build the worktree path for an issue.
|
|
76
|
+
*/
|
|
77
|
+
export function getWorktreePath(cwd, stateDir, issueNumber) {
|
|
78
|
+
return join(cwd, stateDir, "worktrees", `issue-${issueNumber}`);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Clean up all worktrees in the dispatch state directory.
|
|
82
|
+
* Useful for crash recovery at pipeline start.
|
|
83
|
+
*/
|
|
84
|
+
export async function cleanupAllWorktrees(cwd, stateDir) {
|
|
85
|
+
try {
|
|
86
|
+
await git(["worktree", "prune"], cwd);
|
|
87
|
+
const worktreeDir = join(cwd, stateDir, "worktrees");
|
|
88
|
+
await rm(worktreeDir, { recursive: true, force: true });
|
|
89
|
+
}
|
|
90
|
+
catch { /* ignore */ }
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=worktree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../../src/utils/worktree.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "dispatch-ai",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Dispatch your GitHub issues. Receive pull requests. AI-powered batch issue solver.",
|
|
5
|
+
"author": "Mehul Patel <nomadicmehul@gmail.com>",
|
|
6
|
+
"license": "Apache-2.0 WITH Commons-Clause",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"dispatch": "./dist/bin/dispatch.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./dist/src/index.js",
|
|
12
|
+
"types": "./dist/src/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/bin",
|
|
15
|
+
"dist/src"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsc --watch",
|
|
20
|
+
"start": "node dist/bin/dispatch.js",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"test": "node --test dist/test/*.test.js",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@anthropic-ai/claude-code": "^1.0.0",
|
|
27
|
+
"@octokit/plugin-retry": "^7.0.0",
|
|
28
|
+
"@octokit/plugin-throttling": "^9.0.0",
|
|
29
|
+
"@octokit/rest": "^21.0.0",
|
|
30
|
+
"chalk": "^5.3.0",
|
|
31
|
+
"commander": "^13.0.0",
|
|
32
|
+
"inquirer": "^12.0.0",
|
|
33
|
+
"ora": "^8.1.0",
|
|
34
|
+
"slugify": "^1.6.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/inquirer": "^9.0.0",
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"typescript": "^5.7.0"
|
|
40
|
+
},
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=20.0.0"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"github",
|
|
46
|
+
"issues",
|
|
47
|
+
"pull-requests",
|
|
48
|
+
"ai",
|
|
49
|
+
"claude",
|
|
50
|
+
"automation",
|
|
51
|
+
"dispatch",
|
|
52
|
+
"cli"
|
|
53
|
+
],
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "https://github.com/nomadicmehul/dispatch.git"
|
|
57
|
+
},
|
|
58
|
+
"bugs": {
|
|
59
|
+
"url": "https://github.com/nomadicmehul/dispatch/issues"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/nomadicmehul/dispatch#readme"
|
|
62
|
+
}
|