@gethmy/agent 1.0.0 → 1.0.1

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 (52) hide show
  1. package/README.md +5 -5
  2. package/dist/board-helpers.d.ts +23 -0
  3. package/dist/board-helpers.js +131 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +2 -11761
  6. package/dist/completion.d.ts +7 -0
  7. package/dist/completion.js +132 -0
  8. package/dist/config.d.ts +23 -0
  9. package/dist/config.js +91 -0
  10. package/dist/git-pr.d.ts +25 -0
  11. package/dist/git-pr.js +305 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.js +165 -11730
  14. package/dist/log.d.ts +10 -0
  15. package/dist/log.js +35 -0
  16. package/dist/merge-monitor.d.ts +23 -0
  17. package/dist/merge-monitor.js +155 -0
  18. package/dist/pm.d.ts +14 -0
  19. package/dist/pm.js +63 -0
  20. package/dist/pool.d.ts +36 -0
  21. package/dist/pool.js +134 -0
  22. package/dist/progress-tracker.d.ts +39 -0
  23. package/dist/progress-tracker.js +189 -0
  24. package/dist/prompt.d.ts +5 -0
  25. package/dist/prompt.js +40 -0
  26. package/dist/queue.d.ts +37 -0
  27. package/dist/queue.js +96 -0
  28. package/dist/reconcile.d.ts +21 -0
  29. package/dist/reconcile.js +107 -0
  30. package/dist/review-completion.d.ts +31 -0
  31. package/dist/review-completion.js +247 -0
  32. package/dist/review-knowledge.d.ts +14 -0
  33. package/dist/review-knowledge.js +89 -0
  34. package/dist/review-prompt.d.ts +12 -0
  35. package/dist/review-prompt.js +100 -0
  36. package/dist/review-worker.d.ts +35 -0
  37. package/dist/review-worker.js +302 -0
  38. package/dist/review-worktree.d.ts +12 -0
  39. package/dist/review-worktree.js +83 -0
  40. package/dist/stream-parser.d.ts +22 -0
  41. package/dist/stream-parser.js +81 -0
  42. package/dist/types.d.ts +74 -0
  43. package/dist/types.js +53 -0
  44. package/dist/verification.d.ts +16 -0
  45. package/dist/verification.js +251 -0
  46. package/dist/watcher.d.ts +21 -0
  47. package/dist/watcher.js +62 -0
  48. package/dist/worker.d.ts +34 -0
  49. package/dist/worker.js +268 -0
  50. package/dist/worktree.d.ts +13 -0
  51. package/dist/worktree.js +115 -0
  52. package/package.json +6 -5
@@ -0,0 +1,115 @@
1
+ import { execFileSync, execSync } from "node:child_process";
2
+ import { existsSync, rmSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { log } from "./log.js";
5
+ import { installCommand } from "./pm.js";
6
+ const TAG = "worktree";
7
+ /**
8
+ * Create a git worktree for the agent to work in.
9
+ * Returns the absolute path to the new worktree.
10
+ */
11
+ export function createWorktree(basePath, baseBranch, branchName) {
12
+ const repoRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
13
+ encoding: "utf-8",
14
+ }).trim();
15
+ const worktreeDir = resolve(repoRoot, basePath, branchName);
16
+ if (existsSync(worktreeDir)) {
17
+ log.warn(TAG, `Worktree already exists at ${worktreeDir}, cleaning up`);
18
+ cleanupWorktree(worktreeDir);
19
+ }
20
+ // Fetch latest from remote to ensure base branch is up to date
21
+ try {
22
+ execFileSync("git", ["fetch", "origin", baseBranch], {
23
+ cwd: repoRoot,
24
+ stdio: "pipe",
25
+ });
26
+ }
27
+ catch {
28
+ log.warn(TAG, "Failed to fetch latest — continuing with local state");
29
+ }
30
+ // Delete stale branch if it exists from a previous run
31
+ try {
32
+ execFileSync("git", ["branch", "-D", branchName], {
33
+ cwd: repoRoot,
34
+ stdio: "pipe",
35
+ });
36
+ log.info(TAG, `Deleted stale branch: ${branchName}`);
37
+ }
38
+ catch {
39
+ // Branch doesn't exist — that's fine
40
+ }
41
+ // Create worktree with a new branch based on origin/<baseBranch>
42
+ log.info(TAG, `Creating worktree: ${worktreeDir} (branch: ${branchName})`);
43
+ execFileSync("git", ["worktree", "add", "-b", branchName, worktreeDir, `origin/${baseBranch}`], { cwd: repoRoot, stdio: "pipe" });
44
+ // Install dependencies in the worktree
45
+ log.info(TAG, "Installing dependencies in worktree...");
46
+ try {
47
+ execSync(installCommand(), {
48
+ cwd: worktreeDir,
49
+ stdio: "pipe",
50
+ timeout: 60_000,
51
+ });
52
+ }
53
+ catch {
54
+ log.warn(TAG, "Install failed (may be fine if deps are hoisted)");
55
+ }
56
+ return worktreeDir;
57
+ }
58
+ /**
59
+ * Remove a git worktree and its branch.
60
+ */
61
+ export function cleanupWorktree(worktreePath, branchName) {
62
+ const repoRoot = execFileSync("git", ["rev-parse", "--show-toplevel"], {
63
+ encoding: "utf-8",
64
+ }).trim();
65
+ try {
66
+ execFileSync("git", ["worktree", "remove", worktreePath, "--force"], {
67
+ cwd: repoRoot,
68
+ stdio: "pipe",
69
+ });
70
+ log.info(TAG, `Removed worktree: ${worktreePath}`);
71
+ }
72
+ catch (err) {
73
+ log.warn(TAG, `Failed to remove worktree cleanly: ${err instanceof Error ? err.message : err}`);
74
+ // Force-remove the directory if git worktree remove failed
75
+ if (existsSync(worktreePath)) {
76
+ rmSync(worktreePath, { recursive: true, force: true });
77
+ }
78
+ // Prune stale worktree entries
79
+ try {
80
+ execFileSync("git", ["worktree", "prune"], {
81
+ cwd: repoRoot,
82
+ stdio: "pipe",
83
+ });
84
+ }
85
+ catch {
86
+ // best-effort
87
+ }
88
+ }
89
+ // Delete the branch so it doesn't block future runs
90
+ if (branchName) {
91
+ try {
92
+ execFileSync("git", ["branch", "-D", branchName], {
93
+ cwd: repoRoot,
94
+ stdio: "pipe",
95
+ });
96
+ }
97
+ catch {
98
+ // best-effort
99
+ }
100
+ }
101
+ }
102
+ /**
103
+ * Generate a branch name from a card's short ID and title.
104
+ */
105
+ export function makeBranchName(shortId, title) {
106
+ const slug = title
107
+ .toLowerCase()
108
+ .trim()
109
+ .replace(/[^\w\s-]/g, "")
110
+ .replace(/\s+/g, "-")
111
+ .replace(/-+/g, "-")
112
+ .replace(/^-+|-+$/g, "")
113
+ .slice(0, 40);
114
+ return `agent/${shortId}-${slug || "task"}`;
115
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gethmy/agent",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Push-based agent daemon for Harmony — watches board assignments and spawns Claude CLI workers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,17 +32,18 @@
32
32
  "automation"
33
33
  ],
34
34
  "engines": {
35
+ "node": ">=18.0.0",
35
36
  "bun": ">=1.0.0"
36
37
  },
37
38
  "scripts": {
38
- "start": "bun src/index.ts",
39
- "build": "bun build src/index.ts src/cli.ts --outdir dist --target bun",
39
+ "start": "node dist/index.js",
40
+ "build": "tsc",
40
41
  "typecheck": "tsc --noEmit",
41
- "prepublishOnly": "bun run build"
42
+ "prepublishOnly": "npm run build"
42
43
  },
43
44
  "dependencies": {
44
45
  "@supabase/supabase-js": "2.95.3",
45
- "@gethmy/mcp": "workspace:*"
46
+ "@gethmy/mcp": "^2.0.0"
46
47
  },
47
48
  "devDependencies": {
48
49
  "@harmony/shared": "workspace:*",