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,95 @@
1
+ export function planStrategy(issue) {
2
+ const classification = issue.classification || "unknown";
3
+ switch (classification) {
4
+ case "code-fix":
5
+ return {
6
+ classification,
7
+ steps: [
8
+ "Read the issue to understand the bug",
9
+ "Find the relevant code files",
10
+ "Reproduce or understand the bug",
11
+ "Implement the fix",
12
+ "Check for regressions",
13
+ "Run tests if available",
14
+ ],
15
+ preferredTools: ["Read", "Edit", "Grep", "Glob", "Bash"],
16
+ expectedOutput: "code-changes",
17
+ };
18
+ case "feature":
19
+ return {
20
+ classification,
21
+ steps: [
22
+ "Understand the feature request",
23
+ "Explore the codebase architecture",
24
+ "Plan the implementation",
25
+ "Implement the feature",
26
+ "Add tests if applicable",
27
+ "Update docs if needed",
28
+ ],
29
+ preferredTools: ["Read", "Write", "Edit", "Grep", "Glob", "Bash"],
30
+ expectedOutput: "code-changes",
31
+ };
32
+ case "investigation":
33
+ return {
34
+ classification,
35
+ steps: [
36
+ "Understand what needs investigating",
37
+ "Explore the relevant codebase",
38
+ "Gather evidence and data",
39
+ "Analyze findings",
40
+ "Write investigation report",
41
+ ],
42
+ preferredTools: ["Read", "Grep", "Glob", "Write", "Bash"],
43
+ expectedOutput: "document",
44
+ };
45
+ case "documentation":
46
+ return {
47
+ classification,
48
+ steps: [
49
+ "Understand what needs documenting",
50
+ "Read the relevant code",
51
+ "Write clear documentation",
52
+ "Add code examples if helpful",
53
+ ],
54
+ preferredTools: ["Read", "Write", "Glob", "Grep"],
55
+ expectedOutput: "document",
56
+ };
57
+ case "audit":
58
+ return {
59
+ classification,
60
+ steps: [
61
+ "Understand audit scope and criteria",
62
+ "Systematically review codebase",
63
+ "Categorize findings by severity",
64
+ "Write audit report with recommendations",
65
+ ],
66
+ preferredTools: ["Read", "Grep", "Glob", "Write", "Bash"],
67
+ expectedOutput: "document",
68
+ };
69
+ case "refactor":
70
+ return {
71
+ classification,
72
+ steps: [
73
+ "Understand refactoring goals",
74
+ "Map current code structure",
75
+ "Plan incremental changes",
76
+ "Execute refactoring",
77
+ "Verify behavior preserved",
78
+ ],
79
+ preferredTools: ["Read", "Edit", "Grep", "Glob", "Bash"],
80
+ expectedOutput: "code-changes",
81
+ };
82
+ default:
83
+ return {
84
+ classification: "unknown",
85
+ steps: [
86
+ "Read the issue carefully",
87
+ "Explore relevant code",
88
+ "Take the most appropriate action",
89
+ ],
90
+ preferredTools: ["Read", "Edit", "Write", "Grep", "Glob", "Bash"],
91
+ expectedOutput: "mixed",
92
+ };
93
+ }
94
+ }
95
+ //# sourceMappingURL=planner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"planner.js","sourceRoot":"","sources":["../../../src/orchestrator/planner.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,YAAY,CAAC,KAAY;IACvC,MAAM,cAAc,GAAG,KAAK,CAAC,cAAc,IAAI,SAAS,CAAC;IAEzD,QAAQ,cAAc,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,sCAAsC;oBACtC,8BAA8B;oBAC9B,iCAAiC;oBACjC,mBAAmB;oBACnB,uBAAuB;oBACvB,wBAAwB;iBACzB;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBACxD,cAAc,EAAE,cAAc;aAC/B,CAAC;QAEJ,KAAK,SAAS;YACZ,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,gCAAgC;oBAChC,mCAAmC;oBACnC,yBAAyB;oBACzB,uBAAuB;oBACvB,yBAAyB;oBACzB,uBAAuB;iBACxB;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjE,cAAc,EAAE,cAAc;aAC/B,CAAC;QAEJ,KAAK,eAAe;YAClB,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,qCAAqC;oBACrC,+BAA+B;oBAC/B,0BAA0B;oBAC1B,kBAAkB;oBAClB,4BAA4B;iBAC7B;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;gBACzD,cAAc,EAAE,UAAU;aAC3B,CAAC;QAEJ,KAAK,eAAe;YAClB,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,mCAAmC;oBACnC,wBAAwB;oBACxB,2BAA2B;oBAC3B,8BAA8B;iBAC/B;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjD,cAAc,EAAE,UAAU;aAC3B,CAAC;QAEJ,KAAK,OAAO;YACV,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,qCAAqC;oBACrC,gCAAgC;oBAChC,iCAAiC;oBACjC,yCAAyC;iBAC1C;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC;gBACzD,cAAc,EAAE,UAAU;aAC3B,CAAC;QAEJ,KAAK,UAAU;YACb,OAAO;gBACL,cAAc;gBACd,KAAK,EAAE;oBACL,8BAA8B;oBAC9B,4BAA4B;oBAC5B,0BAA0B;oBAC1B,qBAAqB;oBACrB,2BAA2B;iBAC5B;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBACxD,cAAc,EAAE,cAAc;aAC/B,CAAC;QAEJ;YACE,OAAO;gBACL,cAAc,EAAE,SAAS;gBACzB,KAAK,EAAE;oBACL,0BAA0B;oBAC1B,uBAAuB;oBACvB,kCAAkC;iBACnC;gBACD,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;gBACjE,cAAc,EAAE,OAAO;aACxB,CAAC;IACN,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import type { SolveResult } from "../engine/types.js";
2
+ /** Adjust confidence based on heuristics */
3
+ export declare function adjustConfidence(result: SolveResult): SolveResult;
4
+ /** Determine PR type based on confidence */
5
+ export declare function shouldBeDraft(confidence: number, threshold: number): boolean;
6
+ /** Generate a human-readable confidence label */
7
+ export declare function confidenceLabel(score: number): string;
8
+ //# sourceMappingURL=scorer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.d.ts","sourceRoot":"","sources":["../../../src/orchestrator/scorer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,4CAA4C;AAC5C,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,CA2BjE;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5E;AAED,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMrD"}
@@ -0,0 +1,41 @@
1
+ /** Adjust confidence based on heuristics */
2
+ export function adjustConfidence(result) {
3
+ let adjustedScore = result.confidence;
4
+ // Boost confidence if there are changed files and no uncertainties
5
+ if (result.changedFiles.length > 0 && result.uncertainties.length === 0) {
6
+ adjustedScore = Math.min(10, adjustedScore + 1);
7
+ }
8
+ // Lower confidence if many files changed (risky)
9
+ if (result.changedFiles.length > 10) {
10
+ adjustedScore = Math.max(1, adjustedScore - 1);
11
+ }
12
+ // Lower confidence if no files changed but success claimed
13
+ if (result.success && result.changedFiles.length === 0) {
14
+ adjustedScore = Math.min(adjustedScore, 3);
15
+ }
16
+ // Lower confidence if too many uncertainties
17
+ if (result.uncertainties.length >= 3) {
18
+ adjustedScore = Math.max(1, adjustedScore - 1);
19
+ }
20
+ return {
21
+ ...result,
22
+ confidence: adjustedScore,
23
+ };
24
+ }
25
+ /** Determine PR type based on confidence */
26
+ export function shouldBeDraft(confidence, threshold) {
27
+ return confidence < threshold;
28
+ }
29
+ /** Generate a human-readable confidence label */
30
+ export function confidenceLabel(score) {
31
+ if (score >= 9)
32
+ return "Very High — ship it";
33
+ if (score >= 7)
34
+ return "High — review recommended";
35
+ if (score >= 5)
36
+ return "Medium — careful review needed";
37
+ if (score >= 3)
38
+ return "Low — significant manual review";
39
+ return "Very Low — mostly exploratory";
40
+ }
41
+ //# sourceMappingURL=scorer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scorer.js","sourceRoot":"","sources":["../../../src/orchestrator/scorer.ts"],"names":[],"mappings":"AAEA,4CAA4C;AAC5C,MAAM,UAAU,gBAAgB,CAAC,MAAmB;IAClD,IAAI,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC;IAEtC,mEAAmE;IACnE,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxE,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,iDAAiD;IACjD,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QACpC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,2DAA2D;IAC3D,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvD,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,6CAA6C;IAC7C,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;QACrC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,OAAO;QACL,GAAG,MAAM;QACT,UAAU,EAAE,aAAa;KAC1B,CAAC;AACJ,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,SAAiB;IACjE,OAAO,UAAU,GAAG,SAAS,CAAC;AAChC,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,qBAAqB,CAAC;IAC7C,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,2BAA2B,CAAC;IACnD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,gCAAgC,CAAC;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,OAAO,iCAAiC,CAAC;IACzD,OAAO,+BAA+B,CAAC;AACzC,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface IssueSummary {
2
+ number: number;
3
+ title: string;
4
+ classification: string;
5
+ status: "solved" | "failed" | "skipped" | "no-changes";
6
+ confidence?: number;
7
+ prNumber?: number;
8
+ prUrl?: string;
9
+ summary?: string;
10
+ error?: string;
11
+ }
12
+ export interface RunSummary {
13
+ startedAt: string;
14
+ duration: number;
15
+ issues: IssueSummary[];
16
+ totalAttempted: number;
17
+ totalSolved: number;
18
+ totalFailed: number;
19
+ prsCreated: Array<{
20
+ number: number;
21
+ url: string;
22
+ issueNumber: number;
23
+ }>;
24
+ }
25
+ export declare function saveSummary(summary: RunSummary, cwd: string, stateDir: string): Promise<string>;
26
+ export declare function loadLastSummary(cwd: string, stateDir: string): Promise<RunSummary | null>;
27
+ /** Format a human-readable morning summary */
28
+ export declare function formatMorningSummary(summary: RunSummary): string;
29
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../src/reporter/summary.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,YAAY,CAAC;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAQ5B;AAED,8CAA8C;AAC9C,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAyDhE"}
@@ -0,0 +1,77 @@
1
+ import { mkdir, writeFile, readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ export async function saveSummary(summary, cwd, stateDir) {
4
+ const dir = join(cwd, stateDir);
5
+ await mkdir(dir, { recursive: true });
6
+ const filePath = join(dir, "last-run.json");
7
+ await writeFile(filePath, JSON.stringify(summary, null, 2) + "\n", "utf-8");
8
+ // Also save timestamped run
9
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
10
+ const historyPath = join(dir, `run-${timestamp}.json`);
11
+ await writeFile(historyPath, JSON.stringify(summary, null, 2) + "\n", "utf-8");
12
+ return filePath;
13
+ }
14
+ export async function loadLastSummary(cwd, stateDir) {
15
+ try {
16
+ const filePath = join(cwd, stateDir, "last-run.json");
17
+ const raw = await readFile(filePath, "utf-8");
18
+ return JSON.parse(raw);
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ /** Format a human-readable morning summary */
25
+ export function formatMorningSummary(summary) {
26
+ const duration = Math.round(summary.duration / 1000 / 60);
27
+ const lines = [];
28
+ lines.push(`☀️ Dispatch Morning Report`);
29
+ lines.push(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
30
+ lines.push(`Run started: ${summary.startedAt}`);
31
+ lines.push(`Duration: ${duration} minutes`);
32
+ lines.push(``);
33
+ lines.push(`📊 Results: ${summary.totalSolved} solved, ${summary.totalFailed} failed, ${summary.issues.length} total`);
34
+ lines.push(``);
35
+ if (summary.prsCreated.length > 0) {
36
+ lines.push(`🔗 Pull Requests:`);
37
+ for (const pr of summary.prsCreated) {
38
+ const issue = summary.issues.find((i) => i.number === pr.issueNumber);
39
+ const confidence = issue?.confidence ? ` (confidence: ${issue.confidence}/10)` : "";
40
+ lines.push(` → PR #${pr.number} for issue #${pr.issueNumber}${confidence}`);
41
+ lines.push(` ${pr.url}`);
42
+ }
43
+ lines.push(``);
44
+ }
45
+ const solved = summary.issues.filter((i) => i.status === "solved");
46
+ if (solved.length > 0) {
47
+ lines.push(`✅ Solved:`);
48
+ for (const issue of solved) {
49
+ lines.push(` #${issue.number}: ${issue.title}`);
50
+ if (issue.summary) {
51
+ lines.push(` └─ ${issue.summary}`);
52
+ }
53
+ }
54
+ lines.push(``);
55
+ }
56
+ const failed = summary.issues.filter((i) => i.status === "failed");
57
+ if (failed.length > 0) {
58
+ lines.push(`❌ Failed:`);
59
+ for (const issue of failed) {
60
+ lines.push(` #${issue.number}: ${issue.title}`);
61
+ if (issue.error) {
62
+ lines.push(` └─ ${issue.error}`);
63
+ }
64
+ }
65
+ lines.push(``);
66
+ }
67
+ const noChanges = summary.issues.filter((i) => i.status === "no-changes");
68
+ if (noChanges.length > 0) {
69
+ lines.push(`⚪ No changes needed:`);
70
+ for (const issue of noChanges) {
71
+ lines.push(` #${issue.number}: ${issue.title}`);
72
+ }
73
+ lines.push(``);
74
+ }
75
+ return lines.join("\n");
76
+ }
77
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/reporter/summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ export interface DispatchConfig {
2
+ /** AI engine to use: "claude" (default), future: "gemini", "openai" */
3
+ engine: string;
4
+ /** Model to use with the engine */
5
+ model: string;
6
+ /** Issue labels to include (empty = all open issues) */
7
+ labels: string[];
8
+ /** Issue labels to exclude */
9
+ exclude: string[];
10
+ /** Max issues to process per run */
11
+ maxIssues: number;
12
+ /** Max agentic turns per issue */
13
+ maxTurnsPerIssue: number;
14
+ /** Branch name prefix */
15
+ branchPrefix: string;
16
+ /** Create draft PRs instead of regular PRs */
17
+ createDraftPRs: boolean;
18
+ /** Auto-label issues with classification */
19
+ autoLabel: boolean;
20
+ /** Base branch to create PRs against */
21
+ baseBranch: string;
22
+ /** Confidence threshold below which PRs are created as drafts */
23
+ draftThreshold: number;
24
+ /** Directory for dispatch state/logs */
25
+ stateDir: string;
26
+ /** Timeout per issue solve in milliseconds (default: 10 minutes) */
27
+ timeoutPerIssue: number;
28
+ /** Number of issues to process in parallel (default: 3) */
29
+ concurrency: number;
30
+ }
31
+ declare const DEFAULT_CONFIG: DispatchConfig;
32
+ declare const CONFIG_FILENAME = ".dispatchrc.json";
33
+ export declare function loadConfig(cwd?: string): Promise<DispatchConfig>;
34
+ export declare function saveConfig(config: DispatchConfig, cwd?: string): Promise<string>;
35
+ export declare function applyCliOverrides(config: DispatchConfig, options: Record<string, unknown>): DispatchConfig;
36
+ export { DEFAULT_CONFIG, CONFIG_FILENAME };
37
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/utils/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,8BAA8B;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,cAAc,EAAE,OAAO,CAAC;IACxB,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,eAAe,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,QAAA,MAAM,cAAc,EAAE,cAerB,CAAC;AAEF,QAAA,MAAM,eAAe,qBAAqB,CAAC;AAE3C,wBAAsB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,cAAc,CAAC,CAWrF;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAIrG;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAc1G;AAED,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { readFile, writeFile, access } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ const DEFAULT_CONFIG = {
4
+ engine: "claude",
5
+ model: "sonnet",
6
+ labels: [],
7
+ exclude: ["wontfix", "blocked", "duplicate"],
8
+ maxIssues: 10,
9
+ maxTurnsPerIssue: 10,
10
+ branchPrefix: "dispatch/",
11
+ createDraftPRs: false,
12
+ autoLabel: true,
13
+ baseBranch: "main",
14
+ draftThreshold: 5,
15
+ stateDir: ".dispatch",
16
+ timeoutPerIssue: 10 * 60 * 1000, // 10 minutes
17
+ concurrency: 3,
18
+ };
19
+ const CONFIG_FILENAME = ".dispatchrc.json";
20
+ export async function loadConfig(cwd = process.cwd()) {
21
+ const configPath = join(cwd, CONFIG_FILENAME);
22
+ try {
23
+ await access(configPath);
24
+ const raw = await readFile(configPath, "utf-8");
25
+ const fileConfig = JSON.parse(raw);
26
+ return { ...DEFAULT_CONFIG, ...fileConfig };
27
+ }
28
+ catch {
29
+ return { ...DEFAULT_CONFIG };
30
+ }
31
+ }
32
+ export async function saveConfig(config, cwd = process.cwd()) {
33
+ const configPath = join(cwd, CONFIG_FILENAME);
34
+ await writeFile(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
35
+ return configPath;
36
+ }
37
+ export function applyCliOverrides(config, options) {
38
+ const merged = { ...config };
39
+ if (options.engine)
40
+ merged.engine = String(options.engine);
41
+ if (options.model)
42
+ merged.model = String(options.model);
43
+ if (options.maxIssues)
44
+ merged.maxIssues = Number(options.maxIssues);
45
+ if (options.maxTurns)
46
+ merged.maxTurnsPerIssue = Number(options.maxTurns);
47
+ if (options.label)
48
+ merged.labels = Array.isArray(options.label) ? options.label : [String(options.label)];
49
+ if (options.exclude)
50
+ merged.exclude = Array.isArray(options.exclude) ? options.exclude : [String(options.exclude)];
51
+ if (options.draft !== undefined)
52
+ merged.createDraftPRs = Boolean(options.draft);
53
+ if (options.baseBranch)
54
+ merged.baseBranch = String(options.baseBranch);
55
+ if (options.concurrency)
56
+ merged.concurrency = Number(options.concurrency);
57
+ return merged;
58
+ }
59
+ export { DEFAULT_CONFIG, CONFIG_FILENAME };
60
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export interface GitResult {
2
+ stdout: string;
3
+ stderr: string;
4
+ }
5
+ /** Get the current branch name */
6
+ export declare function getCurrentBranch(cwd?: string): Promise<string>;
7
+ /** Get the remote origin URL and parse owner/repo */
8
+ export declare function getRepoInfo(cwd?: string): Promise<{
9
+ owner: string;
10
+ repo: string;
11
+ }>;
12
+ /** Create and checkout a new branch */
13
+ export declare function createBranch(branchName: string, baseBranch: string, cwd?: string): Promise<void>;
14
+ /** Stage all changes, commit, and push — with sensitive file protection */
15
+ export declare function commitAndPush(branchName: string, message: string, cwd?: string): Promise<{
16
+ hasChanges: boolean;
17
+ }>;
18
+ /** Get list of changed files vs base branch */
19
+ export declare function getChangedFiles(baseBranch: string, cwd?: string): Promise<string[]>;
20
+ /** Switch back to a branch (cleanup) */
21
+ export declare function checkoutBranch(branchName: string, cwd?: string): Promise<void>;
22
+ /** Clean up working directory */
23
+ export declare function cleanWorkingDir(cwd?: string): Promise<void>;
24
+ /** Delete a local branch */
25
+ export declare function deleteBranch(branchName: string, cwd?: string): Promise<void>;
26
+ /** Get short diff summary for PR description */
27
+ export declare function getDiffSummary(baseBranch: string, cwd?: string): Promise<string>;
28
+ /** Check if working directory is clean */
29
+ export declare function isClean(cwd?: string): Promise<boolean>;
30
+ //# sourceMappingURL=git.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../../src/utils/git.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAWD,kCAAkC;AAClC,wBAAsB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGpE;AAED,qDAAqD;AACrD,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAiBxF;AAED,uCAAuC;AACvC,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGtG;AAKD,2EAA2E;AAC3E,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IAAE,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA2BlC;AAED,+CAA+C;AAC/C,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAGzF;AAED,wCAAwC;AACxC,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpF;AAED,iCAAiC;AACjC,wBAAsB,eAAe,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjE;AAED,4BAA4B;AAC5B,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED,gDAAgD;AAChD,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtF;AAED,0CAA0C;AAC1C,wBAAsB,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG5D"}
@@ -0,0 +1,95 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { log } from "./logger.js";
4
+ const exec = promisify(execFile);
5
+ async function git(args, cwd) {
6
+ log.debug(`git ${args.join(" ")}`);
7
+ const { stdout, stderr } = await exec("git", args, {
8
+ cwd: cwd || process.cwd(),
9
+ maxBuffer: 10 * 1024 * 1024,
10
+ });
11
+ return { stdout: stdout.trim(), stderr: stderr.trim() };
12
+ }
13
+ /** Get the current branch name */
14
+ export async function getCurrentBranch(cwd) {
15
+ const { stdout } = await git(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
16
+ return stdout;
17
+ }
18
+ /** Get the remote origin URL and parse owner/repo */
19
+ export async function getRepoInfo(cwd) {
20
+ const { stdout } = await git(["remote", "get-url", "origin"], cwd);
21
+ const url = stdout;
22
+ // Handle SSH: git@github.com:owner/repo.git
23
+ const sshMatch = url.match(/git@github\.com:(.+?)\/(.+?)(?:\.git)?$/);
24
+ if (sshMatch) {
25
+ return { owner: sshMatch[1], repo: sshMatch[2] };
26
+ }
27
+ // Handle HTTPS: https://github.com/owner/repo.git
28
+ const httpsMatch = url.match(/github\.com\/(.+?)\/(.+?)(?:\.git)?$/);
29
+ if (httpsMatch) {
30
+ return { owner: httpsMatch[1], repo: httpsMatch[2] };
31
+ }
32
+ throw new Error(`Could not parse GitHub repo from remote URL: ${url}`);
33
+ }
34
+ /** Create and checkout a new branch */
35
+ export async function createBranch(branchName, baseBranch, cwd) {
36
+ await git(["fetch", "origin", baseBranch], cwd);
37
+ await git(["checkout", "-b", branchName, `origin/${baseBranch}`], cwd);
38
+ }
39
+ /** Sensitive file patterns that should never be staged */
40
+ const SENSITIVE_PATTERNS = [".env*", "*.pem", "*.key", "credentials*", "*.secret", ".secrets*"];
41
+ /** Stage all changes, commit, and push — with sensitive file protection */
42
+ export async function commitAndPush(branchName, message, cwd) {
43
+ // Check for changes
44
+ const { stdout: status } = await git(["status", "--porcelain"], cwd);
45
+ if (!status) {
46
+ return { hasChanges: false };
47
+ }
48
+ await git(["add", "-A"], cwd);
49
+ // Unstage sensitive files before committing
50
+ for (const pattern of SENSITIVE_PATTERNS) {
51
+ try {
52
+ await git(["reset", "HEAD", "--", pattern], cwd);
53
+ }
54
+ catch {
55
+ // Pattern didn't match any staged files — that's fine
56
+ }
57
+ }
58
+ // Check if there are still staged changes after filtering
59
+ const { stdout: staged } = await git(["diff", "--cached", "--name-only"], cwd);
60
+ if (!staged) {
61
+ return { hasChanges: false };
62
+ }
63
+ await git(["commit", "-m", message], cwd);
64
+ await git(["push", "-u", "origin", branchName], cwd);
65
+ return { hasChanges: true };
66
+ }
67
+ /** Get list of changed files vs base branch */
68
+ export async function getChangedFiles(baseBranch, cwd) {
69
+ const { stdout } = await git(["diff", "--name-only", `origin/${baseBranch}...HEAD`], cwd);
70
+ return stdout ? stdout.split("\n").filter(Boolean) : [];
71
+ }
72
+ /** Switch back to a branch (cleanup) */
73
+ export async function checkoutBranch(branchName, cwd) {
74
+ await git(["checkout", branchName], cwd);
75
+ }
76
+ /** Clean up working directory */
77
+ export async function cleanWorkingDir(cwd) {
78
+ await git(["checkout", "."], cwd);
79
+ await git(["clean", "-fd"], cwd);
80
+ }
81
+ /** Delete a local branch */
82
+ export async function deleteBranch(branchName, cwd) {
83
+ await git(["branch", "-D", branchName], cwd);
84
+ }
85
+ /** Get short diff summary for PR description */
86
+ export async function getDiffSummary(baseBranch, cwd) {
87
+ const { stdout } = await git(["diff", "--stat", `origin/${baseBranch}...HEAD`], cwd);
88
+ return stdout;
89
+ }
90
+ /** Check if working directory is clean */
91
+ export async function isClean(cwd) {
92
+ const { stdout } = await git(["status", "--porcelain"], cwd);
93
+ return !stdout;
94
+ }
95
+ //# sourceMappingURL=git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../../src/utils/git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export declare enum LogLevel {
2
+ DEBUG = 0,
3
+ INFO = 1,
4
+ WARN = 2,
5
+ ERROR = 3,
6
+ SILENT = 4
7
+ }
8
+ export declare function setLogLevel(level: LogLevel): void;
9
+ /** Initialize file-based logging. Creates .dispatch/logs/ directory. */
10
+ export declare function initFileLogging(stateDir: string, cwd: string): Promise<void>;
11
+ /** Get the log directory path (for computing per-issue log paths). */
12
+ export declare function getLogDir(): string | null;
13
+ export declare const log: {
14
+ debug(msg: string, ...args: unknown[]): void;
15
+ info(msg: string, ...args: unknown[]): void;
16
+ success(msg: string, ...args: unknown[]): void;
17
+ warn(msg: string, ...args: unknown[]): void;
18
+ error(msg: string, ...args: unknown[]): void;
19
+ header(msg: string): void;
20
+ issue(number: number, title: string, status: string): void;
21
+ };
22
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAIA,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;IACT,MAAM,IAAI;CACX;AAID,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,QAE1C;AAqBD,wEAAwE;AACxE,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKlF;AAED,sEAAsE;AACtE,wBAAgB,SAAS,IAAI,MAAM,GAAG,IAAI,CAEzC;AAoBD,eAAO,MAAM,GAAG;eACH,MAAM,WAAW,OAAO,EAAE;cAM3B,MAAM,WAAW,OAAO,EAAE;iBAOvB,MAAM,WAAW,OAAO,EAAE;cAO7B,MAAM,WAAW,OAAO,EAAE;eAOzB,MAAM,WAAW,OAAO,EAAE;gBAOzB,MAAM;kBASJ,MAAM,SAAS,MAAM,UAAU,MAAM;CAapD,CAAC"}