@hizliemre/horse-code 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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +150 -0
  3. package/dist/app-SB2L34JW.js +6217 -0
  4. package/dist/chunk-2DGO2BUB.js +4490 -0
  5. package/dist/chunk-2SVAHH5N.js +60 -0
  6. package/dist/chunk-3XVZXTB6.js +4469 -0
  7. package/dist/chunk-5UWA2UBM.js +69 -0
  8. package/dist/chunk-7TBYMFMG.js +147 -0
  9. package/dist/chunk-B67BK5GQ.js +34 -0
  10. package/dist/chunk-BY4DP7IE.js +20 -0
  11. package/dist/chunk-DKVIN43T.js +54 -0
  12. package/dist/chunk-DTWKSZXY.js +162 -0
  13. package/dist/chunk-F2IALVBU.js +212 -0
  14. package/dist/chunk-FFYBY2NA.js +392 -0
  15. package/dist/chunk-FGVJFMK5.js +123 -0
  16. package/dist/chunk-H2FDGPVW.js +42 -0
  17. package/dist/chunk-HBSC2HT2.js +85 -0
  18. package/dist/chunk-IW2KBAVZ.js +21 -0
  19. package/dist/chunk-JWAEW7AJ.js +121 -0
  20. package/dist/chunk-NNTIACT4.js +163 -0
  21. package/dist/chunk-O74BDQKS.js +28 -0
  22. package/dist/chunk-PGOYDOI4.js +426 -0
  23. package/dist/chunk-QF4MP6BS.js +69 -0
  24. package/dist/chunk-SSDLHWSF.js +35 -0
  25. package/dist/chunk-TOPZL5SU.js +1052 -0
  26. package/dist/chunk-YBWTCXUS.js +153 -0
  27. package/dist/chunk-YILDXPSI.js +1363 -0
  28. package/dist/clean-YOQATBMZ.js +18 -0
  29. package/dist/cli.js +1495 -0
  30. package/dist/discover-5URG7C4J.js +52 -0
  31. package/dist/fix-HBBOTUWM.js +34 -0
  32. package/dist/frontmatter-UNIPNLLO.js +6 -0
  33. package/dist/git-VTSZALSR.js +6 -0
  34. package/dist/install-O34KMWJB.js +113 -0
  35. package/dist/main-branch-KGWUINYQ.js +19 -0
  36. package/dist/ongoing-OV5XROTU.js +70 -0
  37. package/dist/project-graph-IOPCSZUA.js +56 -0
  38. package/dist/run-LQOZ5I7Z.js +610 -0
  39. package/dist/save-skills-OHYGVTQ4.js +13 -0
  40. package/dist/source-cache-XEK5WN7I.js +29 -0
  41. package/dist/trace-ZMB7LT7W.js +66 -0
  42. package/dist/trace-adopt-C6TUWFJL.js +79 -0
  43. package/dist/trace-run-F23MFTY4.js +24 -0
  44. package/dist/triage-2J3T5PVQ.js +30 -0
  45. package/dist/verify-WQ3GHION.js +479 -0
  46. package/dist/worktree-F7TWLWLN.js +87 -0
  47. package/package.json +64 -0
@@ -0,0 +1,87 @@
1
+ // src/migrate/worktree.ts
2
+ import { existsSync, realpathSync } from "fs";
3
+ import { join } from "path";
4
+ var CLAUDE_WORKTREE_DIR = join(".claude", "worktrees");
5
+ async function listClaudeWorktrees(git, repoRoot) {
6
+ const dir = join(repoRoot, CLAUDE_WORKTREE_DIR);
7
+ if (!existsSync(dir)) return [];
8
+ const real = (p) => {
9
+ try {
10
+ return realpathSync(p);
11
+ } catch {
12
+ return p;
13
+ }
14
+ };
15
+ const base = real(dir);
16
+ const r = await git(["worktree", "list", "--porcelain"], repoRoot);
17
+ const names = [];
18
+ for (const line of r.stdout.split("\n")) {
19
+ if (!line.startsWith("worktree ")) continue;
20
+ const p = real(line.slice("worktree ".length).trim());
21
+ if (p.startsWith(base + "/") || p.startsWith(base + "\\")) names.push(p.slice(base.length + 1));
22
+ }
23
+ return names.sort();
24
+ }
25
+ var AdoptError = class extends Error {
26
+ constructor(message, available = []) {
27
+ super(message);
28
+ this.available = available;
29
+ }
30
+ available;
31
+ };
32
+ async function adoptClaudeWorktree(git, repoRoot, name, base) {
33
+ const wanted = name.trim().replace(/^["']|["']$/g, "");
34
+ if (!wanted) throw new AdoptError("Name the worktree to continue from.", await listClaudeWorktrees(git, repoRoot));
35
+ const available = await listClaudeWorktrees(git, repoRoot);
36
+ if (!available.includes(wanted)) {
37
+ throw new AdoptError(`No git worktree named \`${wanted}\` under \`${CLAUDE_WORKTREE_DIR}\`.`, available);
38
+ }
39
+ const path = join(repoRoot, CLAUDE_WORKTREE_DIR, wanted);
40
+ const head = await git(["rev-parse", "--abbrev-ref", "HEAD"], path);
41
+ const branch = head.stdout.trim();
42
+ if (head.code !== 0 || !branch || branch === "HEAD") {
43
+ throw new AdoptError(`\`${wanted}\` is not on a branch (detached HEAD) \u2014 nothing to continue from.`, available);
44
+ }
45
+ const log = await git(["log", "--format=%h%x00%s", `${base}...${branch}`, "--right-only"], repoRoot);
46
+ const commits = log.code === 0 ? log.stdout.split("\n").map((l) => l.trim()).filter(Boolean).map((l) => {
47
+ const [sha, ...rest] = l.split("\0");
48
+ return { sha, subject: rest.join("\0") };
49
+ }) : [];
50
+ const status = await git(["status", "--porcelain"], path);
51
+ const dirty = status.code === 0 ? status.stdout.split("\n").map((l) => l.slice(3).trim()).filter(Boolean) : [];
52
+ const changed = await git(["diff", "--name-only", `${base}...${branch}`], repoRoot);
53
+ const docs = changed.code === 0 ? changed.stdout.split("\n").map((l) => l.trim()).filter((f) => /\.md$/i.test(f)) : [];
54
+ return { name: wanted, path, branch, commits, dirty, docs, base };
55
+ }
56
+ var SHOWN = 8;
57
+ function describeAdoption(w) {
58
+ const lines = [
59
+ `**Continuing from \`${w.name}\`** \u2014 branch \`${w.branch}\`.`,
60
+ "",
61
+ `horse-code will branch its next session FROM this branch, so its ${w.commits.length} commit(s) are inherited rather than rewritten. The worktree at \`${CLAUDE_WORKTREE_DIR}/${w.name}\` is left untouched.`
62
+ ];
63
+ if (w.commits.length) {
64
+ lines.push("", `**What is on it** (vs \`${w.base}\`):`);
65
+ lines.push(...w.commits.slice(0, SHOWN).map((c) => `- \`${c.sha}\` ${c.subject}`));
66
+ if (w.commits.length > SHOWN) lines.push(`- _\u2026and ${w.commits.length - SHOWN} more_`);
67
+ } else {
68
+ lines.push("", `_No commits of its own against \`${w.base}\` \u2014 the branch is even with the base._`);
69
+ }
70
+ if (w.docs.length) {
71
+ lines.push("", `**Notes written for this work:** ${w.docs.slice(0, SHOWN).map((d) => `\`${d}\``).join(", ")}` + (w.docs.length > SHOWN ? ` _+${w.docs.length - SHOWN} more_` : ""));
72
+ }
73
+ if (w.dirty.length) {
74
+ lines.push("", `\u26A0\uFE0F **${w.dirty.length} uncommitted change(s)** in that worktree \u2014 these are NOT inherited, only what is committed on \`${w.branch}\` is: ${w.dirty.slice(0, SHOWN).map((f) => `\`${f}\``).join(", ")}` + (w.dirty.length > SHOWN ? ` _+${w.dirty.length - SHOWN} more_` : "") + `
75
+
76
+ _Commit them there first if they should carry over._`);
77
+ }
78
+ lines.push("", `Now tell me what to work on next and it starts from here.`);
79
+ return lines.join("\n");
80
+ }
81
+ export {
82
+ AdoptError,
83
+ CLAUDE_WORKTREE_DIR,
84
+ adoptClaudeWorktree,
85
+ describeAdoption,
86
+ listClaudeWorktrees
87
+ };
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@hizliemre/horse-code",
3
+ "version": "0.1.0",
4
+ "description": "Terminal coding agent: one sentence to reviewed, committed code — in its own git worktree",
5
+ "license": "MIT",
6
+ "author": "Emre Hızlı <hizliemre@gmail.com>",
7
+ "homepage": "https://github.com/hizliemre/horse-code#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/hizliemre/horse-code.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/hizliemre/horse-code/issues"
14
+ },
15
+ "keywords": [
16
+ "ai",
17
+ "agent",
18
+ "cli",
19
+ "coding-agent",
20
+ "llm",
21
+ "terminal",
22
+ "tui",
23
+ "code-review",
24
+ "claude",
25
+ "mcp"
26
+ ],
27
+ "type": "module",
28
+ "bin": {
29
+ "hcode": "./dist/cli.js"
30
+ },
31
+ "engines": {
32
+ "node": ">=20"
33
+ },
34
+ "files": [
35
+ "dist"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "prepare": "npm run build",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest",
42
+ "typecheck": "tsc --noEmit",
43
+ "prepublishOnly": "npm run typecheck && npm test && npm run build"
44
+ },
45
+ "dependencies": {
46
+ "@modelcontextprotocol/sdk": "^1.29.0",
47
+ "ink": "^7.1.1",
48
+ "picomatch": "^4.0.5",
49
+ "react": "^19.2.8",
50
+ "zod": "^4.4.3"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^26.1.1",
54
+ "@types/picomatch": "^4.0.3",
55
+ "@types/react": "^19.2.17",
56
+ "ink-testing-library": "^4.0.0",
57
+ "pngjs": "^7.0.0",
58
+ "react-devtools-core": "^7.0.1",
59
+ "react-dom": "^19.2.8",
60
+ "tsup": "^8.5.1",
61
+ "typescript": "^7.0.2",
62
+ "vitest": "^4.1.10"
63
+ }
64
+ }