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.
Files changed (91) hide show
  1. package/LICENSE +229 -0
  2. package/README.md +177 -0
  3. package/dist/bin/dispatch.d.ts +3 -0
  4. package/dist/bin/dispatch.d.ts.map +1 -0
  5. package/dist/bin/dispatch.js +42 -0
  6. package/dist/bin/dispatch.js.map +1 -0
  7. package/dist/src/commands/create.d.ts +3 -0
  8. package/dist/src/commands/create.d.ts.map +1 -0
  9. package/dist/src/commands/create.js +154 -0
  10. package/dist/src/commands/create.js.map +1 -0
  11. package/dist/src/commands/init.d.ts +3 -0
  12. package/dist/src/commands/init.d.ts.map +1 -0
  13. package/dist/src/commands/init.js +100 -0
  14. package/dist/src/commands/init.js.map +1 -0
  15. package/dist/src/commands/run.d.ts +3 -0
  16. package/dist/src/commands/run.d.ts.map +1 -0
  17. package/dist/src/commands/run.js +72 -0
  18. package/dist/src/commands/run.js.map +1 -0
  19. package/dist/src/commands/status.d.ts +3 -0
  20. package/dist/src/commands/status.d.ts.map +1 -0
  21. package/dist/src/commands/status.js +34 -0
  22. package/dist/src/commands/status.js.map +1 -0
  23. package/dist/src/engine/base.d.ts +12 -0
  24. package/dist/src/engine/base.d.ts.map +1 -0
  25. package/dist/src/engine/base.js +161 -0
  26. package/dist/src/engine/base.js.map +1 -0
  27. package/dist/src/engine/claude.d.ts +25 -0
  28. package/dist/src/engine/claude.d.ts.map +1 -0
  29. package/dist/src/engine/claude.js +215 -0
  30. package/dist/src/engine/claude.js.map +1 -0
  31. package/dist/src/engine/types.d.ts +88 -0
  32. package/dist/src/engine/types.d.ts.map +1 -0
  33. package/dist/src/engine/types.js +2 -0
  34. package/dist/src/engine/types.js.map +1 -0
  35. package/dist/src/github/client.d.ts +58 -0
  36. package/dist/src/github/client.d.ts.map +1 -0
  37. package/dist/src/github/client.js +189 -0
  38. package/dist/src/github/client.js.map +1 -0
  39. package/dist/src/github/issues.d.ts +13 -0
  40. package/dist/src/github/issues.d.ts.map +1 -0
  41. package/dist/src/github/issues.js +67 -0
  42. package/dist/src/github/issues.js.map +1 -0
  43. package/dist/src/github/pulls.d.ts +15 -0
  44. package/dist/src/github/pulls.d.ts.map +1 -0
  45. package/dist/src/github/pulls.js +65 -0
  46. package/dist/src/github/pulls.js.map +1 -0
  47. package/dist/src/index.d.ts +7 -0
  48. package/dist/src/index.d.ts.map +1 -0
  49. package/dist/src/index.js +5 -0
  50. package/dist/src/index.js.map +1 -0
  51. package/dist/src/orchestrator/classifier.d.ts +4 -0
  52. package/dist/src/orchestrator/classifier.d.ts.map +1 -0
  53. package/dist/src/orchestrator/classifier.js +45 -0
  54. package/dist/src/orchestrator/classifier.js.map +1 -0
  55. package/dist/src/orchestrator/pipeline.d.ts +13 -0
  56. package/dist/src/orchestrator/pipeline.d.ts.map +1 -0
  57. package/dist/src/orchestrator/pipeline.js +246 -0
  58. package/dist/src/orchestrator/pipeline.js.map +1 -0
  59. package/dist/src/orchestrator/planner.d.ts +13 -0
  60. package/dist/src/orchestrator/planner.d.ts.map +1 -0
  61. package/dist/src/orchestrator/planner.js +95 -0
  62. package/dist/src/orchestrator/planner.js.map +1 -0
  63. package/dist/src/orchestrator/scorer.d.ts +8 -0
  64. package/dist/src/orchestrator/scorer.d.ts.map +1 -0
  65. package/dist/src/orchestrator/scorer.js +41 -0
  66. package/dist/src/orchestrator/scorer.js.map +1 -0
  67. package/dist/src/reporter/summary.d.ts +29 -0
  68. package/dist/src/reporter/summary.d.ts.map +1 -0
  69. package/dist/src/reporter/summary.js +77 -0
  70. package/dist/src/reporter/summary.js.map +1 -0
  71. package/dist/src/utils/config.d.ts +37 -0
  72. package/dist/src/utils/config.d.ts.map +1 -0
  73. package/dist/src/utils/config.js +60 -0
  74. package/dist/src/utils/config.js.map +1 -0
  75. package/dist/src/utils/git.d.ts +30 -0
  76. package/dist/src/utils/git.d.ts.map +1 -0
  77. package/dist/src/utils/git.js +95 -0
  78. package/dist/src/utils/git.js.map +1 -0
  79. package/dist/src/utils/logger.d.ts +22 -0
  80. package/dist/src/utils/logger.d.ts.map +1 -0
  81. package/dist/src/utils/logger.js +109 -0
  82. package/dist/src/utils/logger.js.map +1 -0
  83. package/dist/src/utils/semaphore.d.ts +19 -0
  84. package/dist/src/utils/semaphore.d.ts.map +1 -0
  85. package/dist/src/utils/semaphore.js +41 -0
  86. package/dist/src/utils/semaphore.js.map +1 -0
  87. package/dist/src/utils/worktree.d.ts +20 -0
  88. package/dist/src/utils/worktree.d.ts.map +1 -0
  89. package/dist/src/utils/worktree.js +92 -0
  90. package/dist/src/utils/worktree.js.map +1 -0
  91. 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
+ }