millhouse 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 +8 -0
- package/README.md +248 -0
- package/commands/millhouse.md +223 -0
- package/dist/analysis/graph-builder.d.ts +42 -0
- package/dist/analysis/graph-builder.d.ts.map +1 -0
- package/dist/analysis/graph-builder.js +98 -0
- package/dist/analysis/graph-builder.js.map +1 -0
- package/dist/analysis/issue-analyzer.d.ts +20 -0
- package/dist/analysis/issue-analyzer.d.ts.map +1 -0
- package/dist/analysis/issue-analyzer.js +167 -0
- package/dist/analysis/issue-analyzer.js.map +1 -0
- package/dist/analysis/plan-parser.d.ts +8 -0
- package/dist/analysis/plan-parser.d.ts.map +1 -0
- package/dist/analysis/plan-parser.js +112 -0
- package/dist/analysis/plan-parser.js.map +1 -0
- package/dist/cli/cleanup.d.ts +20 -0
- package/dist/cli/cleanup.d.ts.map +1 -0
- package/dist/cli/cleanup.js +186 -0
- package/dist/cli/cleanup.js.map +1 -0
- package/dist/cli/commands/clean.d.ts +2 -0
- package/dist/cli/commands/clean.d.ts.map +1 -0
- package/dist/cli/commands/clean.js +16 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/resume.d.ts +2 -0
- package/dist/cli/commands/resume.d.ts.map +1 -0
- package/dist/cli/commands/resume.js +82 -0
- package/dist/cli/commands/resume.js.map +1 -0
- package/dist/cli/commands/run.d.ts +10 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +352 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +6 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +74 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.d.ts +7 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +83 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/progress-display.d.ts +93 -0
- package/dist/cli/progress-display.d.ts.map +1 -0
- package/dist/cli/progress-display.js +318 -0
- package/dist/cli/progress-display.js.map +1 -0
- package/dist/core/orchestrator.d.ts +79 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +389 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/scheduler.d.ts +72 -0
- package/dist/core/scheduler.d.ts.map +1 -0
- package/dist/core/scheduler.js +234 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/execution/claude-runner.d.ts +41 -0
- package/dist/execution/claude-runner.d.ts.map +1 -0
- package/dist/execution/claude-runner.js +241 -0
- package/dist/execution/claude-runner.js.map +1 -0
- package/dist/execution/worktree-manager.d.ts +52 -0
- package/dist/execution/worktree-manager.d.ts.map +1 -0
- package/dist/execution/worktree-manager.js +208 -0
- package/dist/execution/worktree-manager.js.map +1 -0
- package/dist/github/client.d.ts +27 -0
- package/dist/github/client.d.ts.map +1 -0
- package/dist/github/client.js +178 -0
- package/dist/github/client.js.map +1 -0
- package/dist/github/issue-discoverer.d.ts +20 -0
- package/dist/github/issue-discoverer.d.ts.map +1 -0
- package/dist/github/issue-discoverer.js +83 -0
- package/dist/github/issue-discoverer.js.map +1 -0
- package/dist/github/label-manager.d.ts +44 -0
- package/dist/github/label-manager.d.ts.map +1 -0
- package/dist/github/label-manager.js +93 -0
- package/dist/github/label-manager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/config.d.ts +4 -0
- package/dist/storage/config.d.ts.map +1 -0
- package/dist/storage/config.js +25 -0
- package/dist/storage/config.js.map +1 -0
- package/dist/storage/json-store.d.ts +20 -0
- package/dist/storage/json-store.d.ts.map +1 -0
- package/dist/storage/json-store.js +92 -0
- package/dist/storage/json-store.js.map +1 -0
- package/dist/types.d.ts +142 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +36 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { MILLHOUSE_LABELS } from '../types.js';
|
|
2
|
+
const LABEL_COLORS = {
|
|
3
|
+
[MILLHOUSE_LABELS.QUEUED]: 'c5def5', // Light blue
|
|
4
|
+
[MILLHOUSE_LABELS.IN_PROGRESS]: '0e8a16', // Green
|
|
5
|
+
[MILLHOUSE_LABELS.BLOCKED]: 'fbca04', // Yellow
|
|
6
|
+
[MILLHOUSE_LABELS.FAILED]: 'd73a4a', // Red
|
|
7
|
+
[MILLHOUSE_LABELS.DONE]: '6f42c1', // Purple
|
|
8
|
+
};
|
|
9
|
+
const LABEL_DESCRIPTIONS = {
|
|
10
|
+
[MILLHOUSE_LABELS.QUEUED]: 'Issue is queued for Millhouse execution',
|
|
11
|
+
[MILLHOUSE_LABELS.IN_PROGRESS]: 'Millhouse is actively working on this issue',
|
|
12
|
+
[MILLHOUSE_LABELS.BLOCKED]: 'Waiting for dependency to complete',
|
|
13
|
+
[MILLHOUSE_LABELS.FAILED]: 'Millhouse execution failed',
|
|
14
|
+
[MILLHOUSE_LABELS.DONE]: 'Millhouse completed work on this issue',
|
|
15
|
+
};
|
|
16
|
+
const STATUS_TO_LABEL = {
|
|
17
|
+
'queued': MILLHOUSE_LABELS.QUEUED,
|
|
18
|
+
'blocked': MILLHOUSE_LABELS.BLOCKED,
|
|
19
|
+
'ready': MILLHOUSE_LABELS.QUEUED,
|
|
20
|
+
'in-progress': MILLHOUSE_LABELS.IN_PROGRESS,
|
|
21
|
+
'completed': MILLHOUSE_LABELS.DONE,
|
|
22
|
+
'failed': MILLHOUSE_LABELS.FAILED,
|
|
23
|
+
};
|
|
24
|
+
export class LabelManager {
|
|
25
|
+
client;
|
|
26
|
+
constructor(client) {
|
|
27
|
+
this.client = client;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Ensure all Millhouse labels exist in the repository.
|
|
31
|
+
*/
|
|
32
|
+
async ensureLabelsExist() {
|
|
33
|
+
const labelPromises = Object.values(MILLHOUSE_LABELS).map(label => this.client.createLabel(label, LABEL_COLORS[label], LABEL_DESCRIPTIONS[label]));
|
|
34
|
+
await Promise.all(labelPromises);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Remove all Millhouse labels from an issue.
|
|
38
|
+
*/
|
|
39
|
+
async clearMillhouseLabels(issueNumber) {
|
|
40
|
+
const removePromises = Object.values(MILLHOUSE_LABELS).map(label => this.client.removeLabel(issueNumber, label));
|
|
41
|
+
await Promise.all(removePromises);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Set the Millhouse status label for an issue.
|
|
45
|
+
* Removes any existing Millhouse labels first.
|
|
46
|
+
*/
|
|
47
|
+
async setStatus(issueNumber, status) {
|
|
48
|
+
const label = STATUS_TO_LABEL[status];
|
|
49
|
+
// Remove all Millhouse labels first
|
|
50
|
+
await this.clearMillhouseLabels(issueNumber);
|
|
51
|
+
// Add the new label if applicable
|
|
52
|
+
if (label) {
|
|
53
|
+
await this.client.addLabels(issueNumber, [label]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Set multiple issues to a status.
|
|
58
|
+
*/
|
|
59
|
+
async setStatusBatch(issueNumbers, status) {
|
|
60
|
+
await Promise.all(issueNumbers.map(n => this.setStatus(n, status)));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Mark an issue as queued.
|
|
64
|
+
*/
|
|
65
|
+
async markQueued(issueNumber) {
|
|
66
|
+
await this.setStatus(issueNumber, 'queued');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Mark an issue as in progress.
|
|
70
|
+
*/
|
|
71
|
+
async markInProgress(issueNumber) {
|
|
72
|
+
await this.setStatus(issueNumber, 'in-progress');
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Mark an issue as blocked.
|
|
76
|
+
*/
|
|
77
|
+
async markBlocked(issueNumber) {
|
|
78
|
+
await this.setStatus(issueNumber, 'blocked');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Mark an issue as failed.
|
|
82
|
+
*/
|
|
83
|
+
async markFailed(issueNumber) {
|
|
84
|
+
await this.setStatus(issueNumber, 'failed');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Mark an issue as done.
|
|
88
|
+
*/
|
|
89
|
+
async markDone(issueNumber) {
|
|
90
|
+
await this.setStatus(issueNumber, 'completed');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=label-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"label-manager.js","sourceRoot":"","sources":["../../src/github/label-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { runPlanCommand, runIssuesCommand } from './cli/commands/run.js';
|
|
4
|
+
import { statusCommand } from './cli/commands/status.js';
|
|
5
|
+
import { resumeCommand } from './cli/commands/resume.js';
|
|
6
|
+
import { setupCommand } from './cli/commands/setup.js';
|
|
7
|
+
import { cleanCommand } from './cli/commands/clean.js';
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name('millhouse')
|
|
11
|
+
.description('Orchestrates multiple parallel Claude Code instances to work on GitHub issues or plan files')
|
|
12
|
+
.version('0.1.0');
|
|
13
|
+
// Main run command - defaults to plan mode
|
|
14
|
+
const runCmd = program
|
|
15
|
+
.command('run')
|
|
16
|
+
.description('Execute a plan file (default) or GitHub issues')
|
|
17
|
+
.argument('[plan]', 'Path to plan file (omit to use latest from ~/.claude/plans/)')
|
|
18
|
+
.option('-n, --concurrency <number>', 'Number of parallel workers', '8')
|
|
19
|
+
.option('-d, --display <mode>', 'Display mode: compact or detailed', 'compact')
|
|
20
|
+
.option('--dry-run', 'Analyze and plan without executing')
|
|
21
|
+
.option('--dangerously-skip-permissions', 'Skip permission prompts in spawned Claude instances')
|
|
22
|
+
.action(runPlanCommand);
|
|
23
|
+
// Subcommand for GitHub issues mode
|
|
24
|
+
runCmd
|
|
25
|
+
.command('issues')
|
|
26
|
+
.description('Execute GitHub issues')
|
|
27
|
+
.argument('[numbers]', 'Comma-separated issue numbers (omit to run all open issues)')
|
|
28
|
+
.option('-n, --concurrency <number>', 'Number of parallel workers', '8')
|
|
29
|
+
.option('-d, --display <mode>', 'Display mode: compact or detailed', 'compact')
|
|
30
|
+
.option('--dry-run', 'Analyze and plan without executing')
|
|
31
|
+
.option('--dangerously-skip-permissions', 'Skip permission prompts in spawned Claude instances')
|
|
32
|
+
.action(runIssuesCommand);
|
|
33
|
+
program
|
|
34
|
+
.command('status')
|
|
35
|
+
.description('Show current run status')
|
|
36
|
+
.option('--run-id <id>', 'Show status for specific run')
|
|
37
|
+
.option('--json', 'Output as JSON')
|
|
38
|
+
.action(statusCommand);
|
|
39
|
+
program
|
|
40
|
+
.command('resume')
|
|
41
|
+
.description('Resume an interrupted run')
|
|
42
|
+
.argument('<run-id>', 'The run ID to resume')
|
|
43
|
+
.action(resumeCommand);
|
|
44
|
+
program
|
|
45
|
+
.command('setup')
|
|
46
|
+
.description('Install Claude Code slash commands')
|
|
47
|
+
.option('-g, --global', 'Install to ~/.claude/commands/ instead of ./.claude/commands/')
|
|
48
|
+
.action(setupCommand);
|
|
49
|
+
program
|
|
50
|
+
.command('clean')
|
|
51
|
+
.description('Clean up leftover worktrees, branches, and state from interrupted runs')
|
|
52
|
+
.action(cleanCommand);
|
|
53
|
+
program.parse();
|
|
54
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,6FAA6F,CAAC;KAC1G,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,2CAA2C;AAC3C,MAAM,MAAM,GAAG,OAAO;KACnB,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,gDAAgD,CAAC;KAC7D,QAAQ,CAAC,QAAQ,EAAE,8DAA8D,CAAC;KAClF,MAAM,CAAC,4BAA4B,EAAE,4BAA4B,EAAE,GAAG,CAAC;KACvE,MAAM,CAAC,sBAAsB,EAAE,mCAAmC,EAAE,SAAS,CAAC;KAC9E,MAAM,CAAC,WAAW,EAAE,oCAAoC,CAAC;KACzD,MAAM,CAAC,gCAAgC,EAAE,qDAAqD,CAAC;KAC/F,MAAM,CAAC,cAAc,CAAC,CAAC;AAE1B,oCAAoC;AACpC,MAAM;KACH,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uBAAuB,CAAC;KACpC,QAAQ,CAAC,WAAW,EAAE,6DAA6D,CAAC;KACpF,MAAM,CAAC,4BAA4B,EAAE,4BAA4B,EAAE,GAAG,CAAC;KACvE,MAAM,CAAC,sBAAsB,EAAE,mCAAmC,EAAE,SAAS,CAAC;KAC9E,MAAM,CAAC,WAAW,EAAE,oCAAoC,CAAC;KACzD,MAAM,CAAC,gCAAgC,EAAE,qDAAqD,CAAC;KAC/F,MAAM,CAAC,gBAAgB,CAAC,CAAC;AAE5B,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,eAAe,EAAE,8BAA8B,CAAC;KACvD,MAAM,CAAC,QAAQ,EAAE,gBAAgB,CAAC;KAClC,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,2BAA2B,CAAC;KACxC,QAAQ,CAAC,UAAU,EAAE,sBAAsB,CAAC;KAC5C,MAAM,CAAC,aAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,oCAAoC,CAAC;KACjD,MAAM,CAAC,cAAc,EAAE,+DAA+D,CAAC;KACvF,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wEAAwE,CAAC;KACrF,MAAM,CAAC,YAAY,CAAC,CAAC;AAExB,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/storage/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAIxD,wBAAsB,UAAU,CAAC,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAelF;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGhG"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ConfigSchema } from '../types.js';
|
|
4
|
+
const CONFIG_FILES = ['.millhouserc.json', '.millhouserc', 'millhouse.config.json'];
|
|
5
|
+
export async function loadConfig(basePath = process.cwd()) {
|
|
6
|
+
// Try each config file name
|
|
7
|
+
for (const fileName of CONFIG_FILES) {
|
|
8
|
+
const filePath = path.join(basePath, fileName);
|
|
9
|
+
try {
|
|
10
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
11
|
+
const parsed = JSON.parse(content);
|
|
12
|
+
return ConfigSchema.parse(parsed);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Try next file
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
// Return defaults if no config file found
|
|
19
|
+
return ConfigSchema.parse({});
|
|
20
|
+
}
|
|
21
|
+
export async function saveConfig(config, basePath = process.cwd()) {
|
|
22
|
+
const filePath = path.join(basePath, CONFIG_FILES[0]);
|
|
23
|
+
await fs.writeFile(filePath, JSON.stringify(config, null, 2));
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/storage/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAe,MAAM,aAAa,CAAC;AAExD,MAAM,YAAY,GAAG,CAAC,mBAAmB,EAAE,cAAc,EAAE,uBAAuB,CAAC,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC/D,4BAA4B;IAC5B,KAAK,MAAM,QAAQ,IAAI,YAAY,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,OAAO,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAAc,EAAE,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC/E,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RunState, WorktreeInfo } from '../types.js';
|
|
2
|
+
export declare class JsonStore {
|
|
3
|
+
private basePath;
|
|
4
|
+
constructor(basePath?: string);
|
|
5
|
+
private get millhouseDir();
|
|
6
|
+
private get runsDir();
|
|
7
|
+
private get worktreesPath();
|
|
8
|
+
ensureDirectories(): Promise<void>;
|
|
9
|
+
generateRunId(): string;
|
|
10
|
+
saveRun(run: RunState): Promise<void>;
|
|
11
|
+
getRun(runId: string): Promise<RunState | null>;
|
|
12
|
+
listRuns(): Promise<RunState[]>;
|
|
13
|
+
deleteRun(runId: string): Promise<void>;
|
|
14
|
+
getWorktrees(): Promise<WorktreeInfo[]>;
|
|
15
|
+
saveWorktree(worktree: WorktreeInfo): Promise<void>;
|
|
16
|
+
removeWorktree(path: string): Promise<void>;
|
|
17
|
+
getWorktreeForIssue(runId: string, issueNumber: number): Promise<WorktreeInfo | undefined>;
|
|
18
|
+
getWorktreesForRun(runId: string): Promise<WorktreeInfo[]>;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=json-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-store.d.ts","sourceRoot":"","sources":["../../src/storage/json-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAM1D,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,GAAE,MAAsB;IAI5C,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,OAAO,GAElB;IAED,OAAO,KAAK,aAAa,GAExB;IAEK,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxC,aAAa,IAAI,MAAM;IAQjB,OAAO,CAAC,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAMrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAU/C,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IAkB/B,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvC,YAAY,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IASvC,YAAY,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3C,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;IAK1F,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAIjE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import crypto from 'node:crypto';
|
|
4
|
+
const MILLHOUSE_DIR = '.millhouse';
|
|
5
|
+
const RUNS_DIR = 'runs';
|
|
6
|
+
const WORKTREES_FILE = 'worktrees.json';
|
|
7
|
+
export class JsonStore {
|
|
8
|
+
basePath;
|
|
9
|
+
constructor(basePath = process.cwd()) {
|
|
10
|
+
this.basePath = basePath;
|
|
11
|
+
}
|
|
12
|
+
get millhouseDir() {
|
|
13
|
+
return path.join(this.basePath, MILLHOUSE_DIR);
|
|
14
|
+
}
|
|
15
|
+
get runsDir() {
|
|
16
|
+
return path.join(this.millhouseDir, RUNS_DIR);
|
|
17
|
+
}
|
|
18
|
+
get worktreesPath() {
|
|
19
|
+
return path.join(this.millhouseDir, WORKTREES_FILE);
|
|
20
|
+
}
|
|
21
|
+
async ensureDirectories() {
|
|
22
|
+
await fs.mkdir(this.runsDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
generateRunId() {
|
|
25
|
+
const timestamp = Date.now().toString(36);
|
|
26
|
+
const random = crypto.randomBytes(4).toString('hex');
|
|
27
|
+
return `${timestamp}-${random}`;
|
|
28
|
+
}
|
|
29
|
+
// Run state operations
|
|
30
|
+
async saveRun(run) {
|
|
31
|
+
await this.ensureDirectories();
|
|
32
|
+
const filePath = path.join(this.runsDir, `${run.id}.json`);
|
|
33
|
+
await fs.writeFile(filePath, JSON.stringify(run, null, 2));
|
|
34
|
+
}
|
|
35
|
+
async getRun(runId) {
|
|
36
|
+
const filePath = path.join(this.runsDir, `${runId}.json`);
|
|
37
|
+
try {
|
|
38
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
39
|
+
return JSON.parse(content);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async listRuns() {
|
|
46
|
+
await this.ensureDirectories();
|
|
47
|
+
const files = await fs.readdir(this.runsDir);
|
|
48
|
+
const runs = [];
|
|
49
|
+
for (const file of files) {
|
|
50
|
+
if (file.endsWith('.json')) {
|
|
51
|
+
const content = await fs.readFile(path.join(this.runsDir, file), 'utf-8');
|
|
52
|
+
runs.push(JSON.parse(content));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Sort by creation date, newest first
|
|
56
|
+
return runs.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
57
|
+
}
|
|
58
|
+
async deleteRun(runId) {
|
|
59
|
+
const filePath = path.join(this.runsDir, `${runId}.json`);
|
|
60
|
+
await fs.unlink(filePath).catch(() => { });
|
|
61
|
+
}
|
|
62
|
+
// Worktree tracking
|
|
63
|
+
async getWorktrees() {
|
|
64
|
+
try {
|
|
65
|
+
const content = await fs.readFile(this.worktreesPath, 'utf-8');
|
|
66
|
+
return JSON.parse(content);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async saveWorktree(worktree) {
|
|
73
|
+
await this.ensureDirectories();
|
|
74
|
+
const worktrees = await this.getWorktrees();
|
|
75
|
+
worktrees.push(worktree);
|
|
76
|
+
await fs.writeFile(this.worktreesPath, JSON.stringify(worktrees, null, 2));
|
|
77
|
+
}
|
|
78
|
+
async removeWorktree(path) {
|
|
79
|
+
const worktrees = await this.getWorktrees();
|
|
80
|
+
const filtered = worktrees.filter(w => w.path !== path);
|
|
81
|
+
await fs.writeFile(this.worktreesPath, JSON.stringify(filtered, null, 2));
|
|
82
|
+
}
|
|
83
|
+
async getWorktreeForIssue(runId, issueNumber) {
|
|
84
|
+
const worktrees = await this.getWorktrees();
|
|
85
|
+
return worktrees.find(w => w.runId === runId && w.issueNumber === issueNumber);
|
|
86
|
+
}
|
|
87
|
+
async getWorktreesForRun(runId) {
|
|
88
|
+
const worktrees = await this.getWorktrees();
|
|
89
|
+
return worktrees.filter(w => w.runId === runId);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=json-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"json-store.js","sourceRoot":"","sources":["../../src/storage/json-store.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export interface WorkItem {
|
|
3
|
+
id: number;
|
|
4
|
+
title: string;
|
|
5
|
+
body: string | null;
|
|
6
|
+
dependencies: number[];
|
|
7
|
+
affectedPaths: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface AnalyzedWorkItem extends WorkItem {
|
|
10
|
+
analyzedAt: string;
|
|
11
|
+
}
|
|
12
|
+
export interface GitHubIssue {
|
|
13
|
+
number: number;
|
|
14
|
+
title: string;
|
|
15
|
+
body: string | null;
|
|
16
|
+
state: 'open' | 'closed';
|
|
17
|
+
labels: string[];
|
|
18
|
+
url: string;
|
|
19
|
+
htmlUrl: string;
|
|
20
|
+
}
|
|
21
|
+
export interface AnalyzedIssue extends GitHubIssue {
|
|
22
|
+
affectedPaths: string[];
|
|
23
|
+
dependencies: number[];
|
|
24
|
+
analyzedAt: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function issueToWorkItem(issue: AnalyzedIssue): AnalyzedWorkItem;
|
|
27
|
+
export type TaskStatus = 'queued' | 'blocked' | 'ready' | 'in-progress' | 'completed' | 'failed';
|
|
28
|
+
export interface Task {
|
|
29
|
+
issueNumber: number;
|
|
30
|
+
status: TaskStatus;
|
|
31
|
+
worktreePath?: string;
|
|
32
|
+
startedAt?: string;
|
|
33
|
+
completedAt?: string;
|
|
34
|
+
error?: string;
|
|
35
|
+
commits?: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface RunState {
|
|
38
|
+
id: string;
|
|
39
|
+
createdAt: string;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
status: 'running' | 'completed' | 'failed' | 'interrupted';
|
|
42
|
+
baseBranch: string;
|
|
43
|
+
runBranch: string;
|
|
44
|
+
issues: AnalyzedIssue[];
|
|
45
|
+
tasks: Task[];
|
|
46
|
+
completedIssues: number[];
|
|
47
|
+
failedIssues: number[];
|
|
48
|
+
pullRequestUrl?: string;
|
|
49
|
+
error?: string;
|
|
50
|
+
}
|
|
51
|
+
export interface WorktreeInfo {
|
|
52
|
+
issueNumber: number;
|
|
53
|
+
runId: string;
|
|
54
|
+
path: string;
|
|
55
|
+
branch: string;
|
|
56
|
+
createdAt: string;
|
|
57
|
+
}
|
|
58
|
+
export declare const ConfigSchema: z.ZodObject<{
|
|
59
|
+
execution: z.ZodDefault<z.ZodObject<{
|
|
60
|
+
concurrency: z.ZodDefault<z.ZodNumber>;
|
|
61
|
+
baseBranch: z.ZodDefault<z.ZodString>;
|
|
62
|
+
maxBudgetPerIssue: z.ZodDefault<z.ZodNumber>;
|
|
63
|
+
maxTotalBudget: z.ZodDefault<z.ZodNumber>;
|
|
64
|
+
continueOnError: z.ZodDefault<z.ZodBoolean>;
|
|
65
|
+
}, "strip", z.ZodTypeAny, {
|
|
66
|
+
concurrency: number;
|
|
67
|
+
baseBranch: string;
|
|
68
|
+
maxBudgetPerIssue: number;
|
|
69
|
+
maxTotalBudget: number;
|
|
70
|
+
continueOnError: boolean;
|
|
71
|
+
}, {
|
|
72
|
+
concurrency?: number | undefined;
|
|
73
|
+
baseBranch?: string | undefined;
|
|
74
|
+
maxBudgetPerIssue?: number | undefined;
|
|
75
|
+
maxTotalBudget?: number | undefined;
|
|
76
|
+
continueOnError?: boolean | undefined;
|
|
77
|
+
}>>;
|
|
78
|
+
pullRequests: z.ZodDefault<z.ZodObject<{
|
|
79
|
+
createAsDraft: z.ZodDefault<z.ZodBoolean>;
|
|
80
|
+
mergeStrategy: z.ZodDefault<z.ZodEnum<["merge", "squash", "rebase"]>>;
|
|
81
|
+
branchPrefix: z.ZodDefault<z.ZodString>;
|
|
82
|
+
}, "strip", z.ZodTypeAny, {
|
|
83
|
+
createAsDraft: boolean;
|
|
84
|
+
mergeStrategy: "merge" | "squash" | "rebase";
|
|
85
|
+
branchPrefix: string;
|
|
86
|
+
}, {
|
|
87
|
+
createAsDraft?: boolean | undefined;
|
|
88
|
+
mergeStrategy?: "merge" | "squash" | "rebase" | undefined;
|
|
89
|
+
branchPrefix?: string | undefined;
|
|
90
|
+
}>>;
|
|
91
|
+
}, "strip", z.ZodTypeAny, {
|
|
92
|
+
execution: {
|
|
93
|
+
concurrency: number;
|
|
94
|
+
baseBranch: string;
|
|
95
|
+
maxBudgetPerIssue: number;
|
|
96
|
+
maxTotalBudget: number;
|
|
97
|
+
continueOnError: boolean;
|
|
98
|
+
};
|
|
99
|
+
pullRequests: {
|
|
100
|
+
createAsDraft: boolean;
|
|
101
|
+
mergeStrategy: "merge" | "squash" | "rebase";
|
|
102
|
+
branchPrefix: string;
|
|
103
|
+
};
|
|
104
|
+
}, {
|
|
105
|
+
execution?: {
|
|
106
|
+
concurrency?: number | undefined;
|
|
107
|
+
baseBranch?: string | undefined;
|
|
108
|
+
maxBudgetPerIssue?: number | undefined;
|
|
109
|
+
maxTotalBudget?: number | undefined;
|
|
110
|
+
continueOnError?: boolean | undefined;
|
|
111
|
+
} | undefined;
|
|
112
|
+
pullRequests?: {
|
|
113
|
+
createAsDraft?: boolean | undefined;
|
|
114
|
+
mergeStrategy?: "merge" | "squash" | "rebase" | undefined;
|
|
115
|
+
branchPrefix?: string | undefined;
|
|
116
|
+
} | undefined;
|
|
117
|
+
}>;
|
|
118
|
+
export type Config = z.infer<typeof ConfigSchema>;
|
|
119
|
+
export declare const MILLHOUSE_LABELS: {
|
|
120
|
+
readonly QUEUED: "millhouse:queued";
|
|
121
|
+
readonly IN_PROGRESS: "millhouse:in-progress";
|
|
122
|
+
readonly BLOCKED: "millhouse:blocked";
|
|
123
|
+
readonly FAILED: "millhouse:failed";
|
|
124
|
+
readonly DONE: "millhouse:done";
|
|
125
|
+
};
|
|
126
|
+
export type MillhouseLabel = typeof MILLHOUSE_LABELS[keyof typeof MILLHOUSE_LABELS];
|
|
127
|
+
export type SchedulerEvent = {
|
|
128
|
+
type: 'task-started';
|
|
129
|
+
issueNumber: number;
|
|
130
|
+
} | {
|
|
131
|
+
type: 'task-completed';
|
|
132
|
+
issueNumber: number;
|
|
133
|
+
commits: string[];
|
|
134
|
+
} | {
|
|
135
|
+
type: 'task-failed';
|
|
136
|
+
issueNumber: number;
|
|
137
|
+
error: string;
|
|
138
|
+
} | {
|
|
139
|
+
type: 'tasks-unblocked';
|
|
140
|
+
issueNumbers: number[];
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// Convert AnalyzedIssue to AnalyzedWorkItem
|
|
3
|
+
export function issueToWorkItem(issue) {
|
|
4
|
+
return {
|
|
5
|
+
id: issue.number,
|
|
6
|
+
title: issue.title,
|
|
7
|
+
body: issue.body,
|
|
8
|
+
dependencies: issue.dependencies,
|
|
9
|
+
affectedPaths: issue.affectedPaths,
|
|
10
|
+
analyzedAt: issue.analyzedAt,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
// Configuration schema
|
|
14
|
+
export const ConfigSchema = z.object({
|
|
15
|
+
execution: z.object({
|
|
16
|
+
concurrency: z.number().min(1).max(16).default(8),
|
|
17
|
+
baseBranch: z.string().default('main'),
|
|
18
|
+
maxBudgetPerIssue: z.number().positive().default(5.0),
|
|
19
|
+
maxTotalBudget: z.number().positive().default(100.0),
|
|
20
|
+
continueOnError: z.boolean().default(true),
|
|
21
|
+
}).default({}),
|
|
22
|
+
pullRequests: z.object({
|
|
23
|
+
createAsDraft: z.boolean().default(true),
|
|
24
|
+
mergeStrategy: z.enum(['merge', 'squash', 'rebase']).default('squash'),
|
|
25
|
+
branchPrefix: z.string().default('millhouse/issue-'),
|
|
26
|
+
}).default({}),
|
|
27
|
+
});
|
|
28
|
+
// Millhouse labels
|
|
29
|
+
export const MILLHOUSE_LABELS = {
|
|
30
|
+
QUEUED: 'millhouse:queued',
|
|
31
|
+
IN_PROGRESS: 'millhouse:in-progress',
|
|
32
|
+
BLOCKED: 'millhouse:blocked',
|
|
33
|
+
FAILED: 'millhouse:failed',
|
|
34
|
+
DONE: 'millhouse:done',
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA0CxB,4CAA4C;AAC5C,MAAM,UAAU,eAAe,CAAC,KAAoB;IAClD,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,MAAM;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC;AACJ,CAAC;AA+CD,uBAAuB;AACvB,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;QAClB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACjD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;QACtC,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;QACrD,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QACpD,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;KAC3C,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACd,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC;QACrB,aAAa,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;QACxC,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC;KACrD,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACf,CAAC,CAAC;AAIH,mBAAmB;AACnB,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,MAAM,EAAE,kBAAkB;IAC1B,WAAW,EAAE,uBAAuB;IACpC,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,kBAAkB;IAC1B,IAAI,EAAE,gBAAgB;CACd,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "millhouse",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Orchestrate parallel Claude Code instances to implement GitHub issues or plan files",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"millhouse": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"commands"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"dev": "tsx src/index.ts",
|
|
17
|
+
"start": "node dist/index.js",
|
|
18
|
+
"test": "vitest",
|
|
19
|
+
"lint": "eslint src/",
|
|
20
|
+
"typecheck": "tsc --noEmit",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/dave/millhouse.git"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/dave/millhouse#readme",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/dave/millhouse/issues"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@anthropic-ai/claude-code": "^1.0.0",
|
|
33
|
+
"@octokit/rest": "^21.0.0",
|
|
34
|
+
"chalk": "^5.3.0",
|
|
35
|
+
"commander": "^12.1.0",
|
|
36
|
+
"graphlib": "^2.1.8",
|
|
37
|
+
"ora": "^8.0.1",
|
|
38
|
+
"zod": "^3.23.0"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/graphlib": "^2.1.12",
|
|
42
|
+
"@types/node": "^20.14.0",
|
|
43
|
+
"eslint": "^9.0.0",
|
|
44
|
+
"tsx": "^4.15.0",
|
|
45
|
+
"typescript": "^5.5.0",
|
|
46
|
+
"vitest": "^2.0.0"
|
|
47
|
+
},
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
},
|
|
51
|
+
"keywords": [
|
|
52
|
+
"claude",
|
|
53
|
+
"ai",
|
|
54
|
+
"github",
|
|
55
|
+
"automation",
|
|
56
|
+
"cli"
|
|
57
|
+
],
|
|
58
|
+
"author": "",
|
|
59
|
+
"license": "MIT"
|
|
60
|
+
}
|