codedeck 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 (72) hide show
  1. package/README.md +211 -0
  2. package/dist/cli/commands/diff.js +43 -0
  3. package/dist/cli/commands/diff.js.map +1 -0
  4. package/dist/cli/commands/doctor.js +90 -0
  5. package/dist/cli/commands/doctor.js.map +1 -0
  6. package/dist/cli/commands/logs.js +139 -0
  7. package/dist/cli/commands/logs.js.map +1 -0
  8. package/dist/cli/commands/ps.js +59 -0
  9. package/dist/cli/commands/ps.js.map +1 -0
  10. package/dist/cli/commands/run.js +145 -0
  11. package/dist/cli/commands/run.js.map +1 -0
  12. package/dist/cli/commands/send.js +29 -0
  13. package/dist/cli/commands/send.js.map +1 -0
  14. package/dist/cli/commands/show.js +99 -0
  15. package/dist/cli/commands/show.js.map +1 -0
  16. package/dist/cli/commands/stop.js +27 -0
  17. package/dist/cli/commands/stop.js.map +1 -0
  18. package/dist/cli/index.js +63 -0
  19. package/dist/cli/index.js.map +1 -0
  20. package/dist/config/config.js +26 -0
  21. package/dist/config/config.js.map +1 -0
  22. package/dist/config/paths.js +43 -0
  23. package/dist/config/paths.js.map +1 -0
  24. package/dist/core/capabilities.js +14 -0
  25. package/dist/core/capabilities.js.map +1 -0
  26. package/dist/core/driver.js +2 -0
  27. package/dist/core/driver.js.map +1 -0
  28. package/dist/core/errors.js +61 -0
  29. package/dist/core/errors.js.map +1 -0
  30. package/dist/core/events.js +10 -0
  31. package/dist/core/events.js.map +1 -0
  32. package/dist/core/session.js +33 -0
  33. package/dist/core/session.js.map +1 -0
  34. package/dist/daemon/daemon.js +534 -0
  35. package/dist/daemon/daemon.js.map +1 -0
  36. package/dist/daemon/ipc.js +292 -0
  37. package/dist/daemon/ipc.js.map +1 -0
  38. package/dist/daemon/process-manager.js +55 -0
  39. package/dist/daemon/process-manager.js.map +1 -0
  40. package/dist/daemon/protocol.js +2 -0
  41. package/dist/daemon/protocol.js.map +1 -0
  42. package/dist/drivers/claude/driver.js +247 -0
  43. package/dist/drivers/claude/driver.js.map +1 -0
  44. package/dist/drivers/claude/parser.js +184 -0
  45. package/dist/drivers/claude/parser.js.map +1 -0
  46. package/dist/drivers/codex/driver.js +241 -0
  47. package/dist/drivers/codex/driver.js.map +1 -0
  48. package/dist/drivers/codex/parser.js +184 -0
  49. package/dist/drivers/codex/parser.js.map +1 -0
  50. package/dist/drivers/helpers.js +85 -0
  51. package/dist/drivers/helpers.js.map +1 -0
  52. package/dist/drivers/omp/driver.js +372 -0
  53. package/dist/drivers/omp/driver.js.map +1 -0
  54. package/dist/drivers/opencode/driver.js +307 -0
  55. package/dist/drivers/opencode/driver.js.map +1 -0
  56. package/dist/drivers/registry.js +48 -0
  57. package/dist/drivers/registry.js.map +1 -0
  58. package/dist/git/diff.js +100 -0
  59. package/dist/git/diff.js.map +1 -0
  60. package/dist/git/repository.js +68 -0
  61. package/dist/git/repository.js.map +1 -0
  62. package/dist/git/worktree.js +89 -0
  63. package/dist/git/worktree.js.map +1 -0
  64. package/dist/store/database.js +85 -0
  65. package/dist/store/database.js.map +1 -0
  66. package/dist/store/events.js +39 -0
  67. package/dist/store/events.js.map +1 -0
  68. package/dist/store/sessions.js +128 -0
  69. package/dist/store/sessions.js.map +1 -0
  70. package/dist/utils/process.js +35 -0
  71. package/dist/utils/process.js.map +1 -0
  72. package/package.json +43 -0
@@ -0,0 +1,307 @@
1
+ import { spawn } from "node:child_process";
2
+ import { detectBinary, createLineReader } from "../helpers.js";
3
+ import { EventEmitter } from "node:events";
4
+ function parseOpencodeLine(line, sessionId) {
5
+ let obj;
6
+ try {
7
+ obj = JSON.parse(line);
8
+ }
9
+ catch {
10
+ return [];
11
+ }
12
+ const ts = new Date().toISOString();
13
+ const raw = obj;
14
+ const events = [];
15
+ // Opencode JSON format varies; observed error shape {"type":"error","sessionID":...}
16
+ // For success, likely {"type":"text","text":"..."} or similar; we handle generically
17
+ if (obj.type === "error") {
18
+ events.push({
19
+ type: "session.failed",
20
+ sessionId,
21
+ timestamp: ts,
22
+ error: obj.error?.data?.message || obj.error?.message || obj.message || JSON.stringify(obj.error || obj),
23
+ raw,
24
+ });
25
+ return events;
26
+ }
27
+ if (obj.type === "session.created" || obj.type === "session_created") {
28
+ events.push({
29
+ type: "session.started",
30
+ sessionId,
31
+ timestamp: ts,
32
+ nativeSessionId: obj.sessionID || obj.sessionId || obj.id,
33
+ raw,
34
+ });
35
+ return events;
36
+ }
37
+ if (obj.type === "message" || obj.type === "text" || obj.type === "assistant") {
38
+ const text = obj.text || obj.content || obj.delta || "";
39
+ if (text) {
40
+ events.push({
41
+ type: "message",
42
+ sessionId,
43
+ timestamp: ts,
44
+ role: "assistant",
45
+ content: String(text),
46
+ raw,
47
+ });
48
+ events.push({
49
+ type: "text.delta",
50
+ sessionId,
51
+ timestamp: ts,
52
+ delta: String(text),
53
+ raw,
54
+ });
55
+ }
56
+ return events;
57
+ }
58
+ if (obj.type === "tool.use" || obj.type === "tool.started") {
59
+ events.push({
60
+ type: "tool.started",
61
+ sessionId,
62
+ timestamp: ts,
63
+ tool: { name: obj.tool || obj.name || "tool", id: obj.id, input: obj.input },
64
+ raw,
65
+ });
66
+ return events;
67
+ }
68
+ if (obj.type === "tool.result" || obj.type === "tool.completed") {
69
+ events.push({
70
+ type: "tool.completed",
71
+ sessionId,
72
+ timestamp: ts,
73
+ tool: { name: obj.tool || obj.name || "tool", id: obj.id, output: obj.output, success: !obj.isError },
74
+ raw,
75
+ });
76
+ return events;
77
+ }
78
+ if (obj.type === "session.completed" || obj.type === "done") {
79
+ events.push({
80
+ type: "session.completed",
81
+ sessionId,
82
+ timestamp: ts,
83
+ reason: "completed",
84
+ raw,
85
+ });
86
+ return events;
87
+ }
88
+ // Generic fallback: if has sessionID and text, treat as message
89
+ if (obj.sessionID && obj.text) {
90
+ events.push({
91
+ type: "message",
92
+ sessionId,
93
+ timestamp: ts,
94
+ role: "assistant",
95
+ content: String(obj.text),
96
+ raw,
97
+ });
98
+ return events;
99
+ }
100
+ // If object contains delta
101
+ if (obj.delta) {
102
+ events.push({
103
+ type: "text.delta",
104
+ sessionId,
105
+ timestamp: ts,
106
+ delta: String(obj.delta),
107
+ raw,
108
+ });
109
+ return events;
110
+ }
111
+ return [];
112
+ }
113
+ export class OpencodeDriver {
114
+ id = "opencode";
115
+ handles = new Map();
116
+ capabilities() {
117
+ return {
118
+ streaming: true,
119
+ resume: true,
120
+ fork: true,
121
+ approvals: true,
122
+ usage: true,
123
+ cost: true,
124
+ modelSelection: true,
125
+ nativeDiff: false,
126
+ interrupt: true,
127
+ };
128
+ }
129
+ async detect() {
130
+ const res = await detectBinary("opencode");
131
+ if (!res.installed)
132
+ return { installed: false, error: "opencode binary not found" };
133
+ return { installed: true, path: res.path, version: res.version, details: "opencode run --format json" };
134
+ }
135
+ async start(options) {
136
+ const args = ["run", "--format", "json"];
137
+ if (options.model)
138
+ args.push("--model", options.model);
139
+ if (options.resumeSessionId) {
140
+ args.push("--session", options.resumeSessionId);
141
+ }
142
+ // Auto-approve? For automation we may need --auto? But risk
143
+ // Use --dir to set cwd if supported; otherwise rely on cwd spawn
144
+ // opencode run --dir <cwd> is not standard; we use spawn cwd
145
+ args.push(options.prompt);
146
+ const proc = spawn("opencode", args, {
147
+ cwd: options.cwd,
148
+ env: { ...process.env },
149
+ stdio: ["pipe", "pipe", "pipe"],
150
+ });
151
+ proc.stdin?.end();
152
+ const emitter = new EventEmitter();
153
+ const buffer = [];
154
+ let nativeId = options.resumeSessionId;
155
+ let done = false;
156
+ let exitCode = null;
157
+ const push = (ev) => {
158
+ ev.sessionId = options.sessionId;
159
+ if (ev.nativeSessionId)
160
+ nativeId = ev.nativeSessionId;
161
+ if (ev.raw?.sessionID)
162
+ nativeId = ev.raw.sessionID;
163
+ buffer.push(ev);
164
+ emitter.emit("event", ev);
165
+ };
166
+ createLineReader(proc.stdout, (line) => {
167
+ const evs = parseOpencodeLine(line, options.sessionId);
168
+ for (const ev of evs)
169
+ push(ev);
170
+ // Also capture sessionID from raw json even if not parsed
171
+ try {
172
+ const obj = JSON.parse(line);
173
+ if (obj.sessionID && !nativeId)
174
+ nativeId = obj.sessionID;
175
+ if (obj.sessionId && !nativeId)
176
+ nativeId = obj.sessionId;
177
+ if (obj.session_id && !nativeId)
178
+ nativeId = obj.session_id;
179
+ }
180
+ catch { }
181
+ // If no known event but line is JSON, treat as generic message?
182
+ if (evs.length === 0) {
183
+ try {
184
+ const obj = JSON.parse(line);
185
+ // If stdout contains plain text fallback, we could ignore
186
+ }
187
+ catch { }
188
+ }
189
+ });
190
+ let stderrBuf = "";
191
+ proc.stderr?.on("data", (c) => (stderrBuf += c.toString()));
192
+ proc.on("close", (code) => {
193
+ exitCode = code;
194
+ done = true;
195
+ const hasTerminal = buffer.some((e) => e.type === "session.completed" || e.type === "session.failed");
196
+ if (!hasTerminal) {
197
+ if (code === 0) {
198
+ push({
199
+ type: "session.completed",
200
+ sessionId: options.sessionId,
201
+ timestamp: new Date().toISOString(),
202
+ reason: "exit 0",
203
+ exitCode: 0,
204
+ raw: { stderr: stderrBuf.slice(0, 2000) },
205
+ });
206
+ }
207
+ else {
208
+ // For opencode, many failures are due to model config; provide stderr
209
+ push({
210
+ type: "session.failed",
211
+ sessionId: options.sessionId,
212
+ timestamp: new Date().toISOString(),
213
+ error: stderrBuf.slice(0, 2000) || `Opencode exited with code ${code}`,
214
+ exitCode: code ?? 1,
215
+ raw: { stderr: stderrBuf.slice(0, 2000) },
216
+ });
217
+ }
218
+ }
219
+ emitter.emit("done");
220
+ });
221
+ proc.on("error", (err) => {
222
+ push({
223
+ type: "session.failed",
224
+ sessionId: options.sessionId,
225
+ timestamp: new Date().toISOString(),
226
+ error: err.message,
227
+ raw: err,
228
+ });
229
+ done = true;
230
+ emitter.emit("done");
231
+ });
232
+ const handle = { proc, emitter, buffer, done, exitCode, nativeSessionId: nativeId };
233
+ this.handles.set(options.sessionId, handle);
234
+ return {
235
+ id: options.sessionId,
236
+ nativeSessionId: nativeId,
237
+ pid: proc.pid,
238
+ cwd: options.cwd,
239
+ model: options.model,
240
+ handle,
241
+ };
242
+ }
243
+ async send(session, message) {
244
+ const h = this.handles.get(session.id);
245
+ let nativeId = session.nativeSessionId || h?.nativeSessionId;
246
+ if (!nativeId)
247
+ throw new Error("No native session id for Opencode resume");
248
+ const newSession = await this.start({
249
+ sessionId: session.id,
250
+ prompt: message,
251
+ cwd: session.cwd,
252
+ model: session.model,
253
+ resumeSessionId: nativeId,
254
+ });
255
+ session.pid = newSession.pid;
256
+ session.handle = newSession.handle;
257
+ }
258
+ async stop(session) {
259
+ const h = this.handles.get(session.id);
260
+ const proc = (h?.proc ?? session.handle?.proc);
261
+ if (!proc || proc.killed)
262
+ return;
263
+ try {
264
+ proc.kill("SIGTERM");
265
+ await new Promise((resolve) => {
266
+ let done = false;
267
+ const t = setTimeout(() => { if (!done) {
268
+ try {
269
+ proc.kill("SIGKILL");
270
+ }
271
+ catch { }
272
+ ;
273
+ done = true;
274
+ resolve();
275
+ } }, 3000);
276
+ proc.once("close", () => { if (!done) {
277
+ clearTimeout(t);
278
+ done = true;
279
+ resolve();
280
+ } });
281
+ });
282
+ }
283
+ catch { }
284
+ }
285
+ async *events(session) {
286
+ const h = this.handles.get(session.id);
287
+ if (!h)
288
+ return;
289
+ let idx = 0;
290
+ while (true) {
291
+ while (idx < h.buffer.length)
292
+ yield h.buffer[idx++];
293
+ if (h.done && idx >= h.buffer.length)
294
+ break;
295
+ await new Promise((resolve) => {
296
+ const onEvent = () => { h.emitter.off("event", onEvent); h.emitter.off("done", onDone); resolve(); };
297
+ const onDone = () => { h.emitter.off("event", onEvent); h.emitter.off("done", onDone); resolve(); };
298
+ h.emitter.once("event", onEvent);
299
+ h.emitter.once("done", onDone);
300
+ });
301
+ }
302
+ }
303
+ getHandle(sessionId) {
304
+ return this.handles.get(sessionId);
305
+ }
306
+ }
307
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/drivers/opencode/driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { ClaudeDriver } from "./claude/driver.js";
2
+ import { CodexDriver } from "./codex/driver.js";
3
+ import { OpencodeDriver } from "./opencode/driver.js";
4
+ import { OmpDriver } from "./omp/driver.js";
5
+ export class DriverRegistry {
6
+ drivers;
7
+ constructor() {
8
+ this.drivers = new Map();
9
+ this.register(new ClaudeDriver());
10
+ this.register(new CodexDriver());
11
+ this.register(new OpencodeDriver());
12
+ this.register(new OmpDriver());
13
+ }
14
+ register(driver) {
15
+ this.drivers.set(driver.id, driver);
16
+ }
17
+ get(agent) {
18
+ const d = this.drivers.get(agent);
19
+ if (!d)
20
+ throw new Error(`Unknown agent: ${agent}`);
21
+ return d;
22
+ }
23
+ has(agent) {
24
+ return this.drivers.has(agent);
25
+ }
26
+ list() {
27
+ return [...this.drivers.values()];
28
+ }
29
+ async detectAll() {
30
+ const result = {};
31
+ await Promise.all([...this.drivers.entries()].map(async ([id, driver]) => {
32
+ try {
33
+ result[id] = await driver.detect();
34
+ }
35
+ catch (e) {
36
+ result[id] = { installed: false, error: e instanceof Error ? e.message : String(e) };
37
+ }
38
+ }));
39
+ return result;
40
+ }
41
+ }
42
+ let singleton = null;
43
+ export function getRegistry() {
44
+ if (!singleton)
45
+ singleton = new DriverRegistry();
46
+ return singleton;
47
+ }
48
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/drivers/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,cAAc;IACjB,OAAO,CAA4B;IAE3C;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,GAAG,EAAE,CAAC;QACzB,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,QAAQ,CAAC,IAAI,WAAW,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,cAAc,EAAE,CAAC,CAAC;QACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC;IACjC,CAAC;IAED,QAAQ,CAAC,MAAmB;QAC1B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,GAAG,CAAC,KAAc;QAChB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAClC,IAAI,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;QACnD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,GAAG,CAAC,KAAc;QAChB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAsC,EAAE,CAAC;QACrD,MAAM,OAAO,CAAC,GAAG,CACf,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE;YACrD,IAAI,CAAC;gBACH,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,CAAC;YACrC,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YACvF,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QACF,OAAO,MAA4C,CAAC;IACtD,CAAC;CACF;AAED,IAAI,SAAS,GAA0B,IAAI,CAAC;AAE5C,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,SAAS;QAAE,SAAS,GAAG,IAAI,cAAc,EAAE,CAAC;IACjD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ const execFileAsync = promisify(execFile);
4
+ export async function getDiff(options) {
5
+ const cwd = options.worktree || options.cwd;
6
+ const repoRoot = options.repository || cwd;
7
+ let base = options.baseCommit ?? null;
8
+ if (!base) {
9
+ try {
10
+ const { stdout } = await execFileAsync("git", ["merge-base", "HEAD", "HEAD"], { cwd });
11
+ base = stdout.trim();
12
+ }
13
+ catch {
14
+ try {
15
+ const { stdout } = await execFileAsync("git", ["rev-parse", "HEAD"], { cwd });
16
+ base = stdout.trim();
17
+ }
18
+ catch {
19
+ base = null;
20
+ }
21
+ }
22
+ }
23
+ let diff = "";
24
+ let stat = "";
25
+ let files = [];
26
+ // Try diff against baseCommit if available in original repo
27
+ // In worktree case, diff against origin branch or HEAD of base?
28
+ // Simplified: git diff baseCommit..HEAD or git diff HEAD
29
+ try {
30
+ if (base) {
31
+ // diff between base and current worktree HEAD plus unstaged
32
+ // For worktree, base is the commit at creation time, so diff base -> HEAD + working dir
33
+ const { stdout } = await execFileAsync("git", ["diff", `${base}...HEAD`, "--patch"], { cwd });
34
+ const { stdout: wd } = await execFileAsync("git", ["diff", "--patch"], { cwd });
35
+ const { stdout: staged } = await execFileAsync("git", ["diff", "--cached", "--patch"], { cwd });
36
+ const { stdout: untracked } = await execFileAsync("git", ["ls-files", "--others", "--exclude-standard"], { cwd });
37
+ diff = [stdout, wd, staged].filter(Boolean).join("\n");
38
+ // also include untracked files content via git diff --no-index? simpler list
39
+ if (untracked.trim()) {
40
+ // Append untracked info
41
+ diff += `\n# Untracked files:\n# ${untracked.trim().split("\n").join("\n# ")}`;
42
+ }
43
+ }
44
+ else {
45
+ const { stdout } = await execFileAsync("git", ["diff", "HEAD", "--patch"], { cwd });
46
+ diff = stdout;
47
+ }
48
+ }
49
+ catch (e) {
50
+ try {
51
+ const { stdout } = await execFileAsync("git", ["status", "--porcelain"], { cwd });
52
+ diff = stdout ? `# git status:\n${stdout}` : "";
53
+ }
54
+ catch {
55
+ diff = "No diff available";
56
+ }
57
+ }
58
+ try {
59
+ if (base) {
60
+ const { stdout } = await execFileAsync("git", ["diff", "--stat", `${base}...HEAD`], { cwd });
61
+ const { stdout: wdStat } = await execFileAsync("git", ["diff", "--stat"], { cwd });
62
+ stat = [stdout, wdStat].filter(Boolean).join("\n");
63
+ }
64
+ else {
65
+ const { stdout } = await execFileAsync("git", ["diff", "--stat", "HEAD"], { cwd });
66
+ stat = stdout;
67
+ }
68
+ }
69
+ catch {
70
+ stat = "";
71
+ }
72
+ try {
73
+ if (base) {
74
+ const { stdout } = await execFileAsync("git", ["diff", "--name-only", `${base}...HEAD`], { cwd });
75
+ const { stdout: wd } = await execFileAsync("git", ["diff", "--name-only"], { cwd });
76
+ const all = new Set([...stdout.split("\n").filter(Boolean), ...wd.split("\n").filter(Boolean)]);
77
+ files = [...all];
78
+ }
79
+ else {
80
+ const { stdout } = await execFileAsync("git", ["diff", "--name-only", "HEAD"], { cwd });
81
+ files = stdout.split("\n").filter(Boolean);
82
+ }
83
+ }
84
+ catch {
85
+ files = [];
86
+ }
87
+ // Fallback: if diff empty, show untracked diff via git status
88
+ if (!diff.trim() && files.length === 0) {
89
+ try {
90
+ const { stdout } = await execFileAsync("git", ["status", "--short"], { cwd });
91
+ if (stdout.trim()) {
92
+ diff = `# Working tree status:\n${stdout}`;
93
+ stat = stdout;
94
+ }
95
+ }
96
+ catch { }
97
+ }
98
+ return { base, diff, stat, files };
99
+ }
100
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/git/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ const execFileAsync = promisify(execFile);
6
+ export async function getGitInfo(cwd) {
7
+ try {
8
+ const { stdout: root } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], { cwd });
9
+ const repoRoot = root.trim();
10
+ let head = null;
11
+ let branch = null;
12
+ let isDirty = false;
13
+ try {
14
+ const { stdout } = await execFileAsync("git", ["rev-parse", "HEAD"], { cwd });
15
+ head = stdout.trim();
16
+ }
17
+ catch {
18
+ head = null;
19
+ }
20
+ try {
21
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd });
22
+ const b = stdout.trim();
23
+ branch = b === "HEAD" ? null : b;
24
+ }
25
+ catch {
26
+ branch = null;
27
+ }
28
+ try {
29
+ const { stdout } = await execFileAsync("git", ["status", "--porcelain"], { cwd });
30
+ isDirty = stdout.trim().length > 0;
31
+ }
32
+ catch {
33
+ isDirty = false;
34
+ }
35
+ return { root: repoRoot, head, branch, isDirty };
36
+ }
37
+ catch {
38
+ return null;
39
+ }
40
+ }
41
+ export async function getBaseCommit(cwd) {
42
+ try {
43
+ const { stdout } = await execFileAsync("git", ["rev-parse", "HEAD"], { cwd });
44
+ return stdout.trim();
45
+ }
46
+ catch {
47
+ return null;
48
+ }
49
+ }
50
+ export function isGitRepository(cwd) {
51
+ try {
52
+ // check .git existence upward
53
+ let cur = path.resolve(cwd);
54
+ while (true) {
55
+ if (fs.existsSync(path.join(cur, ".git")))
56
+ return true;
57
+ const parent = path.dirname(cur);
58
+ if (parent === cur)
59
+ break;
60
+ cur = parent;
61
+ }
62
+ return false;
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ }
68
+ //# sourceMappingURL=repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/git/repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import crypto from "node:crypto";
6
+ import { getPaths } from "../config/paths.js";
7
+ import { WorktreeCreationFailedError } from "../core/errors.js";
8
+ const execFileAsync = promisify(execFile);
9
+ function repoHash(repoRoot) {
10
+ return crypto.createHash("sha1").update(repoRoot).digest("hex").slice(0, 8);
11
+ }
12
+ function slugify(prompt) {
13
+ return prompt
14
+ .toLowerCase()
15
+ .replace(/[^a-z0-9]+/g, "-")
16
+ .replace(/^-|-$/g, "")
17
+ .slice(0, 30) || "task";
18
+ }
19
+ export async function createWorktree(options) {
20
+ const { repoRoot, sessionId, prompt, name } = options;
21
+ const baseSlug = name ? slugify(name) : slugify(prompt);
22
+ const branch = `ra/${baseSlug}-${sessionId}`;
23
+ const hash = repoHash(repoRoot);
24
+ const worktreePath = path.join(getPaths().worktreesDir, hash, sessionId);
25
+ fs.mkdirSync(path.dirname(worktreePath), { recursive: true });
26
+ let baseCommit = null;
27
+ try {
28
+ const { stdout } = await execFileAsync("git", ["rev-parse", "HEAD"], { cwd: repoRoot });
29
+ baseCommit = stdout.trim();
30
+ }
31
+ catch {
32
+ baseCommit = null;
33
+ }
34
+ try {
35
+ // Create worktree from HEAD
36
+ await execFileAsync("git", ["worktree", "add", "-b", branch, worktreePath, "HEAD"], { cwd: repoRoot });
37
+ }
38
+ catch (err) {
39
+ // If branch exists, try without -b
40
+ const msg = err instanceof Error ? err.message : String(err);
41
+ if (msg.includes("already exists")) {
42
+ try {
43
+ await execFileAsync("git", ["worktree", "add", worktreePath, branch], { cwd: repoRoot });
44
+ }
45
+ catch (e) {
46
+ throw new WorktreeCreationFailedError(e);
47
+ }
48
+ }
49
+ else {
50
+ throw new WorktreeCreationFailedError(err);
51
+ }
52
+ }
53
+ return { path: worktreePath, branch, baseCommit };
54
+ }
55
+ export async function removeWorktree(worktreePath, repoRoot) {
56
+ const cwd = repoRoot || path.dirname(worktreePath);
57
+ try {
58
+ await execFileAsync("git", ["worktree", "remove", "--force", worktreePath], { cwd });
59
+ }
60
+ catch {
61
+ // Fallback: remove dir
62
+ try {
63
+ fs.rmSync(worktreePath, { recursive: true, force: true });
64
+ if (repoRoot) {
65
+ // Prune
66
+ try {
67
+ await execFileAsync("git", ["worktree", "prune"], { cwd: repoRoot });
68
+ }
69
+ catch { }
70
+ }
71
+ }
72
+ catch { }
73
+ }
74
+ }
75
+ export async function listWorktrees(repoRoot) {
76
+ try {
77
+ const { stdout } = await execFileAsync("git", ["worktree", "list", "--porcelain"], { cwd: repoRoot });
78
+ const paths = [];
79
+ for (const line of stdout.split("\n")) {
80
+ if (line.startsWith("worktree "))
81
+ paths.push(line.slice(9).trim());
82
+ }
83
+ return paths;
84
+ }
85
+ catch {
86
+ return [];
87
+ }
88
+ }
89
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/git/worktree.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,MAAM,mBAAmB,CAAC;AAEhE,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAQ1C,SAAS,QAAQ,CAAC,QAAgB;IAChC,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,SAAS,OAAO,CAAC,MAAc;IAC7B,OAAO,MAAM;SACV,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAKpC;IACC,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,YAAY,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IAEzE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE9D,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,WAAW,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxF,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,UAAU,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzG,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,mCAAmC;QACnC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,IAAI,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;YAC3F,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,IAAI,2BAA2B,CAAC,CAAC,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,2BAA2B,CAAC,GAAG,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,YAAoB,EAAE,QAAiB;IAC1E,MAAM,GAAG,GAAG,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IACvF,CAAC;IAAC,MAAM,CAAC;QACP,uBAAuB;QACvB,IAAI,CAAC;YACH,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ;gBACR,IAAI,CAAC;oBAAC,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;gBAAC,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACxF,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB;IAClD,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtG,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}