@aku11i/phantom 0.1.2 → 0.2.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/README.md +60 -0
- package/dist/garden.js +133 -69
- package/dist/garden.js.map +4 -4
- package/dist/phantom.js +108 -96
- package/dist/phantom.js.map +4 -4
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -82,6 +82,7 @@ yarn global add @aku11i/phantom
|
|
|
82
82
|
git clone https://github.com/aku11i/phantom.git
|
|
83
83
|
cd phantom
|
|
84
84
|
pnpm install
|
|
85
|
+
pnpm build
|
|
85
86
|
npm link
|
|
86
87
|
```
|
|
87
88
|
|
|
@@ -165,6 +166,65 @@ pnpm lint
|
|
|
165
166
|
pnpm ready
|
|
166
167
|
```
|
|
167
168
|
|
|
169
|
+
## 🚀 Release Process
|
|
170
|
+
|
|
171
|
+
To release a new version of Phantom:
|
|
172
|
+
|
|
173
|
+
1. **Ensure you're on main branch and up to date**
|
|
174
|
+
```bash
|
|
175
|
+
git checkout main
|
|
176
|
+
git pull
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
2. **Run all checks**
|
|
180
|
+
```bash
|
|
181
|
+
pnpm ready
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
3. **Bump version**
|
|
185
|
+
```bash
|
|
186
|
+
# For patch releases (bug fixes)
|
|
187
|
+
npm version patch
|
|
188
|
+
|
|
189
|
+
# For minor releases (new features)
|
|
190
|
+
npm version minor
|
|
191
|
+
|
|
192
|
+
# For major releases (breaking changes)
|
|
193
|
+
npm version major
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
4. **Push the version commit and tag**
|
|
197
|
+
```bash
|
|
198
|
+
git push && git push --tags
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
5. **Publish to npm**
|
|
202
|
+
```bash
|
|
203
|
+
pnpm publish
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
6. **Create GitHub release**
|
|
207
|
+
```bash
|
|
208
|
+
# Create a release with automatically generated notes
|
|
209
|
+
gh release create v<version> \
|
|
210
|
+
--title "Phantom v<version>" \
|
|
211
|
+
--generate-notes \
|
|
212
|
+
--target main
|
|
213
|
+
|
|
214
|
+
# Example for v0.1.3:
|
|
215
|
+
gh release create v0.1.3 \
|
|
216
|
+
--title "Phantom v0.1.3" \
|
|
217
|
+
--generate-notes \
|
|
218
|
+
--target main
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The build process is automatically handled by the `prepublishOnly` script, which:
|
|
222
|
+
- Runs all tests and checks
|
|
223
|
+
- Builds the TypeScript source to JavaScript using esbuild
|
|
224
|
+
- Creates bundled executables in the `dist/` directory
|
|
225
|
+
|
|
226
|
+
**Note**: The `dist/` directory is git-ignored and only created during the publish process.
|
|
227
|
+
|
|
168
228
|
## 🤝 Contributing
|
|
169
229
|
|
|
170
230
|
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
package/dist/garden.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/bin/garden.ts
|
|
4
|
-
import { argv, exit as
|
|
4
|
+
import { argv, exit as exit5 } from "node:process";
|
|
5
5
|
|
|
6
6
|
// src/gardens/commands/create.ts
|
|
7
|
-
import { access, mkdir } from "node:fs/promises";
|
|
8
|
-
import { join } from "node:path";
|
|
9
|
-
import { exit } from "node:process";
|
|
7
|
+
import { access as access2, mkdir } from "node:fs/promises";
|
|
8
|
+
import { join as join2 } from "node:path";
|
|
9
|
+
import { exit as exit3 } from "node:process";
|
|
10
10
|
|
|
11
11
|
// src/git/libs/add-worktree.ts
|
|
12
12
|
import { exec } from "node:child_process";
|
|
@@ -26,6 +26,98 @@ async function getGitRoot() {
|
|
|
26
26
|
return stdout.trim();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// src/phantom/command/shell.ts
|
|
30
|
+
import { spawn } from "node:child_process";
|
|
31
|
+
import { exit as exit2 } from "node:process";
|
|
32
|
+
|
|
33
|
+
// src/gardens/commands/where.ts
|
|
34
|
+
import { access } from "node:fs/promises";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
import { exit } from "node:process";
|
|
37
|
+
async function whereGarden(name) {
|
|
38
|
+
if (!name) {
|
|
39
|
+
return { success: false, message: "Error: garden name required" };
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const gitRoot = await getGitRoot();
|
|
43
|
+
const gardensPath = join(gitRoot, ".git", "phantom", "gardens");
|
|
44
|
+
const gardenPath = join(gardensPath, name);
|
|
45
|
+
try {
|
|
46
|
+
await access(gardenPath);
|
|
47
|
+
} catch {
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
message: `Error: Garden '${name}' does not exist`
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
success: true,
|
|
55
|
+
path: gardenPath
|
|
56
|
+
};
|
|
57
|
+
} catch (error) {
|
|
58
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
message: `Error locating garden: ${errorMessage}`
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async function gardensWhereHandler(args2) {
|
|
66
|
+
const name = args2[0];
|
|
67
|
+
const result = await whereGarden(name);
|
|
68
|
+
if (!result.success) {
|
|
69
|
+
console.error(result.message);
|
|
70
|
+
exit(1);
|
|
71
|
+
}
|
|
72
|
+
console.log(result.path);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/phantom/command/shell.ts
|
|
76
|
+
async function shellInGarden(gardenName) {
|
|
77
|
+
if (!gardenName) {
|
|
78
|
+
return { success: false, message: "Error: garden name required" };
|
|
79
|
+
}
|
|
80
|
+
const gardenResult = await whereGarden(gardenName);
|
|
81
|
+
if (!gardenResult.success) {
|
|
82
|
+
return { success: false, message: gardenResult.message };
|
|
83
|
+
}
|
|
84
|
+
const gardenPath = gardenResult.path;
|
|
85
|
+
const shell = process.env.SHELL || "/bin/sh";
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
const childProcess = spawn(shell, [], {
|
|
88
|
+
cwd: gardenPath,
|
|
89
|
+
stdio: "inherit",
|
|
90
|
+
env: {
|
|
91
|
+
...process.env,
|
|
92
|
+
// Add environment variable to indicate we're in a phantom garden
|
|
93
|
+
PHANTOM_GARDEN: gardenName,
|
|
94
|
+
PHANTOM_GARDEN_PATH: gardenPath
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
childProcess.on("error", (error) => {
|
|
98
|
+
resolve({
|
|
99
|
+
success: false,
|
|
100
|
+
message: `Error starting shell: ${error.message}`
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
childProcess.on("exit", (code, signal) => {
|
|
104
|
+
if (signal) {
|
|
105
|
+
resolve({
|
|
106
|
+
success: false,
|
|
107
|
+
message: `Shell terminated by signal: ${signal}`,
|
|
108
|
+
exitCode: 128 + (signal === "SIGTERM" ? 15 : 1)
|
|
109
|
+
});
|
|
110
|
+
} else {
|
|
111
|
+
const exitCode = code ?? 0;
|
|
112
|
+
resolve({
|
|
113
|
+
success: exitCode === 0,
|
|
114
|
+
exitCode
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
29
121
|
// src/gardens/commands/create.ts
|
|
30
122
|
async function createGarden(name) {
|
|
31
123
|
if (!name) {
|
|
@@ -33,15 +125,15 @@ async function createGarden(name) {
|
|
|
33
125
|
}
|
|
34
126
|
try {
|
|
35
127
|
const gitRoot = await getGitRoot();
|
|
36
|
-
const gardensPath =
|
|
37
|
-
const worktreePath =
|
|
128
|
+
const gardensPath = join2(gitRoot, ".git", "phantom", "gardens");
|
|
129
|
+
const worktreePath = join2(gardensPath, name);
|
|
38
130
|
try {
|
|
39
|
-
await
|
|
131
|
+
await access2(gardensPath);
|
|
40
132
|
} catch {
|
|
41
133
|
await mkdir(gardensPath, { recursive: true });
|
|
42
134
|
}
|
|
43
135
|
try {
|
|
44
|
-
await
|
|
136
|
+
await access2(worktreePath);
|
|
45
137
|
return {
|
|
46
138
|
success: false,
|
|
47
139
|
message: `Error: garden '${name}' already exists`
|
|
@@ -50,7 +142,7 @@ async function createGarden(name) {
|
|
|
50
142
|
}
|
|
51
143
|
await addWorktree({
|
|
52
144
|
path: worktreePath,
|
|
53
|
-
branch:
|
|
145
|
+
branch: name,
|
|
54
146
|
commitish: "HEAD"
|
|
55
147
|
});
|
|
56
148
|
return {
|
|
@@ -68,19 +160,33 @@ async function createGarden(name) {
|
|
|
68
160
|
}
|
|
69
161
|
async function gardensCreateHandler(args2) {
|
|
70
162
|
const name = args2[0];
|
|
163
|
+
const openShell = args2.includes("--shell");
|
|
71
164
|
const result = await createGarden(name);
|
|
72
165
|
if (!result.success) {
|
|
73
166
|
console.error(result.message);
|
|
74
|
-
|
|
167
|
+
exit3(1);
|
|
75
168
|
}
|
|
76
169
|
console.log(result.message);
|
|
170
|
+
if (openShell && result.path) {
|
|
171
|
+
console.log(`
|
|
172
|
+
Entering garden '${name}' at ${result.path}`);
|
|
173
|
+
console.log("Type 'exit' to return to your original directory\n");
|
|
174
|
+
const shellResult = await shellInGarden(name);
|
|
175
|
+
if (!shellResult.success) {
|
|
176
|
+
if (shellResult.message) {
|
|
177
|
+
console.error(shellResult.message);
|
|
178
|
+
}
|
|
179
|
+
exit3(shellResult.exitCode ?? 1);
|
|
180
|
+
}
|
|
181
|
+
exit3(shellResult.exitCode ?? 0);
|
|
182
|
+
}
|
|
77
183
|
}
|
|
78
184
|
|
|
79
185
|
// src/gardens/commands/delete.ts
|
|
80
186
|
import { exec as exec3 } from "node:child_process";
|
|
81
|
-
import { access as
|
|
82
|
-
import { join as
|
|
83
|
-
import { exit as
|
|
187
|
+
import { access as access3 } from "node:fs/promises";
|
|
188
|
+
import { join as join3 } from "node:path";
|
|
189
|
+
import { exit as exit4 } from "node:process";
|
|
84
190
|
import { promisify as promisify3 } from "node:util";
|
|
85
191
|
var execAsync3 = promisify3(exec3);
|
|
86
192
|
async function deleteGarden(name, options = {}) {
|
|
@@ -90,10 +196,10 @@ async function deleteGarden(name, options = {}) {
|
|
|
90
196
|
const { force = false } = options;
|
|
91
197
|
try {
|
|
92
198
|
const gitRoot = await getGitRoot();
|
|
93
|
-
const gardensPath =
|
|
94
|
-
const gardenPath =
|
|
199
|
+
const gardensPath = join3(gitRoot, ".git", "phantom", "gardens");
|
|
200
|
+
const gardenPath = join3(gardensPath, name);
|
|
95
201
|
try {
|
|
96
|
-
await
|
|
202
|
+
await access3(gardenPath);
|
|
97
203
|
} catch {
|
|
98
204
|
return {
|
|
99
205
|
success: false,
|
|
@@ -172,23 +278,23 @@ async function gardensDeleteHandler(args2) {
|
|
|
172
278
|
const result = await deleteGarden(name, { force });
|
|
173
279
|
if (!result.success) {
|
|
174
280
|
console.error(result.message);
|
|
175
|
-
|
|
281
|
+
exit4(1);
|
|
176
282
|
}
|
|
177
283
|
console.log(result.message);
|
|
178
284
|
}
|
|
179
285
|
|
|
180
286
|
// src/gardens/commands/list.ts
|
|
181
287
|
import { exec as exec4 } from "node:child_process";
|
|
182
|
-
import { access as
|
|
183
|
-
import { join as
|
|
288
|
+
import { access as access4, readdir } from "node:fs/promises";
|
|
289
|
+
import { join as join4 } from "node:path";
|
|
184
290
|
import { promisify as promisify4 } from "node:util";
|
|
185
291
|
var execAsync4 = promisify4(exec4);
|
|
186
292
|
async function listGardens() {
|
|
187
293
|
try {
|
|
188
294
|
const gitRoot = await getGitRoot();
|
|
189
|
-
const gardensPath =
|
|
295
|
+
const gardensPath = join4(gitRoot, ".git", "phantom", "gardens");
|
|
190
296
|
try {
|
|
191
|
-
await
|
|
297
|
+
await access4(gardensPath);
|
|
192
298
|
} catch {
|
|
193
299
|
return {
|
|
194
300
|
success: true,
|
|
@@ -202,8 +308,8 @@ async function listGardens() {
|
|
|
202
308
|
const validEntries = await Promise.all(
|
|
203
309
|
entries.map(async (entry) => {
|
|
204
310
|
try {
|
|
205
|
-
const entryPath =
|
|
206
|
-
await
|
|
311
|
+
const entryPath = join4(gardensPath, entry);
|
|
312
|
+
await access4(entryPath);
|
|
207
313
|
return entry;
|
|
208
314
|
} catch {
|
|
209
315
|
return null;
|
|
@@ -229,7 +335,7 @@ async function listGardens() {
|
|
|
229
335
|
}
|
|
230
336
|
const gardens = await Promise.all(
|
|
231
337
|
gardenNames.map(async (name) => {
|
|
232
|
-
const gardenPath =
|
|
338
|
+
const gardenPath = join4(gardensPath, name);
|
|
233
339
|
let branch = "unknown";
|
|
234
340
|
try {
|
|
235
341
|
const { stdout } = await execAsync4("git branch --show-current", {
|
|
@@ -294,48 +400,6 @@ async function gardensListHandler() {
|
|
|
294
400
|
Total: ${result.gardens.length} gardens`);
|
|
295
401
|
}
|
|
296
402
|
|
|
297
|
-
// src/gardens/commands/where.ts
|
|
298
|
-
import { access as access4 } from "node:fs/promises";
|
|
299
|
-
import { join as join4 } from "node:path";
|
|
300
|
-
import { exit as exit3 } from "node:process";
|
|
301
|
-
async function whereGarden(name) {
|
|
302
|
-
if (!name) {
|
|
303
|
-
return { success: false, message: "Error: garden name required" };
|
|
304
|
-
}
|
|
305
|
-
try {
|
|
306
|
-
const gitRoot = await getGitRoot();
|
|
307
|
-
const gardensPath = join4(gitRoot, ".git", "phantom", "gardens");
|
|
308
|
-
const gardenPath = join4(gardensPath, name);
|
|
309
|
-
try {
|
|
310
|
-
await access4(gardenPath);
|
|
311
|
-
} catch {
|
|
312
|
-
return {
|
|
313
|
-
success: false,
|
|
314
|
-
message: `Error: Garden '${name}' does not exist`
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
return {
|
|
318
|
-
success: true,
|
|
319
|
-
path: gardenPath
|
|
320
|
-
};
|
|
321
|
-
} catch (error) {
|
|
322
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
323
|
-
return {
|
|
324
|
-
success: false,
|
|
325
|
-
message: `Error locating garden: ${errorMessage}`
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
async function gardensWhereHandler(args2) {
|
|
330
|
-
const name = args2[0];
|
|
331
|
-
const result = await whereGarden(name);
|
|
332
|
-
if (!result.success) {
|
|
333
|
-
console.error(result.message);
|
|
334
|
-
exit3(1);
|
|
335
|
-
}
|
|
336
|
-
console.log(result.path);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
403
|
// src/bin/garden.ts
|
|
340
404
|
var commands = [
|
|
341
405
|
{
|
|
@@ -373,14 +437,14 @@ function findCommand(cmdName, commands2) {
|
|
|
373
437
|
var args = argv.slice(2);
|
|
374
438
|
if (args.length === 0 || args[0] === "-h" || args[0] === "--help") {
|
|
375
439
|
printHelp();
|
|
376
|
-
|
|
440
|
+
exit5(0);
|
|
377
441
|
}
|
|
378
442
|
var command = findCommand(args[0], commands);
|
|
379
443
|
if (!command || !command.handler) {
|
|
380
444
|
console.error(`Error: Unknown command '${args[0]}'
|
|
381
445
|
`);
|
|
382
446
|
printHelp();
|
|
383
|
-
|
|
447
|
+
exit5(1);
|
|
384
448
|
}
|
|
385
449
|
try {
|
|
386
450
|
await command.handler(args.slice(1));
|
|
@@ -389,6 +453,6 @@ try {
|
|
|
389
453
|
"Error:",
|
|
390
454
|
error instanceof Error ? error.message : String(error)
|
|
391
455
|
);
|
|
392
|
-
|
|
456
|
+
exit5(1);
|
|
393
457
|
}
|
|
394
458
|
//# sourceMappingURL=garden.js.map
|
package/dist/garden.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/bin/garden.ts", "../src/gardens/commands/create.ts", "../src/git/libs/add-worktree.ts", "../src/git/libs/get-git-root.ts", "../src/gardens/commands/
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { gardensCreateHandler } from \"../gardens/commands/create.ts\";\nimport { gardensDeleteHandler } from \"../gardens/commands/delete.ts\";\nimport { gardensListHandler } from \"../gardens/commands/list.ts\";\nimport { gardensWhereHandler } from \"../gardens/commands/where.ts\";\n\ninterface Command {\n name: string;\n description: string;\n handler?: (args: string[]) => void | Promise<void>;\n}\n\nconst commands: Command[] = [\n {\n name: \"create\",\n description: \"Create a new worktree (garden)\",\n handler: gardensCreateHandler,\n },\n {\n name: \"list\",\n description: \"List all gardens\",\n handler: gardensListHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific garden\",\n handler: gardensWhereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a garden (use --force for dirty gardens)\",\n handler: gardensDeleteHandler,\n },\n];\n\nfunction printHelp() {\n console.log(\"Usage: garden <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${cmd.name.padEnd(20)} ${cmd.description}`);\n }\n console.log(\"\\nThis is an alias for 'phantom garden' commands.\");\n}\n\nfunction findCommand(cmdName: string, commands: Command[]): Command | null {\n return commands.find((cmd) => cmd.name === cmdName) || null;\n}\n\nconst args = argv.slice(2);\n\nif (args.length === 0 || args[0] === \"-h\" || args[0] === \"--help\") {\n printHelp();\n exit(0);\n}\n\nconst command = findCommand(args[0], commands);\n\nif (!command || !command.handler) {\n console.error(`Error: Unknown command '${args[0]}'\\n`);\n printHelp();\n exit(1);\n}\n\ntry {\n await command.handler(args.slice(1));\n} catch (error) {\n console.error(\n \"Error:\",\n error instanceof Error ? error.message : String(error),\n );\n exit(1);\n}\n", "import { access, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { addWorktree } from \"../../git/libs/add-worktree.ts\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function createGarden(name: string): Promise<{\n success: boolean;\n message: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const worktreePath = join(gardensPath, name);\n\n try {\n await access(gardensPath);\n } catch {\n await mkdir(gardensPath, { recursive: true });\n }\n\n try {\n await access(worktreePath);\n return {\n success: false,\n message: `Error: garden '${name}' already exists`,\n };\n } catch {\n // Path doesn't exist, which is what we want\n }\n\n await addWorktree({\n path: worktreePath,\n branch: `phantom/gardens/${name}`,\n commitish: \"HEAD\",\n });\n\n return {\n success: true,\n message: `Created garden '${name}' at ${worktreePath}`,\n path: worktreePath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error creating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensCreateHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await createGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport interface AddWorktreeOptions {\n path: string;\n branch: string;\n commitish?: string;\n}\n\nexport async function addWorktree(options: AddWorktreeOptions): Promise<void> {\n const { path, branch, commitish = \"HEAD\" } = options;\n\n await execAsync(`git worktree add \"${path}\" -b \"${branch}\" ${commitish}`);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await execAsync(\"git rev-parse --show-toplevel\");\n return stdout.trim();\n}\n", "import { exec } from \"node:child_process\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport async function deleteGarden(\n name: string,\n options: { force?: boolean } = {},\n): Promise<{\n success: boolean;\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n const { force = false } = options;\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n // Check for uncommitted changes\n let hasUncommittedChanges = false;\n let changedFiles = 0;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n hasUncommittedChanges = true;\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume no changes\n hasUncommittedChanges = false;\n }\n\n // If garden has uncommitted changes and --force is not specified, refuse deletion\n if (hasUncommittedChanges && !force) {\n return {\n success: false,\n message: `Error: Garden '${name}' has uncommitted changes (${changedFiles} files). Use --force to delete anyway.`,\n hasUncommittedChanges: true,\n changedFiles,\n };\n }\n\n // Remove git worktree\n try {\n await execAsync(`git worktree remove \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch (error) {\n // If worktree remove fails, try force removal\n try {\n await execAsync(`git worktree remove --force \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch {\n return {\n success: false,\n message: `Error: Failed to remove worktree for garden '${name}'`,\n };\n }\n }\n\n // Delete associated branch\n const branchName = `phantom/gardens/${name}`;\n try {\n await execAsync(`git branch -D \"${branchName}\"`, {\n cwd: gitRoot,\n });\n } catch {\n // Branch might not exist or already deleted - this is not an error\n // We'll still report success for the worktree removal\n }\n\n let message = `Deleted garden '${name}' and its branch '${branchName}'`;\n if (hasUncommittedChanges) {\n message = `Warning: Garden '${name}' had uncommitted changes (${changedFiles} files)\\n${message}`;\n }\n\n return {\n success: true,\n message,\n hasUncommittedChanges,\n changedFiles: hasUncommittedChanges ? changedFiles : undefined,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error deleting garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensDeleteHandler(args: string[]): Promise<void> {\n // Parse arguments for --force flag\n const forceIndex = args.indexOf(\"--force\");\n const force = forceIndex !== -1;\n\n // Remove --force from args to get the garden name\n const filteredArgs = args.filter((arg) => arg !== \"--force\");\n const name = filteredArgs[0];\n\n const result = await deleteGarden(name, { force });\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { access, readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport interface GardenInfo {\n name: string;\n branch: string;\n status: \"clean\" | \"dirty\";\n changedFiles?: number;\n}\n\nexport async function listGardens(): Promise<{\n success: boolean;\n message?: string;\n gardens?: GardenInfo[];\n}> {\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n\n // Check if gardens directory exists\n try {\n await access(gardensPath);\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (gardens directory doesn't exist)\",\n };\n }\n\n // Read gardens directory\n let gardenNames: string[];\n try {\n const entries = await readdir(gardensPath);\n // Filter entries to only include directories\n const validEntries = await Promise.all(\n entries.map(async (entry) => {\n try {\n const entryPath = join(gardensPath, entry);\n await access(entryPath);\n return entry;\n } catch {\n return null;\n }\n }),\n );\n gardenNames = validEntries.filter(\n (entry): entry is string => entry !== null,\n );\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (unable to read gardens directory)\",\n };\n }\n\n if (gardenNames.length === 0) {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found\",\n };\n }\n\n // Get detailed information for each garden\n const gardens: GardenInfo[] = await Promise.all(\n gardenNames.map(async (name) => {\n const gardenPath = join(gardensPath, name);\n\n // Get current branch\n let branch = \"unknown\";\n try {\n const { stdout } = await execAsync(\"git branch --show-current\", {\n cwd: gardenPath,\n });\n branch = stdout.trim() || \"detached HEAD\";\n } catch {\n branch = \"unknown\";\n }\n\n // Get working directory status\n let status: \"clean\" | \"dirty\" = \"clean\";\n let changedFiles: number | undefined;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n status = \"dirty\";\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume unknown status\n status = \"clean\";\n }\n\n return {\n name,\n branch,\n status,\n changedFiles,\n };\n }),\n );\n\n return {\n success: true,\n gardens,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error listing gardens: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensListHandler(): Promise<void> {\n const result = await listGardens();\n\n if (!result.success) {\n console.error(result.message);\n return;\n }\n\n if (!result.gardens || result.gardens.length === 0) {\n console.log(result.message || \"No gardens found\");\n return;\n }\n\n console.log(\"Gardens:\");\n for (const garden of result.gardens) {\n const statusText =\n garden.status === \"clean\"\n ? \"[clean]\"\n : `[dirty: ${garden.changedFiles} files]`;\n\n console.log(\n ` ${garden.name.padEnd(20)} (branch: ${garden.branch.padEnd(20)}) ${statusText}`,\n );\n }\n\n console.log(`\\nTotal: ${result.gardens.length} gardens`);\n}\n", "import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function whereGarden(name: string): Promise<{\n success: boolean;\n message?: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n return {\n success: true,\n path: gardenPath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error locating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensWhereHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await whereGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.path);\n}\n"],
|
|
5
|
-
"mappings": ";;;AAEA,SAAS,MAAM,QAAAA,aAAY;;;ACF3B,SAAS,
|
|
6
|
-
"names": ["exit", "
|
|
3
|
+
"sources": ["../src/bin/garden.ts", "../src/gardens/commands/create.ts", "../src/git/libs/add-worktree.ts", "../src/git/libs/get-git-root.ts", "../src/phantom/command/shell.ts", "../src/gardens/commands/where.ts", "../src/gardens/commands/delete.ts", "../src/gardens/commands/list.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { gardensCreateHandler } from \"../gardens/commands/create.ts\";\nimport { gardensDeleteHandler } from \"../gardens/commands/delete.ts\";\nimport { gardensListHandler } from \"../gardens/commands/list.ts\";\nimport { gardensWhereHandler } from \"../gardens/commands/where.ts\";\n\ninterface Command {\n name: string;\n description: string;\n handler?: (args: string[]) => void | Promise<void>;\n}\n\nconst commands: Command[] = [\n {\n name: \"create\",\n description: \"Create a new worktree (garden)\",\n handler: gardensCreateHandler,\n },\n {\n name: \"list\",\n description: \"List all gardens\",\n handler: gardensListHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific garden\",\n handler: gardensWhereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a garden (use --force for dirty gardens)\",\n handler: gardensDeleteHandler,\n },\n];\n\nfunction printHelp() {\n console.log(\"Usage: garden <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${cmd.name.padEnd(20)} ${cmd.description}`);\n }\n console.log(\"\\nThis is an alias for 'phantom garden' commands.\");\n}\n\nfunction findCommand(cmdName: string, commands: Command[]): Command | null {\n return commands.find((cmd) => cmd.name === cmdName) || null;\n}\n\nconst args = argv.slice(2);\n\nif (args.length === 0 || args[0] === \"-h\" || args[0] === \"--help\") {\n printHelp();\n exit(0);\n}\n\nconst command = findCommand(args[0], commands);\n\nif (!command || !command.handler) {\n console.error(`Error: Unknown command '${args[0]}'\\n`);\n printHelp();\n exit(1);\n}\n\ntry {\n await command.handler(args.slice(1));\n} catch (error) {\n console.error(\n \"Error:\",\n error instanceof Error ? error.message : String(error),\n );\n exit(1);\n}\n", "import { access, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { addWorktree } from \"../../git/libs/add-worktree.ts\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\nimport { shellInGarden } from \"../../phantom/command/shell.ts\";\n\nexport async function createGarden(name: string): Promise<{\n success: boolean;\n message: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const worktreePath = join(gardensPath, name);\n\n try {\n await access(gardensPath);\n } catch {\n await mkdir(gardensPath, { recursive: true });\n }\n\n try {\n await access(worktreePath);\n return {\n success: false,\n message: `Error: garden '${name}' already exists`,\n };\n } catch {\n // Path doesn't exist, which is what we want\n }\n\n await addWorktree({\n path: worktreePath,\n branch: name,\n commitish: \"HEAD\",\n });\n\n return {\n success: true,\n message: `Created garden '${name}' at ${worktreePath}`,\n path: worktreePath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error creating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensCreateHandler(args: string[]): Promise<void> {\n const name = args[0];\n const openShell = args.includes(\"--shell\");\n\n const result = await createGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n\n if (openShell && result.path) {\n console.log(`\\nEntering garden '${name}' at ${result.path}`);\n console.log(\"Type 'exit' to return to your original directory\\n\");\n\n const shellResult = await shellInGarden(name);\n\n if (!shellResult.success) {\n if (shellResult.message) {\n console.error(shellResult.message);\n }\n exit(shellResult.exitCode ?? 1);\n }\n\n exit(shellResult.exitCode ?? 0);\n }\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport interface AddWorktreeOptions {\n path: string;\n branch: string;\n commitish?: string;\n}\n\nexport async function addWorktree(options: AddWorktreeOptions): Promise<void> {\n const { path, branch, commitish = \"HEAD\" } = options;\n\n await execAsync(`git worktree add \"${path}\" -b \"${branch}\" ${commitish}`);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await execAsync(\"git rev-parse --show-toplevel\");\n return stdout.trim();\n}\n", "import { spawn } from \"node:child_process\";\nimport { exit } from \"node:process\";\nimport { whereGarden } from \"../../gardens/commands/where.ts\";\n\nexport async function shellInGarden(gardenName: string): Promise<{\n success: boolean;\n message?: string;\n exitCode?: number;\n}> {\n if (!gardenName) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n // Validate garden exists and get its path\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n return { success: false, message: gardenResult.message };\n }\n\n const gardenPath = gardenResult.path as string;\n // Use user's preferred shell or fallback to /bin/sh\n const shell = process.env.SHELL || \"/bin/sh\";\n\n return new Promise((resolve) => {\n const childProcess = spawn(shell, [], {\n cwd: gardenPath,\n stdio: \"inherit\",\n env: {\n ...process.env,\n // Add environment variable to indicate we're in a phantom garden\n PHANTOM_GARDEN: gardenName,\n PHANTOM_GARDEN_PATH: gardenPath,\n },\n });\n\n childProcess.on(\"error\", (error) => {\n resolve({\n success: false,\n message: `Error starting shell: ${error.message}`,\n });\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve({\n success: false,\n message: `Shell terminated by signal: ${signal}`,\n exitCode: 128 + (signal === \"SIGTERM\" ? 15 : 1),\n });\n } else {\n const exitCode = code ?? 0;\n resolve({\n success: exitCode === 0,\n exitCode,\n });\n }\n });\n });\n}\n\nexport async function shellHandler(args: string[]): Promise<void> {\n if (args.length < 1) {\n console.error(\"Usage: phantom shell <garden-name>\");\n exit(1);\n }\n\n const gardenName = args[0];\n\n // Get garden path for display\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n console.error(gardenResult.message);\n exit(1);\n }\n\n // Display entering message\n console.log(`Entering garden '${gardenName}' at ${gardenResult.path}`);\n console.log(\"Type 'exit' to return to your original directory\\n\");\n\n const result = await shellInGarden(gardenName);\n\n if (!result.success) {\n if (result.message) {\n console.error(result.message);\n }\n exit(result.exitCode ?? 1);\n }\n\n // Exit with the same code as the shell\n exit(result.exitCode ?? 0);\n}\n", "import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function whereGarden(name: string): Promise<{\n success: boolean;\n message?: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n return {\n success: true,\n path: gardenPath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error locating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensWhereHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await whereGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.path);\n}\n", "import { exec } from \"node:child_process\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport async function deleteGarden(\n name: string,\n options: { force?: boolean } = {},\n): Promise<{\n success: boolean;\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n const { force = false } = options;\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n // Check for uncommitted changes\n let hasUncommittedChanges = false;\n let changedFiles = 0;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n hasUncommittedChanges = true;\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume no changes\n hasUncommittedChanges = false;\n }\n\n // If garden has uncommitted changes and --force is not specified, refuse deletion\n if (hasUncommittedChanges && !force) {\n return {\n success: false,\n message: `Error: Garden '${name}' has uncommitted changes (${changedFiles} files). Use --force to delete anyway.`,\n hasUncommittedChanges: true,\n changedFiles,\n };\n }\n\n // Remove git worktree\n try {\n await execAsync(`git worktree remove \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch (error) {\n // If worktree remove fails, try force removal\n try {\n await execAsync(`git worktree remove --force \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch {\n return {\n success: false,\n message: `Error: Failed to remove worktree for garden '${name}'`,\n };\n }\n }\n\n // Delete associated branch\n const branchName = `phantom/gardens/${name}`;\n try {\n await execAsync(`git branch -D \"${branchName}\"`, {\n cwd: gitRoot,\n });\n } catch {\n // Branch might not exist or already deleted - this is not an error\n // We'll still report success for the worktree removal\n }\n\n let message = `Deleted garden '${name}' and its branch '${branchName}'`;\n if (hasUncommittedChanges) {\n message = `Warning: Garden '${name}' had uncommitted changes (${changedFiles} files)\\n${message}`;\n }\n\n return {\n success: true,\n message,\n hasUncommittedChanges,\n changedFiles: hasUncommittedChanges ? changedFiles : undefined,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error deleting garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensDeleteHandler(args: string[]): Promise<void> {\n // Parse arguments for --force flag\n const forceIndex = args.indexOf(\"--force\");\n const force = forceIndex !== -1;\n\n // Remove --force from args to get the garden name\n const filteredArgs = args.filter((arg) => arg !== \"--force\");\n const name = filteredArgs[0];\n\n const result = await deleteGarden(name, { force });\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { access, readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport interface GardenInfo {\n name: string;\n branch: string;\n status: \"clean\" | \"dirty\";\n changedFiles?: number;\n}\n\nexport async function listGardens(): Promise<{\n success: boolean;\n message?: string;\n gardens?: GardenInfo[];\n}> {\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n\n // Check if gardens directory exists\n try {\n await access(gardensPath);\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (gardens directory doesn't exist)\",\n };\n }\n\n // Read gardens directory\n let gardenNames: string[];\n try {\n const entries = await readdir(gardensPath);\n // Filter entries to only include directories\n const validEntries = await Promise.all(\n entries.map(async (entry) => {\n try {\n const entryPath = join(gardensPath, entry);\n await access(entryPath);\n return entry;\n } catch {\n return null;\n }\n }),\n );\n gardenNames = validEntries.filter(\n (entry): entry is string => entry !== null,\n );\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (unable to read gardens directory)\",\n };\n }\n\n if (gardenNames.length === 0) {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found\",\n };\n }\n\n // Get detailed information for each garden\n const gardens: GardenInfo[] = await Promise.all(\n gardenNames.map(async (name) => {\n const gardenPath = join(gardensPath, name);\n\n // Get current branch\n let branch = \"unknown\";\n try {\n const { stdout } = await execAsync(\"git branch --show-current\", {\n cwd: gardenPath,\n });\n branch = stdout.trim() || \"detached HEAD\";\n } catch {\n branch = \"unknown\";\n }\n\n // Get working directory status\n let status: \"clean\" | \"dirty\" = \"clean\";\n let changedFiles: number | undefined;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n status = \"dirty\";\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume unknown status\n status = \"clean\";\n }\n\n return {\n name,\n branch,\n status,\n changedFiles,\n };\n }),\n );\n\n return {\n success: true,\n gardens,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error listing gardens: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensListHandler(): Promise<void> {\n const result = await listGardens();\n\n if (!result.success) {\n console.error(result.message);\n return;\n }\n\n if (!result.gardens || result.gardens.length === 0) {\n console.log(result.message || \"No gardens found\");\n return;\n }\n\n console.log(\"Gardens:\");\n for (const garden of result.gardens) {\n const statusText =\n garden.status === \"clean\"\n ? \"[clean]\"\n : `[dirty: ${garden.changedFiles} files]`;\n\n console.log(\n ` ${garden.name.padEnd(20)} (branch: ${garden.branch.padEnd(20)}) ${statusText}`,\n );\n }\n\n console.log(`\\nTotal: ${result.gardens.length} gardens`);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["exit", "access", "join", "exit", "exec", "promisify", "execAsync", "exit", "args", "join", "access", "args", "exit", "exec", "access", "join", "exit", "promisify", "execAsync", "promisify", "exec", "join", "access", "args", "exit", "exec", "access", "join", "promisify", "execAsync", "promisify", "exec", "join", "access", "commands", "exit"]
|
|
7
7
|
}
|
package/dist/phantom.js
CHANGED
|
@@ -3,25 +3,37 @@
|
|
|
3
3
|
// src/bin/phantom.ts
|
|
4
4
|
import { argv, exit as exit6 } from "node:process";
|
|
5
5
|
|
|
6
|
-
// src/commands/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
// src/gardens/commands/where.ts
|
|
11
|
-
import { access } from "node:fs/promises";
|
|
12
|
-
import { join } from "node:path";
|
|
13
|
-
import { exit } from "node:process";
|
|
6
|
+
// src/gardens/commands/create.ts
|
|
7
|
+
import { access as access2, mkdir } from "node:fs/promises";
|
|
8
|
+
import { join as join2 } from "node:path";
|
|
9
|
+
import { exit as exit3 } from "node:process";
|
|
14
10
|
|
|
15
|
-
// src/git/libs/
|
|
11
|
+
// src/git/libs/add-worktree.ts
|
|
16
12
|
import { exec } from "node:child_process";
|
|
17
13
|
import { promisify } from "node:util";
|
|
18
14
|
var execAsync = promisify(exec);
|
|
15
|
+
async function addWorktree(options) {
|
|
16
|
+
const { path, branch, commitish = "HEAD" } = options;
|
|
17
|
+
await execAsync(`git worktree add "${path}" -b "${branch}" ${commitish}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// src/git/libs/get-git-root.ts
|
|
21
|
+
import { exec as exec2 } from "node:child_process";
|
|
22
|
+
import { promisify as promisify2 } from "node:util";
|
|
23
|
+
var execAsync2 = promisify2(exec2);
|
|
19
24
|
async function getGitRoot() {
|
|
20
|
-
const { stdout } = await
|
|
25
|
+
const { stdout } = await execAsync2("git rev-parse --show-toplevel");
|
|
21
26
|
return stdout.trim();
|
|
22
27
|
}
|
|
23
28
|
|
|
29
|
+
// src/phantom/command/shell.ts
|
|
30
|
+
import { spawn } from "node:child_process";
|
|
31
|
+
import { exit as exit2 } from "node:process";
|
|
32
|
+
|
|
24
33
|
// src/gardens/commands/where.ts
|
|
34
|
+
import { access } from "node:fs/promises";
|
|
35
|
+
import { join } from "node:path";
|
|
36
|
+
import { exit } from "node:process";
|
|
25
37
|
async function whereGarden(name) {
|
|
26
38
|
if (!name) {
|
|
27
39
|
return { success: false, message: "Error: garden name required" };
|
|
@@ -60,68 +72,7 @@ async function gardensWhereHandler(args2) {
|
|
|
60
72
|
console.log(result.path);
|
|
61
73
|
}
|
|
62
74
|
|
|
63
|
-
// src/
|
|
64
|
-
async function execInGarden(gardenName, command2) {
|
|
65
|
-
if (!gardenName) {
|
|
66
|
-
return { success: false, message: "Error: garden name required" };
|
|
67
|
-
}
|
|
68
|
-
if (!command2 || command2.length === 0) {
|
|
69
|
-
return { success: false, message: "Error: command required" };
|
|
70
|
-
}
|
|
71
|
-
const gardenResult = await whereGarden(gardenName);
|
|
72
|
-
if (!gardenResult.success) {
|
|
73
|
-
return { success: false, message: gardenResult.message };
|
|
74
|
-
}
|
|
75
|
-
const gardenPath = gardenResult.path;
|
|
76
|
-
const [cmd, ...args2] = command2;
|
|
77
|
-
return new Promise((resolve) => {
|
|
78
|
-
const childProcess = spawn(cmd, args2, {
|
|
79
|
-
cwd: gardenPath,
|
|
80
|
-
stdio: "inherit"
|
|
81
|
-
});
|
|
82
|
-
childProcess.on("error", (error) => {
|
|
83
|
-
resolve({
|
|
84
|
-
success: false,
|
|
85
|
-
message: `Error executing command: ${error.message}`
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
childProcess.on("exit", (code, signal) => {
|
|
89
|
-
if (signal) {
|
|
90
|
-
resolve({
|
|
91
|
-
success: false,
|
|
92
|
-
message: `Command terminated by signal: ${signal}`,
|
|
93
|
-
exitCode: 128 + (signal === "SIGTERM" ? 15 : 1)
|
|
94
|
-
});
|
|
95
|
-
} else {
|
|
96
|
-
const exitCode = code ?? 0;
|
|
97
|
-
resolve({
|
|
98
|
-
success: exitCode === 0,
|
|
99
|
-
exitCode
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
async function execHandler(args2) {
|
|
106
|
-
if (args2.length < 2) {
|
|
107
|
-
console.error("Usage: phantom exec <garden-name> <command> [args...]");
|
|
108
|
-
exit2(1);
|
|
109
|
-
}
|
|
110
|
-
const gardenName = args2[0];
|
|
111
|
-
const command2 = args2.slice(1);
|
|
112
|
-
const result = await execInGarden(gardenName, command2);
|
|
113
|
-
if (!result.success) {
|
|
114
|
-
if (result.message) {
|
|
115
|
-
console.error(result.message);
|
|
116
|
-
}
|
|
117
|
-
exit2(result.exitCode ?? 1);
|
|
118
|
-
}
|
|
119
|
-
exit2(result.exitCode ?? 0);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/commands/shell.ts
|
|
123
|
-
import { spawn as spawn2 } from "node:child_process";
|
|
124
|
-
import { exit as exit3 } from "node:process";
|
|
75
|
+
// src/phantom/command/shell.ts
|
|
125
76
|
async function shellInGarden(gardenName) {
|
|
126
77
|
if (!gardenName) {
|
|
127
78
|
return { success: false, message: "Error: garden name required" };
|
|
@@ -133,7 +84,7 @@ async function shellInGarden(gardenName) {
|
|
|
133
84
|
const gardenPath = gardenResult.path;
|
|
134
85
|
const shell = process.env.SHELL || "/bin/sh";
|
|
135
86
|
return new Promise((resolve) => {
|
|
136
|
-
const childProcess =
|
|
87
|
+
const childProcess = spawn(shell, [], {
|
|
137
88
|
cwd: gardenPath,
|
|
138
89
|
stdio: "inherit",
|
|
139
90
|
env: {
|
|
@@ -169,13 +120,13 @@ async function shellInGarden(gardenName) {
|
|
|
169
120
|
async function shellHandler(args2) {
|
|
170
121
|
if (args2.length < 1) {
|
|
171
122
|
console.error("Usage: phantom shell <garden-name>");
|
|
172
|
-
|
|
123
|
+
exit2(1);
|
|
173
124
|
}
|
|
174
125
|
const gardenName = args2[0];
|
|
175
126
|
const gardenResult = await whereGarden(gardenName);
|
|
176
127
|
if (!gardenResult.success) {
|
|
177
128
|
console.error(gardenResult.message);
|
|
178
|
-
|
|
129
|
+
exit2(1);
|
|
179
130
|
}
|
|
180
131
|
console.log(`Entering garden '${gardenName}' at ${gardenResult.path}`);
|
|
181
132
|
console.log("Type 'exit' to return to your original directory\n");
|
|
@@ -184,23 +135,9 @@ async function shellHandler(args2) {
|
|
|
184
135
|
if (result.message) {
|
|
185
136
|
console.error(result.message);
|
|
186
137
|
}
|
|
187
|
-
|
|
138
|
+
exit2(result.exitCode ?? 1);
|
|
188
139
|
}
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/gardens/commands/create.ts
|
|
193
|
-
import { access as access2, mkdir } from "node:fs/promises";
|
|
194
|
-
import { join as join2 } from "node:path";
|
|
195
|
-
import { exit as exit4 } from "node:process";
|
|
196
|
-
|
|
197
|
-
// src/git/libs/add-worktree.ts
|
|
198
|
-
import { exec as exec2 } from "node:child_process";
|
|
199
|
-
import { promisify as promisify2 } from "node:util";
|
|
200
|
-
var execAsync2 = promisify2(exec2);
|
|
201
|
-
async function addWorktree(options) {
|
|
202
|
-
const { path, branch, commitish = "HEAD" } = options;
|
|
203
|
-
await execAsync2(`git worktree add "${path}" -b "${branch}" ${commitish}`);
|
|
140
|
+
exit2(result.exitCode ?? 0);
|
|
204
141
|
}
|
|
205
142
|
|
|
206
143
|
// src/gardens/commands/create.ts
|
|
@@ -227,7 +164,7 @@ async function createGarden(name) {
|
|
|
227
164
|
}
|
|
228
165
|
await addWorktree({
|
|
229
166
|
path: worktreePath,
|
|
230
|
-
branch:
|
|
167
|
+
branch: name,
|
|
231
168
|
commitish: "HEAD"
|
|
232
169
|
});
|
|
233
170
|
return {
|
|
@@ -245,19 +182,33 @@ async function createGarden(name) {
|
|
|
245
182
|
}
|
|
246
183
|
async function gardensCreateHandler(args2) {
|
|
247
184
|
const name = args2[0];
|
|
185
|
+
const openShell = args2.includes("--shell");
|
|
248
186
|
const result = await createGarden(name);
|
|
249
187
|
if (!result.success) {
|
|
250
188
|
console.error(result.message);
|
|
251
|
-
|
|
189
|
+
exit3(1);
|
|
252
190
|
}
|
|
253
191
|
console.log(result.message);
|
|
192
|
+
if (openShell && result.path) {
|
|
193
|
+
console.log(`
|
|
194
|
+
Entering garden '${name}' at ${result.path}`);
|
|
195
|
+
console.log("Type 'exit' to return to your original directory\n");
|
|
196
|
+
const shellResult = await shellInGarden(name);
|
|
197
|
+
if (!shellResult.success) {
|
|
198
|
+
if (shellResult.message) {
|
|
199
|
+
console.error(shellResult.message);
|
|
200
|
+
}
|
|
201
|
+
exit3(shellResult.exitCode ?? 1);
|
|
202
|
+
}
|
|
203
|
+
exit3(shellResult.exitCode ?? 0);
|
|
204
|
+
}
|
|
254
205
|
}
|
|
255
206
|
|
|
256
207
|
// src/gardens/commands/delete.ts
|
|
257
208
|
import { exec as exec3 } from "node:child_process";
|
|
258
209
|
import { access as access3 } from "node:fs/promises";
|
|
259
210
|
import { join as join3 } from "node:path";
|
|
260
|
-
import { exit as
|
|
211
|
+
import { exit as exit4 } from "node:process";
|
|
261
212
|
import { promisify as promisify3 } from "node:util";
|
|
262
213
|
var execAsync3 = promisify3(exec3);
|
|
263
214
|
async function deleteGarden(name, options = {}) {
|
|
@@ -349,7 +300,7 @@ async function gardensDeleteHandler(args2) {
|
|
|
349
300
|
const result = await deleteGarden(name, { force });
|
|
350
301
|
if (!result.success) {
|
|
351
302
|
console.error(result.message);
|
|
352
|
-
|
|
303
|
+
exit4(1);
|
|
353
304
|
}
|
|
354
305
|
console.log(result.message);
|
|
355
306
|
}
|
|
@@ -471,6 +422,67 @@ async function gardensListHandler() {
|
|
|
471
422
|
Total: ${result.gardens.length} gardens`);
|
|
472
423
|
}
|
|
473
424
|
|
|
425
|
+
// src/phantom/command/exec.ts
|
|
426
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
427
|
+
import { exit as exit5 } from "node:process";
|
|
428
|
+
async function execInGarden(gardenName, command2) {
|
|
429
|
+
if (!gardenName) {
|
|
430
|
+
return { success: false, message: "Error: garden name required" };
|
|
431
|
+
}
|
|
432
|
+
if (!command2 || command2.length === 0) {
|
|
433
|
+
return { success: false, message: "Error: command required" };
|
|
434
|
+
}
|
|
435
|
+
const gardenResult = await whereGarden(gardenName);
|
|
436
|
+
if (!gardenResult.success) {
|
|
437
|
+
return { success: false, message: gardenResult.message };
|
|
438
|
+
}
|
|
439
|
+
const gardenPath = gardenResult.path;
|
|
440
|
+
const [cmd, ...args2] = command2;
|
|
441
|
+
return new Promise((resolve) => {
|
|
442
|
+
const childProcess = spawn2(cmd, args2, {
|
|
443
|
+
cwd: gardenPath,
|
|
444
|
+
stdio: "inherit"
|
|
445
|
+
});
|
|
446
|
+
childProcess.on("error", (error) => {
|
|
447
|
+
resolve({
|
|
448
|
+
success: false,
|
|
449
|
+
message: `Error executing command: ${error.message}`
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
childProcess.on("exit", (code, signal) => {
|
|
453
|
+
if (signal) {
|
|
454
|
+
resolve({
|
|
455
|
+
success: false,
|
|
456
|
+
message: `Command terminated by signal: ${signal}`,
|
|
457
|
+
exitCode: 128 + (signal === "SIGTERM" ? 15 : 1)
|
|
458
|
+
});
|
|
459
|
+
} else {
|
|
460
|
+
const exitCode = code ?? 0;
|
|
461
|
+
resolve({
|
|
462
|
+
success: exitCode === 0,
|
|
463
|
+
exitCode
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
async function execHandler(args2) {
|
|
470
|
+
if (args2.length < 2) {
|
|
471
|
+
console.error("Usage: phantom exec <garden-name> <command> [args...]");
|
|
472
|
+
exit5(1);
|
|
473
|
+
}
|
|
474
|
+
const gardenName = args2[0];
|
|
475
|
+
const command2 = args2.slice(1);
|
|
476
|
+
const result = await execInGarden(gardenName, command2);
|
|
477
|
+
if (!result.success) {
|
|
478
|
+
if (result.message) {
|
|
479
|
+
console.error(result.message);
|
|
480
|
+
}
|
|
481
|
+
exit5(result.exitCode ?? 1);
|
|
482
|
+
}
|
|
483
|
+
exit5(result.exitCode ?? 0);
|
|
484
|
+
}
|
|
485
|
+
|
|
474
486
|
// src/bin/phantom.ts
|
|
475
487
|
var commands = [
|
|
476
488
|
{
|
|
@@ -479,7 +491,7 @@ var commands = [
|
|
|
479
491
|
subcommands: [
|
|
480
492
|
{
|
|
481
493
|
name: "create",
|
|
482
|
-
description: "Create a new worktree (garden)",
|
|
494
|
+
description: "Create a new worktree (garden) [--shell to open shell]",
|
|
483
495
|
handler: gardensCreateHandler
|
|
484
496
|
},
|
|
485
497
|
{
|
package/dist/phantom.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/bin/phantom.ts", "../src/commands/
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { execHandler } from \"../commands/exec.ts\";\nimport { shellHandler } from \"../commands/shell.ts\";\nimport { gardensCreateHandler } from \"../gardens/commands/create.ts\";\nimport { gardensDeleteHandler } from \"../gardens/commands/delete.ts\";\nimport { gardensListHandler } from \"../gardens/commands/list.ts\";\nimport { gardensWhereHandler } from \"../gardens/commands/where.ts\";\n\ninterface Command {\n name: string;\n description: string;\n subcommands?: Command[];\n handler?: (args: string[]) => void | Promise<void>;\n}\n\nconst commands: Command[] = [\n {\n name: \"garden\",\n description: \"Manage git worktrees (gardens)\",\n subcommands: [\n {\n name: \"create\",\n description: \"Create a new worktree (garden)\",\n handler: gardensCreateHandler,\n },\n {\n name: \"list\",\n description: \"List all gardens\",\n handler: gardensListHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific garden\",\n handler: gardensWhereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a garden (use --force for dirty gardens)\",\n handler: gardensDeleteHandler,\n },\n ],\n },\n {\n name: \"exec\",\n description: \"Execute a command in a garden directory\",\n handler: execHandler,\n },\n {\n name: \"shell\",\n description: \"Open interactive shell in a garden directory\",\n handler: shellHandler,\n },\n];\n\nfunction printHelp(commands: Command[], prefix = \"\") {\n console.log(\"Usage: phantom <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${prefix}${cmd.name.padEnd(20)} ${cmd.description}`);\n if (cmd.subcommands) {\n for (const subcmd of cmd.subcommands) {\n console.log(` ${subcmd.name.padEnd(18)} ${subcmd.description}`);\n }\n }\n }\n}\n\nfunction findCommand(\n args: string[],\n commands: Command[],\n): { command: Command | null; remainingArgs: string[] } {\n if (args.length === 0) {\n return { command: null, remainingArgs: [] };\n }\n\n const [cmdName, ...rest] = args;\n const command = commands.find((cmd) => cmd.name === cmdName);\n\n if (!command) {\n return { command: null, remainingArgs: args };\n }\n\n if (command.subcommands && rest.length > 0) {\n const { command: subcommand, remainingArgs } = findCommand(\n rest,\n command.subcommands,\n );\n if (subcommand) {\n return { command: subcommand, remainingArgs };\n }\n }\n\n return { command, remainingArgs: rest };\n}\n\nconst args = argv.slice(2);\n\nif (args.length === 0 || args[0] === \"-h\" || args[0] === \"--help\") {\n printHelp(commands);\n exit(0);\n}\n\nconst { command, remainingArgs } = findCommand(args, commands);\n\nif (!command || !command.handler) {\n console.error(`Error: Unknown command '${args.join(\" \")}'\\n`);\n printHelp(commands);\n exit(1);\n}\n\ntry {\n await command.handler(remainingArgs);\n} catch (error) {\n console.error(\n \"Error:\",\n error instanceof Error ? error.message : String(error),\n );\n exit(1);\n}\n", "import { spawn } from \"node:child_process\";\nimport { exit } from \"node:process\";\nimport { whereGarden } from \"../gardens/commands/where.ts\";\n\nexport async function execInGarden(\n gardenName: string,\n command: string[],\n): Promise<{\n success: boolean;\n message?: string;\n exitCode?: number;\n}> {\n if (!gardenName) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n if (!command || command.length === 0) {\n return { success: false, message: \"Error: command required\" };\n }\n\n // Validate garden exists and get its path\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n return { success: false, message: gardenResult.message };\n }\n\n const gardenPath = gardenResult.path as string;\n const [cmd, ...args] = command;\n\n return new Promise((resolve) => {\n const childProcess = spawn(cmd, args, {\n cwd: gardenPath,\n stdio: \"inherit\",\n });\n\n childProcess.on(\"error\", (error) => {\n resolve({\n success: false,\n message: `Error executing command: ${error.message}`,\n });\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve({\n success: false,\n message: `Command terminated by signal: ${signal}`,\n exitCode: 128 + (signal === \"SIGTERM\" ? 15 : 1),\n });\n } else {\n const exitCode = code ?? 0;\n resolve({\n success: exitCode === 0,\n exitCode,\n });\n }\n });\n });\n}\n\nexport async function execHandler(args: string[]): Promise<void> {\n if (args.length < 2) {\n console.error(\"Usage: phantom exec <garden-name> <command> [args...]\");\n exit(1);\n }\n\n const gardenName = args[0];\n const command = args.slice(1);\n\n const result = await execInGarden(gardenName, command);\n\n if (!result.success) {\n if (result.message) {\n console.error(result.message);\n }\n exit(result.exitCode ?? 1);\n }\n\n // For successful commands, exit with the same code as the child process\n exit(result.exitCode ?? 0);\n}\n", "import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function whereGarden(name: string): Promise<{\n success: boolean;\n message?: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n return {\n success: true,\n path: gardenPath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error locating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensWhereHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await whereGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.path);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await execAsync(\"git rev-parse --show-toplevel\");\n return stdout.trim();\n}\n", "import { spawn } from \"node:child_process\";\nimport { exit } from \"node:process\";\nimport { whereGarden } from \"../gardens/commands/where.ts\";\n\nexport async function shellInGarden(gardenName: string): Promise<{\n success: boolean;\n message?: string;\n exitCode?: number;\n}> {\n if (!gardenName) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n // Validate garden exists and get its path\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n return { success: false, message: gardenResult.message };\n }\n\n const gardenPath = gardenResult.path as string;\n // Use user's preferred shell or fallback to /bin/sh\n const shell = process.env.SHELL || \"/bin/sh\";\n\n return new Promise((resolve) => {\n const childProcess = spawn(shell, [], {\n cwd: gardenPath,\n stdio: \"inherit\",\n env: {\n ...process.env,\n // Add environment variable to indicate we're in a phantom garden\n PHANTOM_GARDEN: gardenName,\n PHANTOM_GARDEN_PATH: gardenPath,\n },\n });\n\n childProcess.on(\"error\", (error) => {\n resolve({\n success: false,\n message: `Error starting shell: ${error.message}`,\n });\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve({\n success: false,\n message: `Shell terminated by signal: ${signal}`,\n exitCode: 128 + (signal === \"SIGTERM\" ? 15 : 1),\n });\n } else {\n const exitCode = code ?? 0;\n resolve({\n success: exitCode === 0,\n exitCode,\n });\n }\n });\n });\n}\n\nexport async function shellHandler(args: string[]): Promise<void> {\n if (args.length < 1) {\n console.error(\"Usage: phantom shell <garden-name>\");\n exit(1);\n }\n\n const gardenName = args[0];\n\n // Get garden path for display\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n console.error(gardenResult.message);\n exit(1);\n }\n\n // Display entering message\n console.log(`Entering garden '${gardenName}' at ${gardenResult.path}`);\n console.log(\"Type 'exit' to return to your original directory\\n\");\n\n const result = await shellInGarden(gardenName);\n\n if (!result.success) {\n if (result.message) {\n console.error(result.message);\n }\n exit(result.exitCode ?? 1);\n }\n\n // Exit with the same code as the shell\n exit(result.exitCode ?? 0);\n}\n", "import { access, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { addWorktree } from \"../../git/libs/add-worktree.ts\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function createGarden(name: string): Promise<{\n success: boolean;\n message: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const worktreePath = join(gardensPath, name);\n\n try {\n await access(gardensPath);\n } catch {\n await mkdir(gardensPath, { recursive: true });\n }\n\n try {\n await access(worktreePath);\n return {\n success: false,\n message: `Error: garden '${name}' already exists`,\n };\n } catch {\n // Path doesn't exist, which is what we want\n }\n\n await addWorktree({\n path: worktreePath,\n branch: `phantom/gardens/${name}`,\n commitish: \"HEAD\",\n });\n\n return {\n success: true,\n message: `Created garden '${name}' at ${worktreePath}`,\n path: worktreePath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error creating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensCreateHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await createGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport interface AddWorktreeOptions {\n path: string;\n branch: string;\n commitish?: string;\n}\n\nexport async function addWorktree(options: AddWorktreeOptions): Promise<void> {\n const { path, branch, commitish = \"HEAD\" } = options;\n\n await execAsync(`git worktree add \"${path}\" -b \"${branch}\" ${commitish}`);\n}\n", "import { exec } from \"node:child_process\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport async function deleteGarden(\n name: string,\n options: { force?: boolean } = {},\n): Promise<{\n success: boolean;\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n const { force = false } = options;\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n // Check for uncommitted changes\n let hasUncommittedChanges = false;\n let changedFiles = 0;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n hasUncommittedChanges = true;\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume no changes\n hasUncommittedChanges = false;\n }\n\n // If garden has uncommitted changes and --force is not specified, refuse deletion\n if (hasUncommittedChanges && !force) {\n return {\n success: false,\n message: `Error: Garden '${name}' has uncommitted changes (${changedFiles} files). Use --force to delete anyway.`,\n hasUncommittedChanges: true,\n changedFiles,\n };\n }\n\n // Remove git worktree\n try {\n await execAsync(`git worktree remove \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch (error) {\n // If worktree remove fails, try force removal\n try {\n await execAsync(`git worktree remove --force \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch {\n return {\n success: false,\n message: `Error: Failed to remove worktree for garden '${name}'`,\n };\n }\n }\n\n // Delete associated branch\n const branchName = `phantom/gardens/${name}`;\n try {\n await execAsync(`git branch -D \"${branchName}\"`, {\n cwd: gitRoot,\n });\n } catch {\n // Branch might not exist or already deleted - this is not an error\n // We'll still report success for the worktree removal\n }\n\n let message = `Deleted garden '${name}' and its branch '${branchName}'`;\n if (hasUncommittedChanges) {\n message = `Warning: Garden '${name}' had uncommitted changes (${changedFiles} files)\\n${message}`;\n }\n\n return {\n success: true,\n message,\n hasUncommittedChanges,\n changedFiles: hasUncommittedChanges ? changedFiles : undefined,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error deleting garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensDeleteHandler(args: string[]): Promise<void> {\n // Parse arguments for --force flag\n const forceIndex = args.indexOf(\"--force\");\n const force = forceIndex !== -1;\n\n // Remove --force from args to get the garden name\n const filteredArgs = args.filter((arg) => arg !== \"--force\");\n const name = filteredArgs[0];\n\n const result = await deleteGarden(name, { force });\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { access, readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport interface GardenInfo {\n name: string;\n branch: string;\n status: \"clean\" | \"dirty\";\n changedFiles?: number;\n}\n\nexport async function listGardens(): Promise<{\n success: boolean;\n message?: string;\n gardens?: GardenInfo[];\n}> {\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n\n // Check if gardens directory exists\n try {\n await access(gardensPath);\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (gardens directory doesn't exist)\",\n };\n }\n\n // Read gardens directory\n let gardenNames: string[];\n try {\n const entries = await readdir(gardensPath);\n // Filter entries to only include directories\n const validEntries = await Promise.all(\n entries.map(async (entry) => {\n try {\n const entryPath = join(gardensPath, entry);\n await access(entryPath);\n return entry;\n } catch {\n return null;\n }\n }),\n );\n gardenNames = validEntries.filter(\n (entry): entry is string => entry !== null,\n );\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (unable to read gardens directory)\",\n };\n }\n\n if (gardenNames.length === 0) {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found\",\n };\n }\n\n // Get detailed information for each garden\n const gardens: GardenInfo[] = await Promise.all(\n gardenNames.map(async (name) => {\n const gardenPath = join(gardensPath, name);\n\n // Get current branch\n let branch = \"unknown\";\n try {\n const { stdout } = await execAsync(\"git branch --show-current\", {\n cwd: gardenPath,\n });\n branch = stdout.trim() || \"detached HEAD\";\n } catch {\n branch = \"unknown\";\n }\n\n // Get working directory status\n let status: \"clean\" | \"dirty\" = \"clean\";\n let changedFiles: number | undefined;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n status = \"dirty\";\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume unknown status\n status = \"clean\";\n }\n\n return {\n name,\n branch,\n status,\n changedFiles,\n };\n }),\n );\n\n return {\n success: true,\n gardens,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error listing gardens: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensListHandler(): Promise<void> {\n const result = await listGardens();\n\n if (!result.success) {\n console.error(result.message);\n return;\n }\n\n if (!result.gardens || result.gardens.length === 0) {\n console.log(result.message || \"No gardens found\");\n return;\n }\n\n console.log(\"Gardens:\");\n for (const garden of result.gardens) {\n const statusText =\n garden.status === \"clean\"\n ? \"[clean]\"\n : `[dirty: ${garden.changedFiles} files]`;\n\n console.log(\n ` ${garden.name.padEnd(20)} (branch: ${garden.branch.padEnd(20)}) ${statusText}`,\n );\n }\n\n console.log(`\\nTotal: ${result.gardens.length} gardens`);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["exit", "
|
|
3
|
+
"sources": ["../src/bin/phantom.ts", "../src/gardens/commands/create.ts", "../src/git/libs/add-worktree.ts", "../src/git/libs/get-git-root.ts", "../src/phantom/command/shell.ts", "../src/gardens/commands/where.ts", "../src/gardens/commands/delete.ts", "../src/gardens/commands/list.ts", "../src/phantom/command/exec.ts"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport { argv, exit } from \"node:process\";\nimport { gardensCreateHandler } from \"../gardens/commands/create.ts\";\nimport { gardensDeleteHandler } from \"../gardens/commands/delete.ts\";\nimport { gardensListHandler } from \"../gardens/commands/list.ts\";\nimport { gardensWhereHandler } from \"../gardens/commands/where.ts\";\nimport { execHandler } from \"../phantom/command/exec.ts\";\nimport { shellHandler } from \"../phantom/command/shell.ts\";\n\ninterface Command {\n name: string;\n description: string;\n subcommands?: Command[];\n handler?: (args: string[]) => void | Promise<void>;\n}\n\nconst commands: Command[] = [\n {\n name: \"garden\",\n description: \"Manage git worktrees (gardens)\",\n subcommands: [\n {\n name: \"create\",\n description: \"Create a new worktree (garden) [--shell to open shell]\",\n handler: gardensCreateHandler,\n },\n {\n name: \"list\",\n description: \"List all gardens\",\n handler: gardensListHandler,\n },\n {\n name: \"where\",\n description: \"Output the path of a specific garden\",\n handler: gardensWhereHandler,\n },\n {\n name: \"delete\",\n description: \"Delete a garden (use --force for dirty gardens)\",\n handler: gardensDeleteHandler,\n },\n ],\n },\n {\n name: \"exec\",\n description: \"Execute a command in a garden directory\",\n handler: execHandler,\n },\n {\n name: \"shell\",\n description: \"Open interactive shell in a garden directory\",\n handler: shellHandler,\n },\n];\n\nfunction printHelp(commands: Command[], prefix = \"\") {\n console.log(\"Usage: phantom <command> [options]\\n\");\n console.log(\"Commands:\");\n for (const cmd of commands) {\n console.log(` ${prefix}${cmd.name.padEnd(20)} ${cmd.description}`);\n if (cmd.subcommands) {\n for (const subcmd of cmd.subcommands) {\n console.log(` ${subcmd.name.padEnd(18)} ${subcmd.description}`);\n }\n }\n }\n}\n\nfunction findCommand(\n args: string[],\n commands: Command[],\n): { command: Command | null; remainingArgs: string[] } {\n if (args.length === 0) {\n return { command: null, remainingArgs: [] };\n }\n\n const [cmdName, ...rest] = args;\n const command = commands.find((cmd) => cmd.name === cmdName);\n\n if (!command) {\n return { command: null, remainingArgs: args };\n }\n\n if (command.subcommands && rest.length > 0) {\n const { command: subcommand, remainingArgs } = findCommand(\n rest,\n command.subcommands,\n );\n if (subcommand) {\n return { command: subcommand, remainingArgs };\n }\n }\n\n return { command, remainingArgs: rest };\n}\n\nconst args = argv.slice(2);\n\nif (args.length === 0 || args[0] === \"-h\" || args[0] === \"--help\") {\n printHelp(commands);\n exit(0);\n}\n\nconst { command, remainingArgs } = findCommand(args, commands);\n\nif (!command || !command.handler) {\n console.error(`Error: Unknown command '${args.join(\" \")}'\\n`);\n printHelp(commands);\n exit(1);\n}\n\ntry {\n await command.handler(remainingArgs);\n} catch (error) {\n console.error(\n \"Error:\",\n error instanceof Error ? error.message : String(error),\n );\n exit(1);\n}\n", "import { access, mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { addWorktree } from \"../../git/libs/add-worktree.ts\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\nimport { shellInGarden } from \"../../phantom/command/shell.ts\";\n\nexport async function createGarden(name: string): Promise<{\n success: boolean;\n message: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const worktreePath = join(gardensPath, name);\n\n try {\n await access(gardensPath);\n } catch {\n await mkdir(gardensPath, { recursive: true });\n }\n\n try {\n await access(worktreePath);\n return {\n success: false,\n message: `Error: garden '${name}' already exists`,\n };\n } catch {\n // Path doesn't exist, which is what we want\n }\n\n await addWorktree({\n path: worktreePath,\n branch: name,\n commitish: \"HEAD\",\n });\n\n return {\n success: true,\n message: `Created garden '${name}' at ${worktreePath}`,\n path: worktreePath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error creating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensCreateHandler(args: string[]): Promise<void> {\n const name = args[0];\n const openShell = args.includes(\"--shell\");\n\n const result = await createGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n\n if (openShell && result.path) {\n console.log(`\\nEntering garden '${name}' at ${result.path}`);\n console.log(\"Type 'exit' to return to your original directory\\n\");\n\n const shellResult = await shellInGarden(name);\n\n if (!shellResult.success) {\n if (shellResult.message) {\n console.error(shellResult.message);\n }\n exit(shellResult.exitCode ?? 1);\n }\n\n exit(shellResult.exitCode ?? 0);\n }\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport interface AddWorktreeOptions {\n path: string;\n branch: string;\n commitish?: string;\n}\n\nexport async function addWorktree(options: AddWorktreeOptions): Promise<void> {\n const { path, branch, commitish = \"HEAD\" } = options;\n\n await execAsync(`git worktree add \"${path}\" -b \"${branch}\" ${commitish}`);\n}\n", "import { exec } from \"node:child_process\";\nimport { promisify } from \"node:util\";\n\nconst execAsync = promisify(exec);\n\nexport async function getGitRoot(): Promise<string> {\n const { stdout } = await execAsync(\"git rev-parse --show-toplevel\");\n return stdout.trim();\n}\n", "import { spawn } from \"node:child_process\";\nimport { exit } from \"node:process\";\nimport { whereGarden } from \"../../gardens/commands/where.ts\";\n\nexport async function shellInGarden(gardenName: string): Promise<{\n success: boolean;\n message?: string;\n exitCode?: number;\n}> {\n if (!gardenName) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n // Validate garden exists and get its path\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n return { success: false, message: gardenResult.message };\n }\n\n const gardenPath = gardenResult.path as string;\n // Use user's preferred shell or fallback to /bin/sh\n const shell = process.env.SHELL || \"/bin/sh\";\n\n return new Promise((resolve) => {\n const childProcess = spawn(shell, [], {\n cwd: gardenPath,\n stdio: \"inherit\",\n env: {\n ...process.env,\n // Add environment variable to indicate we're in a phantom garden\n PHANTOM_GARDEN: gardenName,\n PHANTOM_GARDEN_PATH: gardenPath,\n },\n });\n\n childProcess.on(\"error\", (error) => {\n resolve({\n success: false,\n message: `Error starting shell: ${error.message}`,\n });\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve({\n success: false,\n message: `Shell terminated by signal: ${signal}`,\n exitCode: 128 + (signal === \"SIGTERM\" ? 15 : 1),\n });\n } else {\n const exitCode = code ?? 0;\n resolve({\n success: exitCode === 0,\n exitCode,\n });\n }\n });\n });\n}\n\nexport async function shellHandler(args: string[]): Promise<void> {\n if (args.length < 1) {\n console.error(\"Usage: phantom shell <garden-name>\");\n exit(1);\n }\n\n const gardenName = args[0];\n\n // Get garden path for display\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n console.error(gardenResult.message);\n exit(1);\n }\n\n // Display entering message\n console.log(`Entering garden '${gardenName}' at ${gardenResult.path}`);\n console.log(\"Type 'exit' to return to your original directory\\n\");\n\n const result = await shellInGarden(gardenName);\n\n if (!result.success) {\n if (result.message) {\n console.error(result.message);\n }\n exit(result.exitCode ?? 1);\n }\n\n // Exit with the same code as the shell\n exit(result.exitCode ?? 0);\n}\n", "import { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nexport async function whereGarden(name: string): Promise<{\n success: boolean;\n message?: string;\n path?: string;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n return {\n success: true,\n path: gardenPath,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error locating garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensWhereHandler(args: string[]): Promise<void> {\n const name = args[0];\n const result = await whereGarden(name);\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.path);\n}\n", "import { exec } from \"node:child_process\";\nimport { access } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { exit } from \"node:process\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport async function deleteGarden(\n name: string,\n options: { force?: boolean } = {},\n): Promise<{\n success: boolean;\n message: string;\n hasUncommittedChanges?: boolean;\n changedFiles?: number;\n}> {\n if (!name) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n const { force = false } = options;\n\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n const gardenPath = join(gardensPath, name);\n\n // Check if garden exists\n try {\n await access(gardenPath);\n } catch {\n return {\n success: false,\n message: `Error: Garden '${name}' does not exist`,\n };\n }\n\n // Check for uncommitted changes\n let hasUncommittedChanges = false;\n let changedFiles = 0;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n hasUncommittedChanges = true;\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume no changes\n hasUncommittedChanges = false;\n }\n\n // If garden has uncommitted changes and --force is not specified, refuse deletion\n if (hasUncommittedChanges && !force) {\n return {\n success: false,\n message: `Error: Garden '${name}' has uncommitted changes (${changedFiles} files). Use --force to delete anyway.`,\n hasUncommittedChanges: true,\n changedFiles,\n };\n }\n\n // Remove git worktree\n try {\n await execAsync(`git worktree remove \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch (error) {\n // If worktree remove fails, try force removal\n try {\n await execAsync(`git worktree remove --force \"${gardenPath}\"`, {\n cwd: gitRoot,\n });\n } catch {\n return {\n success: false,\n message: `Error: Failed to remove worktree for garden '${name}'`,\n };\n }\n }\n\n // Delete associated branch\n const branchName = `phantom/gardens/${name}`;\n try {\n await execAsync(`git branch -D \"${branchName}\"`, {\n cwd: gitRoot,\n });\n } catch {\n // Branch might not exist or already deleted - this is not an error\n // We'll still report success for the worktree removal\n }\n\n let message = `Deleted garden '${name}' and its branch '${branchName}'`;\n if (hasUncommittedChanges) {\n message = `Warning: Garden '${name}' had uncommitted changes (${changedFiles} files)\\n${message}`;\n }\n\n return {\n success: true,\n message,\n hasUncommittedChanges,\n changedFiles: hasUncommittedChanges ? changedFiles : undefined,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error deleting garden: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensDeleteHandler(args: string[]): Promise<void> {\n // Parse arguments for --force flag\n const forceIndex = args.indexOf(\"--force\");\n const force = forceIndex !== -1;\n\n // Remove --force from args to get the garden name\n const filteredArgs = args.filter((arg) => arg !== \"--force\");\n const name = filteredArgs[0];\n\n const result = await deleteGarden(name, { force });\n\n if (!result.success) {\n console.error(result.message);\n exit(1);\n }\n\n console.log(result.message);\n}\n", "import { exec } from \"node:child_process\";\nimport { access, readdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\nimport { promisify } from \"node:util\";\nimport { getGitRoot } from \"../../git/libs/get-git-root.ts\";\n\nconst execAsync = promisify(exec);\n\nexport interface GardenInfo {\n name: string;\n branch: string;\n status: \"clean\" | \"dirty\";\n changedFiles?: number;\n}\n\nexport async function listGardens(): Promise<{\n success: boolean;\n message?: string;\n gardens?: GardenInfo[];\n}> {\n try {\n const gitRoot = await getGitRoot();\n const gardensPath = join(gitRoot, \".git\", \"phantom\", \"gardens\");\n\n // Check if gardens directory exists\n try {\n await access(gardensPath);\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (gardens directory doesn't exist)\",\n };\n }\n\n // Read gardens directory\n let gardenNames: string[];\n try {\n const entries = await readdir(gardensPath);\n // Filter entries to only include directories\n const validEntries = await Promise.all(\n entries.map(async (entry) => {\n try {\n const entryPath = join(gardensPath, entry);\n await access(entryPath);\n return entry;\n } catch {\n return null;\n }\n }),\n );\n gardenNames = validEntries.filter(\n (entry): entry is string => entry !== null,\n );\n } catch {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found (unable to read gardens directory)\",\n };\n }\n\n if (gardenNames.length === 0) {\n return {\n success: true,\n gardens: [],\n message: \"No gardens found\",\n };\n }\n\n // Get detailed information for each garden\n const gardens: GardenInfo[] = await Promise.all(\n gardenNames.map(async (name) => {\n const gardenPath = join(gardensPath, name);\n\n // Get current branch\n let branch = \"unknown\";\n try {\n const { stdout } = await execAsync(\"git branch --show-current\", {\n cwd: gardenPath,\n });\n branch = stdout.trim() || \"detached HEAD\";\n } catch {\n branch = \"unknown\";\n }\n\n // Get working directory status\n let status: \"clean\" | \"dirty\" = \"clean\";\n let changedFiles: number | undefined;\n try {\n const { stdout } = await execAsync(\"git status --porcelain\", {\n cwd: gardenPath,\n });\n const changes = stdout.trim();\n if (changes) {\n status = \"dirty\";\n changedFiles = changes.split(\"\\n\").length;\n }\n } catch {\n // If git status fails, assume unknown status\n status = \"clean\";\n }\n\n return {\n name,\n branch,\n status,\n changedFiles,\n };\n }),\n );\n\n return {\n success: true,\n gardens,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n message: `Error listing gardens: ${errorMessage}`,\n };\n }\n}\n\nexport async function gardensListHandler(): Promise<void> {\n const result = await listGardens();\n\n if (!result.success) {\n console.error(result.message);\n return;\n }\n\n if (!result.gardens || result.gardens.length === 0) {\n console.log(result.message || \"No gardens found\");\n return;\n }\n\n console.log(\"Gardens:\");\n for (const garden of result.gardens) {\n const statusText =\n garden.status === \"clean\"\n ? \"[clean]\"\n : `[dirty: ${garden.changedFiles} files]`;\n\n console.log(\n ` ${garden.name.padEnd(20)} (branch: ${garden.branch.padEnd(20)}) ${statusText}`,\n );\n }\n\n console.log(`\\nTotal: ${result.gardens.length} gardens`);\n}\n", "import { spawn } from \"node:child_process\";\nimport { exit } from \"node:process\";\nimport { whereGarden } from \"../../gardens/commands/where.ts\";\n\nexport async function execInGarden(\n gardenName: string,\n command: string[],\n): Promise<{\n success: boolean;\n message?: string;\n exitCode?: number;\n}> {\n if (!gardenName) {\n return { success: false, message: \"Error: garden name required\" };\n }\n\n if (!command || command.length === 0) {\n return { success: false, message: \"Error: command required\" };\n }\n\n // Validate garden exists and get its path\n const gardenResult = await whereGarden(gardenName);\n if (!gardenResult.success) {\n return { success: false, message: gardenResult.message };\n }\n\n const gardenPath = gardenResult.path as string;\n const [cmd, ...args] = command;\n\n return new Promise((resolve) => {\n const childProcess = spawn(cmd, args, {\n cwd: gardenPath,\n stdio: \"inherit\",\n });\n\n childProcess.on(\"error\", (error) => {\n resolve({\n success: false,\n message: `Error executing command: ${error.message}`,\n });\n });\n\n childProcess.on(\"exit\", (code, signal) => {\n if (signal) {\n resolve({\n success: false,\n message: `Command terminated by signal: ${signal}`,\n exitCode: 128 + (signal === \"SIGTERM\" ? 15 : 1),\n });\n } else {\n const exitCode = code ?? 0;\n resolve({\n success: exitCode === 0,\n exitCode,\n });\n }\n });\n });\n}\n\nexport async function execHandler(args: string[]): Promise<void> {\n if (args.length < 2) {\n console.error(\"Usage: phantom exec <garden-name> <command> [args...]\");\n exit(1);\n }\n\n const gardenName = args[0];\n const command = args.slice(1);\n\n const result = await execInGarden(gardenName, command);\n\n if (!result.success) {\n if (result.message) {\n console.error(result.message);\n }\n exit(result.exitCode ?? 1);\n }\n\n // For successful commands, exit with the same code as the child process\n exit(result.exitCode ?? 0);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["exit", "access", "join", "exit", "exec", "promisify", "execAsync", "exit", "args", "args", "exit", "join", "access", "args", "exit", "exec", "access", "join", "exit", "promisify", "execAsync", "promisify", "exec", "join", "access", "args", "exit", "exec", "access", "join", "promisify", "execAsync", "promisify", "exec", "join", "access", "spawn", "exit", "command", "args", "spawn", "exit", "commands", "args", "command", "remainingArgs", "exit"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aku11i/phantom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A CLI tool for managing Git worktrees (gardens) with enhanced functionality",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"git",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"garden": "./dist/garden.js"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22.0.0"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist/",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"garden": "node ./src/bin/garden.ts",
|
|
47
47
|
"build": "node build.ts",
|
|
48
48
|
"type-check": "tsc --noEmit",
|
|
49
|
-
"test": "node --test --experimental-test-module-mocks src/**/*.test.ts",
|
|
49
|
+
"test": "node --test --experimental-strip-types --experimental-test-module-mocks src/**/*.test.ts",
|
|
50
50
|
"lint": "biome check .",
|
|
51
51
|
"fix": "biome check --write .",
|
|
52
52
|
"ready": "pnpm fix && pnpm type-check && pnpm test",
|